GRAVEYARD THIS.
This is actually a remake of some old spell I made, but the thread is old so I made a new one.
MUI/MPI - MUI
GUI/Jass/vJass - vJass
Requirements
Latest Jasshelper/JNGP
Timer32
The caster disappears from sight, dropping a trap on the ground. Anything going to the trap will be struck by the caster.
The picture doesn't really show the spell much, it just looks like the dude is using wind walk or something.
JASS:
// Spike Trap
//x----------------x
//| How to import: \
//x-x----------------x----------------------------------------------------------------------------------------x |
//x-|1. Copy the spell and T32 to your map. |
//x-|2. Create a new trigger with any name, click Edit-->Convert to Custom Text, then paste the spell's code. |
//x-|3. Do the same as the second step, but with T32. |
//x-x---------------------------------------------------------------------------------------------------------x
//REQUIRES A VJASS COMPILER OR JNGP
scope SpikeTrap
globals
//Configuration
private constant integer ABILITY_ID = 039;A000039;
//The raw code of the spell, use Ctrl+D in the object editor to find it
private constant string FINISH_ANIMATION = "attack walk stand"
//The animation used after the trap is triggered
private constant real ANIMATION_TIME = 0.5
//How long the animation lasts
private constant string CASTER_EFFECT = "Abilities\\Spells\\NightElf\\BattleRoar\\RoarCaster.mdl"
//The model of the effect created on the caster
private constant string TRAP_EFFECT = "Abilities\\Spells\\Orc\\SpikeBarrier\\SpikeBarrier.mdl"
//The model of the trap
private constant string TRIGGER_EFFECT = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
//The effect emitted when the trap is triggered
private constant real RADIUS = 150.
//How far a unit has to be from the center of a trap to be affected
private constant real SIGHT_RADIUS = 500.
//How far the player has visibility
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_CHAOS
//The attack type
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_UNIVERSAL
//The damage type
private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS
//The weapon type
endglobals
private function MAX_TARGETS takes integer level returns integer
return level * 5 - 1
endfunction
//Maximum targets
private function DAMAGE takes integer level returns real
return I2R(level) * 50 + 25
endfunction
//The damage
private function TRAP_DURATION takes integer level returns real
return 16 - I2R(level) * 4
endfunction
//How long the traps last
//End of Configuration
native UnitAlive takes unit u returns boolean
private struct SpikeTrap
private static player LOCAL_PLAYER
private static group GROUP = CreateGroup()
private static thistype TEMP
private static filterfunc FILTER
unit caster
player owner
real x
real y
fogmodifier visibility
integer level
integer targetsLeft
integer tick
integer isAnimationPlaying = 0
effect sfx
private static method groupActions takes nothing returns boolean
local unit u = GetFilterUnit()
if(IsUnitEnemy(u, TEMP.owner) and IsUnitType(u, UNIT_TYPE_GROUND) and TEMP.targetsLeft > 0 and UnitAlive(u)) then
call DestroyEffect(AddSpecialEffect(TRIGGER_EFFECT, GetUnitX(u), GetUnitY(u)))
call UnitDamageTarget(TEMP.caster, u, DAMAGE(TEMP.level), false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call PauseUnit(TEMP.caster, false)
call ShowUnit(TEMP.caster, true)
call SelectUnit(TEMP.caster, LOCAL_PLAYER == TEMP.owner)
call IssueImmediateOrder(TEMP.caster, "stop")
call SetUnitAnimation(TEMP.caster, FINISH_ANIMATION)
call DestroyEffect(TEMP.sfx)
set TEMP.isAnimationPlaying = 1
call FogModifierStop(TEMP.visibility)
call DestroyFogModifier(TEMP.visibility)
set TEMP.tick = T32_Tick + R2I(ANIMATION_TIME / T32_PERIOD)
endif
set u = null
return false
endmethod
private method periodic takes nothing returns nothing
local integer i = 0
if(this.tick >= T32_Tick) then
if(this.isAnimationPlaying == 0) then
set TEMP = this
call GroupEnumUnitsInRange(GROUP, this.x, this.y, RADIUS, FILTER)
endif
else
call this.stopPeriodic()
if(this.isAnimationPlaying == 0) then
call PauseUnit(this.caster, false)
call ShowUnit(this.caster, true)
call SelectUnit(this.caster, LOCAL_PLAYER == this.owner)
call DestroyEffect(this.sfx)
call DestroyEffect(AddSpecialEffect(CASTER_EFFECT, this.x, this.y))
set this.caster = null
else
call SetUnitAnimation(this.caster, "stand")
set this.caster = null
endif
call FogModifierStop(this.visibility)
call DestroyFogModifier(this.visibility)
call this.destroy()
endif
endmethod
implement T32x
private static method actions takes nothing returns nothing
local thistype d = thistype.create()
set d.caster = GetTriggerUnit()
set d.x = GetUnitX(d.caster)
set d.y = GetUnitY(d.caster)
set d.owner = GetOwningPlayer(d.caster)
set d.visibility = CreateFogModifierRadius(d.owner, FOG_OF_WAR_VISIBLE, d.x, d.y, SIGHT_RADIUS, true, false)
call FogModifierStart(d.visibility)
set d.sfx = AddSpecialEffect(TRAP_EFFECT, d.x, d.y)
set d.level = GetUnitAbilityLevel(d.caster, ABILITY_ID)
set d.tick = T32_Tick + R2I(TRAP_DURATION(d.level) / T32_PERIOD)
set d.targetsLeft = MAX_TARGETS
call IssueImmediateOrder(d.caster, "stop")
call PauseUnit(d.caster, true)
call ShowUnit(d.caster, false)
call d.startPeriodic()
endmethod
private static method condition takes nothing returns boolean
if(GetSpellAbilityId() == ABILITY_ID) then
call .actions()
endif
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
set FILTER = Filter(function thistype.groupActions)
set LOCAL_PLAYER = GetLocalPlayer()
loop
exitwhen i == 15
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set i = i + 1
endloop
call TriggerAddCondition(t, Condition(function thistype.condition))
endmethod
endstruct
endscope
V1 - Release
V1.1 - Removed a few useless things from the code
V1.2 - Laziness Update.
V1.3 - Much more laziness.
V1.1 - Removed a few useless things from the code
V1.2 - Laziness Update.
V1.3 - Much more laziness.