| 05-20-2009, 02:56 PM | #1 |
JASS:////! external ObjectMerger w3h BPSE STNB fnam "Custom Stun" ////! external ObjectMerger w3a AHtb STUN abuf 1 STNB alev 1 aher 1 ahdu 1 0 adur 1 0 Htb1 1 0 amat "" amcs 1 0 anam "Custom Stun" library CustomStun initializer Init uses AutoIndex globals private constant real INTERVAL = 0.03125 //Interval of the timer, thus, delta value private constant integer Dummy_Id = 'h003' //Dummy ID private constant integer Bolt_Id = 'STUN' //Storm bolt ID private constant integer Buff_Id = 'B005' //Stun buff ID private constant integer LOCUST = 'Aloc' private unit stunner = null endglobals struct stun real Stunned = 0. unit target real duration static timer Timer = CreateTimer() static stun array D static integer Count = 0 static method create takes unit target, real duration returns stun local stun d = stun.allocate() set d.target = target set d.duration = 0. set d.Stunned = duration if stun.Count == 0 then call TimerStart(stun.Timer,INTERVAL,true,function stun.Periodic) endif set stun.D[stun.Count] = d set stun.Count = stun.Count + 1 return d endmethod static method Periodic takes nothing returns nothing local stun this local integer i = 0 loop exitwhen i >= .Count set this = .D[i] if .duration >= .Stunned or GetWidgetLife(.target) < 0.405 then call .destroy() set .Count = .Count - 1 if .Count > 0 then set .D[i] = .D[.Count] set i = i - 1 else call PauseTimer(.Timer) endif endif set .duration = .duration + INTERVAL set i = i + 1 endloop endmethod private method onDestroy takes nothing returns nothing set .Stunned = 0 call UnitRemoveAbility(.target, Buff_Id) endmethod implement AutoData endstruct function IsStunned takes unit target returns boolean return stun[target] != 0 endfunction function StopStun takes unit target returns nothing call UnitRemoveAbility(target,Buff_Id) endfunction function StunUnit takes unit target, real duration returns nothing local stun d = stun[target] call SetUnitX(stunner,GetUnitX(target)) call SetUnitY(stunner,GetUnitY(target)) call IssueTargetOrder(stunner, "thunderbolt", target ) if d == 0 then set d = stun.create(target,duration) set stun[target] = d else set d = stun[target] set d.Stunned = duration set d.duration = 0. endif endfunction private function Init takes nothing returns nothing set stunner = CreateUnit(Player(12),Dummy_Id,0,0,0) call UnitAddAbility(stunner,Bolt_Id ) call UnitAddAbility(stunner,LOCUST) endfunction endlibrary JASS:scope TidalWave initializer Init globals private constant integer SPELL = 'A008' private constant integer STOMP = 'A009' private constant string EFFECT = "MDX\\TidalErruption.mdx" private boolexpr b endglobals private function Conditions takes nothing returns boolean return GetSpellAbilityId() == SPELL endfunction private function LineFilter takes nothing returns boolean return IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(GetTriggerUnit())) and GetWidgetLife(GetFilterUnit()) > 0.0451 endfunction private function Actions takes nothing returns nothing local unit caster = GetTriggerUnit() local location target = GetSpellTargetLoc() local unit dummy local group g = NewGroup() local group hitgroup = NewGroup() local integer i = 1 local integer effects = 4 local real dist = 600 local real divdist = dist/effects local real cx = GetUnitX(caster) local real cy = GetUnitY(caster) local real tx = GetLocationX(target) local real ty = GetLocationY(target) local real angle = Atan2(ty-cy,tx-cx) local real x local real y local unit u local integer c = 0 loop exitwhen i > effects call TriggerSleepAction(0.1) set x = GetUnitX(caster) + (divdist * i) * Cos(angle) set y = GetUnitY(caster) + (divdist * i) * Sin(angle) set dummy = CreateUnit(GetOwningPlayer(caster),DUMMY,x,y,GetUnitFacing(caster)) call SetUnitScale(dummy,2,2,2) call AddTimedEffectTarget(EFFECT,dummy,"origin",3) call UnitApplyTimedLife(dummy,'BTLF',3.5) call GroupEnumUnitsInRangeOfSegment(g,cx,cy,x,y,100,b) loop set u = FirstOfGroup(g) exitwhen u == null if not IsUnitInGroup(u,hitgroup) then call ThrowUnitToAir(u,28) call StunUnit(u,3) call GroupAddUnit(hitgroup,u) endif call GroupRemoveUnit(g,u) endloop set i = i + 1 set c = c + 150 endloop set u = null set caster = null set dummy = null call RemoveLocation(target) call ReleaseGroup(g) call ReleaseGroup(hitgroup) set target = null endfunction //=========================================================================== private function Init takes nothing returns nothing local trigger t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddAction( t, function Actions ) call TriggerAddCondition(t,Condition(function Conditions)) set b = Filter(function LineFilter) endfunction endscope Here when I use this spell 3 or 4 times stacking together, the stun buff never gets removed. I think it's not Multiple Unit Stackable? I have checked that the dummy unit casting the spell is not dead throughout the instances. Here's AutoData JASS:module AutoData private static thistype array data static method operator []= takes unit u, integer data returns nothing set .data[GetUnitId(u)] = data endmethod static method operator [] takes unit u returns integer return .data[GetUnitId(u)] endmethod endmodule |
| 05-20-2009, 03:57 PM | #2 |
I only wrote that AutoData thing in notepad in about 10 seconds to show you how easy it is to use unit indexing for attachment. If you actually look at what it does you should see that there is no way it can be "not working" unless AutoIndex is completely not working. I would say first update AutoIndex, if that doesn't help, the bug is probably somewhere in your system. Anyway I'm going to be posting my own stun system in a day or two so maybe you should focus your efforts on something else rather than debugging this thing. |
