| 10-30-2008, 08:02 PM | #1 |
This spell is meant to create a link network amongst particular towers. There are two forms, attacking mode/link mode. When an attacker attacks, it searches for links in a certain radius and gets a damage bonus based on number found. The problem is that apparently it randomly stops firing. Once the glitch occurs I can't get the trigger to fire again. I could sell the towers and make new ones, and still the attacking ones will not draw from links. There is no apparent cause for why this happens, far as I know. I'd appreciate if you guys could take a look at the code, and be kind enough to point out any problems or optimizations. JASS:scope Prism //======================= globals private constant integer TOWERID_1 = 'n022' //This is the id of the actual Prism Tower. (LINK MODE) private constant integer TOWERID_2 = 'n02C' //This is the id of the actual Prism Tower. (LINK MODE) //private constant integer PWRUPID = 'A046' //This is the id of the power up ability in the object editor. private constant real RANGE = 700.0 //This is the range of the tower - it will be used to determine how far the towers will look for support towers. private constant real DAMAGE1 = 3000.0 //This is how much damage a powering up tower does. private constant real DAMAGE2 = 15000.0 //This is how much damage a powering up tower does. private constant real BASE1 = 6000.0 //This is how much damage an attacking tower does normally. private constant real BASE2 = 30000.0 //This is how much damage an attacking tower does normally. //private constant real EXPONENT = 1.05 //This determines the factor that each tower adds to the damage of the shot. private constant real COOLDOWN = 0.33 //This is the cooldown of the Prism Tower's attack. //private constant string ORDERSTRING = "spiritlink" //This is the Order String of the effect ability. endglobals //======================= //======================= type UnitArray extends unit array[500] globals private unit CurrentTower = null private integer array TowerValues private UnitArray tempArray private group mainP = CreateGroup() private timer Tprism = CreateTimer() private integer Total = 0 private Prism_data array structArray //private real tempPower private integer tempCount endglobals //======================= //======================================================================================= //needed struct struct Prism_data UnitArray towers integer size method Start_Prism takes UnitArray chain, integer count returns nothing set .towers = chain set .size = count endmethod method onDestroy takes nothing returns nothing loop exitwhen .size < 0 //call UnitRemoveAbility(towerChain[i], PWRUPID) set TowerValues[GetUnitIndex(.towers[.size])] = TowerValues[GetUnitIndex(.towers[.size])] - 1 set .towers[.size] = null set .size = .size - 1 endloop endmethod endstruct //movement and effects function Prism_Go takes nothing returns nothing local integer i = 1 local Prism_data dat loop exitwhen i > Total set dat = structArray[i] call dat.destroy() set structArray[i] = structArray[Total] set Total = Total - 1 endloop if Total==0 then call PauseTimer(Tprism) endif //call Msg("Run",Player(0)) endfunction private function TowerFilter1 takes nothing returns boolean return GetOwningPlayer(GetFilterUnit()) == GetOwningPlayer(GetEventDamageSource()) and GetUnitTypeId(GetFilterUnit()) == TOWERID_1 and TowerValues[GetUnitIndex(GetFilterUnit())] < 3 and GetUnitCurrentOrder(GetFilterUnit()) == OrderId("none") and GetFilterUnit() != CurrentTower and GetWidgetLife(GetFilterUnit()) > 0.405 endfunction private function TowerFilter2 takes nothing returns boolean return GetOwningPlayer(GetFilterUnit()) == GetOwningPlayer(GetEventDamageSource()) and GetUnitTypeId(GetFilterUnit()) == TOWERID_2 and TowerValues[GetUnitIndex(GetFilterUnit())] < 3 and GetUnitCurrentOrder(GetFilterUnit()) == OrderId("none") and GetFilterUnit() != CurrentTower and GetWidgetLife(GetFilterUnit()) > 0.405 endfunction private function TowerForGroup takes nothing returns nothing // use our globals here //set tempPower = tempPower * EXPONENT set tempCount = tempCount + 1 set tempArray[tempCount] = GetEnumUnit() set TowerValues[GetUnitIndex(GetEnumUnit())] = TowerValues[GetUnitIndex(GetEnumUnit())] + 1 endfunction //starts the effects function Trig_Prism_Actions takes nothing returns nothing local real x local real y //local real power = EXPONENT local real speed local real bonus local real dam local real time local integer towerChainCount = 0 local integer i local unit attacker = GetEventDamageSource() local UnitArray towerChain = UnitArray.create() local Prism_data dat //Fire Up bonus damage if GetUnitAbilityLevel(attacker, 'B00A') > 0 then set bonus = 1.25 elseif GetUnitAbilityLevel(attacker, 'B00J') > 0 then set bonus = 1.5 elseif GetUnitAbilityLevel(attacker, 'B00K') > 0 then set bonus = 3.0 else set bonus = 1.0 endif //Spring Forward bonus speed if GetUnitAbilityLevel(attacker, 'B007') > 0 then set speed = 1.25 elseif GetUnitAbilityLevel(attacker, 'B00V') > 0 then set speed = 1.5 elseif GetUnitAbilityLevel(attacker, 'B00W') > 0 then set speed = 3.0 else set speed = 1.0 endif //Get available towers and add them to the array. set CurrentTower = attacker set TowerValues[GetUnitIndex(CurrentTower)] = TowerValues[GetUnitIndex(CurrentTower)] + 1 set towerChain[0] = CurrentTower set x = GetUnitX(CurrentTower) set y = GetUnitY(CurrentTower) call GroupClear(mainP) if GetUnitTypeId(attacker)==TOWER_GOLEM then call GroupEnumUnitsInRange(mainP, x, y, RANGE, Condition(function TowerFilter1)) elseif GetUnitTypeId(attacker)==TOWER_ABOMINATION then call GroupEnumUnitsInRange(mainP, x, y, RANGE, Condition(function TowerFilter2)) endif // Set out temp globals to their values before we call the ForGroup() set tempArray = towerChain //set tempPower = power set tempCount = towerChainCount // now we can use these globals in the forgroup call ForGroup(mainP,function TowerForGroup) // no we setback each local we will use with the global from the group set towerChainCount = tempCount set towerChain = tempArray // I don't think this is needed since the array reference never changes, only the values in it //set power = tempPower //Go through each tower, starting at the end, add the power up ability and order it to fire. set i = towerChainCount loop exitwhen i == 0 //call UnitAddAbility(towerChain[i], PWRUPID) //call IssueTargetOrder(towerChain[i], ORDERSTRING, towerChain[0]) call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\ManaFlare\\ManaFlareBoltImpact.mdl",attacker,"chest")) if GetUnitTypeId(attacker)==TOWER_GOLEM then call TextTagUnit("+" + I2S(R2I(DAMAGE1)),attacker,255,0,0,255,.01,1.) elseif GetUnitTypeId(attacker)==TOWER_ABOMINATION then call TextTagUnit("+" + I2S(R2I(DAMAGE2)),attacker,255,0,0,255,.01,1.) endif set i = i - 1 endloop //Add the power up damage, checking for additional towers and making sure the unit is not out of range. if GetUnitTypeId(attacker)==TOWER_GOLEM then set dam = BASE1 + (DAMAGE1 * towerChainCount) //* power elseif GetUnitTypeId(attacker)==TOWER_ABOMINATION then set dam = BASE2 + (DAMAGE2 * towerChainCount) //* power endif set dam = dam*bonus call UnitDamageTarget(attacker, GetTriggerUnit(), dam, false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL, null) call TextTagUnit(I2S(R2I(dam)),GetTriggerUnit(),255,0,0,200,.03,2.) set time = COOLDOWN/speed set dat = Prism_data.create() call dat.Start_Prism(towerChain,towerChainCount) set Total = Total + 1 set structArray[Total] = dat if Total==1 then call TimerStart(Tprism,time,false,function Prism_Go) endif set attacker = null endfunction endscope //==== Init Trigger Prism ==== function InitTrig_Prism takes nothing returns nothing call ORBEngine_RegisterOrb(TOWER_GOLEM, function Trig_Prism_Actions, "TOWER_GOLEM: Prism") call ORBEngine_RegisterOrb(TOWER_ABOMINATION, function Trig_Prism_Actions, "TOWER_ABOMINATION: Prism") endfunction |
| 10-31-2008, 06:19 AM | #2 |
This doesn't happen right away, but a few seconds after they start attacking for the first time. Also, after awhile the trigger stops working. See http://www.wc3campaigns.net/showthread.php?t=102785. |
