| 12-20-2009, 06:36 PM | #1 |
Based on a conglomeration of different "meathook" spells out there I put together a somewhat cleaner version from the gui versions. However, I am wondering if this will cause any problems in multiplayer. It uses the TimerUtils. JASS:library Hook needs TimerUtils private struct HookData unit array chains[200] unit caster unit victim real angle real distance real linkdistance real maxdistance real snatchrange integer chainlink integer playerid integer hookart endstruct private function HookFilter takes nothing returns boolean return GetUnitTypeId(GetFilterUnit()) == 'z000' // Hook will only "grab" this unit type endfunction private function HookGrab takes nothing returns nothing local timer t = GetExpiredTimer() local HookData d = HookData(GetTimerData(t)) local real PolarX = GetUnitX(d.caster) + d.distance * Cos(d.angle) local real PolarY = GetUnitY(d.caster) + d.distance * Sin(d.angle) call RemoveUnit(d.chains[d.chainlink]) set d.chains[d.chainlink] = null set d.chainlink = d.chainlink - 1 call SetUnitPosition(d.victim, PolarX, PolarY) if d.chainlink == 0 then call ReleaseTimer(t) call SetUnitMoveSpeed(d.caster, GetUnitDefaultMoveSpeed(d.caster)) else set d.distance = d.distance - d.linkdistance endif endfunction private function HookLaunch takes nothing returns nothing local timer t = GetExpiredTimer() local timer x local HookData d = HookData(GetTimerData(t)) local group grabselection = CreateGroup() local unit cast = d.caster local real PolarX = GetUnitX(cast) + d.distance * Cos(d.angle) local real PolarY = GetUnitY(cast) + d.distance * Sin(d.angle) local real count set d.chains[d.chainlink] = CreateUnit(Player(d.playerid), d.hookart, PolarX, PolarY, d.angle) call GroupEnumUnitsInRange(grabselection, PolarX, PolarY, d.snatchrange, Condition(function HookFilter)) set count = CountUnitsInGroup(grabselection) if count > 0 then set d.victim = GroupPickRandomUnit(grabselection) endif if count > 0 or d.distance >= d.maxdistance then call ReleaseTimer(t) set x = NewTimer() //call DisplayTimedTextToPlayer(Player(0), 0, 0, 5, "RETRACT!") call SetTimerData(x, integer(d)) call TimerStart(x, 0.035, true, function HookGrab) else set d.distance = d.distance + d.linkdistance set d.chainlink = d.chainlink + 1 endif call DestroyGroup(grabselection) set grabselection = null set cast = null endfunction // call Hook_Launch(caster, targetx, targety, distance, linkdistance, art) public function Launch takes unit cast, real x, real y, real distance, real linkdist, integer art, real speed, real grabsize returns nothing local timer t = NewTimer() local HookData d = HookData.create() set d.hookart = art set d.playerid = GetPlayerId(GetOwningPlayer(cast)) set d.caster = cast set d.angle = Atan2(y-GetUnitY(cast),x-GetUnitX(cast)) set d.maxdistance = distance set d.linkdistance = linkdist set d.distance = 0.25 set d.chainlink = 1 set d.snatchrange = grabsize call SetUnitFacing(cast, d.angle) call SetUnitMoveSpeed(d.caster, 0) call SetTimerData(t, integer(d)) call TimerStart(t, speed, true, function HookLaunch) set cast = null endfunction endlibrary I'm not too experienced with structs and the such, let alone playing with timers like these. Please advise. Any help appreciated. Thanks EDIT: Whoa I noticed the x timer is defined twice. Gotta fix. |
| 12-20-2009, 07:07 PM | #2 |
JASS:
set x = CreateTimer()
call SetTimerData(x, integer(d))
...
local timer t = CreateTimer()
Use NewTimer, CreateTimer+SetTimerData+ReleaseTimer should make this fail, or at least not use TimerUtils Timer Stack properly. Also, for all the people out here who not play dota, you might want to explain, what this spell should actually do. |
| 12-20-2009, 07:21 PM | #3 | |
Quote:
I'm confused on what you mean, can you elaborate? I want to get this to work without problems. It does work atm but I want to make sure I eliminate anything that might cause problems behind the scenes. As for what the spell should do, it should in effect launch what looks to be like a "chain" from the target and whatever unit the chain comes across (in this case a unittypeid 'z000', it will "grab" that unit and drag it back to point of origin. |
| 12-20-2009, 07:25 PM | #4 |
TimerUtils has the functions NewTimer() and ReleaseTimer() to replace CreateTimer() and DestroyTimer(). For the system to work correctly, do not use Create or Destroy Timer but always New/Release Timer. |
| 12-20-2009, 07:32 PM | #5 | |
Quote:
Did NOT know that, awesome! I got a lot of replacing to do then. |
