- Joined
- Jan 9, 2005
- Messages
- 2,126
I'm working on this system that shoots a series of lightning effects, and I'm using 2 timers to A) control the interval between each shot and B) fade out each individual lightning effect. I'm having some issues getting the fade timer to work, however. It just doesn't run. I've used DebugMsg in all functions and the ones in IndividualLaser_Timer don't print on screen when I test it.
JASS:
library BL initializer BurstLaser_Setup
globals
private trigger BurstLaserTrigger = CreateTrigger()
public boolean array UsesBurstLaser //Must always be true or the system won't work.
public boolean array Uninterruptible //If true, lasers will keep firing even if the target is stunned or dead.
public boolean array IsLaserGrounded //If true, then your Lasers will always strike the ground. Invalidates LaserSpreadZ. Can be useful for AoE ground attacks.
public integer array NumberOfLasers //CANNOT BE LESS THAN 1 or you will deal no damage. The number of lasers that will be shot per attack. CANNOT BE LESS THAN 1
public integer array LaserDuration //How long an individual laser will last before it starts to fade.
public integer array LaserFadeTime //How long it takes for each laser to fade. 32 == 1 second.
public integer array LaserInterval //The time between lasers. 32 == 1 second.
public string array LaserLaunchFX //The string of the special effect that plays on the launch dummy.
public string array LaserImpactFX //The string of the special effect that plays on the impact dummy.
public string array LaserAreaFX //The string of the special effect that plays on the impact dummy in addition to the ImpactFX. Works better with an AOE laser.
public real array LaserLaunchScale //Size of the Launch
public real array LaserImpactScale //Size of the Impact
public real array LaserAreaScale //Size of the Area effect
public string array LaserString //The string of lightning effect itself.
public real array LaserAOE //If greater that 0. will deal damage in an area around the impact.
public real array LaserLaunchOffset //How far forward with the Launch effect be. Use negative values to move backwards.
public real array LaserLaunchHeight //Adjusts the Launch effect along the Z axis. Positive value go up, negative values go down.
public real array LaserLaunchAngle //By how many degrees will the Launch effect be? Positive values adjust the angle counter-clockwise.
public real array LaserSpreadXY //How much your laser will spread out along the X and Y axis.
public real array LaserSpreadZ //How much your laser will spread out along the Z axis.
public attacktype array LaserAttackType //Vanilla attack type like ATTACK_TYPE_HERO, ATTACK_TYPE_PIERCE, etc
public integer array LaserDamageType //The damage type from Damage Engine
public boolean array LaserHitAll //The laser will harm all units in the LaserAOE. If LaserAOE is <= 0. this does nothing.
public boolean array LaserFriendlyFire //AOE damage will damage allies
public unit array LaserSentry //This is optional. If something is set as the Sentry, the lasers will shoot from that unit instead.
public integer array LaserDummyType //This is the dummy used for launch and impact effects.
public real array RED
public real array BLUE
public real array GREEN
public real array ALPHA
//Events
public real EVENT = 0.
public unit EVENT_Source = null
public unit EVENT_Target = null
endglobals
function BurstLaser_onIndex takes nothing returns boolean
local unit Source = udg_UDexUnits[udg_UDex]
local integer ID = udg_UDex
if udg_UnitIndexEvent == 1. then
//Raycaster
if GetUnitTypeId(Source) == 'aray' then
set UsesBurstLaser[ID] = true
set LaserString[ID] = "YLLN"
set RED[ID] = 1.
set BLUE[ID] = 1.
set GREEN[ID] = 1.
set ALPHA[ID] = 1.
set LaserLaunchFX[ID] = "Abilities\\Weapons\\ProcMissile\\ProcMissile.mdl"
set LaserImpactFX[ID] = "Abilities\\Weapons\\ProcMissile\\ProcMissile.mdl"
set LaserAreaFX[ID] = ""
set LaserLaunchScale[ID] = 1.
set LaserImpactScale[ID] = 1.
set LaserAreaScale[ID] = 1.
set NumberOfLasers[ID] = 3
set LaserDuration[ID] = 7
set LaserFadeTime[ID] = 11
set LaserInterval[ID] = 7
set LaserAOE[ID] = 0.
set IsLaserGrounded[ID] = false
set LaserLaunchOffset[ID] = 40.
set LaserLaunchHeight[ID] = 60.
set LaserLaunchAngle[ID] = 0.
set LaserSpreadXY[ID] = 20.
set LaserSpreadZ[ID] = 20.
set LaserAttackType[ID] = ATTACK_TYPE_PIERCE
set LaserDamageType[ID] = udg_DamageTypeCode
set Uninterruptible[ID] = false
set LaserHitAll[ID] = false
set LaserFriendlyFire[ID] = false
set LaserSentry[ID] = null
set LaserDummyType[ID] = 'dumi'
//Fire Beam
elseif GetUnitTypeId(Source) == '????' then
endif
else
set UsesBurstLaser[ID] = false
set LaserString[ID] = ""
set RED[ID] = 1.
set BLUE[ID] = 1.
set GREEN[ID] = 1.
set ALPHA[ID] = 1.
set LaserLaunchFX[ID] = ""
set LaserImpactFX[ID] = ""
set LaserAreaFX[ID] = ""
set LaserLaunchScale[ID] = 1.
set LaserImpactScale[ID] = 1.
set LaserAreaScale[ID] = 1.
set NumberOfLasers[ID] = 1
set LaserDuration[ID] = 1
set LaserFadeTime[ID] = 1
set LaserInterval[ID] = 1
set LaserAOE[ID] = 0.
set IsLaserGrounded[ID] = false
set LaserLaunchOffset[ID] = 0.
set LaserLaunchHeight[ID] = 0.
set LaserLaunchAngle[ID] = 0.
set LaserSpreadXY[ID] = 0.
set LaserSpreadZ[ID] = 0.
set LaserAttackType[ID] = null
set LaserDamageType[ID] = 0
set Uninterruptible[ID] = false
set LaserHitAll[ID] = false
set LaserFriendlyFire[ID] = false
set LaserSentry[ID] = null
set LaserDummyType[ID] = 0
endif
set Source = null
return false
endfunction
function BurstLaser_Setup takes nothing returns nothing
call TriggerRegisterVariableEvent( BurstLaserTrigger, "udg_UnitIndexEvent", EQUAL, 1.00 )
call TriggerRegisterVariableEvent( BurstLaserTrigger, "udg_UnitIndexEvent", EQUAL, 2.00 )
call TriggerAddCondition( BurstLaserTrigger, function BurstLaser_onIndex)
endfunction
endlibrary
JASS:
scope BLonAttack initializer BL_onAttack
globals
private trigger BL_onAttack_Trigger = CreateTrigger()
private group DamageGroup = CreateGroup()
private constant real MAX_COLLISION_SIZE = 196.
private real array Damage
private real array FadeAmount
private real array LaserRED
private real array LaserBLUE
private real array LaserGREEN
private real array LaserALPHA
private unit array LaserSource
private unit array LaserTarget
private unit array LaserDummyImpact
private unit array LaserDummyLaunch
private unit array LaserDummyArea
private integer array LaserDummyType
private integer array LaserInterval
private integer array LaserIntervalSave
private integer array LaserCount
private lightning array Laser
private boolean array IsLaserFading
private boolean array IsLaserGrounded
private boolean array LaserHitAll
private boolean array LaserFriendlyFire
private real array LaserLaunchOffset
private real array LaserLaunchHeight
private real array LaserLaunchAngle
private real array LaserSpreadXY
private real array LaserSpreadZ
private string array LaserString
private string array LaserLaunchFX
private string array LaserImpactFX
private string array LaserAreaFX
private real array LaserLaunchScale
private real array LaserImpactScale
private real array LaserAreaScale
private real array LaserDamage
private real array LaserAOE
private attacktype array LaserAttackType
private integer array LaserDamageType
endglobals
function IndividualLaser_Timer takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer NewTimerID = GetTimerData(t)
if IsLaserFading[NewTimerID] then
call BJDebugMsg("fade")
set LaserALPHA[NewTimerID] = LaserALPHA[NewTimerID] - FadeAmount[NewTimerID]
call SetLightningColor(Laser[NewTimerID], LaserRED[NewTimerID], LaserBLUE[NewTimerID], LaserGREEN[NewTimerID], LaserALPHA[NewTimerID])
if LaserALPHA[NewTimerID] <= 0. then
if LIBRARY_MissileRecycler then
call RecycleMissile(LaserDummyLaunch[NewTimerID])
call RecycleMissile(LaserDummyImpact[NewTimerID])
call RecycleMissile(LaserDummyArea[NewTimerID])
else
call RemoveUnit(LaserDummyLaunch[NewTimerID])
call RemoveUnit(LaserDummyImpact[NewTimerID])
call RemoveUnit(LaserDummyArea[NewTimerID])
endif
set LaserDummyLaunch[NewTimerID] = null
set LaserDummyImpact[NewTimerID] = null
set LaserDummyArea[NewTimerID] = null
call DestroyLightning(Laser[NewTimerID])
set Laser[NewTimerID] = null
call IndexDeallocate(NewTimerID)
call ReleaseTimer(t)
endif
else
call BJDebugMsg("duration")
set LaserInterval[NewTimerID] = LaserInterval[NewTimerID] - 1
if LaserInterval[NewTimerID] <= 0 then
set IsLaserFading[NewTimerID] = true
endif
endif
endfunction
function BurstLaser_Timer takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer tID = GetTimerData(t)
local timer New_t = null
local integer NewTimerID = 0
local player SourcePlayer = GetOwningPlayer(LaserSource[tID])
local boolean b = false
local real SOURCE_X = GetUnitX(LaserSource[tID])
local real SOURCE_Y = GetUnitY(LaserSource[tID])
local real TARGET_X = GetUnitX(LaserTarget[tID])
local real TARGET_Y = GetUnitY(LaserTarget[tID])
local real Angle = Atan2(SOURCE_Y - TARGET_Y, SOURCE_X - TARGET_X) + LaserLaunchAngle[tID]
local unit u = null
local real TargetColl = GetUnitCollision(LaserTarget[tID])
local real LAUNCH_X = SOURCE_X + Cos(Angle) * LaserLaunchOffset[tID]
local real LAUNCH_Y = SOURCE_Y + Sin(Angle) * LaserLaunchOffset[tID]
local real LAUNCH_Z = GetUnitZ(LaserSource[tID]) + LaserLaunchHeight[tID]
local real IMPACT_X = (TARGET_X + Cos(Angle + 3.14159) * (TargetColl * .8)) + GetRandomReal(LaserSpreadXY[tID] * -1, LaserSpreadXY[tID])
local real IMPACT_Y = (TARGET_Y + Sin(Angle + 3.14159) * (TargetColl * .8)) + GetRandomReal(LaserSpreadXY[tID] * -1, LaserSpreadXY[tID])
local real IMPACT_Z = GetUnitZ(LaserTarget[tID]) + GetRandomReal(LaserSpreadZ[tID] * -1, LaserSpreadZ[tID])
set LaserInterval[tID] = LaserInterval[tID] - 1
if LaserInterval[tID] <= 0 then
set LaserCount[tID] = LaserCount[tID] - 1
set LaserInterval[tID] = LaserIntervalSave[tID]
set NewTimerID = IndexAllocate()
//Launch
if LaserLaunchFX[tID] != null then
set b = true
if LIBRARY_MissileRecycler then
set LaserDummyLaunch[NewTimerID] = GetRecycledMissile(LAUNCH_X, LAUNCH_Y, LAUNCH_Z, Angle)
else
set LaserDummyLaunch[NewTimerID] = CreateUnit(Player(14), LaserDummyType[tID], LAUNCH_X, LAUNCH_Y, Angle)
call SetUnitFlyHeight(LaserDummyLaunch[NewTimerID], IMPACT_Z, 0.)
endif
call SetUnitScale(LaserDummyLaunch[NewTimerID], LaserLaunchScale[NewTimerID], 0., 0.)
call DestroyEffect(AddSpecialEffectTarget(LaserLaunchFX[tID], LaserDummyLaunch[NewTimerID], "origin"))
endif
//Impact
if LaserImpactFX[tID] != null then
set b = true
/*if IsLaserGrounded[tID] then
set IMPACT_Z = 0.
endif
if LIBRARY_MissileRecycler then
set LaserDummyImpact[NewTimerID] = GetRecycledMissile(IMPACT_X, IMPACT_Y, IMPACT_Z, Angle)
else*/
set LaserDummyImpact[NewTimerID] = CreateUnit(Player(14), LaserDummyType[tID], IMPACT_X, IMPACT_Y, Angle)
call SetUnitFlyHeight(LaserDummyImpact[NewTimerID], IMPACT_Z, 0.)
//endif
call SetUnitScale(LaserDummyImpact[NewTimerID], LaserImpactScale[NewTimerID], 0., 0.)
call DestroyEffect(AddSpecialEffectTarget(LaserImpactFX[tID], LaserDummyImpact[NewTimerID], "origin"))
endif
//Area
if LaserAreaFX[tID] != null then
set b = true
if LIBRARY_MissileRecycler then
set LaserDummyArea[NewTimerID] = GetRecycledMissile(IMPACT_X, IMPACT_Y, IMPACT_Z, Angle)
else
set LaserDummyArea[NewTimerID] = CreateUnit(Player(14), LaserDummyType[tID], IMPACT_X, IMPACT_Y, Angle)
call SetUnitFlyHeight(LaserDummyArea[NewTimerID], IMPACT_Z, 0.)
endif
call SetUnitScale(LaserDummyArea[NewTimerID], LaserAreaScale[NewTimerID], 0., 0.)
call DestroyEffect(AddSpecialEffectTarget(LaserAreaFX[tID], LaserDummyArea[NewTimerID], "origin"))
endif
//Laser
if LaserString[tID] != null then
set b = true
set LaserRED[NewTimerID] = LaserRED[tID]
set LaserBLUE[NewTimerID] = LaserBLUE[tID]
set LaserGREEN[NewTimerID] = LaserGREEN[tID]
set LaserALPHA[NewTimerID] = LaserALPHA[tID]
set Laser[NewTimerID] = AddLightningEx(LaserString[tID], true, LAUNCH_X, LAUNCH_Y, LAUNCH_Z, IMPACT_X, IMPACT_Y, IMPACT_Z)
call SetLightningColor(Laser[NewTimerID], LaserRED[NewTimerID], LaserBLUE[NewTimerID], LaserGREEN[NewTimerID], LaserALPHA[NewTimerID])
set FadeAmount[NewTimerID] = LaserALPHA[NewTimerID] / FadeAmount[tID]
endif
//Damage
if LaserAOE[tID] > 0. then
call GroupEnumUnitsInRange(DamageGroup, IMPACT_X, IMPACT_Y, LaserAOE[tID] + MAX_COLLISION_SIZE, null)
loop
set u = FirstOfGroup(DamageGroup)
call GroupRemoveUnit(DamageGroup, u)
exitwhen u == null
if IsUnitInRangeXY(u, IMPACT_X, IMPACT_Y, LaserAOE[tID]) and UnitAlive(u) and /*
[Friendly Fire] */( (LaserFriendlyFire[tID] and (IsUnitEnemy(u, SourcePlayer) or IsUnitAlly(u, SourcePlayer))) or /*
[Enemy] */ (not LaserFriendlyFire[tID] and IsUnitEnemy(u, SourcePlayer)) ) and /*
[Invulnerable] */ not IsUnitInvulnerable(u) and /*
[Magic Immune] */( (LaserAttackType[tID] == ATTACK_TYPE_MAGIC and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)) or /*
[Ethereal] */ (LaserAttackType[tID] != ATTACK_TYPE_MAGIC and not IsUnitType(u, UNIT_TYPE_ETHEREAL)) ) then
if not LaserHitAll[tID] and ( (not IsUnitType(u, UNIT_TYPE_FLYING) and not IsUnitType(LaserTarget[tID], UNIT_TYPE_FLYING)) or /*
*/ (IsUnitType(u, UNIT_TYPE_FLYING) and IsUnitType(LaserTarget[tID], UNIT_TYPE_FLYING)) ) then
set udg_NextDamageType = LaserDamageType[tID]
call UnitDamageTarget(LaserSource[tID], u, LaserDamage[tID], true, true, LaserAttackType[tID], DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
call TriggerEvaluate(udg_ClearDamageEvent)
elseif LaserHitAll[tID] then
set udg_NextDamageType = LaserDamageType[tID]
call UnitDamageTarget(LaserSource[tID], u, LaserDamage[tID], true, true, LaserAttackType[tID], DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
call TriggerEvaluate(udg_ClearDamageEvent)
endif
endif
endloop
else
set udg_NextDamageType = LaserDamageType[tID]
call UnitDamageTarget(LaserSource[tID], LaserTarget[tID], LaserDamage[tID], true, true, LaserAttackType[tID], DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
call TriggerEvaluate(udg_ClearDamageEvent)
endif
//Timer
if b then
set b = false
set LaserInterval[NewTimerID] = LaserInterval[tID]
set IsLaserFading[NewTimerID] = false
set New_t = NewTimerEx(NewTimerID)
call TimerStart(New_t, .03125, true, function IndividualLaser_Timer)
set New_t = null
else
call IndexDeallocate(NewTimerID)
endif
endif
if LaserCount[tID] <= 0 then
call IndexDeallocate(tID)
call ReleaseTimer(t)
endif
endfunction
function BurstLaser takes nothing returns boolean
local unit Source = udg_DamageEventSource
local unit Target = udg_DamageEventTarget
local integer Source_ID = GetUnitUserData(Source)
local timer t = null
local integer tID = 0
local real SOURCE_X = 0.
local real SOURCE_Y = 0.
local real TARGET_X = 0.
local real TARGET_Y = 0.
local real LAUNCH_X = 0.
local real LAUNCH_Y = 0.
local real IMPACT_X = 0.
local real IMPACT_Y = 0.
local real Angle = 0.
local real Damage = 0.
if BL_UsesBurstLaser[Source_ID] and udg_DamageEventType == 0 and not udg_IsDamageSpell then
set udg_DamageEventAmount = 0.
set Damage = GetFullDamage(udg_DamageEventPrevAmt, GetUnitArmor(udg_DamageEventTarget)) / BL_NumberOfLasers[Source_ID]
if BL_NumberOfLasers[Source_ID] > 0 then
set tID = IndexAllocate()
set t = NewTimerEx(tID)
set LaserSource[tID] = udg_DamageEventSource
set LaserTarget[tID] = udg_DamageEventTarget
set LaserDamage[tID] = Damage
set LaserAOE[tID] = BL_LaserAOE[Source_ID]
set LaserAttackType[tID] = BL_LaserAttackType[Source_ID]
set LaserDamageType[tID] = BL_LaserDamageType[Source_ID]
set LaserHitAll[tID] = BL_LaserHitAll[Source_ID]
set LaserFriendlyFire[tID] = BL_LaserFriendlyFire[Source_ID]
set LaserInterval[tID] = BL_LaserDuration[Source_ID]
set LaserIntervalSave[tID] = BL_LaserDuration[Source_ID]
set LaserCount[tID] = BL_NumberOfLasers[Source_ID]
set LaserLaunchOffset[tID] = BL_LaserLaunchOffset[Source_ID]
set LaserLaunchHeight[tID] = BL_LaserLaunchHeight[Source_ID]
set LaserLaunchAngle[tID] = BL_LaserLaunchAngle[Source_ID]
set LaserSpreadXY[tID] = BL_LaserSpreadXY[Source_ID]
set LaserSpreadZ[tID] = BL_LaserSpreadZ[Source_ID]
set LaserLaunchFX[tID] = BL_LaserLaunchFX[Source_ID]
set LaserImpactFX[tID] = BL_LaserImpactFX[Source_ID]
set LaserAreaFX[tID] = BL_LaserAreaFX[Source_ID]
set LaserLaunchScale[tID] = BL_LaserLaunchScale[Source_ID]
set LaserImpactScale[tID] = BL_LaserImpactScale[Source_ID]
set LaserAreaScale[tID] = BL_LaserAreaScale[Source_ID]
set LaserString[tID] = BL_LaserString[Source_ID]
set LaserRED[tID] = BL_RED[Source_ID]
set LaserBLUE[tID] = BL_BLUE[Source_ID]
set LaserGREEN[tID] = BL_GREEN[Source_ID]
set LaserALPHA[tID] = BL_ALPHA[Source_ID]
set IsLaserFading[tID] = false
call TimerStart(t, .03125, true, function BurstLaser_Timer)
set t = null
endif
endif
set Source = null
set Target = null
return false
endfunction
function BL_onAttack takes nothing returns nothing
call TriggerRegisterVariableEvent( BL_onAttack_Trigger, "udg_DamageModifierEvent", EQUAL, 1.00 )
call TriggerAddCondition( BL_onAttack_Trigger, function BurstLaser )
endfunction
endscope