- Joined
- Dec 12, 2008
- Messages
- 7,385
My vJass spell keeps bugging up and I can't fix it because I can't figure out what's causing the problem >_>
The plane and the bomb move and drop faster with every cast :O
What could be the cause of this? D:
I posted a map.
JASS:
library AtomicBomb requires CTL, SpellEffectEvent, Particle
globals
// The ability raw code
private constant integer ABIL_CODE = 'A000'
// The plane dummy unit raw code
private constant integer PLANE_CODE = 'h003'
// The bomb dummy unit raw code
private constant integer BOMB_CODE = 'h001'
// Flying Height Enabler
private constant integer FLYING_HEIGHT_ENABLER = 'Amrf'
// Explosion Effect
private constant string EXPLOSION_EFFECT = "Abilities\\Weapons\\FragDriller\\FragDriller.mdl"
// The effect that is created when the plane is created.
private constant string PLANE_IN_EFFECT = "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
// The effect that is created when the plane is destroyed.
private constant string PLANE_OUT_EFFECT = "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
// Bomb and Plane height
private constant real BOMB_HEIGHT = 700.
// Bomb Drop Speed Base (It will accelerate starting from this base-speed)
private constant real BOMB_DROP_SPEED = 1.
// Bomb Drop Acceleration
private constant real BOMB_DROP_ACCEL = 1.
// The dummy owning player
private constant player DUMMY_OWNER = Player(13)
// Destroy trees around the explosion?
private constant boolean DESTROY_TREES = true
// The offset from the point from the target point for plane creation
private constant real PLANE_DISTANCE = 800.
// How long does the plane stay after it drops the bomb?
private constant real PLANE_AFTER_DROP = 2.
// Attack type
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL
// Damage type
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_MAGIC
endglobals
private function GetPlaneSpeedFactor takes integer level returns real
return 9.
endfunction
private function GetDamage takes integer level returns real
return 150 + level * 75.
endfunction
private function GetDamageRadius takes integer level returns real
return 275 + level * 75.
endfunction
// How close do units have to be for the spell to deal bonus damage?
private function GetBonusDamageRadius takes integer level returns real
return 137.5 + level * 37.5
endfunction
// I want the spell to deal double the damage to units closer than the bonus damage radius.
private function GetBonusDamageFactor takes integer level returns real
return 2.
endfunction
private function TargetFilter takes player owner, unit caster, unit target returns boolean
// Placeholder
return true
endfunction
private struct Spell extends array
private static unit array caster
private static unit array plane
private static unit array bomb
private static real array xDis
private static real array yDis
private static real array planeX
private static real array planeY
private static real array dropX
private static real array dropY
private static real array damage
private static real array radius
private static real array bonusDamage
private static real array bonusRadius
private static real array speed
private static real array height
private static integer array counter
private static integer array level
private static boolean array dropped
private static boolean array exploded
private static player array owner
private static Particle array fx
private static unit treeDetector = null
private static real treesRadius = 0
private static real treesX = 0
private static real treesY = 0
private static method isTree takes destructable d returns boolean
return IssueTargetOrderById(treeDetector, 852018, d) and IssueImmediateOrderById(treeDetector, 851972)
endmethod
private static method destroyTree takes nothing returns nothing
local destructable d = GetEnumDestructable()
local real x = GetWidgetX(d)-treesX
local real y = GetWidgetY(d)-treesY
if x*x+y*y <= treesRadius and isTree(d) then
// will add line to destroy tree here
endif
endmethod
implement CTL
local rect r
local unit u
local real x
local real y
implement CTLExpire
// Set the planeX and planeY coordinates
set planeX[this] = planeX[this] + xDis[this]
set planeY[this] = planeY[this] + yDis[this]
// Move the plane
call SetUnitX(plane[this], planeX[this])
call SetUnitY(plane[this], planeY[this])
// If the bomb has been dropped
if dropped[this] then
// If the bomb exploded
if exploded[this] then
// Decrease the counter by 1
set counter[this] = counter[this] - 1
// If the counter is 0, we can end the spell
if counter[this] == 0 then
// Destroy the current instance of the spell
call this.destroy()
// Remove the plane unit
call RemoveUnit(plane[this])
// Destroy the first particle
call Particle(fx[this]).destroy()
// Create a new particle. We need particles here because effects can't be given a Z-coordinate.
set fx[this] = Particle.createEx(Player(13), planeX[this], planeY[this], BOMB_HEIGHT, 0, 0, 1, 255, 255, 255, 255, PLANE_OUT_EFFECT)
// I know I'm leaking Particles, but I'll fix that later
// Null variables
set caster[this] = null
set plane[this] = null
set bomb[this] = null
set owner[this] = null
endif
else
// If the height of the bomb is close to 0
if height[this] <= 5 then
// Remove the bomb
call RemoveUnit(bomb[this])
// Create the explosion
call DestroyEffect(AddSpecialEffect(EXPLOSION_EFFECT, dropX[this], dropY[this]))
// Loop through all units in the area
call GroupEnumUnitsInRange(bj_lastCreatedGroup, dropX[this], dropY[this], radius[this], null)
loop
// Set u to a random unit in the group
set u = FirstOfGroup(bj_lastCreatedGroup)
// If u == null, the group is empty, so we exit the loop
exitwhen u == null
// We remove the unit u from the group
call GroupRemoveUnit(bj_lastCreatedGroup, u)
// If the target unit passes the filter,
if TargetFilter(owner[this], caster[this], u) then
// We set the x and y differences of the unit and the bomb drop point
set x = GetUnitX(u)-dropX[this]
set y = GetUnitY(u)-dropY[this]
// If the unit is closer than the bonusRange
if x*x+y*y <= bonusRadius[this] then
// We deal the bonus damage
call UnitDamageTarget(caster[this], u, bonusDamage[this], false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
else
// Else, we deal the normal damage
call UnitDamageTarget(caster[this], u, damage[this], false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
endif
endif
endloop
static if DESTROY_TREES then
set r = Rect(dropX[this] - radius[this], dropY[this] - radius[this], dropX[this] + radius[this], dropY[this] + radius[this])
set treesRadius = radius[this]*radius[this]
set treesX = dropX[this]
set treesY = dropY[this]
call EnumDestructablesInRect(r, null, function thistype.destroyTree)
call RemoveRect(r)
set r = null
endif
// Utilize the counter variable to specify a number of iterations before we can destroy the spell instance from now.
set counter[this] = R2I(PLANE_AFTER_DROP*32)
// We have exploded the bomb
set exploded[this] = true
else
// Decrease the height of the bomb
set height[this] = height[this] - speed[this]
// Accelerate the bomb
set speed[this] = speed[this] + BOMB_DROP_ACCEL
// Set the height of the bomb
call SetUnitFlyHeight(bomb[this], height[this], 0)
endif
endif
else
// Decrease the counter by 1
set counter[this] = counter[this] - 1
// When the counter is 0, the plane has reached it's destination.
if counter[this] == 0 then
// Create the bomb under the plane
set bomb[this] = CreateUnit(DUMMY_OWNER, BOMB_CODE, planeX[this], planeY[this], 0)
// Set the bomb-drop coordinates that we will use later
set dropX[this] = planeX[this]
set dropY[this] = planeY[this]
// Give the bomb the ability to fly
call UnitAddAbility(bomb[this], FLYING_HEIGHT_ENABLER)
call UnitRemoveAbility(bomb[this], FLYING_HEIGHT_ENABLER)
// Set it's height to the height of the plane
call SetUnitFlyHeight(bomb[this], BOMB_HEIGHT, 0)
// We have dropped the bomb
set dropped[this] = true
// Set the height variable to the height of the plane
set height[this] = BOMB_HEIGHT
// Set the speed of the bomb to the BOMB_DROP_SPEED variable
set speed[this] = BOMB_DROP_SPEED
endif
endif
implement CTLNull
set u = null
implement CTLEnd
private static method run takes nothing returns nothing
local thistype this = create()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local real a
local real s
local real cos
local real sin
// Set the caster
set caster[this] = GetTriggerUnit()
// Set the owner
set owner[this] = GetTriggerPlayer()
// Get the angle between the caster and the target point in radians
set a = Atan2(y - GetUnitX(caster[this]), x - GetUnitY(caster[this]))
// Cache the Cos and Sin of the angle
set cos = Cos(a)
set sin = Sin(a)
// Set the plane coordinates
set planeX[this] = x + PLANE_DISTANCE * -cos
set planeY[this] = y + PLANE_DISTANCE * -sin
// Create the plane at planeX[this] and planeY[this] and make it face the angle between the caster and the target point
set plane[this] = CreateUnit(DUMMY_OWNER, PLANE_CODE, planeX[this], planeY[this], a*bj_RADTODEG)
// Set the level of the ability
set level[this] = GetUnitAbilityLevel(caster[this], ABIL_CODE)
// Set the speed of the plane per 1/32th of a second
set s = GetPlaneSpeedFactor(level[this])
// Set the vector data of the plane's movement
set xDis[this] = cos*s
set yDis[this] = sin*s
// We haven't dropped or exploded the bomb
set dropped[this] = false
set exploded[this] = false
// Set the counter to determine the number of iterations before we drop the bomb
set counter[this] = R2I(PLANE_DISTANCE/s)
// Give the plane the ability to fly (lol)
call UnitAddAbility(plane[this], FLYING_HEIGHT_ENABLER)
call UnitRemoveAbility(plane[this], FLYING_HEIGHT_ENABLER)
// Set the plane's height
call SetUnitFlyHeight(plane[this], BOMB_HEIGHT, 0)
// Create a particle at the position of the plane
set fx[this] = Particle.createEx(Player(13), planeX[this], planeY[this], BOMB_HEIGHT, 0, 0, 1, 255, 255, 255, 255, PLANE_IN_EFFECT)
// Set the damage and the radius
set damage[this] = GetDamage(level[this])
set radius[this] = GetDamageRadius(level[this])
// Set the bonus damage and the bonus radius
set bonusRadius[this] = GetBonusDamageRadius(level[this])
set bonusRadius[this] = bonusRadius[this]*bonusRadius[this]
set bonusDamage[this] = GetBonusDamageFactor(level[this])*damage[this]
endmethod
private static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(ABIL_CODE, function thistype.run)
set treeDetector = CreateUnit(Player(13), 'hpea', 0, 0, 0)
call UnitAddAbility(treeDetector, 'Aloc')
call UnitAddAbility(treeDetector, 'Avul')
call SetUnitScale(treeDetector, 0.01, 0, 0)
endmethod
endstruct
endlibrary
The plane and the bomb move and drop faster with every cast :O
What could be the cause of this? D:
I posted a map.