Faust
You can change this now in User CP.
- Reaction score
- 123
Hey. I'm creating a small, damage over time system for a race in my map.
Using PUI and ABC.
I'm trying to test it with an archer, that has Poison Arrows -like ability (so I can check for buff).
When I damage a unit with an attack, it should create a struct for it, if the struct already exists, modify some of its components (lastAttacker and FlameLevel).
The problem is, it always creates a new struct, so instead of having a value of the struct increase on each attack, it just has multiple struct instances with unchanged variable values.
This is the struct with the methods:
This is the trigger for using the ability (ignore the item conditions and actions, not relevant):
So, what should I do?
Using PUI and ABC.
I'm trying to test it with an archer, that has Poison Arrows -like ability (so I can check for buff).
When I damage a unit with an attack, it should create a struct for it, if the struct already exists, modify some of its components (lastAttacker and FlameLevel).
The problem is, it always creates a new struct, so instead of having a value of the struct increase on each attack, it just has multiple struct instances with unchanged variable values.
This is the struct with the methods:
JASS:
scope Burn// initializer I
struct Burn
//! runtextmacro PUI()
unit victim
unit lastAttacker
timer clock = CreateTimer()
real FlameLevel = 0
effect array FlameEffect [2]
method DestroyEffects takes nothing returns nothing
call DestroyEffect(.FlameEffect[0])
call DestroyEffect(.FlameEffect[1])
endmethod
method CalculateEffect takes unit u, real r returns nothing
local integer i = 0
call .DestroyEffects()
if r >= 66 then
set .FlameEffect[0] = CreateEffectOnUnit("Environment\\LargeBuildingFire\\LargeBuildingFire1.mdl", u, "origin")
set .FlameEffect[1] = CreateEffectOnUnit("Environment\\LargeBuildingFire\\LargeBuildingFire1.mdl", u, "chest")
elseif r >= 33 and r < 66 then
set .FlameEffect[0] = CreateEffectOnUnit("Environment\\LargeBuildingFire\\LargeBuildingFire2.mdl", u, "origin")
set .FlameEffect[1] = CreateEffectOnUnit("Environment\\LargeBuildingFire\\LargeBuildingFire2.mdl", u, "chest")
elseif r < 33 then
set .FlameEffect[0] = CreateEffectOnUnit("Environment\\SmallBuildingFire\\SmallBuildingFire2.mdl", u, "origin")
set .FlameEffect[1] = CreateEffectOnUnit("Environment\\SmallBuildingFire\\SmallBuildingFire2.mdl", u, "chest")
endif
endmethod
method onDestroy takes nothing returns nothing
call PauseTimer(.clock)
call ClearTimerStructA(.clock)
call DestroyTimer(.clock)
call DestroyEffect(.FlameEffect[0])
call DestroyEffect(.FlameEffect[1])
endmethod
static method Burning takes nothing returns nothing
local Burn dat = GetTimerStructA(GetExpiredTimer())
local real r
if dat.FlameLevel > 100 then
set dat.FlameLevel = 100
endif
set r = dat.FlameLevel + ((dat.FlameLevel / 2000) * GetUnitState(dat.victim, UNIT_STATE_MAX_LIFE))
call DisableTrigger(GetTriggeringTrigger())
call DamageTarget(dat.lastAttacker, dat.victim, r, false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call EnableTrigger(GetTriggeringTrigger())
call BJDebugMsg("Flamelevel: " + R2S(dat.FlameLevel))
call dat.CalculateEffect(dat.victim, dat.FlameLevel)
if dat.FlameLevel < 1 or GetWidgetLife(dat.victim) < 1 or dat.victim == null then
call UnitRemoveAbility(dat.victim, 039;A02F039;)
call dat.release()
endif
if dat.FlameLevel < 33 then
set dat.FlameLevel = dat.FlameLevel - 5
endif
endmethod
static method create takes unit Victim, unit LastAttacker returns Burn
local Burn dat = Burn.allocate()
set dat.victim = Victim
set dat.lastAttacker = LastAttacker
call UnitAddAbility(Victim, 039;A02F039;)
set Burn[dat.victim] = dat
call SetTimerStructA(dat.clock, dat)
call TimerStart(dat.clock, 1, true, function Burn.Burning)
return dat
endmethod
endstruct
endscope
This is the trigger for using the ability (ignore the item conditions and actions, not relevant):
JASS:
scope FlamingArrows initializer I
private function C1 takes nothing returns boolean
return GetUnitAbilityLevel(GetTriggerUnit(), 039;B00S039;) > 0
endfunction
private function C2 takes nothing returns boolean
return GetItemTypeId(GetSoldItem()) == 039;I00B039;
endfunction
private function A2 takes nothing returns nothing
set TempItem = GetSoldItem()
call RemoveItemFromStock(GetSellingUnit(), 039;I00B039;)
call UnitRemoveItem(GetTriggerUnit(), TempItem)
call RemoveItem(TempItem)
call UnitAddAbility(GetSellingUnit(), 039;A02E039;)
endfunction
private function A1 takes nothing returns nothing
local Burn dat = GetTriggerUnit():Burn
call UnitRemoveAbility(GetTriggerUnit(), 039;B00S039;)
if dat == null then
set dat = Burn.create(GetTriggerUnit(), GetEventDamageSource())
endif
set dat.lastAttacker = GetEventDamageSource()
set dat.FlameLevel = dat.FlameLevel + GetUnitPointValue(dat.lastAttacker)
call dat.CalculateEffect(dat.victim, dat.FlameLevel)
endfunction
//===========================================================================
private function I takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitDamaged(t)
call TriggerAddCondition(t, Condition(function C1))
call TriggerAddAction(t, function A1)
set t = CreateTrigger()
call TriggerRegisterAnyUnitEvent(t, EVENT_PLAYER_UNIT_SELL_ITEM)
call TriggerAddCondition(t, Condition(function C2))
call TriggerAddAction(t, function A2)
endfunction
endscope
So, what should I do?