| 05-24-2009, 12:48 PM | #1 |
UPDATED the code and looks fine, what i need now is leak check that could possibly lag the game JASS:library ImpaleSystem needs GroupUtils, TimerUtils, AutoIndex //******************************************************************************************* //* //* Impale System //* v.A //* By: waaaks! //* //******************************************************************************************* //* INTRODUCTION //* Having issues with Warcraft III's Impale ability? Want to create abilities based on //* Impale but looks so wrong? Worry no more, Impale System will do the job for you. //* A System remaking the normal Warcraft III Impale System which is more flexible //* and user configurable. With the system you can fully imitate Impale without any //* Impale-based issues. The Impale ability is one of the most used abilities in //* Warcraft III, with the use of special effects with the ability, you can create //* spells like a line stun ability, but Impale cannot Impale units being Impaled or was //* stunned using Impale. //* //* PURPOSE //* To help users imitate Impale based abilities without the said issues. //* //* PROs //* -Create spells which imitates Impale without the issue. //* -Choose what ability to be casted on unit land. //* -Manage wave time. //* -Add a second wave special effect. //* -Very usefull on maps that require lots of spells based on Impale. //* -Removes channeling on Impale which makes the player wait until wave ends. //* //* CONs //* -There is no option to turn of unit tossing. //* -Units will be damaged half when effect starts and half damage on land. //* -Impale source will always be on the casting unit. globals private constant real FACT = 0.5 //Structure damage factor private constant real TICK2 = 0.025 //Timer per Tick private constant integer DUMMY_CASTER = 'e000' //Your Dummy Caster private constant integer FLY = 'Amrf' //The Fly Height Enabler ability private group DUMMY_GROUP = CreateGroup() //Do not touch private integer array FALL private integer array ONCE private boolean array DONE endglobals //******************************************************************************************* //* Please do not touch anything below this line //******************************************************************************************* private struct impaleToss unit cast unit targ real dmg integer dspell integer splvl integer sporder static method impToss takes nothing returns nothing local timer tim = GetExpiredTimer() local impaleToss it = GetTimerData(tim) local real height = GetUnitFlyHeight(it.targ) //***************************************************************************** //* the unit has reached the maximum height, make it fall (FALL[unit] = 1, and //* ONCE[unit] = 1 for conditional uses only) if height > 500.0 and ONCE[GetUnitId(it.targ)] == 0 then set FALL[GetUnitId(it.targ)] = 1 set ONCE[GetUnitId(it.targ)] = 1 endif //***************************************************************************** //* if unit is not falling then that means it is rising (DUH!), make unit rise if FALL[GetUnitId(it.targ)] == 0 then call SetUnitFlyHeight(it.targ,height+40.0,0.0) call SetUnitPathing(it.targ, false) call PauseUnit(it.targ,true) else //make unit fall call SetUnitFlyHeight(it.targ,height-55.0,0.0) call PauseUnit(it.targ,true) call SetUnitPathing(it.targ,false) endif //***************************************************************************** //* if unit is already near land, also ONCE[unit] is used to check if the unit //* is already damaged or not then do some stuffs if height <= 15 and ONCE[GetUnitId(it.targ)] == 1 then call ReleaseTimer(tim) call it.destroy() endif set tim = null endmethod private method onDestroy takes nothing returns nothing local unit dum call SetUnitFlyHeight(.targ,0.0,0.0) call UnitDamageTarget(.cast,.targ,0.5*.dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null) call PauseUnit(.targ,false) call SetUnitPathing(.targ,true) set dum = CreateUnit(GetOwningPlayer(.cast),DUMMY_CASTER,GetUnitX(.cast),GetUnitY(.cast),0.0) call UnitApplyTimedLife(dum,'BTLF',3.0) call UnitAddAbility(dum,'Aloc') call UnitAddAbility(dum,.dspell) call SetUnitAbilityLevel(dum,.dspell,.splvl) call IssueTargetOrderById(dum,.sporder,.targ) call UnitShareVision(.targ,GetOwningPlayer(.cast),false) set FALL[GetUnitId(.targ)] = 0 set ONCE[GetUnitId(.targ)] = 0 set DONE[GetUnitId(.targ)] = false set dum = null endmethod static method create takes unit ccg, unit tcg, real dmg, integer dspell, integer splvl, integer sporder returns impaleToss local impaleToss it = impaleToss.allocate() local timer tim = NewTimer() set it.cast = ccg set it.targ = tcg set it.dmg = dmg set it.dspell = dspell set it.splvl = splvl set it.sporder = sporder call UnitAddAbility(it.targ,FLY) call UnitRemoveAbility(it.targ,FLY) call PauseUnit(it.targ,true) call SetUnitPathing(it.targ,false) call TimerStart(tim,TICK2,true,function impaleToss.impToss) call SetTimerData(tim,it) set tim = null return it endmethod endstruct struct impaleSystem public real isRadius = 150.0 public real isOffset = 100.0 public real isDamage = 100.0 public string isSfxTarget = "Abilities\\Spells\\Undead\\Impale\\ImpaleHitTarget.mdl" public string isSfxPath1 = "Abilities\\Spells\\Undead\\Impale\\ImpaleMissTarget.mdl" public string isSfxPath2 = "" public boolean isAffectStructures = false public integer isAbilityId = 'A000' public integer isLevel = 1 public integer isOrder = OrderId("thunderbolt") unit isCaster = null player isOwningPlayer = Player(15) real isCasterX = 0.0 real isCasterY = 0.0 real isTargetX = 0.0 real isTargetY = 0.0 real isRange = 600.0 boolean isStacking = true unit dum real rx real ry static method ImpRun takes nothing returns nothing local impaleSystem this = GetTimerData(GetExpiredTimer()) local group g = NewGroup() local unit u local real x = GetUnitX(.dum) local real y = GetUnitY(.dum) local real a = Atan2(.ry-y,.rx-x) local real px = x + .isOffset * Cos(a) local real py = y + .isOffset * Sin(a) local real dx = .rx - x local real dy = .ry - y local real dis = SquareRoot(dx*dx+dy*dy) local impaleToss it call GroupEnumUnitsInRange(g,x,y,.isRadius,null) call SetUnitX(.dum,px) call SetUnitY(.dum,py) loop set u = FirstOfGroup(g) exitwhen u == null if .isAffectStructures then if IsUnitEnemy(u,.isOwningPlayer) and GetWidgetLife(u) > 0.405 and not IsUnitInGroup(u,DUMMY_GROUP) then if IsUnitType(u, UNIT_TYPE_STRUCTURE) then call UnitDamageTarget(.isCaster,u,.isDamage*0.5,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null) call DestroyEffect(AddSpecialEffect(.isSfxTarget, GetUnitX(u), GetUnitY(u))) endif if GetWidgetLife(u) > 0.405 and not IsUnitType(u,UNIT_TYPE_STRUCTURE) then if .isStacking == false then if DONE[GetUnitId(u)] == false then set DONE[GetUnitId(u)] = true set it = impaleToss.create(.isCaster,u,.isDamage,.isAbilityId,.isLevel,.isOrder) call UnitDamageTarget(.isCaster,u,.isDamage*0.5,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null) call DestroyEffect(AddSpecialEffect(.isSfxTarget, GetUnitX(u), GetUnitY(u))) call UnitShareVision(u,.isOwningPlayer,true) endif else set it = impaleToss.create(.isCaster,u,.isDamage,.isAbilityId,.isLevel,.isOrder) call UnitDamageTarget(.isCaster,u,.isDamage*0.5,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null) call DestroyEffect(AddSpecialEffect(.isSfxTarget, GetUnitX(u), GetUnitY(u))) call UnitShareVision(u,.isOwningPlayer,true) endif endif endif else if IsUnitEnemy(u,.isOwningPlayer) and GetWidgetLife(u) > 0.405 and not IsUnitType(u,UNIT_TYPE_STRUCTURE) and not IsUnitInGroup(u,DUMMY_GROUP) then if GetWidgetLife(u) > 0.405 then if .isStacking == false then if DONE[GetUnitId(u)] == false then set DONE[GetUnitId(u)] = true set it = impaleToss.create(.isCaster,u,.isDamage,.isAbilityId,.isLevel,.isOrder) call UnitDamageTarget(.isCaster,u,.isDamage*0.5,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null) call DestroyEffect(AddSpecialEffect(.isSfxTarget, GetUnitX(u), GetUnitY(u))) call UnitShareVision(u,.isOwningPlayer,true) endif else set it = impaleToss.create(.isCaster,u,.isDamage,.isAbilityId,.isLevel,.isOrder) call UnitDamageTarget(.isCaster,u,.isDamage*0.5,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null) call DestroyEffect(AddSpecialEffect(.isSfxTarget, GetUnitX(u), GetUnitY(u))) call UnitShareVision(u,.isOwningPlayer,true) endif endif endif endif call GroupAddUnit(DUMMY_GROUP,u) call GroupRemoveUnit(g,u) endloop call ReleaseGroup(g) if dis <= .isOffset then call ReleaseTimer(GetExpiredTimer()) call GroupClear(DUMMY_GROUP) call .destroy() else call DestroyEffect(AddSpecialEffect(.isSfxPath1,px,py)) call DestroyEffect(AddSpecialEffect(.isSfxPath2,px,py)) endif set u = null endmethod static method create takes unit cast, real tx, real ty, real range, real wavetime, boolean stacking returns impaleSystem local impaleSystem is = impaleSystem.allocate() local timer t = NewTimer() local location loc = GetUnitLoc(cast) local real a set is.isStacking = stacking set is.isCaster = cast set is.isOwningPlayer = GetOwningPlayer(cast) set is.isCasterX = GetLocationX(loc) set is.isCasterY = GetLocationY(loc) set is.isTargetX = tx set is.isTargetY = ty set is.isRange = range set a = Atan2(is.isTargetY-is.isCasterY,is.isTargetX-is.isCasterX) set is.dum = CreateUnit(is.isOwningPlayer,DUMMY_CASTER,is.isCasterX,is.isCasterY,0.0) call UnitAddAbility(is.dum,'Aloc') set is.rx = is.isCasterX + is.isRange * Cos(a) set is.ry = is.isCasterY + is.isRange * Sin(a) call TimerStart(t,wavetime,true,function impaleSystem.ImpRun) call SetTimerData(t,is) call RemoveLocation(loc) set loc = null set t = null return is endmethod private method onDestroy takes nothing returns nothing call KillUnit(.dum) set .dum = null endmethod endstruct endlibrary sample usage JASS:scope Impale initializer init private function con takes nothing returns boolean return GetSpellAbilityId() == 'A001' endfunction private function act takes nothing returns nothing local unit cast = GetTriggerUnit() local location loc = GetSpellTargetLoc() local real x = GetLocationX(loc) local real y = GetLocationY(loc) local impaleSystem is = impaleSystem.create(cast,x,y,700.0,0.08, true) call RemoveLocation(loc) set loc = null set cast = 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 act) call TriggerAddCondition(t,Condition(function con)) endfunction endscope |
| 05-24-2009, 07:51 PM | #2 |
Why don't you use a Jump System? And please replace PUI with AutoIndex. You could do this: On create: JASS:if Jumping[GetUnitId(u)] == true then return endif set Jumping[GetUnitId(u)] = true and if the jump ends: set Jumping[GetUnitId(u)] = false |
| 05-25-2009, 02:52 AM | #3 | |||
Quote:
Quote:
Quote:
thanks |
| 06-02-2009, 02:02 PM | #4 |
bump, updated the thread, now i need something like improving the code and some leak check that could possibly lag the game, especially the part when the unit starts jumping, i wanted to use some sort of smooth jumping for this, also i dont know how to initialize the off1 to something like 60 in autoindex (while pui has PUI_PROPERTY), so that i can decrement it, and then increment it when the unit starts falling (to add velocity), which will be useful for smooth jumping -now replaced PUI with autoindex |
