| 03-29-2009, 07:04 AM | #1 |
JASS:function ParabolaZ takes real h, real d, real x returns real return (4 * h / d) * (d - x) * (x / d) endfunction private function fly takes nothing returns nothing local unit u = GetTriggerUnit() call UnitAddAbility(//...storm crow form) call UnitRemoveAbility(//...storm crow form) //what now? endfunction Handwritten, expect errors. How do I make a jump spell? I am using speed as the movement and not distance meaning JASS:set x = cx + d.speed * d.cos set y = cy + d.speed * d.sin set d.speed = d.speed - d.decrement if d.speed <= 0 then // taken out, not needed to know. I don't understand the jump formula much and don't know how to do it using the speed factor. |
| 03-29-2009, 08:20 AM | #2 |
You don't have to, and shouldn't use a variable speed. Use a constant speed, it is more realistic physically, and easier to code. In the ParabolaZ function, h = height of parabola, d = total length of parabola, and x = where in the parabola the z coordinate should come from. For example, ParabolaZ(100, 50, 25) will give the result 100, because the parabola is 100 high, and 50 long, and since the highest point is at 50/2=25, putting 25 as x will result in the highest possible value of the curve. To do the actual movement, you have to use a loop, or even better, a timer. Since using a decreasing speed is bad, you would have to specify either the total time of the jump, or the length of it. I can give you an example script, but it will take some time. |
| 03-29-2009, 09:27 AM | #3 |
How do you get the Z coordinate? |
| 03-29-2009, 09:49 AM | #4 |
function ParabolaZ returns real |
| 03-29-2009, 09:57 AM | #5 |
JASS:set d.distance = -1 * speed * speed / (2 * -decrement / TIME) JASS:call SetUnitFlyHeight(u,ParabolaZ(500,d.distance,d.speed),0) Doesn't work. |
| 03-29-2009, 10:44 AM | #6 |
JASS:private constant function Interval takes nothing returns real return 0.05 endfunction private function GetDistance takes real x1, real y1, real x2, real y2 return SquareRoot((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) endfunction private function GetAngle takes real x1, real y1, real x2, real y2 returns real return Atan2(y2-y1, x2-x1) endfunction private function ParabolaZ takes real h, real d, real x returns real return (4 * h / d) * (d - x) * (x / d) endfunction function Jump takes unit u, real x, real y, real speed returns nothing local JumpData d = JumpData.create() local real distance = GetDistance(GetUnitX(u), GetUnitY(u), x, y) local real distint = (distance/speed)*interval() local integer movecount = R2I(distint/distance) local real angle = GetAngle(GetUnitX(u), GetUnitY(u), x, y) local real dx = Cos(angle)*distint local real dy = Sin(angle)*distint local integer i = 0 //Add the storm crow ability to the unit here loop exitwhen i == movecount call SetUnitFlyHeight(u, ParabolaZ(500, distance, distint*i) call SetUnitY(u, GetUnitY(u)+dy) call SetUnitX(u, GetUnitX(u)+dx) set i = i+1 call PolledWait(Interval()) endloop //Remove the storm crow ability from the unit here endfunction This should describe how to use it. You can steal this script from me if you want to, but it is not very good, since PolledWait() is very inaccurate at short intervals. It could be replaced with a timer, but that would require a much more complex script. |
| 03-29-2009, 10:59 AM | #7 |
Actually, what I want is the knockedback unit to fly, you look like you know quite alot about jumping, throwing the whole code in here for you to see. 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!!!! // //****************************************************************************** //* Formula to calculate the distance * //* - 1 * V * V / ( 2 * A / Interval) * //* Variable V = The amount of speed the knockedback unit has * //* Variable A = The amount of speed reduced per Interval * //* Variable Interval = Located at the top of the Knockback System * //* * //* Some things to note about them * //* Variable A must be a positive number * //* Variable B must be a negative number * //* * //* * //* * //* * //****************************************************************************** library Knockback initializer Init requires BoundSentinel, DestructableLib, IsTerrainWalkable, GroupUtils globals private constant real TIME = 0.03 private constant real CHAINRADIUS = 100 private constant real SPEEDFACTOR = 0.75 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 integer Invulnerable = 'Avul' private constant real RADIUS = 180 private timer Timer = CreateTimer() private integer Count = 0 private integer array Knocker private integer array Index private rect TreeRect private boolexpr TreeCheck private boolexpr ChainFilter private unit source private unit target 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 function ChainCheck takes nothing returns boolean return target != GetFilterUnit() endfunction function ParabolaZ takes real h, real d, real x returns real return (4 * h / d) * (d - x) * (x / d) endfunction private struct Knock //! run textmacro PUI() unit source unit target integer EffectMode group hit real x real y real cos real sin real speed real decrement real distance real MoveDistance effect effects boolean Terrain boolean Trees boolean AllowMove boolean constantspeed boolean chain boolean Fly public method TerrainCheck takes Knock d returns integer local real x = GetUnitX(d.target) local real y = GetUnitY(d.target) if IsTerrainWalkable(x + 50.00 * d.cos,y + 50.00 * d.sin) == false then return 3 else if IsTerrainPathable(x,y,PATHING_TYPE_FLOATABILITY) then return 1 elseif not IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY) then return 2 endif endif return 0 endmethod static method create takes unit source, unit target, real angle,real speed, real decrement, boolean KillTree, boolean Allowmove, boolean ConstantSpeed,boolean Chain,boolean fly 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.Fly = fly set d.constantspeed = ConstantSpeed set d.AllowMove = Allowmove set d.chain = Chain set d.hit = NewGroup() 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.EffectMode = d.TerrainCheck(d) set d.distance = -1 * speed * speed / (2 * -decrement / TIME) 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 if d.EffectMode == 3 then set d.effects = AddSpecialEffectTarget(COLLISION,d.target,ATTACHPOINT) endif return d endmethod method onDestroy takes nothing returns nothing call DestroyEffect(this.effects) call ReleaseGroup(this.hit) set Index[GetUnitIndex(this.target)] = 0 endmethod endstruct private function Update takes nothing returns nothing local Knock d = 0 local Knock c = 0 local unit u local unit t local real x local real y local real cx local real cy local integer i = Count - 1 local integer mode = 0 loop exitwhen i < 0 set d = Knocker[i] set u = d.target set mode = d.EffectMode set cx = GetUnitX(u) set cy = GetUnitY(u) set d.MoveDistance = d.MoveDistance + d.speed if d.speed <= 0 then call d.destroy() set Count = Count - 1 if Count < 0 then call PauseTimer(Timer) set Count = 0 else set Knocker[i] = Knocker[Count] endif else set x = cx + d.speed * d.cos set y = cy + d.speed * d.sin set d.EffectMode = d.TerrainCheck(d) if d.AllowMove == true then call SetUnitX(u,x) call SetUnitY(u,y) else call SetUnitPosition(u,x,y) endif if d.Trees == true then call SetRect(TreeRect,x-RADIUS,y-RADIUS,x+RADIUS,y+RADIUS) call EnumDestructablesInRect(TreeRect,TreeCheck,function Trees) endif if d.EffectMode == 1 and (mode == 2 or mode == 3) then call DestroyEffect(d.effects) set d.effects = AddSpecialEffectTarget(GROUND,d.target,ATTACHPOINT) elseif d.EffectMode == 2 and (mode == 1 or mode == 3) then call DestroyEffect(d.effects) set d.effects = AddSpecialEffectTarget(WATER,d.target,ATTACHPOINT) elseif d.EffectMode == 3 and (mode == 1 or mode == 2) then call DestroyEffect(d.effects) set d.effects = AddSpecialEffectTarget(COLLISION,d.target,ATTACHPOINT) endif set d.speed = d.speed - d.decrement if d.Fly == true then call UnitAddAbility(u,'amrf') call UnitRemoveAbility(u,'amrf') call SetUnitFlyHeight(u,ParabolaZ(500,d.distance,d.MoveDistance),0) call BJDebugMsg(R2S(d.MoveDistance)) endif if d.chain == true then set source = d.source set target = d.target call GroupEnumUnitsInRange(ENUM_GROUP,x,y,CHAINRADIUS,ChainFilter) loop set t = FirstOfGroup(ENUM_GROUP) exitwhen t == null if not IsUnitInGroup(t,d.hit) then set cx = GetUnitX(t) set cy = GetUnitY(t) call GroupAddUnit(d.hit,t) set c = Knock.create(d.source,t,Atan2(cy-y,cx-x),(d.speed/TIME)*SPEEDFACTOR,(d.decrement/TIME),d.Trees,d.AllowMove,d.constantspeed,d.chain,d.Fly) call GroupAddUnit(c.hit,u) set Knocker[Count] = c set Count = Count + 1 endif call GroupRemoveUnit(ENUM_GROUP, t) endloop endif endif set i = i - 1 endloop set u = null set t = null endfunction function KnockbackStop takes unit target returns boolean local integer i = Count - 1 local Knock d = Index[GetUnitIndex(target)] local boolean b = false if d != 0 then call d.destroy() set Count = Count - 1 if Count < 0 then call PauseTimer(Timer) set Count = 0 else set Knocker[i] = Knocker[Count] endif set b = true endif return b endfunction function IsKnockedBack takes unit target returns boolean local integer i = Count - 1 local Knock d = Index[GetUnitIndex(target)] return d != 0 endfunction function KnockbackTarget takes unit source, unit target, real angle, real speed, real decrement,boolean KillTree, boolean AllowMove, boolean ConstantSpeed,boolean Chain,boolean fly 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,AllowMove,ConstantSpeed,Chain,fly) set Index[GetUnitIndex(target)] = d if Count == 0 then call TimerStart(Timer,TIME,true,function Update) endif set Knocker[Count] = d set Count = Count + 1 return true endfunction private function Init takes nothing returns nothing set TreeRect = Rect(0,0,1,1) set TreeCheck = Filter(function CheckTrees) set ChainFilter = Filter(function ChainCheck) endfunction endlibrary Which doesn't works. More detailed, Unit A knocks Unit B 600 feets away and then during that 600 feets, Unit B will fly and not Unit A flying. |
