cr4xzZz
Also known as azwraith_ftL.
- Reaction score
- 51
Nature Wall
A spell from my map - Mini Ashenvale Arena.
GUI/JASS/vJASS? vJASS.
MUI? Yes.
Leakless? Yes.
Lagless? Yes.
Follows JESP? No.
Requires?
- JASS NewGen Editor v1.5a
- ABCT v2.0
- PUI v5.1
Description:
Creates a wall of vines, branches and leaves across the landcape, creating a strong barrier. Units that pass through the wall will be caught in roots for one second. Released units have 1.5 seconds to get away from the wall or they are caught again. Lasts 15 seconds.
Level 1 - Deals 35 DPS.
Level 2 - Deals 55 DPS.
Level 3 - Deals 80 DPS.
Code:
JASS:
scope NatureWall
// Do not touch this textmacro line! It's PUI attaching!
//! runtextmacro PUI_PROPERTY("private", "boolean", "AGAIN", "false")
//===========================================================================
// CONFIGURATION MENU
//===========================================================================
globals
// Raw code of the Nature Wall ability.
private constant integer AID_NATURE_WALL = 039;A000039;
// Raw code of the buff that comes with the aura.
private constant integer BID_NATURE_WALL_AURA = 039;B000039;
// Raw code of the wall units.
private constant integer UID_NATURE_WALL_UNIT = 039;u000039;
// Raw code of the dummy unit.
private constant integer UID_DUMMY = 039;u001039;
// Raw code of the ability that is casted when a unit comes near the wall.
private constant integer AID_NATURE_WALL_ENTANGLE = 039;A002039;
// String for casting the AID_NATURE_WALL_ENTANGLE ability.
private constant string SID_ENTANGLE = "entanglingroots"
// Raw code of the destructibles created on the two sides of the wall (in this case - Ashenvale tree).
private constant integer DID_NATURE_WALL_WOOD = 039;ATtr039;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Period that is given for the unit to get away from the wall, or it will be entangled again.
private constant real ENTANGLE_PERIOD = 1.5
// Period between group picks and special effect creation.
private constant real PICK_PERIOD = 1.
// Special effect created at each wall unit.
private constant string SFX_EFFECT = "Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl"
// Scale of the two destructibles created at the wall's sides.
private constant real TREE_SCALE = 1.
// Range between wall units (used for creation).
private constant integer RANGE = 75
endglobals
// Duration of the wall
private function DURATION takes unit cast, integer lvl returns real
// Included the caster because someone might want to base
// duration on his attributes
return lvl * 10.
endfunction
// Number of wall units.
// More units means increased wall length.
private function N_UNITS takes unit cast, integer lvl returns integer
// Included the caster because someone might want to base
// number of units on his attributes.
return 4 + (lvl * 2)
endfunction
//===========================================================================
// END OF CONFIGURATION MENU
//===========================================================================
private struct Data
unit caster
integer level
unit array wall[100]
destructable array wood[3]
integer ticks
method onDestroy takes nothing returns nothing
call KillDestructable(.wood[1])
call KillDestructable(.wood[2])
endmethod
endstruct
private struct Info
unit picked
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AID_NATURE_WALL
endfunction
private function Filterz takes nothing returns boolean
return GetUnitAbilityLevel(GetFilterUnit(), BID_NATURE_WALL_AURA) > 0
endfunction
private function Wait takes nothing returns boolean
local Info data = ABCT_GetData()
set AGAIN[data.picked] = false
call data.destroy()
return true
endfunction
private function Root takes unit whichUnit, unit whichTarg returns nothing
local unit dum = CreateUnit(GetOwningPlayer(whichUnit), UID_DUMMY, 0., 0., 0.)
local Info data = Info.create()
call UnitApplyTimedLife(dum, 039;BTLF039;, 2.)
call UnitAddAbility(dum, AID_NATURE_WALL_ENTANGLE)
call SetUnitAbilityLevel(dum, AID_NATURE_WALL_ENTANGLE, GetUnitAbilityLevel(whichUnit, AID_NATURE_WALL))
call IssueTargetOrder(dum, SID_ENTANGLE, whichTarg)
call UnitRemoveAbility(whichTarg, BID_NATURE_WALL_AURA) // prevent aura bugs
set AGAIN[whichTarg] = true
set data.picked = whichTarg
call ABCT_Start(function Wait, data, ENTANGLE_PERIOD)
set dum = null
endfunction
private function Callback takes nothing returns boolean
local Data d = ABCT_GetData()
local group gru = CreateGroup()
local unit pick
local integer int
local real x
local real y
call GroupEnumUnitsInRange(gru, 0., 0., 999999., Condition(function Filterz))
loop
set pick = FirstOfGroup(gru)
exitwhen pick == null
if AGAIN[pick] == false then
call Root.execute(d.caster, pick)
endif
call GroupRemoveUnit(gru, pick)
endloop
call DestroyGroup(gru)
set int = 1
loop
exitwhen int > N_UNITS(d.caster, d.level)
set x = GetUnitX(d.wall[int])
set y = GetUnitY(d.wall[int])
call DestroyEffect(AddSpecialEffect(SFX_EFFECT, x, y))
set int = int + 1
endloop
set d.ticks = d.ticks - 1
set gru = null
set pick = null
if d.ticks <= 0 then
call d.destroy()
return true
endif
return false
endfunction
private function Actions takes nothing returns nothing
local unit cast = GetTriggerUnit()
local location spell = GetSpellTargetLoc()
local integer lvl = GetUnitAbilityLevel(cast, AID_NATURE_WALL)
local Data d = Data.create()
local integer int = 1
local real x = GetUnitX(cast)
local real y = GetUnitY(cast)
local real tx = GetLocationX(spell)
local real ty = GetLocationY(spell)
local real angle = Atan2(ty - y, tx - x)
local real dd = (N_UNITS(cast, lvl) +1) * RANGE
set x = Cos(angle + bj_PI / 2) * dd
set y = Sin(angle + bj_PI / 2) * dd
set tx = tx + x / 2
set ty = ty + y / 2
set x = x / (N_UNITS(cast, lvl) + 1)
set y = y / (N_UNITS(cast, lvl) + 1)
set d.caster = cast
set d.ticks = R2I(DURATION(cast, lvl) / PICK_PERIOD)
set d.wood[1] = CreateDestructable(DID_NATURE_WALL_WOOD, tx, ty, 270., TREE_SCALE, GetRandomInt(0, 2))
loop
exitwhen int > N_UNITS(cast, lvl)
set tx = tx - x
set ty = ty - y
set d.wall[int] = CreateUnit(GetOwningPlayer(d.caster), UID_NATURE_WALL_UNIT, tx, ty, 270.)
call UnitApplyTimedLife(d.wall[int], 039;BTLF039;, DURATION(cast, lvl))
set int = int + 1
endloop
set tx = tx - x
set ty = ty - y
set d.wood[2] = CreateDestructable(DID_NATURE_WALL_WOOD, tx, ty, 270., TREE_SCALE, GetRandomInt(0, 2))
set d.level = lvl
call ABCT_Start(function Callback, d, PICK_PERIOD)
call RemoveLocation(spell)
set cast = null
set spell = null
endfunction
//===========================================================================
function InitTrig_NatureWall takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trig, Condition(function Conditions))
call TriggerAddAction(trig, function Actions)
endfunction
endscope
Screenshots:
Also credits to Tinki3 for the map template.
Changelog:
JASS:
// - - - - - - - - - - - - - - - - - - - - - v1.0 - - - - - - - - - - - - - - - - - - - - - - -
- Release
// - - - - - - - - - - - - - - - - - - - - - v2.0 - - - - - - - - - - - - - - - - - - - - - - -
- Fixed a little location leak
- Fixed a bug that made the unit created on the target point of ability being cast
to be always counted as array 7 ( d.wall[7] ), thus bugging the loop in Callback() action.
- Added a better implementation instruction.
// - - - - - - - - - - - - - - - - - - - - - v3.0 - - - - - - - - - - - - - - - - - - - - - - -
- Removed a few unnecessary lines
- Variables are now properly nulled
// - - - - - - - - - - - - - - - - - - - - - v4.0 - - - - - - - - - - - - - - - - - - - - - - -
- Removed a location or two and moved some stuff to reals
- Period between entangles no longer uses TriggerSleepAction() so you can be
sure that it will wait an exact amount of time.
- Ticks are now properly calculated (had a bug with more frequent group checks)
// - - - - - - - - - - - - - - - - - - - - - v4.1 - - - - - - - - - - - - - - - - - - - - - - -
- Edited a little the math on creating the wall.
- Now uses latest PUI - v5.1.
- Edited a little the Configuration Menu. Now it039;s more understandable (I think).