Name | Type | is_array | initial_value |
DivineIntervetionCasterLoc | location | No | |
DivineIntervetionGroup | group | No | |
DivineIntervetionLoc | location | No | |
EntangleGroup | group | No | |
EntangleLevel | real | No | |
EntanglePos | location | No | |
EntangleTargetLoc | location | No | |
lol | integervar | No | |
plyaer | player | No | |
TurnUndeadCasterArea | rect | No | |
TurnUndeadCasterLoc | location | No | |
TurnUndeadTempGroup | group | No |
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Functions used to handle timers. Credits to Vexorian and Captain Griffen
//Check http://www.wc3c.net/showthread.php?t=89072 for more informations
library HandleTimers
globals
private timer array timers
private integer N = 0
endglobals
function NewTimer takes nothing returns timer
if (N==0) then
return CreateTimer()
endif
set N=N-1
return timers[N]
endfunction
function ReleaseTimer takes timer t returns nothing
call PauseTimer(t)
if (N==8191) then
debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!")
//stack is full, the map already has much more troubles than the chance of bug
call DestroyTimer(t)
else
set timers[N]=t
set N=N+1
endif
endfunction
function TimerAttach takes timer t, real time, real value, code func returns nothing
call TimerStart(t, value, false, null)
call PauseTimer(t)
call TimerStart(t, time, false, func)
endfunction
// ONLY call on an expired timer.
function GetTimerInt takes timer t returns integer
return R2I(TimerGetRemaining(t) + 0.5)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
// **************************************************************************
// ** **
// ** Player Changer**
// ** βββββββββββββ **
// ** **
// ** A Struct used to store the original player of a unit and change **
// ** its ownership without using custom values **
// ** **
// ** By: Majin **
// **
// ** **
// **************************************************************************
//How to import:
//When importing this library make sure to also copy paste the
//Changed Ability and modify the PLAYERCHANGERID using the ID
//of the ability on your map
library PlayerChanger initializer Init requires HandleTimers
globals
//ID of a Dummy ability that will be given to the affected unit. Through this ability
//is possible to check if a unit is not currently controlled by its original owner
constant integer PLAYERCHANGERID='A009'
filterfunc ANTILEAKFILTER
endglobals
//This Function is used to avoid leaks with Trigger Events. I put this here because i'm lazy
public function AntiLeak takes nothing returns boolean
return true
endfunction
struct Changer
private unit owner
private player currentPlayer
private player originalPlayer
private timer turnTimer
//This metod creates an instance of the struct, changes the ownership of the unit and adds the dummy ability
public static method create takes unit pOwner, player pPlayer, timer pTimer, boolean changeColor returns Changer
local Changer l=Changer.allocate()
set l.originalPlayer=GetOwningPlayer(pOwner)
set l.turnTimer=pTimer
set l.currentPlayer=pPlayer
set l.owner=pOwner
call UnitAddAbility(l.owner, PLAYERCHANGERID)
call l.ChangePlayer(pPlayer, changeColor)
return l
endmethod
//This is the Method used to change the player. The boolean is used to know
//if the unit color has to be changed or not
public method ChangePlayer takes player pPlayer, boolean b returns nothing
set this.currentPlayer=pPlayer
call SetUnitOwner( this.owner, this.currentPlayer, b )
endmethod
//This method is used to change the unit's ownership back to its original player
//The boolean is used to know if the unit color has to be changed or not
public method RevertPlayer takes boolean b returns nothing
call SetUnitOwner(this.owner, this.originalPlayer, b)
endmethod
//This method adds an ability to the unit (since the variable it's private
//This method is required to do that. Should you need other methos that have to interact
//with the affected unit then you should put them here, or use the GetOwner Method. Since this
//method is used by all of the sample spells here, i rathered putting it here, same stuff for
//the method below)
public stub method AddAbility takes integer abilCode returns nothing
call UnitAddAbility(this.owner, abilCode)
endmethod
public stub method RemoveAbility takes integer abilCode returns nothing
call UnitRemoveAbility(this.owner, abilCode)
endmethod
//This method is used to return the Owner of the unit
public method GetOwner takes nothing returns unit
return this.owner
endmethod
//This method is needed to check if the unit is already under the effect of other player changing
//spells, to avoid messing things up. It is possible to avoid this by using unit custom values
//but the point of this whole thing was to change players to units without using custom values so...
public static method CheckChanged takes nothing returns nothing
local sound s = CreateSound("Sound\\Interface\\Error.wav", false, false, true, 12700, 12700, "")
if(GetUnitAbilityLevel(GetSpellTargetUnit(), PLAYERCHANGERID) > 0) then
call DisplayTextToPlayer( GetOwningPlayer(GetTriggerUnit()), 0, 0, "|cffFFCC00Target is already under a similar effect|r" )
call StartSound(s)
call KillSoundWhenDone(s)
set s = null
call IssueImmediateOrder( GetTriggerUnit(), "stop" )
endif
endmethod
private method onDestroy takes nothing returns nothing
call ReleaseTimer(this.turnTimer)
call UnitRemoveAbility(this.owner, PLAYERCHANGERID)
set this.owner=null
set this.currentPlayer=null
set this.originalPlayer=null
endmethod
endstruct
//Just putting it here because i cba to make another library for just 3 lines of code :P
function Init takes nothing returns nothing
set ANTILEAKFILTER=Filter(function AntiLeak)
endfunction
endlibrary
//TESH.scrollpos=11
//TESH.alwaysfold=0
// **************************************************************************
// ** **
// ** Fear **
// ** βββββββββββββ **
// ** **
// ** The unit affected by this spell will run away in fear rather than fighting **
// ** **
// ** By: Majin **
// **
// ** **
// **************************************************************************
//How to Import:
//This spell requires Both HandleTimers and PlayerChanger libraries
//Plus a dummy ability to be casted (the actual one is based on Acid Bomb)
//and an ability based on Tornado Wanderer (the one on this map is called feared)
//You can copy paste the triggers, the abilities, and the buff from this map
//but make sure to adjust the settings of the trigger, the ability and the Feared
//buff according to your needs.
library Fear initializer InitTrig requires PlayerChanger
globals
//ID of the ability used by this spell
constant integer FEARSPELLID='A005'
//ID of the ability to add to the feared units, has to be a copy of the Tornado Wanderer Ability
constant integer FEARABILITYID='A004'
//Duration in seconds of the spell, make sure to change the ability accordingly. DEPENDANT ON LEVEL
constant real FEARDURATION=5
endglobals
struct Feared extends Changer
private static method create takes unit pOwner, player pPlayer, timer pTimer returns Feared
local Feared l=Feared.allocate(pOwner, pPlayer, pTimer, false)
return l
endmethod
//Since the Tornado Wanderer turns off the unit pathing, it needs to be activated through triggers
public method AddAbility takes integer abilCode returns nothing
call super.AddAbility(abilCode)
call SetUnitPathing(this.GetOwner(), true)
endmethod
private static method EndFearActions takes nothing returns nothing
local Feared l=GetTimerInt(GetExpiredTimer())
call SetUnitMoveSpeed( l.GetOwner(), GetUnitDefaultMoveSpeed(l.GetOwner()))
call l.RemoveAbility(FEARABILITYID)
call l.RevertPlayer(false)
call l.destroy()
endmethod
public static method FearActions takes nothing returns nothing
local timer fearTimer
local Feared l
set fearTimer=NewTimer()
set l=Feared.create(GetSpellTargetUnit(), Player(PLAYER_NEUTRAL_PASSIVE), fearTimer)
call TimerAttach(fearTimer, FEARDURATION*GetUnitAbilityLevel(GetTriggerUnit(), FEARSPELLID), l, function Feared.EndFearActions)
call l.AddAbility(FEARABILITYID)
call SetUnitMoveSpeed( l.GetOwner(), GetUnitDefaultMoveSpeed(l.GetOwner())*2)
set fearTimer=null
endmethod
endstruct
private function FearConditions takes nothing returns boolean
return GetSpellAbilityId() == FEARSPELLID
endfunction
private function InitTrig takes nothing returns nothing
local trigger Fear = CreateTrigger()
local trigger CheckFear = CreateTrigger()
local integer i = 0
loop
exitwhen i == 16
call TriggerRegisterPlayerUnitEvent(Fear,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,ANTILEAKFILTER)
call TriggerRegisterPlayerUnitEvent(CheckFear,Player(i),EVENT_PLAYER_UNIT_SPELL_CAST,ANTILEAKFILTER)
set i = i + 1
endloop
call TriggerAddCondition(Fear, Condition(function FearConditions))
call TriggerAddAction(Fear, function Feared.FearActions)
call TriggerAddCondition(CheckFear, Condition(function FearConditions))
call TriggerAddAction(CheckFear, function Changer.CheckChanged)
set Fear = null
set CheckFear = null
endfunction
endlibrary
//TESH.scrollpos=52
//TESH.alwaysfold=0
// **************************************************************************
// ** **
// ** Berserk **
// ** βββββββββββββ **
// ** **
// ** The unit affected by this spell will become more powerful but will **
// ** attack everyone, even his allies (Except other enraged units) **
// ** **
// ** By: Majin **
// **
// ** **
// **************************************************************************
//How to Import:
//This spell requires Both HandleTimers and PlayerChanger libraries
//Plus a dummy ability to be casted (the actual one is based on Channel)
//and an ability based on Bloodlust (the one on this map is called Enrage)
//You can copy paste the triggers, the abilities, and the buff from this map
//but make sure to adjust the settings of the trigger, the ability and the Berserk
//buff according to your needs.
library Berserk initializer InitTrig requires PlayerChanger
globals
//ID of the ability used by this spell
constant integer BERSERKSPELLID='A007'
//ID of the ability given to units to enrage them. Has to be a copy of the Bloodlust ability
constant integer BERSERKABILITYID='A008'
//Duration in seconds of the spell, make sure to change the ability accordingly. DEPENDANT ON LEVEL
constant real BERSERKDURATION=5
endglobals
struct Enraged extends Changer
private static method create takes unit pOwner, player pPlayer, timer pTimer returns Enraged
local Enraged l=Enraged.allocate(pOwner, pPlayer, pTimer, false)
return l
endmethod
private static method EndRageActions takes nothing returns nothing
local Enraged l=GetTimerInt(GetExpiredTimer())
call l.RemoveAbility(BERSERKABILITYID)
call l.RevertPlayer(false)
call l.destroy()
endmethod
public static method RageActions takes nothing returns nothing
local timer RageTimer
local Enraged l
if(GetUnitAbilityLevel(GetSpellTargetUnit(), PLAYERCHANGERID) <= 0) then
set RageTimer=NewTimer()
set l=Enraged.create(GetSpellTargetUnit(), Player(14), RageTimer)
call TimerAttach(RageTimer, BERSERKDURATION*GetUnitAbilityLevel(GetTriggerUnit(), BERSERKSPELLID), l, function Enraged.EndRageActions)
call l.AddAbility(BERSERKABILITYID)
call SetUnitAbilityLevel(l.GetOwner(), BERSERKABILITYID, GetUnitAbilityLevel(GetTriggerUnit(), BERSERKSPELLID))
call IssueTargetOrder(GetSpellTargetUnit(), "bloodlust", GetSpellTargetUnit())
set RageTimer=null
endif
endmethod
endstruct
private function RageConditions takes nothing returns boolean
return GetSpellAbilityId() == BERSERKSPELLID
endfunction
private function InitTrig takes nothing returns nothing
local trigger Rage = CreateTrigger()
local trigger CheckRage = CreateTrigger()
local integer i = 0
loop
exitwhen i == 16
call TriggerRegisterPlayerUnitEvent(Rage,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,ANTILEAKFILTER)
call TriggerRegisterPlayerUnitEvent(CheckRage,Player(i),EVENT_PLAYER_UNIT_SPELL_CAST,ANTILEAKFILTER)
set i = i + 1
endloop
call TriggerAddCondition(Rage, Condition(function RageConditions))
call TriggerAddAction(Rage, function Enraged.RageActions)
call TriggerAddCondition(CheckRage, Condition(function RageConditions))
call TriggerAddAction(CheckRage, function Changer.CheckChanged)
set Rage = null
set CheckRage = null
endfunction
endlibrary
//TESH.scrollpos=22
//TESH.alwaysfold=0
// **************************************************************************
// ** **
// ** Charm **
// ** βββββββββββββ **
// ** **
// ** The unit affected by this spell will be temporary controlled by the **
// ** Player who casted the spell
// ** **
// ** By: Majin **
// **
// ** **
// **************************************************************************
//How to Import:
//This spell requires Both HandleTimers and PlayerChanger libraries
//Plus a dummy ability to be casted (the actual one is based on Unholy Frenzy)
//You can copy paste the triggers, the ability, and the buff from this map
//but make sure to adjust the settings of the trigger, the ability and the Charmed
//buff according to your needs.
library Charm initializer InitTrig requires PlayerChanger
globals
constant integer CHARMSPELLID='A00G'
constant real CHARMDURATION=5
endglobals
struct Charmed extends Changer
private static method create takes unit pOwner, player pPlayer, timer pTimer returns Charmed
local Charmed l=Charmed.allocate(pOwner, pPlayer, pTimer, true)
return l
endmethod
private static method EndCharmActions takes nothing returns nothing
local Charmed l=GetTimerInt(GetExpiredTimer())
call l.RevertPlayer(true)
call l.destroy()
endmethod
public static method CharmActions takes nothing returns nothing
local timer charmTimer
local Charmed l
if(GetUnitAbilityLevel(GetSpellTargetUnit(), PLAYERCHANGERID) <= 0) then
set charmTimer=NewTimer()
set l=Charmed.create(GetSpellTargetUnit(), GetOwningPlayer(GetTriggerUnit()), charmTimer)
call TimerAttach(charmTimer, CHARMDURATION*GetUnitAbilityLevel(GetTriggerUnit(), CHARMSPELLID), l, function Charmed.EndCharmActions)
set charmTimer=null
endif
endmethod
endstruct
private function CharmConditions takes nothing returns boolean
return GetSpellAbilityId() == CHARMSPELLID
endfunction
private function InitTrig takes nothing returns nothing
local trigger Charm = CreateTrigger()
local trigger CheckCharm = CreateTrigger()
local integer i = 0
loop
exitwhen i == 16
call TriggerRegisterPlayerUnitEvent(Charm,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,ANTILEAKFILTER)
call TriggerRegisterPlayerUnitEvent(CheckCharm,Player(i),EVENT_PLAYER_UNIT_SPELL_CAST,ANTILEAKFILTER)
set i = i + 1
endloop
call TriggerAddCondition(Charm, Condition(function CharmConditions))
call TriggerAddAction(Charm, function Charmed.CharmActions)
call TriggerAddCondition(CheckCharm, Condition(function CharmConditions))
call TriggerAddAction(CheckCharm, function Changer.CheckChanged)
set Charm = null
set CheckCharm = null
endfunction
endlibrary
//TESH.scrollpos=34
//TESH.alwaysfold=0
// **************************************************************************
// ** **
// ** Turn Undead **
// ** βββββββββββββ **
// ** **
// ** The undeads affected by this spell will die, get stunned or run away in fear **
// ** **
// ** By: Majin **
// **
// ** **
// **************************************************************************
//How to Import:
//This spell requires Both HandleTimers and PlayerChanger libraries
//Plus a dummy ability to be casted (the actual one is based on Haste scroll).
//It also requires a dummy unit and two spells with 3 levels that will be
//similar to the Fear spell, and another based on Thunder Bolt for the stunning part of the spell.
//The dummy unit on this map is called "Mr Dummy", the Fear dummy spell "Fear (Dummy)"
//and the dummy spell for the stun is called "Cower (Dummy)".
//You can copy paste the triggers, the abilities, the dummy unit and the buff from this map
//but make sure to adjust the settings of the trigger, the ability, the Turned and the Cowering
//buffs according to your needs.
library Turn initializer InitTrig requires PlayerChanger
globals
//ID of the ability used by this spell
constant integer TURNSPELLID='A003'
//ID of the ability to add to the feared units, has to be a copy of the Tornado Wanderer Ability
constant integer TURNABILITYID='A004'
//ID of the dummy unit used to cast the fear and stun part
constant integer TURNDUMMYID='e000'
//ID of the ability used on the units that will be feared
constant integer TURNDUMMYFEARSPELLID='A006'
//ID of the ability used to make the units cower in fear (they'll just be stunned)
constant integer TURNDUMMYCOWERSPELLID='A000'
//Chance to have the minimum effect (unit runs away in fear) on the affected unit
constant integer MINEFFECTCHANCE=50
//Chance to have the medium effect (unit will cower in fear) on the affected unit
constant integer MIDEFFECTCHANCE=35
//Chance to have the maximum effect (unit is killed) on the affected unit
constant integer MAXEFFECTCHANCE=15
//Duration in seconds of the spell, make sure to change the ability accordingly. DEPENDANT ON LEVEL
constant real TURNDURATION=10
//How big will be the area covered by the spell
constant real TURNAREARADIUS=200
endglobals
struct Turned extends Changer
private static method create takes unit pOwner, player pPlayer, timer pTimer returns Turned
local Turned l=Turned.allocate(pOwner, pPlayer, pTimer, false)
return l
endmethod
//Since the Tornado Wanderer turns off the unit pathing, it needs to be activated through triggers
public method AddAbility takes integer abilCode returns nothing
call super.AddAbility(abilCode)
call SetUnitPathing(this.GetOwner(), true)
endmethod
private static method EndTurnActions takes nothing returns nothing
local Turned l=GetTimerInt(GetExpiredTimer())
call l.RemoveAbility(TURNABILITYID)
call l.RevertPlayer(false)
call l.destroy()
endmethod
public static method TurnDummyActions takes nothing returns nothing
local timer turnTimer
local Turned l
set turnTimer=NewTimer()
set l=Turned.create(GetSpellTargetUnit(), Player(PLAYER_NEUTRAL_PASSIVE), turnTimer)
call TimerAttach(turnTimer, TURNDURATION, l, function Turned.EndTurnActions)
call l.AddAbility(TURNABILITYID)
set turnTimer=null
endmethod
//Filter Function to get the undeads
private static method GetUndeads takes nothing returns boolean
return not(GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) <= 0) and (GetUnitAbilityLevel(GetFilterUnit(), PLAYERCHANGERID) <= 0) and ( IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false ) and ( IsUnitAlly(GetFilterUnit(), GetTriggerPlayer()) == false ) and ( IsUnitType(GetFilterUnit(), UNIT_TYPE_UNDEAD) == true ) and ( GetUnitLevel(GetFilterUnit()) < 6 )
endmethod
//Function of the minimum effect on the affected units (unit will run away in fear)
private static method MinEffectUndead takes real x, real y returns nothing
local unit dummy
set dummy=CreateUnit( GetTriggerPlayer(), TURNDUMMYID, x, y, 0.00 )
call UnitApplyTimedLife( dummy, 'BTLF', 1.50)
call UnitAddAbility( dummy, TURNDUMMYFEARSPELLID)
call IssueTargetOrder( dummy, "acidbomb", GetEnumUnit() )
set dummy=null
endmethod
//Function of the medium effect on the affected units (unit will cower in fear)
private static method MidEffectUndead takes real x, real y returns nothing
local unit dummy
set dummy=CreateUnit( GetTriggerPlayer(), TURNDUMMYID, x, y, 0.00 )
call UnitApplyTimedLife( dummy, 'BTLF', 1.50)
call UnitAddAbility( dummy, TURNDUMMYCOWERSPELLID)
call IssueTargetOrder( dummy, "thunderbolt", GetEnumUnit() )
set dummy=null
endmethod
//Function of the maximum effect on the affected units (unit will die)
private static method MaxEffectUndead takes nothing returns nothing
call UnitApplyTimedLife( GetEnumUnit(), 'BTLF', 0.10)
endmethod
private static method TurnUnit takes nothing returns nothing
local real x=GetUnitX(GetEnumUnit())
local real y=GetUnitY(GetEnumUnit())
local integer total=MINEFFECTCHANCE+MIDEFFECTCHANCE+MAXEFFECTCHANCE
local integer rand
//The unit is already under a player changing effect, the spell won't affect it
if (GetUnitAbilityLevel(GetEnumUnit(), PLAYERCHANGERID)<=0) then
//The unit is low level (1, 2 or 3 depending on the level of the spell)
//With the current settings, it will have a 15% chance to die, 35% chance to Cower in fear
//and a 50% to run away in fear
if (GetUnitLevel(GetEnumUnit())<=0+GetUnitAbilityLevel(GetTriggerUnit(), TURNSPELLID)) then
set rand=GetRandomInt(1, total)
if (rand<=MAXEFFECTCHANCE) then
call Turned.MaxEffectUndead()
else
if(rand<=MAXEFFECTCHANCE+MIDEFFECTCHANCE) then
call Turned.MidEffectUndead(x, y)
else
call Turned.MinEffectUndead(x, y)
endif
endif
endif
//The unit is medium level (2, 3 or 4 depending on the level of the spell)
//With the current settings, it will have a 35% chance to Cower in fear
//and a 50% chance to run away in fear and a 15% chance to have no effect
if (GetUnitLevel(GetEnumUnit())==1+GetUnitAbilityLevel(GetTriggerUnit(), TURNSPELLID)) then
set rand=GetRandomInt(1, total)
if (rand>MAXEFFECTCHANCE) then
if(rand<=MAXEFFECTCHANCE+MIDEFFECTCHANCE) then
call Turned.MidEffectUndead(x, y)
else
call Turned.MinEffectUndead(x, y)
endif
endif
endif
//The unit is medium level (3, 4 or 5 depending on the level of the spell)
//With the current settings, it will have a 65% chance to run away in fear
//and a 35% chance to have no effect
if (GetUnitLevel(GetEnumUnit())==2+GetUnitAbilityLevel(GetTriggerUnit(), TURNSPELLID)) then
set rand=GetRandomInt(1, total)
if (rand>MIDEFFECTCHANCE) then
call Turned.MinEffectUndead(x, y)
endif
endif
endif
endmethod
public static method TurnActions takes nothing returns nothing
local real x=GetUnitX(GetTriggerUnit())
local real y=GetUnitY(GetTriggerUnit())
local rect turnArea=Rect(x-TURNAREARADIUS, y-TURNAREARADIUS, x+TURNAREARADIUS, y+TURNAREARADIUS)
local group g = CreateGroup()
local filterfunc f = Filter(function Turned.GetUndeads)
call GroupEnumUnitsInRect(g, turnArea, f)
call DestroyBoolExpr(f)
call ForGroup( g, function Turned.TurnUnit )
call DestroyGroup(g)
call RemoveRect(turnArea)
set g=null
set f=null
set turnArea=null
endmethod
endstruct
private function TurnConditions takes nothing returns boolean
return GetSpellAbilityId() == TURNSPELLID
endfunction
private function TurnDummyConditions takes nothing returns boolean
return GetSpellAbilityId() == TURNDUMMYFEARSPELLID
endfunction
private function InitTrig takes nothing returns nothing
local trigger Turn = CreateTrigger()
local trigger dummyTurn = CreateTrigger()
local integer i = 0
loop
exitwhen i == 16
call TriggerRegisterPlayerUnitEvent(Turn,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,ANTILEAKFILTER)
call TriggerRegisterPlayerUnitEvent(dummyTurn,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,ANTILEAKFILTER)
set i = i + 1
endloop
call TriggerAddCondition(Turn, Condition(function TurnConditions))
call TriggerAddAction(Turn, function Turned.TurnActions)
call TriggerAddCondition(dummyTurn, Condition(function TurnDummyConditions))
call TriggerAddAction(dummyTurn, function Turned.TurnDummyActions)
set Turn = null
endfunction
endlibrary
//TESH.scrollpos=147
//TESH.alwaysfold=0
// **************************************************************************
// ** **
// ** Confusion and Mass Confusion **
// ** βββββββββββββ **
// ** **
// ** The unit affected by these spells will randomly change owner every **
// ** CONFUSIONDURATION seconds **
// ** **
// ** By: Majin **
// **
// ** **
// **************************************************************************
//How to Import Confusion:
//This spell requires Both HandleTimers and PlayerChanger libraries
//Plus a dummy ability to be casted (the actual one is based on Cripple)
//You can copy paste the triggers, the ability, and the buff from this map
//but make sure to adjust the settings of the trigger, the ability and the Confused
//buff according to your needs.
//How to Import Mass Confusion:
//This spell requires Both HandleTimers and PlayerChanger libraries
//Plus a dummy ability to be casted (the actual one is based on Channel as area spell).
//It also requires a dummy unit and another spell with 3 levels that will be
//similar to the Confusion one of above. The dummy unit on this map is called
//"Mr Dummy" and the dummy spell "Confusion (Dummy)".
//You can copy paste the triggers, the abilities, the dummy unit and the buff from this map
//but make sure to adjust the settings of the trigger, the ability and the Confused
//buff according to your needs.
library Confusion initializer InitTrig requires PlayerChanger
globals
//ID of the ability used by the Confusion spell
constant integer CONFUSIONSPELLID='A00E'
//ID of the ability used by the Mass Confusion spell
constant integer MASSCONFUSIONSPELLID='A00B'
//ID of the ability used by the Dummy unit
constant integer DUMMYCONFUSIONSPELLID='A00F'
//ID of the dummy unit used to cast the confusion spell for the Mass Confusion Spell
constant integer CONFUSIONDUMMYID='e000'
//Interval between a change of player and another
constant real CONFUSIONDURATION=3
//Duration in seconds of the whole spell, make sure to change the ability accordingly. DEPENDANT ON LEVEL
constant real CONFUSIONTOTALDURATION=10
//How big will be the area covered by the spell, make sure to change the ability accordingly
constant real MASSCONFUSIONRADIUS=512
endglobals
struct Confused extends Changer
private timer confusionEndTimer
private boolean endConfusion=false
private static method create takes unit pOwner, player pPlayer, timer pTimer returns Confused
local Confused l=Confused.allocate(pOwner, pPlayer, pTimer, false)
return l
endmethod
//This method returns a random player
public static method GetRandomPlayer takes nothing returns player
local integer playerIndex
set playerIndex=GetRandomInt(0, 15)
return Player(playerIndex)
endmethod
private static method ConfusionEndActions takes nothing returns nothing
local Confused l=GetTimerInt(GetExpiredTimer())
call ReleaseTimer(l.confusionEndTimer)
set l.confusionEndTimer=null
set l.endConfusion=true
call l.RevertPlayer(false)
call l.destroy()
endmethod
private static method ConfusionLoopActions takes nothing returns nothing
local Confused l=GetTimerInt(GetExpiredTimer())
if ((GetUnitState(l.GetOwner(), UNIT_STATE_LIFE) <= 0) == false) and (l.endConfusion==false) then
call SetUnitOwner(l.GetOwner(), Confused.GetRandomPlayer(), false)
call TimerAttach(l.confusionEndTimer, CONFUSIONDURATION, l, function Confused.ConfusionLoopActions)
endif
endmethod
private static method GetConfusedUnits takes nothing returns boolean
return not(GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) <= 0) and (GetUnitAbilityLevel(GetFilterUnit(), PLAYERCHANGERID) <= 0) and ( IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false ) and ( IsUnitAlly(GetFilterUnit(), GetTriggerPlayer()) == false )
endmethod
private static method MassConfusionDummy takes nothing returns nothing
local real x=GetUnitX(GetEnumUnit())
local real y=GetUnitY(GetEnumUnit())
local unit dummy
set dummy=CreateUnit(GetTriggerPlayer(), CONFUSIONDUMMYID, x, y, 0 )
call UnitApplyTimedLife(dummy, 'BTLF', 1.50)
call UnitAddAbility(dummy, DUMMYCONFUSIONSPELLID)
//Use the commented part if you want to make Mass Confusion a 3 levels spell with different durations (make sure to modify the ability accordingly
call SetUnitAbilityLevel(dummy, DUMMYCONFUSIONSPELLID, 3) //GetUnitAbilityLevel(GetTriggerUnit(), MASSCONFUSIONSPELLID))
call IssueTargetOrder( dummy, "cripple", GetEnumUnit() )
set dummy=null
endmethod
//Actions to be taken by the Dummy spell for the Mass confusion spell
public static method DummyConfusionActions takes nothing returns nothing
local timer confusionTimer
local Confused l
set confusionTimer=NewTimer()
set l=Confused.create(GetSpellTargetUnit(), Confused.GetRandomPlayer(), confusionTimer)
set l.confusionEndTimer=NewTimer()
call TimerAttach(l.confusionEndTimer, CONFUSIONDURATION, l, function Confused.ConfusionLoopActions)
call TimerAttach(confusionTimer, CONFUSIONTOTALDURATION*GetUnitAbilityLevel(GetTriggerUnit(), DUMMYCONFUSIONSPELLID), l, function Confused.ConfusionEndActions)
set confusionTimer=null
endmethod
//Actions to be taken by the spell for the Mass confusion ability
public static method MassConfusionActions takes nothing returns nothing
local location massConfusionLoc = GetSpellTargetLoc()
local group g = CreateGroup()
local boolexpr f = Filter(function Confused.GetConfusedUnits)
call GroupEnumUnitsInRangeOfLoc(g, massConfusionLoc, MASSCONFUSIONRADIUS, f)
call ForGroup( g, function Confused.MassConfusionDummy )
call DestroyGroup(g)
call RemoveLocation(massConfusionLoc)
set massConfusionLoc=null
set g=null
set f=null
endmethod
//Actions to be taken by the spell for the confusion ability
public static method ConfusionActions takes nothing returns nothing
local timer confusionTimer
local Confused l
set confusionTimer=NewTimer()
set l=Confused.create(GetSpellTargetUnit(), Confused.GetRandomPlayer(), confusionTimer)
set l.confusionEndTimer=NewTimer()
call TimerAttach(l.confusionEndTimer, CONFUSIONDURATION, l, function Confused.ConfusionLoopActions)
call TimerAttach(confusionTimer, CONFUSIONTOTALDURATION*GetUnitAbilityLevel(GetTriggerUnit(), CONFUSIONSPELLID), l, function Confused.ConfusionEndActions)
set confusionTimer=null
endmethod
endstruct
private function ConfusionConditions takes nothing returns boolean
return GetSpellAbilityId() == CONFUSIONSPELLID
endfunction
private function MassConfusionConditions takes nothing returns boolean
return GetSpellAbilityId() == MASSCONFUSIONSPELLID
endfunction
function DummyConfusionConditions takes nothing returns boolean
return GetSpellAbilityId() == DUMMYCONFUSIONSPELLID
endfunction
private function InitTrig takes nothing returns nothing
local trigger Confusion = CreateTrigger()
local trigger CheckConfusion = CreateTrigger()
local trigger DummyConfusion = CreateTrigger()
local trigger MassConfusion = CreateTrigger()
local integer i = 0
loop
exitwhen i == 16
call TriggerRegisterPlayerUnitEvent(Confusion,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,ANTILEAKFILTER)
call TriggerRegisterPlayerUnitEvent(CheckConfusion,Player(i),EVENT_PLAYER_UNIT_SPELL_CAST,ANTILEAKFILTER)
call TriggerRegisterPlayerUnitEvent(DummyConfusion,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,ANTILEAKFILTER)
call TriggerRegisterPlayerUnitEvent(MassConfusion,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,ANTILEAKFILTER)
set i = i + 1
endloop
call TriggerAddCondition(Confusion, Condition(function ConfusionConditions))
call TriggerAddAction(Confusion, function Confused.ConfusionActions)
call TriggerAddCondition(CheckConfusion, Condition(function ConfusionConditions))
call TriggerAddAction(CheckConfusion, function Changer.CheckChanged)
call TriggerAddCondition(DummyConfusion, Condition(function DummyConfusionConditions))
call TriggerAddAction(DummyConfusion, function Confused.DummyConfusionActions)
call TriggerAddCondition(MassConfusion, Condition(function MassConfusionConditions))
call TriggerAddAction(MassConfusion, function Confused.MassConfusionActions)
set Confusion = null
set CheckConfusion = null
endfunction
endlibrary
//TESH.scrollpos=10
//TESH.alwaysfold=0
// **************************************************************************
// ** **
// ** Item Divine Shield Fix**
// ** βββββββββββββ **
// ** **
// ** Function used to make Divine Shield castable more than once by using an item **
// ** **
// ** By: Majin **
// **
// ** **
// **************************************************************************
scope DivineShieldItem initializer InitTrig
function Conditions takes nothing returns boolean
return GetItemTypeId(GetManipulatedItem()) == 'I000'
endfunction
function GetInventoryIndexOfItem takes unit u, item it returns integer
local integer i=0
loop
if (UnitItemInSlot(u, i) != null) and (UnitItemInSlot(u, i) == it) then
return i
endif
set i=i+1
exitwhen i>=6
endloop
return 0
endfunction
function Actions takes nothing returns nothing
local integer i=GetInventoryIndexOfItem(GetTriggerUnit(), GetManipulatedItem())
call UnitRemoveItem(GetTriggerUnit(), GetManipulatedItem())
call UnitAddItem(GetTriggerUnit(), GetManipulatedItem())
call UnitDropItemSlot(GetTriggerUnit(), GetManipulatedItem(), i)
endfunction
//===========================================================================
function InitTrig takes nothing returns nothing
local trigger DivineShieldItem=CreateTrigger()
local integer i=0
loop
exitwhen i==16
call TriggerRegisterPlayerUnitEvent(DivineShieldItem,Player(i),EVENT_PLAYER_UNIT_USE_ITEM,ANTILEAKFILTER)
set i = i + 1
endloop
call TriggerAddCondition(DivineShieldItem, Condition(function Conditions))
call TriggerAddAction(DivineShieldItem, function Actions)
set DivineShieldItem=null
endfunction
endscope