| 02-14-2007, 05:50 PM | #1 |
Rain bird droppings onto unsuspecting enemies below! (Bombard will only work if the bird is moving.) I read through Vexorians very helpful tutorial on structs and decided to try them out. I previously used gamecache and handle variables on the bombard ability for my war pidgeon. Using structs and a single timer was far less complex. I'm still new to Jass so I'd appreciate it any of you could look through my functions for improvements or to point out leaks. Edit: here's the code JASS:globals timer PigDrop_Timer = CreateTimer() timer PigBomb_Timer = CreateTimer() PigsActiveData array PigsActive_Ar unit array PigBombs_Ar integer PigsActive_Total = 0 integer PigBombs_Total = 0 endglobals struct PigsActiveData unit u real x real y endstruct constant function PigUnit takes nothing returns integer return 'n000' //pig unit endfunction constant function PigBombUnit takes nothing returns integer return 'h000' //bomb unit endfunction constant function BombAbility takes nothing returns integer return 'A000' //bomb ability endfunction constant function BombBuff takes nothing returns integer return 'B000' //bomb ability buff endfunction constant function PigDamageModel takes nothing returns string return "Abilities\\Spells\\Other\\AcidBomb\\BottleImpact.mdl"//bomb explosion effect model path endfunction function PigDamage takes nothing returns real return 100. endfunction function BombAbilityFilter takes nothing returns boolean return GetSpellAbilityId() == BombAbility() endfunction function CheckEnemyAndFlyingFilter takes nothing returns boolean return IsUnitEnemy(GetFilterUnit(), bj_groupEnumOwningPlayer) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING) endfunction function PigDoDamage takes unit u, location loc, real radius returns nothing local group g = CreateGroup() local boolexpr bool = Condition(function CheckEnemyAndFlyingFilter) local unit a set bj_groupEnumOwningPlayer = GetOwningPlayer(u) call GroupEnumUnitsInRangeOfLoc(g, loc, radius, bool) call DestroyBoolExpr(bool) loop set a = FirstOfGroup(g) exitwhen a == null call GroupRemoveUnit(g,a) call UnitDamageTarget(u, a, PigDamage(), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null) endloop call RemoveUnit(u) set a = null call DestroyGroup(g) set g = null call DestroyBoolExpr(bool) set bool = null endfunction function PigBomb_Timer_Callback takes nothing returns nothing local unit u local real z local location loc local integer i =0 loop set u = PigBombs_Ar[i] exitwhen i == PigBombs_Total set loc = GetUnitLoc(u) set z = GetUnitFlyHeight(u) if z <= 15 then call PigDoDamage(u, loc, 60) set PigBombs_Ar[i] = PigBombs_Ar[PigBombs_Total-1] set PigBombs_Total = PigBombs_Total - 1 set i = i -1 call DestroyEffect(AddSpecialEffectLoc(PigDamageModel(), loc)) else call SetUnitFlyHeight(u, (z - 13), 10000) endif set i = i + 1 endloop if PigBombs_Total == 0 then call PauseTimer(PigBomb_Timer) endif set u = null set loc = null endfunction function PigDrop_Timer_Callback takes nothing returns nothing local unit u local unit bomb local PigsActiveData dat local real x local real y local real d local integer i=0 loop exitwhen i == PigsActive_Total set dat = PigsActive_Ar[i] set u = dat.u if GetUnitAbilityLevel(u, BombBuff()) > 0 then set x = GetUnitX(u) set y = GetUnitY(u) set d = SquareRoot((x - dat.x)*(x - dat.x)+(y-dat.y)*(y-dat.y)) set dat.y = y set dat.x = x if d > 2 then set bomb = CreateUnit(GetOwningPlayer(u), PigBombUnit(), x, y, GetUnitFacing(u)) call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) - 10) if PigBombs_Total == 0 then call TimerStart(PigBomb_Timer, .04, TRUE, function PigBomb_Timer_Callback) endif set PigBombs_Ar[PigBombs_Total] = bomb set PigBombs_Total = PigBombs_Total + 1 endif else set PigsActive_Ar[i] = PigsActive_Ar[PigsActive_Total-1] set PigsActive_Total = PigsActive_Total - 1 call dat.destroy() set i = i - 1 endif set i = i + 1 endloop if PigsActive_Total == 0 then call PauseTimer(PigDrop_Timer) endif set u = null set bomb = null endfunction function AddPigsToActiveGroup takes nothing returns nothing local unit u = GetTriggerUnit() local PigsActiveData dat = PigsActiveData.create() set dat.u = u set dat.x = GetUnitX(u) set dat.y = GetUnitY(u) if PigsActive_Total == 0 then call TimerStart(PigDrop_Timer, .15, TRUE, function PigDrop_Timer_Callback) endif set PigsActive_Ar[ PigsActive_Total] = dat set PigsActive_Total = PigsActive_Total +1 set u = null endfunction function InitTrig_Pig takes nothing returns nothing local trigger t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST) call TriggerAddCondition(t, Condition(function BombAbilityFilter)) call TriggerAddAction(t, function AddPigsToActiveGroup) set t = null endfunction |
| 02-14-2007, 10:13 PM | #2 |
Post the code and not the map please. Half of us don't have WC3 installed on the computers we check the forums on. |
| 02-15-2007, 12:47 AM | #3 |
I added the code to the first post. When the bombard ability is activated and the casting unit is moving, it drops bombs which damage any enemy ground unit they land near. |
