Moderator
M
Moderator
12 Nov 2011
Bribe: Everything looks good to me - thanks for making the changes!
Bribe: Everything looks good to me - thanks for making the changes!
//==============================================================================
// SPECTRUM SHOWER v1.2
// BY Ayanami
//==============================================================================
//==============================================================================
// REQUIREMENTS
//==============================================================================
// - JNGP
// - Alloc
// - SpellEffectEvent
// * RegisterPlayerUnitEvent
// * Table
// - Timer32
//==============================================================================
//==============================================================================
// IMPLEMENTATION
//==============================================================================
// 1) Copy the whole "Required Systems" Trigger folder
// 2) Copy the trigger "Spectrum Shower"
// 3) Copy the ability "Spectrum Shower"
// 4) Copy the unit "Spectrum Shower Dummy"
// 5) Go through the configuration section in "Spectrum Shower" trigger
//==============================================================================
library SpectrumShower uses Alloc, SpellEffectEvent, T32
//===========================================================================
// CONFIGURABLES
//===========================================================================
globals
private constant integer ABIL_ID = 'ABSS' // raw code of base ability
private constant integer DUMMY_ID = 'dSPE' // raw code of unit "Spectrum Shower Dummy"
private constant integer BALL_RED = 255 // red hex value for ball
private constant integer BALL_GREEN = 255 // green hex value for ball
private constant integer BALL_BLUE = 255 // blue hex value for ball
private constant integer BALL_TRANS = 255 // transparency for ball
private constant real BALL_AREA = 400. // maximum distance which ball hovers relative to caster
private constant real BALL_HEIGHT = 200. // ball flying height
private constant real BALL_SCALE = 1. // scale size of ball
private constant real BALL_SPEED = 500. // distance travelled by ball per second
private constant string LASER_TYPE = "SPLK" // lightning type for laser
private constant real LASER_RED = 255. / 255. // red value for laser (where 1.0 == 255 in terms of hex)
private constant real LASER_GREEN = 255. / 255. // green value for laser (where 1.0 == 255 in terms of hex)
private constant real LASER_BLUE = 255. / 255. // blue value for laser (where 1.0 == 255 in terms of hex)
private constant real LASER_TRANS = 255. / 255. // red value for laser (where 1.0 == 255 in terms of hex)
private constant real LASER_AREA = 100. // laser circulating distance relative to ball
private constant real LASER_COLLISION = 50. // collision radius of laser (for damage)
private constant real LASER_SPEED = 1. // time taken for laser to do one circular motion relative to ball
private constant real LASER_ADJUST_HEIGHT = 50. // adjustment height for the laser
private constant real ENUM_RADIUS = 176. // max collision size of a unit in your map.
private constant attacktype ATK = ATTACK_TYPE_NORMAL // attack type
private constant damagetype DMG = DAMAGE_TYPE_MAGIC // damage type
endglobals
// number of energy balls
private constant function GetBallCount takes integer level returns integer
return 4 * level
endfunction
// damage dealt per second by each laser
private constant function GetDamage takes integer level returns real
return 20.
endfunction
// duration of spell
private constant function GetDuration takes integer level returns real
return 6.
endfunction
// filter for allowed targets
private constant function GetFilter takes unit u, unit caster returns boolean
return /*
*/ not IsUnitType(u, UNIT_TYPE_DEAD) /* // target is alive
*/ and IsUnitEnemy(u, GetOwningPlayer(caster)) /* // target is an enemy of caster
*/ and not IsUnitType(u, UNIT_TYPE_STRUCTURE) // target is not a structure
endfunction
//===========================================================================
// END CONFIGURABLES
//===========================================================================
globals
private constant player NEUTRAL_PASSIVE = Player(PLAYER_NEUTRAL_PASSIVE)
private constant real TRUE_BALL_SPEED = BALL_SPEED * T32_PERIOD
private constant real RAD = 2 * bj_PI
private constant real ANGLE_RATE = RAD / LASER_SPEED * T32_PERIOD
private constant real TRUE_HEIGHT = BALL_HEIGHT + LASER_ADJUST_HEIGHT
private group G = bj_lastCreatedGroup
endglobals
private struct Data extends array
implement Alloc
private unit u
private unit dummy
private lightning l
private real dmg
private real dur
private real cos
private real sin
private real dist
private real offsetCos
private real offsetSin
private real offset
private real distCount
private real a
private method destroy takes nothing returns nothing
call RemoveUnit(this.dummy)
call DestroyLightning(this.l)
call this.stopPeriodic()
call this.deallocate()
endmethod
private method setOffset takes nothing returns nothing
local real x = GetUnitX(this.dummy)
local real y = GetUnitY(this.dummy)
local real dx = x - GetUnitX(this.u)
local real dy = y - GetUnitY(this.u)
local real a
set this.offset = SquareRoot(dx * dx + dy * dy)
set a = Atan2(dy, dx)
set this.offsetCos = Cos(a)
set this.offsetSin = Sin(a)
set dx = (GetUnitX(this.u) + GetRandomReal(-BALL_AREA, BALL_AREA)) - x
set dy = (GetUnitY(this.u) + GetRandomReal(-BALL_AREA, BALL_AREA)) - y
set this.dist = SquareRoot(dx * dx + dy * dy)
set a = Atan2(dy, dx)
set this.cos = Cos(a)
set this.sin = Sin(a)
set this.distCount = 0
endmethod
private method periodic takes nothing returns nothing
local unit u
local real x
local real y
local real a
if this.dur <= 0 then
call this.destroy()
else
set this.dur = this.dur - T32_PERIOD
set this.dist = this.dist - TRUE_BALL_SPEED
set this.distCount = this.distCount + TRUE_BALL_SPEED
set this.a = this.a + ANGLE_RATE
set x = (GetUnitX(this.u) + this.offset * this.offsetCos) + this.distCount * this.cos
set y = (GetUnitY(this.u) + this.offset * this.offsetSin) + this.distCount * this.sin
call SetUnitX(this.dummy, x)
call SetUnitY(this.dummy, y)
call MoveLightningEx(this.l, true, x, y, TRUE_HEIGHT, x + LASER_AREA * Cos(this.a), y + LASER_AREA * Sin(this.a), -LASER_ADJUST_HEIGHT)
call GroupEnumUnitsInRange(G, x, y, LASER_COLLISION + ENUM_RADIUS, null)
loop
set u = FirstOfGroup(G)
exitwhen u == null
call GroupRemoveUnit(G, u)
if GetFilter(u, this.u) then
call UnitDamageTarget(this.u, u, this.dmg, true, false, ATK, DMG, null)
endif
endloop
if this.dist <= 0 then
call this.setOffset()
endif
endif
endmethod
implement T32x
private static method onCast takes nothing returns boolean
local thistype this
local unit u = GetTriggerUnit()
local integer level = GetUnitAbilityLevel(u, ABIL_ID)
local integer i = GetBallCount(level)
local real dmg = GetDamage(level)
local real dur = GetDuration(level)
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real dx
local real dy
loop
exitwhen i == 0
set this = thistype.allocate()
set this.u = u
set dx = x + GetRandomReal(-BALL_AREA, BALL_AREA)
set dy = y + GetRandomReal(-BALL_AREA, BALL_AREA)
set this.dummy = CreateUnit(NEUTRAL_PASSIVE, DUMMY_ID, dx, dy, 0)
set this.l = AddLightningEx(LASER_TYPE, true, dx, dy, TRUE_HEIGHT, dx + GetRandomReal(-LASER_AREA, LASER_AREA), dy + GetRandomReal(-LASER_AREA, LASER_AREA), -LASER_ADJUST_HEIGHT)
set this.dmg = GetDamage(level) * T32_PERIOD
set this.dur = GetDuration(level)
set this.a = GetRandomReal(-1, 1)
call SetUnitVertexColor(this.dummy, BALL_RED, BALL_GREEN, BALL_BLUE, BALL_TRANS)
call SetUnitScale(this.dummy, BALL_SCALE, BALL_SCALE, BALL_SCALE)
call SetUnitFlyHeight(this.dummy, BALL_HEIGHT, 0)
call SetLightningColor(this.l, LASER_RED, LASER_GREEN, LASER_BLUE, LASER_TRANS)
call this.setOffset()
call this.startPeriodic()
set i = i - 1
endloop
set u = null
return false
endmethod
private static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(ABIL_ID, function thistype.onCast)
endmethod
endstruct
endlibrary