| 03-05-2009, 07:36 AM | #1 |
I have a dash spell here which dashes to the target and knocks the target away well fine. I tried to use SetUnitPosition and then knock units near the caster when he is charging to the target but alas , the unit doesn't get knocked back. Can anybody tell me how do I knock units near my caster during the period where he is charging to the target? JASS:Spell Code scope Dash initializer Init globals private constant integer SPELL = 'A003' private constant real TIME = 0.03 private constant real SPEED = 800 private constant real KnockDistance = 400 private boolexpr Check 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 Distance 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() return d endmethod method onDestroy takes nothing returns nothing call ReleaseTimer(.h) endmethod endstruct private function Conditions takes nothing returns boolean return GetSpellAbilityId() == SPELL endfunction private function KnockCheck takes nothing returns boolean local data d 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 * SPEED set ty = ty + sin * TIME * SPEED call SetUnitX(d.target,tx) call SetUnitY(d.target,ty) set d.distance = d.distance - TIME * SPEED 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 * SPEED set cy = cy + sin * TIME * SPEED call SetUnitPosition(d.caster,cx,cy) 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 * SPEED set y = y + sins * TIME * SPEED call SetUnitX(u,x) call SetUnitY(u,y) call GroupRemoveUnit(d.g,u) endloop 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 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 Things that are related to knocking the units away are highlighted in red. |
| 03-05-2009, 09:50 AM | #2 | |
You aren't defining the struct you are trying to use: Quote:
You could try to do something like this: JASS:globals ... private data dataVar // <-- add this to your global declarations endglobals local data d = dataVar // <-- this is within the KnockCheck boolexpr func ... call SetUnitPosition(d.caster,cx,cy) set dataVar = d // <-- insert this in between these two lines of code, in the Move function call GroupEnumUnitsInRange(d.g,cx,cy,180,Check) loop ... Try that out. |
| 03-05-2009, 10:17 AM | #3 |
Ok, it works fine now , but can you explain to me actually how does the whole thing work? I don't really get what you are doing. Right now I added a speed limit for the ajacent unit that get knocked back which is 400 but right now.. they seem to be teleporting instantly after 400 distance instead of "knocked backed" there. Spell Code JASS:scope Dash initializer Init globals private constant integer SPELL = 'A003' private constant real TIME = 0.03 private constant real SPEED = 800 private constant real KnockDistance = 400 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 Distance 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.Distance = 400 return d endmethod method onDestroy takes nothing returns nothing call ReleaseTimer(.h) 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 * SPEED set ty = ty + sin * TIME * SPEED call SetUnitX(d.target,tx) call SetUnitY(d.target,ty) set d.distance = d.distance - TIME * SPEED 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 * SPEED set cy = cy + sin * TIME * SPEED call SetUnitPosition(d.caster,cx,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 * SPEED set y = y + sins * TIME * SPEED call SetUnitX(u,x) call SetUnitY(u,y) set d.Distance = d.Distance - TIME * SPEED if d.Distance <= 0 then call BJDebugMsg("removing!") call GroupRemoveUnit(d.g,u) endif endloop 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 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 The highlighted lines are the ones I added. |
| 03-05-2009, 10:32 AM | #4 |
All I did was make it so that your referencing was correct - I didn't really change much of how the code works. Let me read it over a bit and I'll see what if I can help you out somehow. Okay, what exactly do you mean by "Adjacent Unit" ? Do you mean the unit you're referencing in function Knock ? |
| 03-05-2009, 01:00 PM | #5 |
It meant that units within the caster who is charging towards the target will get knocked back away meaning , units who obstructed the caster towards his desintination which is the target. |
| 03-06-2009, 04:10 AM | #6 |
bump |
| 03-06-2009, 02:33 PM | #7 |
Sorry wraith, I've been a little sick. JASS:set d.Distance = d.Distance - TIME * SPEED From what I see here you are reducing d.Distance for every unit that is in the unit-group. This means that if you have 6 units you are going to be doing: JASS:set d.Distance = d.Distance - (TIME * SPEED) * 6. Ah. Found your problem. Here, this is what it should read, and I will explain: JASS:
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 * SPEED
set y = y + sins * TIME * SPEED
call SetUnitX(u,x)
call SetUnitY(u,y)
// you do not need the below code at all.
set d.Distance = d.Distance - TIME * SPEED
if d.Distance <= 0 then
call BJDebugMsg("removing!")
call GroupRemoveUnit(d.g,u)
endif
// instead, remove the unit from the group here (in all situations)
call GroupRemoveUnit(d.g, u)
endloop
The reason for this is you are keeping the unit in the unit-group, which will cause its position to constantly be updated up until d.Distance becomes less than or equal to 0, which would result in the unit being knocked back a variable amount based on how many units are in the group. Follow? |
| 03-07-2009, 04:32 AM | #8 |
Works.. thanks! What a foolish mistake that I have made. |
| 03-07-2009, 09:50 AM | #9 |
Its all good. I'm glad you could get it workin'. By the way - you should really check out Dusk's (or mine, though it is not on this site) Knock Back script it would probably handle it a lot more efficiently than coding it yourself. I only refrained from referring you to this so that you could learn. |
| 03-07-2009, 09:55 AM | #10 |
Yeah, I don't want to try to depend on stuffs but instead learn by myself which i think it is a good experience. |
