| 07-22-2007, 02:25 AM | #1 |
So I wanted a system that allowed me to easily slow units in an area around an attacked unit with triggers. It needs to be very resource efficient as it will probably be run a lot. I'm am not a WE guru and very new to jasshelper. Any leak spotting, optimization tips or total rewrite ideas are more than welcome I'll attach a test map, if someone helps me they might find it useful. JASS:library Runner globals private integer N = 1 private runner array RUNNERS private integer array TIMERINT private integer array UNITINT endglobals //***** System functions ***** private function H2I takes handle h returns integer return h return 0 endfunction private function SetTimerInt takes timer t, integer value returns nothing local integer i = H2I(t)-0x100000 set TIMERINT[i] = value endfunction private function GetTimerInt takes timer t returns integer local integer i = H2I(t)-0x100000 return TIMERINT[i] endfunction private function SetUnitInt takes unit u, integer value returns nothing local integer i = H2I(u)-0x100000 set UNITINT[i] = value endfunction private function GetUnitInt takes unit u returns integer local integer i = H2I(u)-0x100000 return UNITINT[i] endfunction //***** END System functions ***** //***** Runner ***** private function RunnerTakesDmg takes nothing returns nothing local unit u = GetTriggerUnit() local group g = GetUnitsInRangeOfLocMatching(200.00, GetUnitLoc(u), null) local unit pu local integer i = 0 loop exitwhen (IsUnitGroupEmptyBJ(g)) set pu = FirstOfGroup(g) set i = GetUnitInt(pu) if (i > 0) then if (pu == u) then call RUNNERS[i].slow(0.75, 1) else call RUNNERS[i].slow(0.35, 1) endif endif call GroupRemoveUnit(g, pu) endloop set u = null set g = null set pu = null endfunction private function RunnerSlowTimerExpires takes nothing returns nothing local timer t = GetExpiredTimer() local integer i = GetTimerInt(t) call RUNNERS[i].removeslow() endfunction struct runner static integer unitid = 'h000' private integer index = 0 private unit u private timer slowtimer = CreateTimer() private real slowfactor = 0 private real speedloss = 0 static method create takes player p, real ax, real ay, real face returns runner local runner r = runner.allocate() local integer i = N local trigger t1 = CreateTrigger() local trigger t2 = CreateTrigger() set N = N + 1 set r.index = i set r.u = CreateUnit(p, r.unitid, ax, ay, face) set RUNNERS[i] = r call SetUnitPathing( r.u, false ) call SetTimerInt(r.slowtimer, i) call SetUnitInt(r.u, i) //Takes dmg trigger call TriggerRegisterUnitEvent( t2, r.u, EVENT_UNIT_DAMAGED ) call TriggerAddAction(t2, function RunnerTakesDmg) return r endmethod method slow takes real factor, real dur returns nothing local real speedloss = 0 if (factor > this.slowfactor) then set speedloss = (GetUnitMoveSpeed(this.u) + speedloss)*factor // Add movespeed lost from last slow, remove movespeed lost from this call SetUnitMoveSpeed(this.u, GetUnitMoveSpeed(this.u) + this.speedloss - speedloss) set this.slowfactor = factor set this.speedloss = speedloss call PauseTimer(this.slowtimer) call TimerStart(this.slowtimer, dur, false, function RunnerSlowTimerExpires) //call BJDebugMsg("Better slow, slowing") elseif (factor == this.slowfactor) then call PauseTimer(this.slowtimer) call TimerStart(this.slowtimer, dur, false, function RunnerSlowTimerExpires) //call BJDebugMsg("Equal slow, reseting timer") else //call BJDebugMsg("Current slow is better, not slowing") endif endmethod method removeslow takes nothing returns nothing call SetUnitMoveSpeed(this.u, GetUnitMoveSpeed(this.u) + this.speedloss) set this.slowfactor = 0 set this.speedloss = 0 //call BJDebugMsg("Removed slow...") endmethod endstruct //***** END Runner ***** endlibrary |
| 07-22-2007, 03:46 AM | #2 |
#1: you dont need those "SetTimer/Unit/Ext int" functions. you need data system (gredit to grim001) http://wc3campaigns.net/pastebint.ph...3ffd04408ae7e1 #2: you dont null this timer local JASS:private function RunnerSlowTimerExpires takes nothing returns nothing local timer t = GetExpiredTimer() local integer i = GetTimerInt(t) call RUNNERS[i].removeslow() endfunction thats all i can see from a quick look-over. if you really are new to vJass and JASS in general, you code verry well. |
| 07-22-2007, 02:00 PM | #3 |
Wow that data system looks handy. From what I see it does about the same as mine do but better and is a lot easier to implement several times? I actually looked around for a prewritten system similar to that before writing what I did. New to vJass not really to Jass or programming in general though. |
| 07-22-2007, 06:20 PM | #4 |
in all truth, you shouldn't need to impliment it several times. at worst you have to create a wrapper struct for a single native type to attatch (as I2H() is the devil) example JASS:struct Unit unit u endstruct function def takes player p returns nothing local Unit u2 = GetData(p) local unit u = u2.u endfunction function abc takes unit u returns nothing local Unit u2 = Unit.create() set u2.u = u call SetData(Player(0), integer(u2)) call def(Player(0)) endfunction you could use a more generalized aproach, like attaching one type of struct to every unit. that one struct could hold all data units can have attatched to them. or, for making spells, have a struct like: JASS:struct SingleTargetAbility unit caster unit target integer spell_level endstruct |
