ToME: the Tales of Maj'Eyal

Everything about ToME
It is currently Wed May 27, 2020 9:29 pm

All times are UTC




Post new topic Reply to topic  [ 3 posts ] 
Author Message
PostPosted: Mon Jul 28, 2014 1:22 pm 
Offline
Uruivellas

Joined: Tue May 14, 2013 3:45 pm
Posts: 884
I have a spell that applies a damage shield to the player, Crimson Barrier. While the shield holds, they gain a number of bonuses. This was working fine, until a player noticed that if they used a shielding rune with a shorter duration while the spell was active, once the rune expired the game would lock up. This appears to be because damage shields have the 'self.damage_shield_absorb = nil' line when they expire, so despite there being another damage shield active, the value would be set to nil causing the UIset to freak out.
So I'm looking for advice on what would be the best way to fix it. Creating a brand new type of damage shield along the lines of Time Shield, which sounds like it'd be very difficult via addon? I'm leaning towards just preventing the use of other shielding while Crimson Barrier is active and visa versa, but I'm unsure how to best implement that. I've included the code for the timed effect below.

Code:
newEffect{
   name = "CRIMSON_BARRIER", image = "talents/crimson_barrier.png",
   desc = "Crimson Barrier",
   long_desc = function(self, eff) return ("The target is surrounded by a shield of blood, absorbing %d/%d damage, increasing healing factor by %d%% and draining %0.2f life from attackers."):format(self.damage_shield_absorb, eff.power, eff.heal, eff.dam) end,
   type = "magical",
   subtype = { arcane=true, shield=true },
   status = "beneficial",
   parameters = { power=100, healing=1, dam=1, empower=0 },
   on_gain = function(self, err) return "A bloody shield forms around #target#.", "+Shield" end,
   on_lose = function(self, err) return "The bloody shield around #target# crumbles.", "-Shield" end,
   on_aegis = function(self, eff, aegis)
      self.damage_shield_absorb = self.damage_shield_absorb + eff.power * aegis / 100
      if core.shader.active(4) then
         self:removeParticles(eff.particle)
         local bc = {0.4, 0.7, 1.0, 1.0}
         local ac = {0x21/255, 0x9f/255, 0xff/255, 1}
         if eff.color then
            bc = table.clone(eff.color) bc[4] = 1
            ac = table.clone(eff.color) ac[4] = 1
         end
         eff.particle = self:addParticles(Particles.new("shader_shield", 1, {size_factor=1.3, img="runicshield"}, {type="runicshield", shieldIntensity=0.14, ellipsoidalFactor=1.2, time_factor=5000, bubbleColor=bc, auraColor=ac}))
      end      
   end,
   damage_feedback = function(self, eff, src, value)
      if eff.particle and eff.particle._shader and eff.particle._shader.shad and src and src.x and src.y then
         local r = -rng.float(0.2, 0.4)
         local a = math.atan2(src.y - self.y, src.x - self.x)
         eff.particle._shader:setUniform("impact", {math.cos(a) * r, math.sin(a) * r})
         eff.particle._shader:setUniform("impact_tick", core.game.getTime())
      end
   end,
   activate = function(self, eff)
      if self:attr("shield_factor") then eff.power = eff.power * (100 + self:attr("shield_factor")) / 100 end
      if self:attr("shield_dur") then eff.dur = eff.dur + self:attr("shield_dur") end
      eff.tmpid = self:addTemporaryValue("damage_shield", eff.power)
      self.damage_shield_absorb = eff.power
      self.damage_shield_absorb_max = eff.power
      eff.healid = self:addTemporaryValue("healing_factor", eff.heal/100)
      eff.leechid = self:addTemporaryValue("on_melee_hit", {[DamageType.DEVOUR_LIFE]=eff.dam})
      if core.shader.active(4) then
         eff.particle = self:addParticles(Particles.new("shader_shield", 1, nil, {type="shield", shieldIntensity=0.2, color=eff.color or {0.4, 0.7, 1.0}}))
      else
         eff.particle = self:addParticles(Particles.new("damage_shield", 1))
      end
   end,
   deactivate = function(self, eff)
      self:removeParticles(eff.particle)
      self:removeTemporaryValue("damage_shield", eff.tmpid)
      self.damage_shield_absorb = nil
      self.damage_shield_absorb_max = nil
      self:removeTemporaryValue("healing_factor", eff.healid)
      self:removeTemporaryValue("on_melee_hit", eff.leechid)       
   end,
   on_timeout = function(self, eff)
      if eff.empower == 1 then
         self:project({type="ball", range=0, friendlyfire=false, radius=3}, self.x, self.y, function(px, py)
            local target = game.level.map(px, py, Map.ACTOR)
            if not target then return end
                  if self:reactionToward(target) < 0 then
                     DamageType:get(DamageType.DEVOUR_LIFE).projector(self, target.x, target.y, DamageType.DEVOUR_LIFE, eff.dam*2)
                  end
         end)
      end
   end,
}


Top
 Profile  
 
PostPosted: Mon Jul 28, 2014 1:39 pm 
Offline
Uruivellas

Joined: Wed Apr 30, 2008 5:55 pm
Posts: 708
I stuck my not-a-damage-shield in the Actor:takeHit hook instead of using the existing damage shield system. You could do something like that.

Simplified version of mine for reference:
Code:
-- Actor:takeHit
hook = function(self, data)
   local value = data.value
   local src = data.src
   local damtype = table.get(data, 'death_note', 'damtype')

   -- Jagged Body
   if value > 0 and self:knowTalent('T_JAGGED_BODY') then
      local blocked = math.min(self.jaggedbody, value)
      self.jaggedbody = self.jaggedbody - blocked
      value = value - blocked
      game:delayedLogDamage(
         src, self, 0, ('#SLATE#(%d absorbed)#LAST#'):format(blocked), false)
   end

   data.value = value
   return true
end
class:bindHook('Actor:takeHit', hook)

_________________
Addons: Arcane Blade Tweaks, Fallen Race, Monk Class, Weapons Pack
Currently working on Elementals. It's a big project, so any help would be appreciated. :)


Top
 Profile  
 
PostPosted: Wed Jul 30, 2014 12:02 pm 
Offline
Uruivellas

Joined: Tue May 14, 2013 3:45 pm
Posts: 884
Got it working, thanks.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group