Fulla
Evil Overlord
- Reaction score
- 31
Basically I'm trying to learn vectors. I thought I'd start out simple, by converting a spell I've already got completed.
I've managed to convert the X/Y calculation & now onto the Z part, but seeking help.
The projectile is shot in arc upwards, which slowly descends back downwards.
The plan is to convert the periodic calculations to just this:
So basically I'm looking for these calculations:
- Setting up the vz
- Scaling down the vz periodically with gravity
(vz = the Z Velocity Vector)
Here is the code stripped down to just the maths/calculations:
Full Code:
Feel free to test out map
Thx for any help
I've managed to convert the X/Y calculation & now onto the Z part, but seeking help.
The projectile is shot in arc upwards, which slowly descends back downwards.
The plan is to convert the periodic calculations to just this:
JASS:
set dat.vz = ?? // Scale it down with gravity
call SetUnitFlyHeight(dat.missile, GetUnitZ(dat.missile) + dat.vz, 0)
So basically I'm looking for these calculations:
- Setting up the vz
- Scaling down the vz periodically with gravity
(vz = the Z Velocity Vector)
Here is the code stripped down to just the maths/calculations:
JASS:
public constant real PERIOD = 0.034
public constant real GRAVITY = 2500
private constant real SPEED = 900
private constant real MINIMUM_DISTANCE = 400
private constant real LAUNCH_Z = 100
//TIMER - Moving the projectile about:
set dat.time = dat.time + PERIOD
set x = GetUnitX(dat.missile)
set y = GetUnitY(dat.missile)
set z = GetZ(x, y)
//Move missile
call SetUnitXY(dat.missile, x + dat.vx, y + dat.vy)
//Adjust height
call SetUnitFlyHeight(dat.missile, dat.sz + dat.vz * dat.time - GRAVITY * dat.time * dat.time / 2 - z, 0)
//Adjust angle/facing
set aoa = R2I(Atan2BJ(dat.vz - GRAVITY * dat.time, SquareRoot(dat.vx * dat.vx + dat.vy * dat.vy))) + 90
call SetUnitAnimationByIndex(dat.missile, aoa)
//SETUP - Setting the structs & figures up
local unit u = GetTriggerUnit()
local location l = GetSpellTargetLoc()
local real dx = GetLocationX(l) - GetUnitX(u)
local real dy = GetLocationY(l) - GetUnitY(u)
local real dz = GetLocationZ(l) - (GetUnitZ(u) + LAUNCH_Z)
local real dist = SquareRoot(dx * dx + dy * dy)
set dat.duration = dist / SPEED
set dat.sx = GetUnitX(u)
set dat.sy = GetUnitY(u)
set dat.sz = GetUnitZ(u) + LAUNCH_Z
set dat.vx = dx / dat.duration * PERIOD
set dat.vy = dy / dat.duration * PERIOD
set dat.vz = dz / dat.duration + GRAVITY * dat.duration / 2
Full Code:
JASS:
scope FreezingArrow
globals
flamingarrowdata array FlamingArrowArray
integer FlamingArrowTotal = 0
public constant real PERIOD = 0.034
public constant real GRAVITY = 2500
private constant integer ABILITY_ID = 039;A002039;
private constant real IMPACT_DAMAGE = 100
private constant real SPEED = 900
private constant real MINIMUM_DISTANCE = 400
private constant real LAUNCH_Z = 100
endglobals
struct flamingarrowdata
unit missile = null
effect sfx = null
integer level = 0
real sx = 0
real sy = 0
real sz = 0
real vx = 0
real vy = 0
real vz = 0
real time = 0
real duration = 0
real acceleration = 0
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == ABILITY_ID
endfunction
private function End takes unit u, integer level returns nothing
local real x = GetUnitX(u)
local real y = GetUnitY(u)
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl", x, y))
endfunction
private function Timer takes nothing returns nothing
local flamingarrowdata dat
local integer i = 0
local integer aoa = 0
local real x = 0
local real y = 0
local real z = 0
loop
exitwhen i >= FlamingArrowTotal
set dat = FlamingArrowArray<i>
set dat.time = dat.time + PERIOD
set x = GetUnitX(dat.missile)
set y = GetUnitY(dat.missile)
set z = GetZ(x, y)
//Move missile
call SetUnitXY(dat.missile, x + dat.vx, y + dat.vy)
//Adjust height
call SetUnitFlyHeight(dat.missile, dat.sz + dat.vz * dat.time - GRAVITY * dat.time * dat.time / 2 - z, 0)
//Adjust angle/facing
set aoa = R2I(Atan2BJ(dat.vz - GRAVITY * dat.time, SquareRoot(dat.vx * dat.vx + dat.vy * dat.vy))) + 90
call SetUnitAnimationByIndex(dat.missile, aoa)
//Has missile has reached its destination?
if GetUnitZ(dat.missile) <= GetZ(x, y) + 1 then
//Add an explosion
call End(dat.missile, dat.level)
//Destroy everything
call DestroyEffect(dat.sfx)
call KillUnit(dat.missile)
set FlamingArrowTotal = FlamingArrowTotal - 1
set FlamingArrowArray<i> = FlamingArrowArray[FlamingArrowTotal]
call dat.destroy()
set i = i - 1
endif
set i = i + 1
endloop
if FlamingArrowTotal==0 then
call ReleaseTimer(GetExpiredTimer())
endif
endfunction
private function Actions takes nothing returns nothing
local flamingarrowdata dat = flamingarrowdata.create()
local unit u = GetTriggerUnit()
local location l = GetSpellTargetLoc()
local real dx = GetLocationX(l) - GetUnitX(u)
local real dy = GetLocationY(l) - GetUnitY(u)
local real dz = GetLocationZ(l) - (GetUnitZ(u) + LAUNCH_Z)
local real dist = SquareRoot(dx * dx + dy * dy)
local real velocity = dist / SPEED
//Minimum distance
if dist < MINIMUM_DISTANCE then
set dx = dx * MINIMUM_DISTANCE / dist
set dy = dy * MINIMUM_DISTANCE / dist
set dist = MINIMUM_DISTANCE
set velocity = dist / SPEED
endif
//Setup structs
set dat.missile = CreateUnit(GetOwningPlayer(u), 039;hmil039;, GetUnitX(u), GetUnitY(u), Atan2BJ(dy, dx))
set dat.sfx = AddSpecialEffectTarget(GetAbilityEffectById(ABILITY_ID, EFFECT_TYPE_MISSILE, 1), dat.missile, "origin")
set dat.level = GetUnitAbilityLevel(u, ABILITY_ID)
set dat.duration = dist / SPEED
set dat.sx = GetUnitX(u)
set dat.sy = GetUnitY(u)
set dat.sz = GetUnitZ(u) + LAUNCH_Z
set dat.vx = dx / velocity * PERIOD
set dat.vy = dy / velocity * PERIOD
set dat.vz = dz / dat.duration + GRAVITY * dat.duration / 2
//set acceleration =
//The Missile is shot/launched from 100 above the caster
call SetUnitFlyHeight(dat.missile, LAUNCH_Z, 0)
if FlamingArrowTotal == 0 then
call TimerStart(NewTimer(), PERIOD, true, function Timer)
endif
set FlamingArrowArray[FlamingArrowTotal] = dat
set FlamingArrowTotal = FlamingArrowTotal + 1
call RemoveLocation(l)
set u = null
endfunction
//===========================================================================
public function InitTrig takes nothing returns nothing
set Trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(Trig, EVENT_PLAYER_UNIT_SPELL_CAST)
call TriggerAddCondition(Trig, Condition(function Conditions))
call TriggerAddAction(Trig, function Actions)
endfunction
endscope</i></i>
Feel free to test out map
Thx for any help