| 03-11-2009, 12:20 PM | #1 |
JASS:scope Warstomp initializer Init globals private constant integer SPELL = 'AOws' private constant real TIME = 0.03 private constant string EFFECT = "MDX\\KnockbackDust.mdx" private boolexpr b private constant real STARTSPEED = 1200 private constant real DECREMENT = 10 endglobals struct data real x real y group g unit caster integer i timer t real distance real fx real speed real decrement effect dust static method create takes nothing returns data local data d = data.allocate() set d.g = CreateGroup() set d.t = NewTimer() set d.caster = GetTriggerUnit() set d.x = GetUnitX(d.caster) set d.y = GetUnitY(d.caster) set d.i = GetUnitAbilityLevel(d.caster,SPELL) set d.speed = STARTSPEED set d.decrement = DECREMENT call GroupEnumUnitsInRange(d.g,d.x,d.y,100+50*d.i,b) return d endmethod method onDestroy takes nothing returns nothing call ReleaseTimer(.t) call DestroyEffect(.dust) endmethod endstruct private function DISTANCE takes integer level returns integer return level * 250 endfunction private function Conditions takes nothing returns boolean return GetSpellAbilityId() == SPELL endfunction private function Check takes nothing returns boolean return IsPlayerEnemy(GetOwningPlayer(GetTriggerUnit()), GetOwningPlayer(GetFilterUnit())) and GetWidgetLife(GetFilterUnit()) > 0.405 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING) endfunction private function Move takes nothing returns nothing local data d = data(GetTimerData(GetExpiredTimer())) local unit t = GetEnumUnit() local real ux = GetUnitX(t) local real uy = GetUnitY(t) local real angle = Atan2(uy-d.y,ux-d.x) local real cos = Cos(angle) local real sin = Sin(angle) set ux = ux + cos * TIME * d.speed set uy = uy + sin * TIME * d.speed call SetUnitPosition(t,ux,uy) call DestroyEffect(d.dust) set d.dust = AddSpecialEffectTarget(EFFECT,t,"origin") endfunction private function Loop takes nothing returns nothing local data d = data(GetTimerData(GetExpiredTimer())) set d.speed = d.speed - d.decrement set d.distance = d.distance - TIME * d.speed if d.distance <= 0 then call d.destroy() endif call ForGroup(d.g,function Move) endfunction private function Actions takes nothing returns nothing local data d = data.create() local unit caster = GetTriggerUnit() set d.distance = DISTANCE(GetUnitAbilityLevel(d.caster,SPELL)) call SetTimerData(d.t,integer(d)) call TimerStart(d.t,TIME,true,function Loop) set caster = null endfunction //=========================================================================== private function Init takes nothing returns nothing local trigger t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( t, Condition( function Conditions ) ) call TriggerAddAction( t, function Actions ) set b = Condition(function Check) endfunction endscope My problem right now is , the effect displays as though there is ... only a little dust effect and not a one straight line meaning it doesn't look complete and when the target has reached his destination , the effect still stays there forever. More information = reply thread. |
| 03-11-2009, 12:28 PM | #2 |
You know what... JASS:scope Warstomp initializer Init // You will notice that I have indented and organized your code. It is no different // than it was before, it just looks better. globals private constant integer SPELL = 'AOws' private constant string EFFECT = "MDX\\KnockbackDust.mdx" private boolexpr b private constant real TIME = 0.03 private constant real STARTSPEED = 1200 private constant real DECREMENT = 10 endglobals struct data unit caster group g effect dust timer t real x real y real fx real speed real decrement real distance integer i // you should really try to think of better naming conventions, it makes the spell code // a heck of a lot easier to follow static method create takes nothing returns data local data d = data.allocate() set d.g = CreateGroup() set d.t = NewTimer() set d.caster = GetTriggerUnit() set d.x = GetUnitX(d.caster) set d.y = GetUnitY(d.caster) set d.i = GetUnitAbilityLevel(d.caster,SPELL) set d.speed = STARTSPEED set d.decrement = DECREMENT call GroupEnumUnitsInRange(d.g,d.x,d.y,100+50*d.i,b) return d endmethod method onDestroy takes nothing returns nothing call ReleaseTimer(.t) call DestroyEffect(.dust) endmethod endstruct private function DISTANCE takes integer level returns integer return level * 250 endfunction private function Conditions takes nothing returns boolean return GetSpellAbilityId() == SPELL endfunction private function Check takes nothing returns boolean return IsPlayerEnemy(GetOwningPlayer(GetTriggerUnit()), GetOwningPlayer(GetFilterUnit())) and GetWidgetLife(GetFilterUnit()) > 0.405 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING) endfunction private function Move takes nothing returns nothing local data d = data(GetTimerData(GetExpiredTimer())) local unit t = GetEnumUnit() local real ux = GetUnitX(t) local real uy = GetUnitY(t) local real angle = Atan2(uy-d.y,ux-d.x) local real cos = Cos(angle) local real sin = Sin(angle) set ux = ux + cos * TIME * d.speed set uy = uy + sin * TIME * d.speed call SetUnitPosition(t,ux,uy) call DestroyEffect(d.dust) set d.dust = AddSpecialEffectTarget(EFFECT,t,"origin") endfunction private function Loop takes nothing returns nothing local data d = data(GetTimerData(GetExpiredTimer())) set d.speed = d.speed - d.decrement set d.distance = d.distance - TIME * d.speed if d.distance <= 0 then call d.destroy() endif call ForGroup(d.g,function Move) endfunction private function Actions takes nothing returns nothing local data d = data.create() local unit caster = GetTriggerUnit() set d.distance = DISTANCE(GetUnitAbilityLevel(d.caster,SPELL)) call SetTimerData(d.t,integer(d)) call TimerStart(d.t,TIME,true,function Loop) set caster = null endfunction //=========================================================================== private function Init takes nothing returns nothing local trigger t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( t, Condition( function Conditions ) ) call TriggerAddAction( t, function Actions ) set b = Condition(function Check) endfunction endscope Thank you baby jesus! Okay, what exactly are ya trying to do here? |
| 03-11-2009, 12:42 PM | #3 |
Er... well solution? And thanks! I was in a hurry to post this so.... pardon me. |
| 03-11-2009, 12:43 PM | #4 |
Is this supposed to be like an area of effect knock back spell? |
| 03-11-2009, 12:54 PM | #5 |
Yes, a warstomp which basically knocks unit away by a x distance. The effects are the problem , spell's fine. |
| 03-11-2009, 01:08 PM | #6 | ||
Quote:
You only have one single effect variable that handles an entire group's worth of special effects. I think what should happen here is the very last enumerated unit will always be given the effect (the others are destroyed almost immediately). Quote:
|
| 03-11-2009, 01:12 PM | #7 |
Why don't you use this?? |
| 03-11-2009, 01:18 PM | #8 |
moyack, you can't learn anything if you are only referenced to other systems. He is doing this for the sake of learning. |
| 03-11-2009, 01:40 PM | #9 | |
Quote:
So , what am I supposed to fix other then the forgroup which has been done. I took Dusk~ knockback system as a reference. Code's here JASS://*************************************************************************************************************** //* * //* K N O C K B A C K * //* Actual Code * //* v1.02 * //* * //* By: Rising_Dusk * //* * //*************************************************************************************************************** library Knockback initializer KnockbackSystemInit globals //********************************************************* //* These are the configuration constants for the system //* //* EffectLocation: Where on the unit the effect attaches //* EffectPath_Water: What special effect to attach over water //* EffectPath_Ground: What special effect to attach over ground //* Dest_Radius: Radius around which destructs die //* private constant string EffectLocation = "origin" private constant string EffectPath_Water = "MDX\\KnockbackWater.mdx" private constant string EffectPath_Ground = "MDX\\KnockbackDust.mdx" private constant real Dest_Radius = 180. //********************************************************* //* These are static constants used by the system and shouldn't be changed //* //* Timer: The timer that runs all of the effects for the spell //* Counter: The counter for how many KB instances exist //* Knockers: The array of all struct instances that exist //* TimerInterval: The interval for the timer that gets run //* Boolexpr: The boolean expression used for finding destructs //* DestRect: The rect used to check for destructables //* private timer Timer = CreateTimer() private integer Counter = 0 private integer array Knockers private constant real TimerInterval = 0.05 private boolexpr Boolexpr private rect DestRect = Rect(0,0,1,1) //* Temporary variables used by the system private real Temp1 private real Temp2 endglobals //********************************************************* //* Functions for the destructable destruction private function KillDests_Check takes nothing returns boolean local real x = GetDestructableX(GetFilterDestructable()) local real y = GetDestructableY(GetFilterDestructable()) return (Temp1-x)*(Temp1-x) + (Temp2-y)*(Temp2-y) <= Dest_Radius*Dest_Radius endfunction private function KillDests takes nothing returns nothing call KillDestructable(GetEnumDestructable()) endfunction //********************************************************* //* Struct for the system, I recommend leaving it alone private struct knocker unit Target effect KBEffect integer FXMode boolean KillDest real Decrement real Speed real SinA real CosA public method checkterrain takes knocker n returns integer local real x = GetUnitX(n.Target) local real y = GetUnitY(n.Target) if IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) then return 1 elseif not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) then return 2 endif return 0 endmethod static method create takes unit targ, real angle, real startspeed, real decrement, boolean killDestructables returns knocker local knocker n = knocker.allocate() set n.Target = targ set n.FXMode = n.checkterrain(n) if n.FXMode == 1 then set n.KBEffect = AddSpecialEffectTarget(EffectPath_Ground, n.Target, EffectLocation) elseif n.FXMode == 2 then set n.KBEffect = AddSpecialEffectTarget(EffectPath_Water, n.Target, EffectLocation) debug else debug call BJDebugMsg("System Error (On Create): Unknown Terrain Type") endif set n.KillDest = killDestructables set n.Decrement = decrement set n.Speed = startspeed set n.SinA = Sin(angle) set n.CosA = Cos(angle) return n endmethod private method onDestroy takes nothing returns nothing call DestroyEffect(this.KBEffect) endmethod endstruct //****************************************************************************** //* The system code itself. private function Update takes nothing returns nothing local unit u local rect r local knocker n = 0 local integer i = Counter - 1 local integer j = 0 local integer mode local real speed local real xi local real yi local real xf local real yf loop exitwhen i < 0 set n = Knockers[i] set u = n.Target set mode = n.FXMode set xi = GetUnitX(u) set yi = GetUnitY(u) if n.Speed <= 0 then call n.destroy() set Counter = Counter - 1 if Counter < 0 then call PauseTimer(Timer) set Counter = 0 else set Knockers[i] = Knockers[Counter] endif else set xf = xi + (n.Speed) * n.CosA set yf = yi + (n.Speed) * n.SinA call SetUnitPosition(u, xf, yf) set n.FXMode = n.checkterrain(n) if n.FXMode == 1 and mode == 2 then call DestroyEffect(n.KBEffect) set n.KBEffect = AddSpecialEffectTarget(EffectPath_Ground, n.Target, EffectLocation) elseif n.FXMode == 2 and mode == 1 then call DestroyEffect(n.KBEffect) set n.KBEffect = AddSpecialEffectTarget(EffectPath_Water, n.Target, EffectLocation) debug elseif n.FXMode == 0 then debug call BJDebugMsg("System Error (In Update): Unknown Terrain Type") endif set n.Speed = n.Speed - n.Decrement //* Destroy destructables if desired if n.KillDest then set Temp1 = GetUnitX(u) set Temp2 = GetUnitY(u) call SetRect(DestRect, xf-Dest_Radius, yf-Dest_Radius, xf+Dest_Radius, yf+Dest_Radius) call EnumDestructablesInRect(DestRect, Boolexpr, function KillDests) endif endif set i = i - 1 endloop set u = null endfunction function KnockbackStop takes unit targ returns boolean local integer i = Counter - 1 local knocker n = 0 local boolean b = false loop exitwhen i < 0 set n = Knockers[i] if n.Target == targ then call n.destroy(n) set Counter = Counter - 1 if Counter < 0 then call PauseTimer(Timer) set Counter = 0 else set Knockers[i] = Knockers[Counter] endif set b = true endif set i = i - 1 endloop return b endfunction function IsKnockedBack takes unit targ returns boolean local integer i = Counter - 1 local knocker n = 0 loop exitwhen i < 0 set n = Knockers[i] if n.Target == targ then return true endif set i = i - 1 endloop return false endfunction function KnockbackTarget takes unit targ, real angle, real startspeed, real decrement, boolean killDestructables returns boolean local knocker n = 0 //* Protect users from themselves if decrement == 0 or startspeed == 0 or targ == null then debug call BJDebugMsg("System Error: Invalid Starting Conditions") return false endif set n = knocker.create(targ, angle*0.01745328, startspeed*TimerInterval, decrement*TimerInterval, killDestructables) if Counter == 0 then call TimerStart(Timer, TimerInterval, true, function Update) endif set Knockers[Counter] = n set Counter = Counter + 1 return true endfunction private function KnockbackSystemInit takes nothing returns nothing set Boolexpr = Condition(function KillDests_Check) endfunction public function InitTrig takes nothing returns nothing endfunction endlibrary |
| 03-11-2009, 01:50 PM | #10 |
Notice how he has a struct that handles each individual unit that is being knocked back? |
| 03-11-2009, 02:32 PM | #11 |
Like how? What? I don't understand this whole thing .... He has a struct like I had which had almost all same identical variables and the only thing that was different was he looped using arrays instead of using TimerUtils. |
| 03-11-2009, 02:35 PM | #12 |
No, see. JASS:function KnockbackTarget takes unit targ, real angle, real startspeed, real decrement, boolean killDestructables returns boolean local knocker n = 0 //* Protect users from themselves if decrement == 0 or startspeed == 0 or targ == null then debug call BJDebugMsg("System Error: Invalid Starting Conditions") return false endif set n = knocker.create(targ, angle*0.01745328, startspeed*TimerInterval, decrement*TimerInterval, killDestructables) if Counter == 0 then call TimerStart(Timer, TimerInterval, true, function Update) endif set Knockers[Counter] = n set Counter = Counter + 1 return true endfunction He creates a struct for every unit that is being knocked back, you only create one that tries to handle all instances. |
| 03-11-2009, 02:39 PM | #13 | |
Quote:
@wraithseeker: You can use my library and just start the effect, it will take care of stopping and cleaning it properly. |
| 03-11-2009, 02:46 PM | #14 | |
Quote:
As you can see, he has read the code, and still does not understand it - I do not like referencing people elsewhere to find help because when I was trying to learn, sometimes the code was a little too much for me to take in all at once |
| 03-11-2009, 03:18 PM | #15 |
Some Off Thread questions in which my other spell invoked some extra problems with this SFX, JASS:scope FlyStrike initializer Init globals private constant integer FLYID = 'Amrf' private constant integer SPELL = 'A000' private constant integer STUN = 'A001' private constant real TIME = 0.03 private constant real SPEED = 1000 private constant real DECREMENT = 10 private boolexpr Checker private constant string EFFECT = "MDX\\KnockbackDust.mdx" private constant real DISTANCE = 450 private data Var endglobals private struct data unit caster real cx real cy real tx real ty timer fly timer knock location target group g real distance real decrement real speed effect dust static method create takes nothing returns data local data d = data.allocate() local unit dummy set d.caster = GetTriggerUnit() set d.cx = GetUnitX(d.caster) set d.cy = GetUnitY(d.caster) set d.g = CreateGroup() set dummy = CreateUnit(GetOwningPlayer(d.caster),'hfoo',d.cx,d.cy,GetUnitFacing(d.caster)) set d.target = GetSpellTargetLoc() set d.tx = GetLocationX(d.target) set d.ty = GetLocationY(d.target) set d.fly = NewTimer() set d.knock = NewTimer() set d.distance = DISTANCE set d.decrement = DECREMENT set d.speed = SPEED call UnitAddAbility(dummy,STUN) call IssueTargetOrder(dummy,"thunderbolt",d.caster) call UnitApplyTimedLife(dummy,'BTLF',3) call SetUnitPathing(d.caster,false) call UnitAddAbility(d.caster,FLYID) call UnitRemoveAbility(d.caster,FLYID) return d endmethod method onDestroy takes nothing returns nothing call ReleaseTimer(.knock) call DestroyEffect(.dust) endmethod endstruct private function Conditions takes nothing returns boolean return GetSpellAbilityId() == SPELL endfunction private function Check takes nothing returns boolean local data d = Var local unit u = GetEnumUnit() return IsUnitEnemy(d.caster, GetOwningPlayer(u)) and GetFilterUnit() != d.caster endfunction private function Damage takes nothing returns nothing local data d = data(GetTimerData(GetExpiredTimer())) local unit u = GetEnumUnit() call UnitDamageTarget(d.caster,u, 200, false, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS) endfunction private function Push takes nothing returns nothing local data d = data(GetTimerData(GetExpiredTimer())) local unit t = GetEnumUnit() local real ux = GetUnitX(t) local real uy = GetUnitY(t) local real angle = Atan2(uy-d.cy,ux-d.cx) local real cos = Cos(angle) local real sin = Sin(angle) set ux = ux + cos * TIME * SPEED set uy = uy + sin * TIME * SPEED call SetUnitPosition(t,ux,uy) call DestroyEffect(d.dust) set d.dust = AddSpecialEffectTarget(EFFECT,t,"origin") endfunction private function Knock takes nothing returns nothing local data d = data(GetTimerData(GetExpiredTimer())) set d.speed = d.speed - d.decrement set d.distance = d.distance - TIME * SPEED if d.distance <= 0 then call d.destroy() endif call ForGroup(d.g,function Push) endfunction private function Kill takes nothing returns nothing local data d = data(GetTimerData(GetExpiredTimer())) set Var = d call GroupEnumUnitsInRange(d.g,d.tx,d.ty,300,Checker) call SetTimerData(d.knock,integer (d)) call TimerStart(d.knock,TIME,true,function Knock) call ReleaseTimer(d.fly) call ForGroup(d.g,function Damage) endfunction private function Down takes nothing returns nothing local data d = data(GetTimerData(GetExpiredTimer())) call SetTimerData(d.fly,integer (d)) call SetUnitAnimation(d.caster,"attack slam") call SetUnitPathing(d.caster,true) call TimerStart(d.fly,0.7,false,function Kill) endfunction private function Fly takes nothing returns nothing local data d = data(GetTimerData(GetExpiredTimer())) call SetUnitX(d.caster,d.tx) call SetUnitY(d.caster,d.ty) set d.cx = GetUnitX(d.caster) set d.cy = GetUnitY(d.caster) call SetUnitFlyHeight(d.caster,0,3000) call SetTimerData(d.fly,integer (d)) call TimerStart(d.fly,1,false,function Down) endfunction private function Actions takes nothing returns nothing local data d = data.create() call SetTimerData(d.fly,integer (d)) call SetUnitFlyHeight(d.caster,999999,3000) call TimerStart(d.fly,1.5,false,function Fly) 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 Checker = Condition(function Check) endfunction endscope Why.... Why.. does this have synax error. undefined type data cannot convert null to integer cannot convert integer to null. Next spell.... the old Dash.. JASS:scope Dash initializer Init globals private constant integer SPELL = 'A003' private constant real TIME = 0.03 private constant real SPEEDCASTER = 1500 private constant real SPEEDTARGET = 1200 private constant real KnockDistance = 500 private constant real DECREMENTCASTER = 20 private constant real DECREMENTTARGET = 10 private constant string EFFECT = "MDX\\KnockbackDust.mdx" private boolexpr Check private data Var endglobals private function DISTANCE takes integer level returns integer return level * 250 endfunction private struct data unit caster unit target real cos real sin real angle real distance timer t timer h group g real casterspeed real targetspeed real casterdecrement real targetdecrement effect dust static method create takes nothing returns data local data d = data.allocate() set d.caster = GetTriggerUnit() set d.target = GetSpellTargetUnit() set d.t = NewTimer() set d.h = NewTimer() set d.distance = DISTANCE(GetUnitAbilityLevel(d.caster,SPELL)) set d.g = CreateGroup() set d.casterspeed = SPEEDCASTER set d.targetspeed = SPEEDTARGET set d.casterdecrement = DECREMENTCASTER set d.targetdecrement = DECREMENTTARGET return d endmethod method onDestroy takes nothing returns nothing call ReleaseTimer(.h) call DestroyEffect(.dust) endmethod endstruct private function Conditions takes nothing returns boolean return GetSpellAbilityId() == SPELL endfunction private function KnockCheck takes nothing returns boolean local data d = Var return GetFilterUnit() != d.caster and GetFilterUnit() != d.target endfunction private function Knock takes nothing returns nothing local data d = data(GetTimerData(GetExpiredTimer())) local real cx = GetUnitX(d.caster) local real cy = GetUnitY(d.caster) local real tx = GetUnitX(d.target) local real ty = GetUnitY(d.target) local real angle = Atan2(ty-cy,tx-cx) local real sin = Sin(angle) local real cos = Cos(angle) set tx = tx + cos * TIME * SPEEDTARGET set ty = ty + sin * TIME * SPEEDTARGET call SetUnitX(d.target,tx) call SetUnitY(d.target,ty) call DestroyEffect(d.dust) set d.dust = AddSpecialEffectTarget(EFFECT,d.target, "origin") set d.targetspeed = d.targetspeed - d.targetdecrement set d.distance = d.distance - TIME * SPEEDTARGET if d.distance <= 0 then call d.destroy() endif endfunction private function Move takes nothing returns nothing local data d = data(GetTimerData(GetExpiredTimer())) local real cx = GetUnitX(d.caster) local real cy = GetUnitY(d.caster) local real tx = GetUnitX(d.target) local real ty = GetUnitY(d.target) local real angle = Atan2(ty-cy,tx-cx) local real sin = Sin(angle) local real cos = Cos(angle) local unit u local real x local real y local real angles local real sins local real coss set cx = cx + cos * TIME * SPEEDCASTER set cy = cy + sin * TIME * SPEEDCASTER call SetUnitX(d.caster,cx) call SetUnitY(d.caster,cy) set Var = d call GroupEnumUnitsInRange(d.g,cx,cy,180,Check) loop set u = FirstOfGroup(d.g) exitwhen u == null set x = GetUnitX(u) set y = GetUnitY(u) set angles = Atan2(y-cy,x-cx) set sins = Sin(angles) set coss = Cos(angles) set x = x + coss * TIME * SPEEDCASTER set y = y + sins * TIME * SPEEDCASTER call SetUnitX(u,x) call SetUnitY(u,y) call DestroyEffect(d.dust) set d.dust = AddSpecialEffectTarget(EFFECT,d.caster, "origin") call GroupRemoveUnit(d.g,u) endloop set d.casterspeed = d.casterspeed - d.casterdecrement if SquareRoot((cx - tx) * (cx - tx) + (cy - ty) * (cy - ty)) <= 128 then call SetUnitAnimation(d.caster, "attack slam alternate") call SetUnitAnimation(d.target, "DEATH") call ReleaseTimer(d.t) call DestroyEffect(d.dust) call SetTimerData(d.h,integer (d)) call TimerStart(d.h,0.03,true,function Knock) endif endfunction private function Actions takes nothing returns nothing local data d = data.create() call SetTimerData(d.t,integer (d)) call TimerStart(d.t,0.03,true,function Move) 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 Check = Condition(function KnockCheck) endfunction endscope Same amount of synax error as above , 3 with all the data var. For the relevant to this thread, so I need to have another struct which have all the things which I need for each unit , instead of trying to merge 2 structs together? meaning I have to do another private struct knock and then etc... |
