- Joined
- Jul 26, 2008
- Messages
- 1,009
Alright this spell is pretty simple.
Using XEcolliders I've made it so when the unit casts Whirlwind, it makes a collider dummy at the targeted point. Any unit that gets within the collision radius will be added to the struct group.
Units in the group are sucked up by the Tornado and whirred around in a circle. If the channeling ends, the units will drop and take damage depending on their fly height.
My problem is I'm not too great at math and I want the units to be picked up and whirred around where they're standing, not a preset point. Also I the distance part of it isn't going as well, and I could use some advice on that.
Using XEcolliders I've made it so when the unit casts Whirlwind, it makes a collider dummy at the targeted point. Any unit that gets within the collision radius will be added to the struct group.
Units in the group are sucked up by the Tornado and whirred around in a circle. If the channeling ends, the units will drop and take damage depending on their fly height.
My problem is I'm not too great at math and I want the units to be picked up and whirred around where they're standing, not a preset point. Also I the distance part of it isn't going as well, and I could use some advice on that.
JASS:
scope Whirlwind initializer init
globals
private constant integer SPELLID = 'WhWi'
private real ANGLE
private real X
private real Y
endglobals
private struct Data extends xecollider
unit caster
group g
real ang
integer i
static method GroupMove takes nothing returns nothing
local real dx = GetUnitX(GetEnumUnit()) - X
local real dy = GetUnitY(GetEnumUnit()) - Y
local real dist = SquareRoot(dx*dx + dy*dy)
set X = X + dist*Cos(ANGLE)
set Y = Y + dist*Sin(ANGLE)
call SetUnitPosition(GetEnumUnit(), X, Y)
call SetUnitFlyHeight(GetEnumUnit(), GetUnitFlyHeight(GetEnumUnit()) + 1.75, 0)
endmethod
method loopControl takes nothing returns nothing
local unit u
local real lvl = GetUnitAbilityLevel(.caster, SPELLID)
local real dam
set .ang = .ang + 0.07
set .i = .i + 1
set .scale = 0.4+0.005*.i
set .collisionSize = 100+2*.i
set ANGLE = .ang
set X = .x
set Y = .y
call ForGroup(.g, function Data.GroupMove)
if GetUnitCurrentOrder(.caster) != OrderId("tornado") then
loop
set u = FirstOfGroup(.g)
exitwhen u == null
set dam = GetUnitFlyHeight(u)
call UnitDamageTarget(.caster, u, 0.6*dam, true, false, ATTACK_TYPE_MELEE, DAMAGE_TYPE_UNIVERSAL, wtype)
call SetUnitFlyHeight(u, GetUnitDefaultFlyHeight(u), 25*.i)
call SetUnitPathing(u,true)
call GroupRemoveUnit(.g, u)
endloop
call .terminate()
call ReleaseGroup(.g)
endif
endmethod
method onUnitHit takes unit target returns nothing
if IsUnitEnemy(target, GetOwningPlayer(.caster)) and not(IsUnitType(target,UNIT_TYPE_STRUCTURE) or IsUnitType(target,UNIT_TYPE_FLYING)) then
call GroupAddUnit(.g, target)
call UnitAddAbility(target,XE_HEIGHT_ENABLER)
call UnitRemoveAbility(target,XE_HEIGHT_ENABLER)
call SetUnitPathing(target,false)
endif
endmethod
static method Actions takes unit c, real x, real y returns nothing
local real angle = Atan2(GetUnitFacing(c) - GetUnitY(c), GetUnitFacing(c) - GetUnitX(c))
local integer lvl = GetUnitAbilityLevel(c, SPELLID)
local timer tim = NewTimer()
local Data xc = Data.create(x, y, 0)
set xc.g = NewGroup()
set xc.caster = c
set xc.expirationTime = 999999
set xc.collisionSize = 100
set xc.fxpath = GetAbilityEffectById(SPELLID, EFFECT_TYPE_MISSILE, 0)
set xc.scale = 0.4
set xc.ang = angle
endmethod
static method Conditions takes nothing returns boolean
if GetSpellAbilityId() == SPELLID then
call Data.Actions(GetTriggerUnit(), GetSpellTargetX(), GetSpellTargetY())
endif
return false
endmethod
endstruct
function Actions takes nothing returns nothing
endfunction
//===========================================================================
public function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CHANNEL )
call TriggerAddCondition( t, function Data.Conditions )
call XE_PreloadAbility(SPELLID)
set t = null
endfunction
endscope