/*====================Confinement v1.2======================
============================================================
====================Made by: Mckill2009=====================
============================================================
============================================================
REQUIRES:
- JassNewGenPack by Vexorian
- T32 by Jesus4Lyf
HOW TO USE:
- Make a new trigger and convert to custom text via EDIT >>> CONVERT CUSTOM TEXT
- Copy ALL that is written here (overwrite the existing texts in the trigger)
- Copy the Dummy unit and the custom ability OR make your own
- You MUST input or change the correct raw ID's (see below)
- To view raw ID, press CTRL+D in the object editor
FULL DESCRIPTION:
Creates two magical fence that loops around a targeted point. Enemy units that is inside or caught within the fence's AoE cannot get out. If an enemy unit touches the fence it will deal damage as well.
|cffffcc00Level 1|r - Spell lasts 10 seconds, vortex damages 8 per touch.
|cffffcc00Level 2|r - Spell lasts 15 seconds, vortex damages 13 per touch.
|cffffcc00Level 3|r - Spell lasts 20 seconds, vortex damages 18 per touch.
|cffffcc00Level 4|r - Spell lasts 25 seconds, vortex damages 23 per touch.
|cffffcc00Level 5|r - Spell lasts 30 seconds, vortex damages 28 per touch.
*/
library Confinement requires T32
globals
private constant integer SPELL_ID = 'A000'
private constant integer DUMMY_ID = 'h001'
private constant integer FENCE1_ID = 'h002'
private constant integer FENCE2_ID = 'h003'
private constant integer AURA_ID = 'h000'
private constant attacktype ATT = ATTACK_TYPE_PIERCE
private constant damagetype DAM = DAMAGE_TYPE_DEATH
private constant real AOE_RANGE = 400 //this is the prison range
private constant real AOE_DAM = 80 //this is the damage range of the fence
private constant real ROTATION_SPEED = 5
private constant group GROUP = bj_lastCreatedGroup
endglobals
private function GetDuration takes integer i returns real
return 5 + i * 5.
endfunction
private function GetDamage takes integer i returns real
return 3 + i * 5.
endfunction
private function FilterUnits takes unit u1, unit u2 returns boolean
return IsUnitEnemy(u1, GetOwningPlayer(u2)) and not IsUnitType(u1, UNIT_TYPE_DEAD) and not IsUnitType(u1, UNIT_TYPE_STRUCTURE) and not IsUnitType(u1, UNIT_TYPE_MECHANICAL)
endfunction
private struct Confinement extends array
private static integer instanceCount = 0
private static thistype recycle = 0
private thistype recycleNext
private unit aura
private unit dum
private unit fence1
private unit fence2
private real x
private real y
private real hurt
private real angle1
private real angle2
private real duration
private method destroy takes nothing returns nothing
set this.aura = null
set this.dum = null
set this.fence1 = null
set this.fence2 = null
set recycleNext = recycle
set recycle = this
endmethod
private method periodic takes nothing returns nothing
local real angle
local real dist
local real angle01
local real angle02
local real x1
local real y1
local real x2
local real y2
local unit u
if .duration > 0 then
set angle01 = .angle1 * bj_DEGTORAD
set angle02 = .angle2 * bj_DEGTORAD
set .angle1 = .angle1 + ROTATION_SPEED
set .angle2 = .angle2 - ROTATION_SPEED
set .duration = .duration - T32_PERIOD
call SetUnitX(.fence1, .x + AOE_RANGE * Cos(angle01))
call SetUnitY(.fence1, .y + AOE_RANGE * Sin(angle01))
call SetUnitX(.fence2, .x + AOE_RANGE * Cos(angle02))
call SetUnitY(.fence2, .y + AOE_RANGE * Sin(angle02))
call GroupEnumUnitsInRange(GROUP, .x, .y, AOE_RANGE, null)
loop
set u = FirstOfGroup(GROUP)
exitwhen u==null
if FilterUnits(u, .dum) then
set x1 = GetUnitX(u)
set y1 = GetUnitY(u)
set x2 = x1-.x
set y2 = y1-.y
set angle = Atan2(y-y1, x-x1)
set dist = (x2*x2) + (y2*y2)
if dist > (AOE_RANGE-50)*(AOE_RANGE-50) then
call SetUnitX(u, x1 + 30 * Cos(angle))
call SetUnitY(u, y1 + 30 * Sin(angle))
endif
endif
call GroupRemoveUnit(GROUP, u)
endloop
call GroupEnumUnitsInRange(GROUP, GetUnitX(.fence1), GetUnitY(.fence1), AOE_DAM, null)
loop
set u = FirstOfGroup(GROUP)
exitwhen u==null
if FilterUnits(u, .dum) then
call UnitDamageTarget(.dum, u, .hurt , false, false, ATT, DAM, null)
endif
call GroupRemoveUnit(GROUP, u)
endloop
call GroupEnumUnitsInRange(GROUP, GetUnitX(.fence2), GetUnitY(.fence2), AOE_DAM, null)
loop
set u = FirstOfGroup(GROUP)
exitwhen u==null
if FilterUnits(u, .dum) then
call UnitDamageTarget(.dum, u, .hurt , false, false, ATT, DAM, null)
endif
call GroupRemoveUnit(GROUP, u)
endloop
else
call KillUnit(.aura)
call KillUnit(.fence1)
call KillUnit(.fence2)
call KillUnit(.dum)
call this.stopPeriodic()
call this.destroy()
endif
endmethod
implement T32x
private static method create takes nothing returns thistype
local thistype this
local unit caster = GetTriggerUnit()
local integer level = GetUnitAbilityLevel(caster, SPELL_ID)
local player p = GetTriggerPlayer()
if (recycle == 0) then
set instanceCount = instanceCount + 1
set this = instanceCount
else
set this = recycle
set recycle = recycle.recycleNext
endif
set this.x = GetSpellTargetX()
set this.y = GetSpellTargetY()
set this.aura = CreateUnit(p, AURA_ID, .x, .y, 0)
set this.dum = CreateUnit(p, DUMMY_ID, .x, .y, 0)
set this.fence1 = CreateUnit(p, FENCE1_ID, .x, .y, 0)
set this.fence2 = CreateUnit(p, FENCE2_ID, .x, .y, 0)
set this.duration = GetDuration(level)
set this.hurt = GetDamage(level)
set this.angle1 = 0
set this.angle2 = 0
call this.startPeriodic()
set p = null
set caster = null
return this
endmethod
private static method Cond takes nothing returns boolean
if GetSpellAbilityId()==SPELL_ID then
call thistype.create()
endif
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, function thistype.Cond)
endmethod
endstruct
endlibrary