| 07-02-2006, 02:54 AM | #1 |
ok so this is an aura ability all units within a certain range take damage dependant on how far they move while they are in this range it works sporadically, sometimes it does, sometimes it just dosn't, can anyone think of a possibly better way to do this, or why it may work sometimes and not other times JASS:function Trig_Ring_of_Fire_Conditions takes nothing returns boolean return GetLearnedSkill() == 'A04I' endfunction function ROF_Effects takes nothing returns nothing local timer t = GetExpiredTimer() local string s = GetAttTable(t) local unit u = GetTableUnit(s,"u") local unit targ = GetTableUnit(s,"targ") local real x = GetTableReal(s,"x") local real y = GetTableReal(s,"y") local real dist = DistanceBetweenPointsXY(GetUnitX(targ),GetUnitY(targ),x,y) local real dam = dist*(.02+(.02*GetUnitAbilityLevel(u,'A04I'))) if dist>5 then call UnitDamageTarget(u,targ,dam,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null) //call TextTagUnit(R2S(dam),targ,255,255,255,255,.03,3) endif call SetTableReal(s,"x",GetUnitX(targ)) call SetTableReal(s,"y",GetUnitY(targ)) set u = null set targ = null endfunction function ROF_Filter takes nothing returns boolean local string s = GetAttTable(GetTriggeringTrigger()) return IsUnitEnemy(GetTriggerUnit(),GetOwningPlayer(GetTableUnit(s,"u")))==true and GetUnitState(GetTriggerUnit(),UNIT_STATE_LIFE)>0 endfunction function ROF_Child takes nothing returns nothing local trigger trig = GetTriggeringTrigger() local string strig = GetAttTable(trig) local unit u = GetTableUnit(strig,"u") local unit targ = GetTriggerUnit() local timer t = CreateTimer() local string s = GetAttTable(t) call SetTableObject(s,"u",u) call SetTableObject(s,"targ",targ) call SetTableReal(s,"x",GetUnitX(targ)) call SetTableReal(s,"y",GetUnitY(targ)) call TimerStart(t,.05,true,function ROF_Effects) loop exitwhen GetUnitState(targ,UNIT_STATE_LIFE)<=0 or DistanceBetweenPointsXY(GetUnitX(u),GetUnitY(u),GetUnitX(targ),GetUnitY(targ))>345. call TriggerSleepAction(.2) endloop call Clearst(s,t) set trig = null set u = null set targ = null endfunction function Trig_Ring_of_Fire_Actions takes nothing returns nothing local unit u = GetTriggerUnit() local trigger trig = CreateTrigger() local string s = GetAttTable(trig) if GetUnitAbilityLevel(u,'A04I')==1 then call TriggerRegisterUnitInRange( trig,u,350.,null) call TriggerAddCondition(trig,Condition(function ROF_Filter)) call TriggerAddAction(trig,function ROF_Child) call SetTableObject(s,"u",u) endif set u = null set trig = null endfunction //=========================================================================== function InitTrig_Ring_of_Fire takes nothing returns nothing set gg_trg_Ring_of_Fire = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Ring_of_Fire, EVENT_PLAYER_HERO_SKILL ) call TriggerAddCondition( gg_trg_Ring_of_Fire, Condition( function Trig_Ring_of_Fire_Conditions ) ) call TriggerAddAction( gg_trg_Ring_of_Fire, function Trig_Ring_of_Fire_Actions ) endfunction while I am at it, I tried to make this so that it only damages each unit once, but it still seems to damage units more then once, what gives? JASS:function Trig_Geyser_Conditions takes nothing returns boolean return GetSpellAbilityId() == 'A03R' endfunction function Geyser_Child takes nothing returns nothing local timer t = GetExpiredTimer() local string s = GetAttTable(t) local integer totdist = GetTableInt(s,"totdist") local integer lvl = GetTableInt(s,"lvl") local unit u = GetTableUnit(s,"u") local unit targ local real dist = GetTableReal(s,"dist") local real ang = GetTableReal(s,"ang") local real x = GetTableReal(s,"x") local real y = GetTableReal(s,"y") local real x1 local real y1 local group g = CreateGroup() local group damaged = CreateGroup() local player p = GetOwningPlayer(u) call GroupAddGroup(GetTableGroup(s,"damaged"),damaged) if totdist<=dist then set x1 = x + totdist * Cos(ang * bj_DEGTORAD) + GetRandomReal(-25, 25 ) set y1 = y + totdist * Sin(ang * bj_DEGTORAD) + GetRandomReal(-25, 25 ) call DestroyEffect(AddSpecialEffect("TidalErruption.mdx",x1,y1)) call GroupEnumUnitsInRange(g,x1,y1,120,null) loop set targ = FirstOfGroup(g) exitwhen targ == null if IsUnitEnemy(targ,p)==true and IsUnitInGroup(targ,damaged)==false then call UnitDamageTarget(u,targ,20+(lvl*70),false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null) set bj_lastCreatedUnit = CreateCaster(p,x1,y1,0,'A03T',lvl) call IssueTargetOrder(bj_lastCreatedUnit,"slow",targ) call GroupAddUnit(damaged,targ) endif call GroupRemoveUnit(g,targ) endloop call SetTableObject(s,"damaged",damaged) call SetTableInt(s,"totdist",totdist+110) else call Clearst(s,t) endif set u = null call DestroyGroup(g) call DestroyGroup(damaged) set g = null set damaged = null set p = null endfunction function Trig_Geyser_Actions takes nothing returns nothing local unit u = GetTriggerUnit() local location l = GetSpellTargetLoc() local integer lvl = GetUnitAbilityLevel(u,'A03R') local real x = GetLocationX(l) local real y = GetLocationY(l) local real x1 = GetUnitX(u) local real y1 = GetUnitY(u) local real ang = AngleBetweenPointsXY(x1,y1,x,y) local real dist = DistanceBetweenPointsXY(x1,y1,x,y) local timer t = CreateTimer() local string s = GetAttTable(t) call SetTableReal(s,"x",x1) call SetTableReal(s,"y",y1) call SetTableReal(s,"dist",dist) call SetTableReal(s,"ang",ang) call SetTableInt(s,"totdist",50) call SetTableInt(s,"lvl",lvl) call SetTableObject(s,"u",u) call SetTableObject(s,"damaged",CreateGroup()) call TimerStart(t,.1,true,function Geyser_Child) call RemoveLocation(l) set l = null set u = null endfunction //=========================================================================== function InitTrig_Geyser takes nothing returns nothing set gg_trg_Geyser = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Geyser, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_Geyser, Condition( function Trig_Geyser_Conditions ) ) call TriggerAddAction( gg_trg_Geyser, function Trig_Geyser_Actions ) endfunction |
| 07-02-2006, 03:02 AM | #2 |
Would it not be better to simply set register the trigger as periodic event? That way you would have to worry about units entering the range to cause it to fire. I'm not sure about the second part, but you could try creating a temporary group that contains all the units of the first group then just looping through those and removing them after dealing damage to them. |
| 07-02-2006, 04:43 PM | #3 |
i am a little confused as to ur first suggestion, and for your second, I thought that is what I did |
| 07-02-2006, 05:28 PM | #4 | ||
For the first part you have: Quote:
I that means that it will only run when an enemy unit comes within range of the unit u, so that might explain why sometimes it doesn't work. I assume you're trying to make a spell thats somewhat like an immolation variant. If you change TriggerRegisterUnitInRange to TriggerRegisterTimerEventPeriodic, you can just grab all the units within the radius and deal the appropriate damage to them, that way you wouldn't have to worry about this: Quote:
And you could simply have one function to call. For the second one, sorry, I misunderstood what you wanted to do, I think I see the issue now; instead of using: JASS:call SetTableObject(s,"damaged",damaged) use: JASS:call GroupAddGroup(damaged, GetTableObject(s,"damaged")) At the end you destroy the local damaged, but that happens to be the same group that GetTableObject(s, "damaged) will be pointing to, so when it runs again it will return null. Doing it like this keeps the group from being destroyed, the only thing is, you'll have to be sure to create a group if one doesn't exist, and get rid of the group when everything is done. |
