Name | Type | is_array | initial_value |
HASH | hashtable | No | |
MET_Error | sound | No | |
MET_NewUnit | integer | Yes |
//TESH.scrollpos=6
//TESH.alwaysfold=0
//===Spell Name: Metasis v1.3
//===Created by Mckill2009
//===INSTRUCTIONS: Follow these steps
//- Be sure to check the 'Automatically create unknown variables...', via File>Preferences>General tab.
//- In the object editor, copy the custom Ability to your map.
//- Be sure to input the correct MET_SpellId(rawID).
//- Copy the "Metasis" trigger to your map.
//- If you want to change the units you may do it by changing the rawID from the MET_SetupNewUnits function.
//- To view the rawID in the object editor press CTRL+D.
//===REQUIRED VARIABLES:
//- HASH = hashtable
//- MET_NewUnit = integer array
//- MET_Error = sound
//Credits to Vexorian for the sound, I got the idea from his SimError library
//===FULL DESCRIPTION:
//Calls a dark magic from the underworld which can transform an ally unit to a random powerful creature such as Death Reverant, Satyr Hellcaller, Bandit Lord, Eredar Warlock or Elder Voidwalker.
//When the creature dies, it restores the original unit but it's life and mana is depleted by x%.
//Heroes and structures are immune to this magic.
//Summoned units will instantly die after restoration.
//Level 1 - Creature lasts 15 seconds, life and mana depleted by 80%
//Level 2 - Creature lasts 30 seconds, life and mana depleted by 65%
//Level 3 - Creature lasts 45 seconds, life and mana depleted by 50%
//Level 4 - Creature lasts 60 seconds, life and mana depleted by 35%
//Level 5 - Creature lasts 75 seconds, life and mana depleted by 20%
function MET_SpellId takes nothing returns integer
return 'A002' //rawID, you may change this when necessary
endfunction
//==========CONFIGURABLES:
function MET_SetupNewUnits takes nothing returns nothing
set udg_MET_NewUnit[1] = 'nbld' //rawID (default Bandit Lord)
set udg_MET_NewUnit[2] = 'nerw' //rawID (default Eredar Warlock)
set udg_MET_NewUnit[3] = 'nrvd' //rawID (default Death Reverant)
set udg_MET_NewUnit[4] = 'nvde' //rawID (default Elder Voidwalker)
set udg_MET_NewUnit[5] = 'nsth' //rawID (default Satyr Hellcaller)
endfunction
function MET_SfxNewUnit takes nothing returns string
return "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl"
endfunction
function MET_SfxRestore takes nothing returns string
return "Abilities\\Spells\\Human\\ReviveHuman\\ReviveHuman.mdl"
endfunction
function MET_ErrorMsg takes nothing returns string
return "This unit has been changed!"
endfunction
function MET_NeedLifeMin takes nothing returns string
return "Life of unit must be at least 80%"
endfunction
function MET_Duration takes integer i returns real
return i * 15.
endfunction
function MET_RestoredState takes real state, integer i returns real
return (state)*(0.15*i+0.05) //0.2,0.35,0.50,0.65,0.80
endfunction
function MET_MaxUnits takes nothing returns integer
return 5 //this number should be the last index number of set udg_MET_NewUnit[5]
endfunction
//==========END OF CONFIGURABLES:
//===================================================
//=====THIS IS THE RESTORE POINT AND RESTORED UNIT
function MET_Restore takes nothing returns boolean
local unit r = GetTriggerUnit()
local integer newunitID = GetHandleId(r)
local unit restoredunit = LoadUnitHandle(udg_HASH, newunitID, 0) //this is the original unit
call SetUnitX(restoredunit, GetUnitX(r))
call SetUnitY(restoredunit, GetUnitY(r))
//Restoring the previous unit
if not (IsUnitType(restoredunit, UNIT_TYPE_SUMMONED) or IsUnitType(restoredunit, UNIT_TYPE_HERO)) then
call DestroyEffect(AddSpecialEffectTarget(MET_SfxRestore(), restoredunit, "origin"))
endif
call PauseUnit(restoredunit, false)
call ShowUnit(restoredunit, true)
call SetUnitInvulnerable(restoredunit, false)
call SetUnitUseFood(restoredunit, true)
call SetWidgetLife(restoredunit, LoadReal(udg_HASH, newunitID, 1)) //statelife
call SetUnitState(restoredunit, UNIT_STATE_MANA, LoadReal(udg_HASH, newunitID, 2)) //statemana
//Summoned and Hero units dies instantly
if IsUnitType(restoredunit, UNIT_TYPE_SUMMONED) or IsUnitType(restoredunit, UNIT_TYPE_HERO) then
call KillUnit(restoredunit)
endif
call FlushChildHashtable(udg_HASH, newunitID)
set r = null
set restoredunit = null
return false
endfunction
//=====THIS IS THE METASIS SPELL
function MET_Looper takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer metkey = GetHandleId(t)
local unit tar = LoadUnitHandle(udg_HASH, metkey, 1)//This is the original unit
local unit newunit
local integer newunitID
local real x = GetUnitX(tar)
local real y = GetUnitY(tar)
call ShowUnit(tar, false)
call SetUnitUseFood(tar, false)
set newunit = CreateUnit(GetOwningPlayer(tar), udg_MET_NewUnit[GetRandomInt(1,MET_MaxUnits())], x, y, 0)
set newunitID = GetHandleId(newunit)// This will be used when the newunit dies and restores the previous unit
call DestroyEffect(AddSpecialEffectTarget(MET_SfxNewUnit(), newunit, "origin"))
//when newunit dies, the target will return to these settings
call SaveUnitHandle(udg_HASH, newunitID, 0, tar) //the original target
call SaveReal(udg_HASH, newunitID, 1, LoadReal(udg_HASH, metkey, 2)) //statelife
call SaveReal(udg_HASH, newunitID, 2, LoadReal(udg_HASH, metkey, 3)) //statemana
call UnitApplyTimedLife(newunit, 'BTLF', LoadReal(udg_HASH, metkey, 4))
call FlushChildHashtable(udg_HASH, metkey)
call PauseTimer(t)
call DestroyTimer(t)
set t = null
set tar = null
set newunit = null
endfunction
function MET_Action takes nothing returns nothing
local timer t
local integer metkey
local unit cas = GetTriggerUnit()
local unit tar = GetSpellTargetUnit()
local integer targetkey = GetHandleId(tar)
local integer level
local string msg
local real maxlife
if HaveSavedHandle(udg_HASH, targetkey, 0) then
call ClearTextMessages()
set msg="\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n|cffffcc00"+MET_ErrorMsg()+"|r"
call IssueImmediateOrder(cas, "stop")
call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0.52, 0.96, 2.00, msg)
call StartSound(udg_MET_Error)
else
set maxlife = GetUnitState(tar,UNIT_STATE_MAX_LIFE)
if GetWidgetLife(tar) > (maxlife*0.8) then
set t = CreateTimer()
set metkey = GetHandleId(t)
set level = GetUnitAbilityLevel(cas, MET_SpellId())
call UnitPauseTimedLife(tar, true) //this is used only for summoned unit
call PauseUnit(tar, true)
call SetUnitInvulnerable(tar, true)
call SaveUnitHandle(udg_HASH, metkey, 1, tar)
call SaveReal(udg_HASH, metkey, 2, MET_RestoredState(GetWidgetLife(tar), level))
call SaveReal(udg_HASH, metkey, 3, MET_RestoredState(GetUnitState(tar, UNIT_STATE_MANA), level))
call SaveReal(udg_HASH, metkey, 4, MET_Duration(level))
call TimerStart(t, 3, false, function MET_Looper)
set t = null
else
call ClearTextMessages()
set msg="\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n|cffffcc00"+MET_NeedLifeMin()+"|r"
call IssueImmediateOrder(cas, "stop")
call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0.52, 0.96, 2.00, msg)
call StartSound(udg_MET_Error)
endif
endif
set tar = null
set cas = null
endfunction
function MET_Condition takes nothing returns boolean
return GetSpellAbilityId()==MET_SpellId()
endfunction
function InitTrig_Metasis takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ (t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function MET_Condition))
call TriggerAddAction(t, function MET_Action)
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(t, function MET_Restore)
set udg_HASH = InitHashtable()
call MET_SetupNewUnits()
set udg_MET_Error = CreateSoundFromLabel("InterfaceError",false,false,false,10,10)
set t = null
endfunction