First, anyone know if spoiler tags work on this forum? And if so, whats the tag, I tried [spoiler][/spoiler] but that didn't work. I'd like to edit this post not to spam this thread with long sections.
Continuing on: The effect reduction is very interesting. So the updateEffectDuration() gets called once in the SLOW effect definition and modifies the duration.
From ActorTemporaryEffects.lua
Code: Select all
--- Adjusts timed effect durations based on rank and other things
function _M:updateEffectDuration(dur, what)
-- Rank reduction: below elite = none; elite = 1, boss = 2, elite boss = 3
local rankmod = 0
if self.rank == 3 then rankmod = 25
elseif self.rank == 3.5 then rankmod = 40
elseif self.rank == 4 then rankmod = 45
elseif self.rank == 5 then rankmod = 75
end
if rankmod <= 0 then return dur end
print("Effect duration reduction <", dur)
if what == "stun" then
local p = self:combatPhysicalResist(), rankmod * (util.bound(self:combatPhysicalResist() * 3, 40, 115) / 100)
dur = dur - math.ceil(dur * (p) / 100)
elseif what == "pin" then
local p = self:combatPhysicalResist(), rankmod * (util.bound(self:combatPhysicalResist() * 3, 40, 115) / 100)
dur = dur - math.ceil(dur * (p) / 100)
elseif what == "disarm" then
local p = self:combatPhysicalResist(), rankmod * (util.bound(self:combatPhysicalResist() * 3, 40, 115) / 100)
dur = dur - math.ceil(dur * (p) / 100)
elseif what == "frozen" then
local p = self:combatSpellResist(), rankmod * (util.bound(self:combatSpellResist() * 3, 40, 115) / 100)
dur = dur - math.ceil(dur * (p) / 100)
elseif what == "blind" then
local p = self:combatMentalResist(), rankmod * (util.bound(self:combatMentalResist() * 3, 40, 115) / 100)
dur = dur - math.ceil(dur * (p) / 100)
elseif what == "silence" then
local p = self:combatMentalResist(), rankmod * (util.bound(self:combatMentalResist() * 3, 40, 115) / 100)
dur = dur - math.ceil(dur * (p) / 100)
elseif what == "slow" then
local p = self:combatPhysicalResist(), rankmod * (util.bound(self:combatPhysicalResist() * 3, 40, 115) / 100)
dur = dur - math.ceil(dur * (p) / 100)
elseif what == "confusion" then
local p = self:combatMentalResist(), rankmod * (util.bound(self:combatMentalResist() * 3, 40, 115) / 100)
dur = dur - math.ceil(dur * (p) / 100)
end
print("Effect duration reduction >", dur)
return dur
end
So as far as I can tell, if you have a physical save of 100, the duration gets set to 0. Assuming you are not playing on insane, at which point your rank 0-ness makes you lose out. I'm not sure why there is a separate calculation when setting p, since I believe only the 1st value (the save) gets applied to the variable.
Turns out the effect was in fact reduced to 2 rounds for Valen. Although the slow was apparently worse than I thought, -0.928. So I guess it was only supposed to be a loss of 1 or 2 turns (like an old style 1 or 2 turn stun).
Code: Select all
[LOG] Valen Sky triggers a trap (glyph of fatigue)!
[LOG] Valen Sky slows down.
addTmpVal table: 0A76E668 global_speed -0.928 :=: 1 4022 mult0
Effect duration reduction < 5
Effect duration reduction > 2
Anyways, even with a duration of 0, it will stick around until the next actTurn(), which in turn calls timedEffects(), since there's no checking on positive durations at the setting the effect up stage. So there's always some effect (for example in the case of stunned, it checks if you're stunned for talent cooldowns before removing effects). However, looking through Valen's death log, I noticed something - several characters acted many times after Valen hit the trap - up to 7. And had that particular one had 3 different talent infusions come off cooldown, on different turns. (See the code section at the end).
So this got me thinking, -- who calls actTurn() and thus removes the effect? The only place in the entire lua code that calls actTurn is act(). act() calls it in a loop to catch up (as far as I can tell).
From Actor.lua:
Code: Select all
-- We compute turns at "default" speed, and only fire some actions when chaning turn
local actturn = math.floor(game.turn / (game.zone.wilderness and 1000 or 10))
if not self.last_act_turn then self.last_act_turn = actturn - 1 end
for i = 1, actturn - self.last_act_turn do self:actTurn() end
self.last_act_turn = actturn
And act() only gets called when you have sufficient energy to act.
From GameEnergyBased.lua:
Code: Select all
local arr = self.entities
for i, e in pairs(arr) do
e = arr[i]
if e and e.act and e.energy then
if e.energy.value < self.energy_to_act then
e.energy.value = (e.energy.value or 0) + self.energy_per_tick * (e.energy.mod or 1) * (e.global_speed or 1)
end
if e.energy.value >= self.energy_to_act then
e.energy.used = false
e:act(self)
end
end
end
So this -0.928 slow was something akin to an 10-11 round old style stun, because it wouldn't be removed until Valen had sufficient energy to act. Actually worse, since he doesn't even get his natural health regen. Oddly enough, this also implies positive effects could be drawn out longer than they should in game turns with a low global speed.
Appendix 1:
I found the same Orc cryomancer (id# 39105) acted 7 times from when the trap hit, until Valen Sky died. With no other actions from Valen. I've included a list of its AI decisions here, which show it choices, as well as the various talents and infusions recharging.
Code: Select all
orc cryomancer 39105 dumb ai talents can use Attack T_ATTACK
dumb ai uses T_ATTACK
orc cryomancer 39105 dumb ai talents can use Attack T_ATTACK
dumb ai uses T_ATTACK
orc cryomancer 39105 dumb ai talents can use Attack T_ATTACK
orc cryomancer 39105 dumb ai talents can use Phase Door T_PHASE_DOOR
dumb ai uses T_ATTACK
orc cryomancer 39105 dumb ai talents can use Freeze T_FREEZE
orc cryomancer 39105 dumb ai talents can use Attack T_ATTACK
orc cryomancer 39105 dumb ai talents can use Phase Door T_PHASE_DOOR
dumb ai uses T_ATTACK
orc cryomancer 39105 dumb ai talents can use Freeze T_FREEZE
orc cryomancer 39105 dumb ai talents can use Attack T_ATTACK
orc cryomancer 39105 dumb ai talents can use Phase Door T_PHASE_DOOR
dumb ai uses T_FREEZE
orc cryomancer 39105 dumb ai talents can use Rune: Controlled Phase Door T_RUNE:_CONTROLLED_PHASE_DOOR_1
orc cryomancer 39105 dumb ai talents can use Attack T_ATTACK
orc cryomancer 39105 dumb ai talents can use Phase Door T_PHASE_DOOR
dumb ai uses T_RUNE:_CONTROLLED_PHASE_DOOR_1
orc cryomancer 39105 dumb ai talents can use Phase Door T_PHASE_DOOR
dumb ai uses T_PHASE_DOOR
Edit: Removed duplicate code sections...