| 11-12-2008, 08:48 PM | #1 |
I have a problem. At first, what does the spell do? It picks allied units around the target loc, sending out a missile to each unit starting with offset from caster's position, flying towards target. if it reaches the target, the target gets bonus damage, armor and LifeRegen. As you can see, i spread the missile and the Bonus-Part. The missile is created with the struct "Data" while the Bonus is added with the struct ApplyBonus. So here is the actual problem: If i want to target let's say 6 allied unit, there are 6 missiles flying to each of them, but when impacting the level debug message of the ApplyBuff struct is SHOWN but there is no Bonus damage, armor, lifeReg added and there is no EXECUTED Debug-Msg for those timers, which i think is pretty strange. Did i miss something? JASS:scope UTIF initializer init globals private constant integer spellid ='A001' private constant real distperinterval = 12. private constant real aoe = 250. private constant integer missileid = 'h004' private constant integer buffspellid = 'A002' private constant integer buffid = 'Basl' private ApplyBonus array applybonuz private constant integer armorperlvl = 2 private constant integer dmgperlvl = 5 private constant integer hpregenperlvl = 1 private boolexpr filter = null endglobals private function ApplyBonus_cb takes nothing returns nothing local timer t = GetExpiredTimer() local ApplyBonus a = GetTimerData(t) local integer id = GetUnitId(a.target) call BJDebugMsg("EXECUTED!") call a.destroy() endfunction struct ApplyBonus unit target timer t integer lvl boolean created static method Create takes unit target returns ApplyBonus local ApplyBonus a = ApplyBonus.allocate() set a.target = target set a.t = CreateTimer() call SetTimerData(a.t,a) set a.created = true set a.lvl = 0 return a endmethod method update takes integer lvl returns nothing call UnitAddBonus(.target,BONUS_DAMAGE,.lvl*-dmgperlvl) call UnitAddBonus(.target,BONUS_ARMOR,.lvl*-armorperlvl) call UnitAddBonus(.target,BONUS_LIFE_REGEN,.lvl*-hpregenperlvl) if lvl > .lvl then set .lvl = lvl endif // if GetUnitAbilityLevel(.target,buffspellid) == 0 then // call UnitAddAbility(.target,buffspellid) // endif if .target == null then call BJDebugMsg("TARGET IS NULL") endif call UnitAddBonus(.target,BONUS_DAMAGE,.lvl*dmgperlvl) call UnitAddBonus(.target,BONUS_ARMOR,.lvl*armorperlvl) call UnitAddBonus(.target,BONUS_LIFE_REGEN,.lvl*hpregenperlvl) call TimerStart(.t,5.,false,function ApplyBonus_cb) if .t == null then call BJDebugMsg("ROFLTARD") endif call BJDebugMsg(I2S(.lvl)) endmethod method onDestroy takes nothing returns nothing call UnitAddBonus(.target,BONUS_DAMAGE,.lvl*-dmgperlvl) call UnitAddBonus(.target,BONUS_ARMOR,.lvl*-armorperlvl) call UnitAddBonus(.target,BONUS_LIFE_REGEN,.lvl*-hpregenperlvl) call UnitRemoveAbility(.target,buffspellid) call UnitRemoveAbility(.target,buffid) call SetTimerData(.t,0) call DestroyTimer(.t) set .created = false set .target = null endmethod endstruct private struct Data unit target unit missile integer lvl integer int static method Create takes unit target,integer lvl, integer int returns Data local Data a = Data.allocate() set a.target = target set a.lvl = lvl set a.int = int return a endmethod method onDestroy takes nothing returns nothing call KillUnit(.missile) set .missile = null set .target = null endmethod endstruct private function callback takes nothing returns nothing local timer t = GetExpiredTimer() local Data a = GetTimerData(t) local real nx = 0 local real ny = 0 local real angle = 0 local integer id = 0 if DistanceBetweenXY(GetUnitX(a.missile),GetUnitY(a.missile),GetUnitX(a.target),GetUnitY(a.target)) >= 35 then set angle = Atan2(GetUnitY(a.target)-GetUnitY(a.missile),GetUnitX(a.target)-GetUnitX(a.missile)) set nx = GetUnitX(a.missile) + distperinterval * Cos(angle) set ny = GetUnitY(a.missile) + distperinterval * Sin(angle) call SetUnitX(a.missile,nx) call SetUnitY(a.missile,ny) else if a.target == null then call BJDebugMsg("IS BULLL ALSDASD") endif set id = GetUnitId(a.target) if applybonuz[id].created == false then set applybonuz[id] = applybonuz[id].Create(a.target) endif call applybonuz[id].update(a.lvl) call a.destroy() call SetTimerData(t,0) call DestroyTimer(t) endif endfunction private function EnchantUnitWithMissile takes unit target, integer lvl, integer int, real cx, real cy returns nothing local Data a = Data.Create(target,lvl,int) local timer t = CreateTimer() local real angle = Atan2(GetUnitY(target)-cy,GetUnitX(target)-cx) local real nx = cx + 65 * Cos(angle) local real ny = cy + 65 * Sin(angle) set a.missile = CreateUnit(GetOwningPlayer(target),missileid,nx,ny,angle*bj_RADTODEG) call SetTimerData(t,a) call TimerStart(t,0.03,true,function callback) endfunction private function Conds takes nothing returns boolean return GetSpellAbilityId() == spellid endfunction private function filterfunction takes nothing returns boolean return IsOrganicAlliedUnit(GetFilterUnit(),tempplayer) endfunction private function EnchantThem takes nothing returns nothing call EnchantUnitWithMissile(GetEnumUnit(),tempint,tempint2,tempreal,tempreal2) endfunction private function Actions takes nothing returns nothing local unit caster = GetTriggerUnit() local real cx = GetUnitX(caster) local real cy = GetUnitY(caster) local group g = CreateGroup() local location tp = GetSpellTargetLoc() set tempplayer = GetOwningPlayer(caster) set tempreal = cx set tempreal2 = cy set tempint = GetUnitAbilityLevel(caster,spellid) set tempint2 = GetHeroInt(caster,true) call GroupEnumUnitsInRange(g,GetLocationX(tp),GetLocationY(tp),aoe,filter) call ForGroup(g,function EnchantThem) call DestroyGroup(g) call RemoveLocation(tp) set g = null set tp = null set caster = null endfunction private function init takes nothing returns nothing local trigger t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(t,Condition(function Conds)) call TriggerAddAction(t,function Actions) set filter = Condition(function filterfunction) endfunction endscope |
| 11-12-2008, 09:33 PM | #2 |
* GetUnitid is PUI? If so, you should try using PUI_struct for that buff struct, I think that's where your problem is laying. * if you are using timerutils, better use NewTimer/ReleaseTimer instead of CreateTimer/DestroyTimer in the part that says "Executed" also add the unit's name and verify the timer is not null |
| 11-13-2008, 12:29 PM | #3 |
Could you try setting the .created boolean to 'false' initially? I don't know what uninitialized booleans return. If they don't return false your applyBuff struct would never be created. This could be checked with a debugMsg in the Create method displaying the used index or something like that. EDIT: One thing I just remembered, uninitialized variables could cause a threadkill so this might be a good explanation why the "EXECUTED" message won't be shown. |
