| 03-15-2009, 05:44 AM | #1 |
Bump. Angle still doesn't work .. sigh.. Code update! JASS:scope KnockTest initializer Init private function Conditions takes nothing returns boolean return GetSpellAbilityId() == 'TEST' endfunction private function Actions takes nothing returns nothing local unit u = GetSpellTargetUnit() local unit t = GetTriggerUnit() local real x = GetUnitX(u) local real y = GetUnitY(u) local real tx = GetUnitY(t) local real ty = GetUnitX(t) local real a = Atan2(y-ty,x-tx)*57.29582 call KnockbackTarget(t,u,a,1000,30) set u = null set t = 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 Actions ) call TriggerAddCondition(t,Condition(function Conditions)) endfunction endscope JASS:library Knockback initializer Init requires BoundSentinel, TimerUtils, DestructableLib globals private real TIME = 0.04 endglobals private struct Knock unit source unit target real x real y real cos real sin real speed real decrement timer Timer effect mode static method create takes unit source, unit target, real angle, real initialspeed, real decrement returns Knock local Knock d = Knock.allocate() set d.source = source set d.target = target set d.speed = initialspeed * TIME set d.decrement = decrement * TIME set d.sin = Sin(angle) set d.cos = Cos(angle) set d.Timer = NewTimer() return d endmethod method onDestroy takes nothing returns nothing call ReleaseTimer(.Timer) endmethod endstruct private function Update takes nothing returns nothing local Knock d = Knock(GetTimerData(GetExpiredTimer())) local unit u = d.target local real sx = GetUnitX(u) local real sy = GetUnitY(u) local real x = sx + d.speed * d.cos local real y = sy + d.speed * d.sin local real tx local real ty if d.speed <= 0 then call d.destroy() endif set x = sx + d.speed * d.cos set y = sy + d.speed * d.sin call SetUnitPosition(u,x,y) set d.speed = d.speed - d.decrement set u = null endfunction function KnockbackTarget takes unit source, unit target , real angle, real initialspeed, real decrement returns boolean local Knock d = 0 if target == null or source == null or initialspeed == null or decrement == null then call BJDebugMsg("Invalid Values!") return false endif set d = Knock.create(source,target,(angle*0.01745328),initialspeed,decrement) call SetTimerData(d.Timer,integer (d)) call TimerStart(d.Timer,TIME,true,function Update) return true endfunction private function Init takes nothing returns nothing endfunction endlibrary |
| 03-15-2009, 05:52 AM | #2 |
You have no reason to be using degrees. Don't convert either way; just use plain radians. And this is the reason it doesn't work: JASS:local real tx = GetUnitY(t) local real ty = GetUnitX(t) |
| 03-15-2009, 06:01 AM | #3 | ||
Quote:
So how do I use plain radians? Quote:
Wow! Silly me man , I must be a blind old man who can't see. I didn't even manage to see that after millions of checking. |
| 03-15-2009, 06:05 AM | #4 |
JASS:
local real a = Atan2(y-ty,x-tx)*57.29582
JASS:,(angle*0.01745328), You can remove both and gain more speed an accuracy at no cost to the system. |
| 03-15-2009, 06:31 AM | #5 |
This script could possibly crash a map, if the unit was knocbacked to a point outside the map bounds. |
| 03-15-2009, 06:34 AM | #6 | |
Quote:
This will check if the given coordinates are inside the map bounds. JASS:function mapbounds takes real x, real y returns boolean return x < GetRectMaxX(bj_mapInitialPlayableArea)-64.00 and x > GetRectMinX(bj_mapInitialPlayableArea)+64.00 and y < GetRectMaxY(bj_mapInitialPlayableArea)-64.00 and y > GetRectMinY(bj_mapInitialPlayableArea)+64.00 endfunction |
| 03-15-2009, 06:46 AM | #7 |
My code shows that it requires BoundSentinel :P. |
| 03-15-2009, 07:17 AM | #8 |
I really don't think SetUnitPosition works outside of map bounds ;; It doesn't matter anyway, unless your speed is fast enough to bypass the entire boundary, which is the users fault anyway... I would just check the pathing before setting the position to it, to avoid wierd errors (there are 2 scripts for this in database) |
| 03-15-2009, 01:42 PM | #9 |
Right now everything works but some effects are not getting destroyed. JASS:library Knockback initializer Init requires BoundSentinel, TimerUtils, DestructableLib globals private constant real TIME = 0.04 private constant string GROUND = "MDX\\KnockbackDust.mdx" private constant string WATER = "MDX\\KnockbackWater.mdx" private constant string ATTACHPOINT = "origin" private constant real RADIUS = 180 private rect TreeRect private boolexpr TreeCheck endglobals private function CheckTrees takes nothing returns boolean if IsDestructableTree(GetFilterDestructable()) then return true endif return false endfunction private function Trees takes nothing returns nothing call KillDestructable(GetEnumDestructable()) endfunction private struct Knock unit source unit target real x real y real cos real sin real speed real decrement timer Timer effect effects boolean Terrain integer EffectMode boolean Trees public method TerrainCheck takes Knock d returns integer local real x = GetUnitX(d.target) local real y = GetUnitY(d.target) if IsTerrainPathingType(x, y, TERRAIN_PATHING_LAND) then return 1 elseif IsTerrainPathingType(x, y, TERRAIN_PATHING_SHALLOW) then return 2 endif return 0 endmethod static method create takes unit source, unit target, real angle, real initialspeed, real decrement, boolean KillTree returns Knock local Knock d = Knock.allocate() local real x local real y set d.source = source set d.target = target set d.Trees = KillTree set d.EffectMode = d.TerrainCheck(d) set x = GetUnitX(d.target) set y = GetUnitY(d.target) set d.speed = initialspeed * TIME set d.decrement = decrement * TIME set d.sin = Sin(angle) set d.cos = Cos(angle) set d.Timer = NewTimer() if d.EffectMode == 1 then set d.effects = AddSpecialEffectTarget(GROUND,d.target,ATTACHPOINT) endif if d.EffectMode == 2 then set d.effects = AddSpecialEffectTarget(WATER,d.target,ATTACHPOINT) endif return d endmethod method onDestroy takes nothing returns nothing call DestroyEffect(this.effects) call ReleaseTimer(this.Timer) endmethod endstruct private function Update takes nothing returns nothing local Knock d = Knock(GetTimerData(GetExpiredTimer())) local unit u = d.target local real sx = GetUnitX(u) local real sy = GetUnitY(u) local real x = sx + d.speed * d.cos local real y = sy + d.speed * d.sin if d.speed <= 0 then call d.destroy() endif if d.Trees == true then set sx = GetUnitX(u) set sy = GetUnitY(u) call SetRect(TreeRect,sx-RADIUS,sy-RADIUS,sx+RADIUS,sy+RADIUS) call EnumDestructablesInRect(TreeRect,TreeCheck,function Trees) endif call SetUnitPosition(u,x,y) set d.EffectMode = d.TerrainCheck(d) if d.EffectMode == 1 then call DestroyEffect(d.effects) set d.effects = AddSpecialEffectTarget(GROUND,d.target,ATTACHPOINT) endif if d.EffectMode == 2 then call DestroyEffect(d.effects) set d.effects = AddSpecialEffectTarget(WATER,d.target,ATTACHPOINT) endif set d.speed = d.speed - d.decrement set u = null endfunction function KnockbackTarget takes unit source, unit target , real angle, real initialspeed, real decrement,boolean KillTree returns boolean local Knock d = 0 if target == null or source == null or initialspeed == null or decrement == null then call BJDebugMsg("Invalid Values!") return false endif set d = Knock.create(source,target,angle,initialspeed,decrement,KillTree) call SetTimerData(d.Timer,integer (d)) call TimerStart(d.Timer,TIME,true,function Update) return true endfunction private function Init takes nothing returns nothing set TreeRect = Rect(0,0,1,1) set TreeCheck = Filter(function CheckTrees) endfunction endlibrary JASS:scope KnockTest initializer Init private function Conditions takes nothing returns boolean return GetSpellAbilityId() == 'TEST' endfunction private function Actions takes nothing returns nothing local unit u = GetSpellTargetUnit() local unit t = GetTriggerUnit() local real x = GetUnitX(u) local real y = GetUnitY(u) local real tx = GetUnitX(t) local real ty = GetUnitY(t) local real a = Atan2(y-ty,x-tx) call KnockbackTarget(t,u,a,1000,30,true) set u = null set t = 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 Actions ) call TriggerAddCondition(t,Condition(function Conditions)) endfunction endscope |
| 03-16-2009, 02:45 AM | #10 |
JASS://Formula to calculate Distance = -1 * V * V / (2 * A / Interval) Where variable V is speed and A is decrement.// // Note! V must be positive and A must be negative!!!! // library Knockback initializer Init requires BoundSentinel, TimerUtils, DestructableLib, TerrainPathability globals private constant real TIME = 0.03 private constant string GROUND = "MDX\\Dust.mdx" private constant string WATER = "MDX\\SlideWater.mdx" private constant string COLLISION = "MDX\\DustAndRocks.mdx" private constant string ATTACHPOINT = "origin" private constant real RADIUS = 180 private rect TreeRect private boolexpr TreeCheck endglobals private function CheckTrees takes nothing returns boolean if IsDestructableTree(GetFilterDestructable()) then return true endif return false endfunction private function Trees takes nothing returns nothing call KillDestructable(GetEnumDestructable()) endfunction private struct Knock unit source unit target real x real y real cos real sin real speed real decrement timer Timer effect effects boolean Terrain integer EffectMode boolean Trees public method TerrainCheck takes Knock d returns integer local real x = GetUnitX(d.target) local real y = GetUnitY(d.target) if IsTerrainPathingType(x, y, TERRAIN_PATHING_LAND) then return 1 elseif IsTerrainPathingType(x, y, TERRAIN_PATHING_SHALLOW) then return 2 endif return 0 endmethod static method create takes unit source, unit target, real angle, real speed, real decrement, boolean KillTree returns Knock local Knock d = Knock.allocate() local real x local real y set d.source = source set d.target = target set d.Trees = KillTree set d.EffectMode = d.TerrainCheck(d) set x = GetUnitX(d.target) set y = GetUnitY(d.target) set d.speed = speed * TIME set d.decrement = decrement * TIME set d.sin = Sin(angle) set d.cos = Cos(angle) set d.Timer = NewTimer() if d.EffectMode == 1 then if IsTerrainWalkable(x,y) then set d.effects = AddSpecialEffectTarget(COLLISION,d.target,ATTACHPOINT) else set d.effects = AddSpecialEffectTarget(GROUND,d.target,ATTACHPOINT) endif endif if d.EffectMode == 2 then set d.effects = AddSpecialEffectTarget(WATER,d.target,ATTACHPOINT) endif if IsTerrainWalkable(x,y) == false then set d.effects = AddSpecialEffectTarget(COLLISION,d.target,ATTACHPOINT) endif return d endmethod method onDestroy takes nothing returns nothing call DestroyEffect(this.effects) call ReleaseTimer(this.Timer) endmethod endstruct private function Update takes nothing returns nothing local Knock d = Knock(GetTimerData(GetExpiredTimer())) local unit u = d.target local real sx = GetUnitX(u) local real sy = GetUnitY(u) local real x = sx + d.speed * d.cos local real y = sy + d.speed * d.sin local integer mode = d.EffectMode if d.speed <= 0 then call d.destroy() endif if d.Trees == true then call SetRect(TreeRect,sx-RADIUS,sy-RADIUS,sx+RADIUS,sy+RADIUS) call EnumDestructablesInRect(TreeRect,TreeCheck,function Trees) endif call SetUnitPosition(u,x,y) set d.EffectMode = d.TerrainCheck(d) if d.EffectMode == 1 and mode == 2 then if IsTerrainWalkable(x,y) then call DestroyEffect(d.effects) set d.effects = AddSpecialEffectTarget(COLLISION,d.target,ATTACHPOINT) else call DestroyEffect(d.effects) set d.effects = AddSpecialEffectTarget(GROUND,d.target,ATTACHPOINT) endif endif if d.EffectMode == 2 and mode == 1 then call DestroyEffect(d.effects) set d.effects = AddSpecialEffectTarget(WATER,d.target,ATTACHPOINT) endif set d.speed = d.speed - d.decrement set u = null endfunction function KnockbackTarget takes unit source, unit target , real angle, real speed, real decrement,boolean KillTree returns boolean local Knock d = 0 if target == null or source == null or speed == null or decrement == null then call BJDebugMsg("Invalid Values!") return false endif set d = Knock.create(source,target,angle,speed,decrement,KillTree) call SetTimerData(d.Timer,integer (d)) call TimerStart(d.Timer,TIME,true,function Update) return true endfunction private function Init takes nothing returns nothing set TreeRect = Rect(0,0,1,1) set TreeCheck = Filter(function CheckTrees) endfunction endlibrary |
