- Joined
- Jan 9, 2005
- Messages
- 2,127
Ok, so I'm converting a system I made to use structs instead because I couldn't fix the existing bug. I don't know much about structs so I figured I'd try to learn it (mostly but looking at this code). The current code is crashing my test map on load start even though JassHelper isn't giving me any errors.
JASS:
library BurstLaser requires BL, GetUnitCollision, ZLibrary, TimerUtils, ArmorUtils, SpecialEffectZ
globals
private group DamageGroup = CreateGroup()
private constant real MAX_COLLISION_SIZE = 196.
private constant real COLLISION_PERCENTAGE = .8
private constant integer MAX_LASERS = 20 //Maximum number of lasers per set. Feel free to increase.
endglobals
struct BurstLaser
unit source
unit target
unit sentry
player owner
integer id
real damage
real red
real blue
real green
real alpha
real fade_amount
real fade_time
integer duration
integer count
integer fx_interval
real interval
//boolean locked_to_target
real lock_angle
real lock_distance
real lock_height
lightning laser
boolean fading
boolean grounded
boolean hit_all
boolean friendly_fire
boolean uninterruptible
real launch_offset
real launch_height
real launch_angle
real spread_xy
real spread_z
//real source_x
//real source_y
//real source_z
real launch_x
real launch_y
real launch_z
real impact_x
real impact_y
real impact_z
real impact_spread_x
real impact_spread_y
real impact_spread_z
real target_coll
real laser_angle
boolean follow_target //If false, Lasers in a set will strike the same point instead of updating their impact location to follow a moving target.
boolean impact_lock //if true then Lasers that have struck a target will follow it around until they have been destroyed.
boolean range_lock //If true will set LaserRangeStart's starting point to the attacker (source of the laser) instead of the taret
real range_start //Adds or subtracts a certain amount of distance from it's starting point.
real range_per_laser //Adds or substracts distance per Laser in a set.
string laser_string
string launch_string
string impact_string
string area_string
real aoe
attacktype attack_type
integer damage_type
real initial_x
real initial_y
timer tmr_volley
timer tmr_laserfade
boolean failsafe_check
boolean force_end
integer laser_num
integer laser_index
//Fade Laser Timer Variables
//unit array f_source[MAX_LASERS]
//unit array f_target[MAX_LASERS]
//unit array f_sentry[MAX_LASERS]
lightning array f_laser[MAX_LASERS]
//real array f_red[MAX_LASERS]
//real array f_blue[MAX_LASERS]
//real array f_green[MAX_LASERS]
real array f_alpha[MAX_LASERS]
real array f_fade_amount[MAX_LASERS]
boolean array f_is_laser_dead[MAX_LASERS]
real array f_lock_angle[MAX_LASERS]
real array f_lock_distance[MAX_LASERS]
real array f_lock_height[MAX_LASERS]
//real array f_launch_offset[MAX_LASERS]
//real array f_launch_height[MAX_LASERS]
//real array f_launch_angle[MAX_LASERS]
real array f_impact_x[MAX_LASERS]
real array f_impact_y[MAX_LASERS]
real array f_impact_z[MAX_LASERS]
real array f_duration[MAX_LASERS]
boolean array f_fading[MAX_LASERS]
boolean array f_uninterruptible[MAX_LASERS]
static code timer_volley_handler
static code timer_laserfade_handler
static method set_handlers takes nothing returns nothing
set timer_volley_handler = function thistype.BurstLaser_Volley
set timer_laserfade_handler = function thistype.LaserFade_Timer
endmethod
static method LaserFade_Timer takes nothing returns nothing
//local timer t = GetExpiredTimer()
local thistype this = GetTimerData(GetExpiredTimer())
local real source_x = GetUnitX(this.source)
local real source_y = GetUnitY(this.source)
local real target_x = GetUnitX(this.target)
local real target_y = GetUnitY(this.target)
local real angle = Atan2(target_y - source_y, target_x - source_x) + this.launch_angle
local real launch_x = 0.
local real launch_y = 0.
local real launch_z = 0.
local real impact_x = 0.
local real impact_y = 0.
local real impact_z = 0.
local integer iLoop = 0
local boolean set_is_ongoing = false
loop
set iLoop = iLoop + 1
if not this.f_is_laser_dead[iLoop] then
if this.sentry == null then
set launch_x = source_x + Cos(angle) * this.launch_offset
set launch_y = source_y + Sin(angle) * this.launch_offset
set launch_z = GetUnitZ(this.source) + this.launch_height
else
set launch_x = GetUnitX(this.sentry) + Cos(angle) * this.launch_offset
set launch_y = GetUnitY(this.sentry) + Sin(angle) * this.launch_offset
set launch_z = GetUnitZ(this.sentry) + this.launch_height
endif
if this.impact_lock then
set impact_x = target_x + Cos(this.f_lock_angle[iLoop]) * this.f_lock_distance[iLoop]
set impact_x = target_y + Sin(this.f_lock_angle[iLoop]) * this.f_lock_distance[iLoop]
set impact_x = GetUnitZ(this.target) + this.f_lock_height[iLoop]
if this.f_laser[iLoop] != null then //I set this if.then.else here because I want the IMPACTS to be set for the EVENTS below.
call MoveLightningEx(this.f_laser[iLoop], true, launch_x, launch_y, launch_z, impact_x, impact_y, impact_z)
endif
else
set impact_x = this.f_impact_x[iLoop]
set impact_y = this.f_impact_y[iLoop]
set impact_z = this.f_impact_z[iLoop]
if this.f_laser[iLoop] != null then
call MoveLightningEx(this.f_laser[iLoop], true, launch_x, launch_y, launch_z, this.f_impact_x[iLoop], this.f_impact_y[iLoop], this.f_impact_z[iLoop])
endif
endif
if this.f_fading[iLoop] then
set this.f_alpha[iLoop] = this.f_alpha[iLoop] - this.fade_amount
if this.f_laser[iLoop] != null then
call SetLightningColor(this.f_laser[iLoop], this.red, this.blue, this.green, this.f_alpha[iLoop])
endif
if this.f_alpha[iLoop] <= 0. then
//EVENT
/*set BL_EVENT_Source = LaserSource[NewTimerID]
set BL_EVENT_Target = LaserTarget[NewTimerID]
set BL_EVENT_Sentry = LaserSentry[NewTimerID]
set BL_EVENT_Launch_x = LAUNCH_X
set BL_EVENT_Launch_y = LAUNCH_Y
set BL_EVENT_Launch_z = LAUNCH_Z
set BL_EVENT_Impact_x = IMPACT_X
set BL_EVENT_Impact_y = IMPACT_Y
set BL_EVENT_Impact_z = IMPACT_Z
set BL_EVENT = 2.5
set BL_EVENT_Source = null
set BL_EVENT_Target = null
set BL_EVENT_Sentry = null
set BL_EVENT_Launch_x = 0.
set BL_EVENT_Launch_y = 0.
set BL_EVENT_Launch_z = 0.
set BL_EVENT_Impact_x = 0.
set BL_EVENT_Impact_y = 0.
set BL_EVENT_Impact_z = 0.
set BL_EVENT = 0.*/
//END EVENT
set this.f_is_laser_dead[iLoop] = true
if this.f_laser[iLoop] != null then
call DestroyLightning(this.f_laser[iLoop])
set this.f_laser[iLoop] = null
endif
endif
else
set this.f_duration[iLoop] = this.f_duration[iLoop] - 1
if this.f_duration[iLoop] <= 0 then
set this.f_fading[iLoop] = true
endif
endif//if this.f_fading[iLoop] then
endif//if not this.f_is_laser_dead[iLoop] then
exitwhen iLoop >= this.laser_num
endloop
set iLoop = 0
loop
set iLoop = iLoop + 1
if not this.f_is_laser_dead[iLoop] then
set set_is_ongoing = true
endif
exitwhen iLoop >= this.laser_num
endloop
if not set_is_ongoing then
call ReleaseTimer(this.tmr_laserfade)
call deallocate(this)
endif
//set t = null
endmethod
static method BurstLaser_Volley takes nothing returns nothing
//local timer t = GetExpiredTimer()
local thistype this = GetTimerData(GetExpiredTimer())
local real source_x = GetUnitX(this.source)
local real source_y = GetUnitY(this.source)
local real target_x = GetUnitX(this.target)
local real target_y = GetUnitY(this.target)
local real angle = Atan2(target_y - source_y, target_x - source_x) + this.launch_angle
local real launch_x = 0.
local real launch_y = 0.
local real launch_z = 0.
local real impact_x = 0.
local real impact_y = 0.
local real impact_z = 0.
local boolean b = false
local unit u = null
if this.sentry == null then
set launch_x = source_x + Cos(angle + this.launch_angle) * this.launch_offset
set launch_y = source_y + Sin(angle + this.launch_angle) * this.launch_offset
set launch_z = GetUnitZ(this.source) + this.launch_height
else
set launch_x = GetUnitX(this.sentry) + Cos(angle + this.launch_angle) * this.launch_offset
set launch_y = GetUnitY(this.sentry) + Sin(angle + this.launch_angle) * this.launch_offset
set launch_z = GetUnitZ(this.sentry) + this.launch_height
endif
if this.range_lock then //if true, start from the source's point
if this.follow_target then
set angle = Atan2(target_y - this.initial_y, target_x - this.initial_x)
set this.impact_x = this.impact_x + Cos(angle) * this.range_per_laser
set this.impact_y = this.impact_y + Sin(angle) * this.range_per_laser
set impact_x = this.impact_x + GetRandomReal(this.spread_xy*-1, this.spread_xy)
set impact_y = this.impact_y + GetRandomReal(this.spread_xy*-1, this.spread_xy)
if this.grounded then
set this.impact_z = 0.
set impact_z = 0.
else
set this.impact_z = GetUnitZ(this.target)
set impact_z = this.impact_z + GetRandomReal(this.spread_z*-1, this.spread_z) + this.target_coll * .8
endif
else
set this.impact_x = this.impact_x + Cos(this.laser_angle) * this.range_per_laser
set this.impact_y = this.impact_y + Sin(this.laser_angle) * this.range_per_laser
set impact_x = this.impact_x + GetRandomReal(this.spread_xy*-1, this.spread_xy)
set impact_y = this.impact_y + GetRandomReal(this.spread_xy*-1, this.spread_xy)
if this.grounded then
set this.impact_z = 0.
set impact_z = 0.
else
set impact_z = this.impact_z + GetRandomReal(this.spread_z*-1, this.spread_z) + this.target_coll * .8
endif
endif
else
if this.follow_target then
set angle = Atan2(target_y - this.initial_y, target_x - this.initial_x)
set this.impact_x = this.impact_x + Cos(angle) * this.range_per_laser
set this.impact_y = this.impact_y + Sin(angle) * this.range_per_laser
set impact_x = this.impact_x + GetRandomReal(this.spread_xy*-1, this.spread_xy)
set impact_y = this.impact_y + GetRandomReal(this.spread_xy*-1, this.spread_xy)
if this.grounded then
set this.impact_z = 0.
set impact_z = 0.
else
set this.impact_z = GetUnitZ(this.target)
set impact_z = this.impact_z + GetRandomReal(this.spread_z*-1, this.spread_z) + this.target_coll * .8
endif
else
set this.impact_x = this.impact_x + Cos(this.laser_angle) * this.range_per_laser
set this.impact_y = this.impact_y + Sin(this.laser_angle) * this.range_per_laser
set impact_x = this.impact_x + GetRandomReal(this.spread_xy*-1, this.spread_xy)
set impact_y = this.impact_y + GetRandomReal(this.spread_xy*-1, this.spread_xy)
if this.grounded then
set this.impact_z = 0.
set impact_z = 0.
else
set impact_z = this.impact_z + GetRandomReal(this.spread_z*-1, this.spread_z) + this.target_coll * .8
endif
endif
endif
//Launch
if this.launch_string != null then
set b = true
call DestroyEffect(AddSpecialEffectZ(this.launch_string, this.launch_x, this.launch_y, this.launch_z))
endif
//Impact
if this.impact_string != null then
set b = true
if this.grounded then
call DestroyEffect(AddSpecialEffect(this.impact_string, impact_x, impact_y))
else
call DestroyEffect(AddSpecialEffectZ(this.impact_string, impact_x, impact_y, impact_z))
endif
endif
//Area
if this.area_string != null then
set b = true
if this.grounded then
call DestroyEffect(AddSpecialEffect(this.area_string, impact_x, impact_y))
else
call DestroyEffect(AddSpecialEffectZ(this.area_string, impact_x, impact_y, impact_z))
endif
endif
//Laser
if this.laser_string != null then
set b = true
set this.laser_index = this.laser_index + 1
set this.f_impact_x[this.laser_index] = impact_x
set this.f_impact_y[this.laser_index] = impact_y
set this.f_impact_z[this.laser_index] = impact_z
set this.f_alpha[this.laser_index] = this.alpha
set this.f_fading[this.laser_index] = false
if this.impact_lock then
set this.f_lock_angle[this.laser_index] = Atan2(impact_y - target_y, impact_x - target_x)
set this.f_lock_distance[this.laser_index] = SquareRoot( (impact_x-target_x)*(impact_x-target_x) + (impact_y-target_y)*(impact_y-target_y) )
set this.f_lock_height[this.laser_index] = impact_z - GetUnitZ(this.target)
endif
set this.fade_amount = this.alpha / this.fade_time
set this.f_laser[this.laser_index] = AddLightningEx(this.laser_string, true, this.launch_x, this.launch_y, this.launch_z, this.impact_spread_x, this.impact_spread_y, this.impact_spread_z)
call SetLightningColor(this.f_laser[this.laser_index], this.red, this.green, this.blue, this.f_alpha[this.laser_index])
endif
//Damage
if this.aoe > 0. then
call GroupEnumUnitsInRange(DamageGroup, impact_x, impact_y, this.aoe + MAX_COLLISION_SIZE, null)
loop
set u = FirstOfGroup(DamageGroup)
call GroupRemoveUnit(DamageGroup, u)
exitwhen u == null
if IsUnitInRangeXY(u, impact_x, impact_y, this.aoe) and UnitAlive(u) and /*
[Friendly Fire] */( (this.friendly_fire and (IsUnitEnemy(u, this.owner) or IsUnitAlly(u, this.owner))) or /*
[Enemy] */ ( (not this.friendly_fire and IsUnitEnemy(u, this.owner)) or /*
[Friendly] */ (not this.friendly_fire and IsUnitAlly(u, this.owner) and u == this.target) ) ) and /*
[Magic Immune] */( (this.attack_type == ATTACK_TYPE_MAGIC and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)) or /*
[Ethereal] */ (this.attack_type != ATTACK_TYPE_MAGIC and not IsUnitType(u, UNIT_TYPE_ETHEREAL)) ) then
if not this.hit_all and /*
[Ground] */ ( (not IsUnitType(u, UNIT_TYPE_FLYING) and not IsUnitType(this.target, UNIT_TYPE_FLYING)) or /*
[Flying] */ (IsUnitType(u, UNIT_TYPE_FLYING) and IsUnitType(this.target, UNIT_TYPE_FLYING)) ) then
set udg_NextDamageType = this.damage_type
call UnitDamageTarget(this.source, u, this.damage, true, true, this.attack_type, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
call TriggerEvaluate(udg_ClearDamageEvent)
elseif this.hit_all then
set udg_NextDamageType = this.damage_type
call UnitDamageTarget(this.source, u, this.damage, true, true, this.attack_type, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
call TriggerEvaluate(udg_ClearDamageEvent)
endif
endif
endloop
else
set udg_NextDamageType = this.damage_type
call UnitDamageTarget(this.source, this.target, this.damage, true, true, this.attack_type, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
call TriggerEvaluate(udg_ClearDamageEvent)
endif
//EVENT
/*set BL_EVENT_Source = LaserSource[tID]
set BL_EVENT_Target = LaserTarget[tID]
set BL_EVENT_Sentry = LaserSentry[tID]
set BL_EVENT_Launch_x = LAUNCH_X
set BL_EVENT_Launch_y = LAUNCH_Y
set BL_EVENT_Launch_z = LAUNCH_Z
set BL_EVENT_Impact_x = IMPACT_X
set BL_EVENT_Impact_y = IMPACT_Y
set BL_EVENT_Impact_z = IMPACT_Z
set BL_EVENT = 2.
set BL_EVENT_Source = null
set BL_EVENT_Target = null
set BL_EVENT_Sentry = null
set BL_EVENT_Launch_x = 0.
set BL_EVENT_Launch_y = 0.
set BL_EVENT_Launch_z = 0.
set BL_EVENT_Impact_x = 0.
set BL_EVENT_Impact_y = 0.
set BL_EVENT_Impact_z = 0.
set BL_EVENT = 0.*/
//END EVENT
set this.count = this.count - 1
if this.count <= 0 or not UnitAlive(this.source) or ( this.uninterruptible and /*
[Move] */ (GetUnitCurrentOrder(this.source) == 851986 or /*
[Stunned] */ GetUnitCurrentOrder(this.source) == 851973 or /*
[Stop] */ GetUnitCurrentOrder(this.source) == 851972) ) then
//EVENT
/*set BL_EVENT_Source = LaserSource[tID]
set BL_EVENT_Target = LaserTarget[tID]
set BL_EVENT_Sentry = LaserSentry[tID]
set BL_EVENT_Launch_x = LAUNCH_X
set BL_EVENT_Launch_y = LAUNCH_Y
set BL_EVENT_Launch_z = LAUNCH_Z
set BL_EVENT_Impact_x = IMPACT_X
set BL_EVENT_Impact_y = IMPACT_Y
set BL_EVENT_Impact_z = IMPACT_Z
set BL_EVENT = 3.
set BL_EVENT_Source = null
set BL_EVENT_Target = null
set BL_EVENT_Sentry = null
set BL_EVENT_Launch_x = 0.
set BL_EVENT_Launch_y = 0.
set BL_EVENT_Launch_z = 0.
set BL_EVENT_Impact_x = 0.
set BL_EVENT_Impact_y = 0.
set BL_EVENT_Impact_z = 0.
set BL_EVENT = 0.*/
//END EVENT
call ReleaseTimer(this.tmr_volley)
set this.tmr_volley = null
if not this.failsafe_check then
call deallocate(this)
call this.destroy()
endif
endif
//set t = null
endmethod
static method create takes unit unit_source, unit unit_target, unit unit_sentry, integer id, real damage returns thistype
local thistype this = allocate()
local real source_x = GetUnitX(unit_source)
local real source_y = GetUnitY(unit_source)
local real target_x = GetUnitX(unit_target)
local real target_y = GetUnitY(unit_target)
local real sentry_x = 0.
local real sentry_y = 0.
local real startangle = Atan2(target_y - source_y, target_x - source_x)
local real range_offset = 0.
local real impact_spread_x = 0.
local real impact_spread_y = 0.
local real impact_spread_z = 0.
local boolean b = false
local unit u = null
set this.owner = GetOwningPlayer(unit_source)
set this.source = unit_source
set this.target = unit_target
set this.sentry = unit_sentry
//set this.id = id
set this.damage = damage
set this.target_coll = GetUnitCollision(unit_target)
set this.laser_string = BL_LaserString[id]
set this.red = BL_RED[id]
set this.blue = BL_BLUE[id]
set this.green = BL_GREEN[id]
set this.alpha = BL_ALPHA[id]
set this.launch_string = BL_LaserLaunchFX[id]
set this.impact_string = BL_LaserImpactFX[id]
set this.area_string = BL_LaserAreaFX[id]
set this.duration = BL_LaserDuration[id]
set this.fade_time = BL_LaserFadeTime[id]
set this.interval = BL_LaserInterval[id]
set this.aoe = BL_LaserAOE[id]
set this.grounded = BL_IsLaserGrounded[id]
set this.launch_offset = BL_LaserLaunchOffset[id]
set this.launch_height = BL_LaserLaunchHeight[id]
set this.launch_angle = BL_LaserLaunchAngle[id]
set this.spread_xy = BL_LaserSpreadXY[id]
set this.spread_z = BL_LaserSpreadZ[id]
set this.follow_target = BL_FollowTarget[id]
set this.impact_lock = BL_LaserImpactLock[id]
set this.range_lock = BL_LaserRangeLock[id]
set this.range_start = BL_LaserRangeStart[id]
set this.range_per_laser = BL_LaserRangePerLaser[id]
set this.attack_type = BL_LaserAttackType[id]
set this.damage_type = BL_LaserDamageType[id]
set this.uninterruptible = BL_Uninterruptible[id]
set this.hit_all = BL_LaserHitAll[id]
set this.friendly_fire = BL_LaserFriendlyFire[id]
//there's a hard limit to how many lasers you may have per set. This is because you have to declare the size of arrays of variables in a struct
//if you want to have more that 20 lasers per set, feel free to change the value of MAX_LASERS at the top.
if BL_NumberOfLasers[id] > MAX_LASERS then
set this.laser_num = MAX_LASERS
else
set this.laser_num = BL_NumberOfLasers[id]
endif
if this.sentry == null then
if this.launch_offset > 0. then
set this.launch_x = source_x + Cos(startangle + this.launch_angle) * this.launch_offset
set this.launch_y = source_y + Sin(startangle + this.launch_angle) * this.launch_offset
else
set this.launch_x = source_x
set this.launch_y = source_y
endif
set this.launch_z = GetUnitZ(this.source) + this.launch_height
else
set sentry_x = GetUnitX(this.sentry)
set sentry_y = GetUnitY(this.sentry)
if this.launch_offset > 0. then
set this.launch_x = sentry_x + Cos(startangle + this.launch_angle) * this.launch_offset
set this.launch_y = sentry_y + Sin(startangle + this.launch_angle) * this.launch_offset
else
set this.launch_x = sentry_x
set this.launch_y = sentry_y
endif
set this.launch_z = GetUnitZ(this.sentry) + this.launch_height
endif
set range_offset = ((this.laser_num-1) * this.range_per_laser + this.range_start) * .5
if this.range_lock then //if true, start from the source's point
set this.impact_x = source_x + Cos(startangle) * (range_offset + this.range_start)
set this.impact_y = source_y + Sin(startangle) * (range_offset + this.range_start)
set startangle = startangle + BL_LaserDirectionalTilt[id]
set this.impact_x = this.impact_x + Cos(startangle) * (range_offset)
set this.impact_y = this.impact_y + Sin(startangle) * (range_offset)
set this.impact_spread_x = this.impact_x + GetRandomReal(this.spread_xy*-1, this.spread_xy)
set this.impact_spread_y = this.impact_y + GetRandomReal(this.spread_xy*-1, this.spread_xy)
if this.grounded then
set this.impact_z = 0.
set this.impact_spread_z = 0.
else
set this.impact_z = GetUnitZ(this.target)
set this.impact_spread_z = this.impact_z + GetRandomReal(this.spread_z*-1, this.spread_z) + this.target_coll * COLLISION_PERCENTAGE
endif
else
set startangle = startangle + BL_LaserDirectionalTilt[id] + 3.14159
if this.range_per_laser != 0. then
set this.impact_x = target_x + Cos(startangle) * (range_offset + this.range_start)
set this.impact_y = target_y + Sin(startangle) * (range_offset + this.range_start)
else
set this.impact_x = target_x + Cos(startangle) * (this.target_coll * COLLISION_PERCENTAGE)
set this.impact_y = target_y + Sin(startangle) * (this.target_coll * COLLISION_PERCENTAGE)
endif
set this.impact_spread_x = this.impact_x + GetRandomReal(this.spread_xy * -1, this.spread_xy)
set this.impact_spread_y = this.impact_y + GetRandomReal(this.spread_xy * -1, this.spread_xy)
if this.grounded then
set this.impact_z = 0.
set this.impact_spread_z = 0.
else
set this.impact_z = GetUnitZ(this.target)
set this.impact_spread_z = this.impact_z + GetRandomReal(this.spread_z*-1, this.spread_z) + this.target_coll * COLLISION_PERCENTAGE
endif
endif
//Launch
if this.launch_string != null then
set b = true
call DestroyEffect(AddSpecialEffectZ(this.launch_string, this.launch_x, this.launch_y, this.launch_z))
endif
//Impact
if this.impact_string != null then
set b = true
if this.grounded then
call DestroyEffect(AddSpecialEffect(this.impact_string, impact_spread_x, impact_spread_y))
else
call DestroyEffect(AddSpecialEffectZ(this.impact_string, impact_spread_x, impact_spread_y, impact_spread_z))
endif
endif
//Area
if this.area_string != null then
set b = true
if this.grounded then
call DestroyEffect(AddSpecialEffect(this.area_string, impact_spread_x, impact_spread_y))
else
call DestroyEffect(AddSpecialEffectZ(this.area_string, impact_spread_x, impact_spread_y, impact_spread_z))
endif
endif
//Laser
if this.laser_string != null then
set b = true
set this.laser_index = this.laser_index + 1
//set this.f_source[this.laser_index] = this.source
//set this.f_target[this.laser_index] = this.arget
//set this.f_sentry[this.laser_index] = this.entry
//set this.f_launch_offset[this.laser_index] = this.launch_offset
//set this.f_launch_height[this.laser_index] = this.launch_height
//set this.f_launch_angle[this.laser_index] = this.launch_angle
//set this.f_impact_lock[this.laser_index] = this.impact_lock
set this.f_impact_x[this.laser_index] = impact_x
set this.f_impact_y[this.laser_index] = impact_y
set this.f_impact_z[this.laser_index] = impact_z
//set this.f_red[this.laser_index] = this.red
//set this.f_blue[this.laser_index] = this.blue
//set this.f_green[this.laser_index] = this.green
set this.f_alpha[this.laser_index] = this.alpha
set this.f_fading[this.laser_index] = false
if this.impact_lock then
set this.f_lock_angle[this.laser_index] = Atan2(impact_y - target_y, impact_x - target_x)
set this.f_lock_distance[this.laser_index] = SquareRoot( (impact_x-target_x)*(impact_x-target_x) + (impact_y-target_y)*(impact_y-target_y) )
set this.f_lock_height[this.laser_index] = impact_z - GetUnitZ(this.target)
endif
set this.fade_amount = this.alpha / this.fade_time
set this.f_laser[this.laser_index] = AddLightningEx(this.laser_string, true, this.launch_x, this.launch_y, this.launch_z, this.impact_spread_x, this.impact_spread_y, this.impact_spread_z)
call SetLightningColor(this.f_laser[this.laser_index], this.red, this.green, this.blue, this.f_alpha[this.laser_index])
endif
//Damage
if this.aoe > 0. then
call GroupEnumUnitsInRange(DamageGroup, impact_x, impact_y, this.aoe + MAX_COLLISION_SIZE, null)
loop
set u = FirstOfGroup(DamageGroup)
call GroupRemoveUnit(DamageGroup, u)
exitwhen u == null
if IsUnitInRangeXY(u, impact_x, impact_y, this.aoe) and UnitAlive(u) and /*
[Friendly Fire] */( (this.friendly_fire and (IsUnitEnemy(u, this.owner) or IsUnitAlly(u, this.owner))) or /*
[Enemy] */ ( (not this.friendly_fire and IsUnitEnemy(u, this.owner)) or /*
[Friendly] */ (not this.friendly_fire and IsUnitAlly(u, this.owner) and u == this.target) ) ) and /*
[Magic Immune] */( (this.attack_type == ATTACK_TYPE_MAGIC and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)) or /*
[Ethereal] */ (this.attack_type != ATTACK_TYPE_MAGIC and not IsUnitType(u, UNIT_TYPE_ETHEREAL)) ) then
if not this.hit_all and /*
[Ground] */ ( (not IsUnitType(u, UNIT_TYPE_FLYING) and not IsUnitType(this.target, UNIT_TYPE_FLYING)) or /*
[Flying] */ (IsUnitType(u, UNIT_TYPE_FLYING) and IsUnitType(this.target, UNIT_TYPE_FLYING)) ) then
set udg_NextDamageType = this.damage_type
call UnitDamageTarget(this.source, u, this.damage, true, true, this.attack_type, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
call TriggerEvaluate(udg_ClearDamageEvent)
elseif this.hit_all then
set udg_NextDamageType = this.damage_type
call UnitDamageTarget(this.source, u, this.damage, true, true, this.attack_type, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
call TriggerEvaluate(udg_ClearDamageEvent)
endif
endif
endloop
else
set udg_NextDamageType = this.damage_type
call UnitDamageTarget(this.source, this.target, this.damage, true, true, this.attack_type, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
call TriggerEvaluate(udg_ClearDamageEvent)
endif
//Volley
if this.laser_num > 1 then
if b then
set this.failsafe_check = true
endif
set this.laser_angle = startangle + 3.14159
set this.initial_x = this.impact_x
set this.initial_y = this.impact_y
set this.tmr_volley = NewTimerEx(this)
call TimerStart(this.tmr_volley, this.interval, true, timer_volley_handler)
endif
//Timer
if b then
set this.failsafe_check = true
set this.tmr_laserfade = NewTimerEx(this)
call TimerStart(this.tmr_laserfade, .03125, true, timer_laserfade_handler)
set b = false
endif
return this
endmethod
endstruct
endlibrary