//TESH.scrollpos=0
//TESH.alwaysfold=0
Name | Type | is_array | initial_value |
//TESH.scrollpos=234
//TESH.alwaysfold=0
//! import "luajass.Aeon_of_War.j"
//! textmacro LUA_FILE_HEADER
//! i do
//! i local FILENAME = "Aeon_of_War"
//! i function getfilename()
//! i return FILENAME
//! i end
//! i local PATH_LUA_p = "grimext\\luadir"
//! i local PATH_JASS_p = PATH_LUA_p .. "\\" .. FILENAME .. "_dir"
//! i local PATH_LUA = PATH_LUA_p .. "\\"
//! i local PATH_JASS = PATH_JASS_p .. "\\"
//! i local JASS_HUB = "jass\\luajass." .. FILENAME .. ".j"
//! i local olddofile = dofile
//! i local oldrequire = require
//! i local oldloadfile = loadfile
//! i function dofile(name)
//! i oldrequire("luadir\\" .. name)
//! i end
//! i function require(name)
//! i dofile(name)
//! i end
//! i function loadfile(name)
//! i dofile(name)
//! i end
//! i local function getluapath(name)
//! i return (PATH_LUA .. name .. ".lua")
//! i end
//! i local function getjasspath(name)
//! i return (PATH_JASS .. name .. ".luajass.j")
//! i end
//! i local function getjassimport(name)
//! i return ("\/\/! import \"..\\" .. getjasspath(name) .. "\"")
//! i end
//! i local function del(name)
//! i os.remove(name)
//! i end
//! i local function read(path)
//! i local file = io.open(path, "r")
//! i code = nil
//! i if (file ~= nil) then
//! i code = file:read("*all")
//! i file:close()
//! i end
//! i return code
//! i end
//! i local function write(path, code)
//! i file = io.open(path, "w")
//! i file:write(code)
//! i file:close()
//! i end
//! i local function import(name)
//! i local code = read(JASS_HUB)
//! i local line = getjassimport(name) .. "\n"
//! i local s,k = code:find(line)
//! i if (s == nil) then
//! i write(JASS_HUB, code .. line)
//! i end
//! i end
//! i function readlua(name)
//! i return read(getluapath(name))
//! i end
//! i function writelua(name, code)
//! i write(getluapath(name), code)
//! i end
//! i function readjass(name)
//! i return read(getjasspath(name))
//! i end
//! i function writejass(name, code)
//! i write(getjasspath(name), code)
//! i import(name)
//! i end
//! i function deletelua(name)
//! i del(getluapath(name))
//! i end
//! i function deletejass(name)
//! i del(getjasspath(name))
//! i local line = getjassimport(name) .. "\n"
//! i local code = read(JASS_HUB)
//! i local s,k = code:find(line)
//! i if (s ~= nil) then
//! i write(JASS_HUB, code:sub(1,s-1) .. code:sub(k+1))
//! i end
//! i end
//! i end
//! endtextmacro
library BasicFunctions requires AutoIndex
function Legal_Hero_Check takes unit u returns boolean
if ( GetUnitTypeId(u) == WARRIOR_ID ) then
return true
endif
if ( GetUnitTypeId(u) == PRIEST_ID ) then
return true
endif
if ( GetUnitTypeId(u) == MAGE_ID ) then
return true
endif
if ( GetUnitTypeId(u) == DRUID_ID ) then
return true
endif
if ( GetUnitTypeId(u) == ROGUE_ID ) then
return true
endif
if ( GetUnitTypeId(u) == HUNTER_ID ) then
return true
endif
if ( GetUnitTypeId(u) == NECRO_ID ) then
return true
endif
if ( GetUnitTypeId(u) == PALADIN_ID ) then
return true
endif
if ( GetUnitTypeId(u) == ENT_ID ) then
return true
endif
// Horde
if ( GetUnitTypeId(u) == WARRIOR_ID2 ) then
return true
endif
if ( GetUnitTypeId(u) == PRIEST_ID2 ) then
return true
endif
if ( GetUnitTypeId(u) == MAGE_ID2 ) then
return true
endif
if ( GetUnitTypeId(u) == DRUID_ID2 ) then
return true
endif
if ( GetUnitTypeId(u) == ROGUE_ID2 ) then
return true
endif
if ( GetUnitTypeId(u) == HUNTER_ID2 ) then
return true
endif
if ( GetUnitTypeId(u) == NECRO_ID2 ) then
return true
endif
if ( GetUnitTypeId(u) == SHAMAN_ID ) then
return true
endif
if ( GetUnitTypeId(u) == ENT_ID2 ) then
return true
endif
return false
endfunction
function Chance takes real r returns boolean
if GetRandomReal(1,100) <= r then
return true
endif
return false
endfunction
function IsTeam1 takes unit u returns boolean
return IsPlayerAlly(GetOwningPlayer(u), Player(1)) == true
endfunction
function Game_Message takes string Message returns nothing
call DisplayTimedTextToPlayer( GetLocalPlayer(), 0, 0, 15.00, EVENT + Message )
endfunction
function Debug_Message takes string Message returns nothing
if DEBUG_MODE then
call DisplayTimedTextToPlayer( GetLocalPlayer(), 0, 0, 15.00, DEBUG + Message )
endif
endfunction
function AI_Only_Check_Callback takes nothing returns nothing
if GetPlayerController(GetEnumPlayer()) == MAP_CONTROL_USER then
// Team 1
if IsPlayerAlly(GetEnumPlayer(), Player(1)) == true then
set AI_Only_Team1 = false
// Team 2
else
set AI_Only_Team2 = false
endif
endif
endfunction
function AI_Only_Check takes nothing returns nothing
set AI_Only = false
// Team 1
set AI_Only_Team1 = true
call ForForce(Players_Team1, function AI_Only_Check_Callback)
// Team 2
set AI_Only_Team2 = true
call ForForce(Players_Team2, function AI_Only_Check_Callback)
if AI_Only_Team1 == true or AI_Only_Team2 == true then
set AI_Only = true
endif
endfunction
function Order_Unit_Move_To_Direct_WP takes unit u, integer i returns nothing
call IssuePointOrderLoc( u, "move", Waypoint_Array[i] )
endfunction
function Order_Unit_To_Next_WP takes unit u returns nothing
local integer i = waypoint_table[GetUnitId(u)]
if i != 0 then
call IssuePointOrderLoc( u, "attack", Waypoint_Array[i] )
endif
endfunction
function Order_Unit_To_Next_WP_Delay takes unit u returns nothing
local integer i = waypoint_table[GetUnitId(u)]
call TriggerSleepAction( 1.00 )
call IssuePointOrderLoc( u, "attack", Waypoint_Array[i] )
endfunction
function UnitUsesWP takes unit u returns boolean
return IsPlayerInForce(GetOwningPlayer(u), AI_Players) and waypoint_table[GetUnitId(u)] > 0 and waypoint_table[GetUnitId(u)] < 60
endfunction
function CreateTagOnUnit takes unit TargetUnit, string Text returns nothing
local integer id = GetPlayerId(GetOwningPlayer(TargetUnit))
local texttag t = CreateTextTag()
set Text = "|c00" + PlayerColors[id] + Text + "|r"
call SetTextTagColor(t, 182, 91, 234, 255)
call SetTextTagText(t, Text, 0.0184)
call SetTextTagPos(t, GetUnitX(TargetUnit), GetUnitY(TargetUnit), 0.00)
call SetTextTagVelocity(t, 0, 0.03)
call SetTextTagVisibility(t, true)
call SetTextTagFadepoint(t, 3)
call SetTextTagLifespan(t, 4)
call SetTextTagPermanent(t, false)
set t = null
endfunction
function CreateDamageTag takes unit source, unit target, real value, boolean isCrit, boolean isHealing returns nothing
local texttag t
local string s
local real life = GetUnitState(target, UNIT_STATE_LIFE)
local real max_life = GetUnitState(target, UNIT_STATE_MAX_LIFE)
local player PlayerSource = GetOwningPlayer(source)
local player PlayerTarget = GetOwningPlayer(target)
// Let's only display damage/healing if it's not 0
if ( not ( value == 0 ) ) then
set t = CreateTextTag()
if value < 0 then
set value = -value
endif
set s = I2S(R2I(value))
call SetTextTagVisibility(t, false)
// crit?
if isCrit then
call SetTextTagText(t, s+"!", CRIT_TAG_SIZE)
if not isHealing then
call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodFootman.mdl", target, "origin"))
endif
// normal
else
call SetTextTagText(t, s, TAG_SIZE) // 0.0184
endif
// Healing
if isHealing then
if PlayerTarget == GetLocalPlayer() then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SetTextTagVisibility(t, true)
endif
call SetTextTagColor(t, 178, 233, 142, 255)
if life >= max_life then
call SetTextTagText(t, "", TAG_SIZE)
endif
// Damage
else
call SetTextTagColor(t, 200, 0, 30, 255)
endif
call SetTextTagPos(t, GetUnitX(target), GetUnitY(target), 0.00)
call SetTextTagVelocity(t, 0, 0.03)
call SetTextTagFadepoint(t, 2)
call SetTextTagLifespan(t, 3)
call SetTextTagPermanent(t, false)
if PlayerSource == GetLocalPlayer() then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SetTextTagVisibility(t, true)
endif
endif
set t = null
set PlayerSource = null
set PlayerTarget = null
endfunction
function Get_Number_Of_Players takes integer team returns integer
local integer number
// Team 1
if team == 1 then
set number = NumberOfPlayersTeam1
// Team 2
elseif team == 2 then
set number = NumberOfPlayersTeam2
// All players
else
set number = NumberOfPlayers
endif
return number
endfunction
function Init_Players_AI_Callback takes nothing returns nothing
if GetPlayerController(GetEnumPlayer()) == MAP_CONTROL_COMPUTER then
set AI_Active = true
// Team 1
if IsPlayerAlly(GetEnumPlayer(), Player(1)) == true then
call ForceAddPlayer( AI_Players_Team1, GetEnumPlayer() )
call ForceAddPlayer( AI_Players, GetEnumPlayer() )
// Team 2
else
call ForceAddPlayer( AI_Players_Team2, GetEnumPlayer() )
call ForceAddPlayer( AI_Players, GetEnumPlayer() )
endif
endif
endfunction
function Init_Players takes nothing returns nothing
local integer id
// Init Colors first
// Team 1 and Team 2
set PlayerColors[0] = "FF0202"
set PlayerColors[1] = "0041FF"
// User Players
set PlayerColors[2] = "1BE5B8"
set PlayerColors[3] = "530080"
set PlayerColors[4] = "FFFC00"
set PlayerColors[5] = "FE890D"
set PlayerColors[6] = "1FBF00"
set PlayerColors[7] = "E45AAF"
set PlayerColors[8] = "949596"
set PlayerColors[9] = "7DBEF1"
set PlayerColors[10] = "0F6145"
set PlayerColors[11] = "4D2903"
// Other Players
set PlayerColors[GetPlayerId(Player(PLAYER_NEUTRAL_AGGRESSIVE))] = "DA4949"
set PlayerColors[GetPlayerId(Player(bj_PLAYER_NEUTRAL_VICTIM))] = "B6B6B6"
set PlayerColors[GetPlayerId(Player(bj_PLAYER_NEUTRAL_EXTRA))] = "B6B6B6"
set PlayerColors[GetPlayerId(Player(PLAYER_NEUTRAL_PASSIVE))] = "94D598"
// Player Names
set PlayerNames[2] = "|cff" + PlayerColors[2] + GetPlayerName(Player(2)) + "|r"
set PlayerNames[3] = "|cff" + PlayerColors[3] + GetPlayerName(Player(3)) + "|r"
set PlayerNames[4] = "|cff" + PlayerColors[4] + GetPlayerName(Player(4)) + "|r"
set PlayerNames[5] = "|cff" + PlayerColors[5] + GetPlayerName(Player(5)) + "|r"
set PlayerNames[6] = "|cff" + PlayerColors[6] + GetPlayerName(Player(6)) + "|r"
set PlayerNames[7] = "|cff" + PlayerColors[7] + GetPlayerName(Player(7)) + "|r"
set PlayerNames[8] = "|cff" + PlayerColors[8] + GetPlayerName(Player(8)) + "|r"
set PlayerNames[9] = "|cff" + PlayerColors[9] + GetPlayerName(Player(9)) + "|r"
set PlayerNames[10] = "|cff" + PlayerColors[10] + GetPlayerName(Player(10)) + "|r"
set PlayerNames[11] = "|cff" + PlayerColors[11] + GetPlayerName(Player(11)) + "|r"
// Init all players
set id = 2
loop
exitwhen id > 11
if GetPlayerSlotState(Player(id)) == PLAYER_SLOT_STATE_PLAYING then
call ForceAddPlayer( Players, Player(id) )
set NumberOfPlayers = NumberOfPlayers + 1
endif
set id = id + 1
endloop
// Init Team 1
if GetPlayerSlotState(Player(2)) == PLAYER_SLOT_STATE_PLAYING then
call ForceAddPlayer( Players_Team1, Player(2) )
set NumberOfPlayersTeam1 = NumberOfPlayersTeam1 + 1
endif
if GetPlayerSlotState(Player(6)) == PLAYER_SLOT_STATE_PLAYING then
call ForceAddPlayer( Players_Team1, Player(6) )
set NumberOfPlayersTeam1 = NumberOfPlayersTeam1 + 1
endif
if GetPlayerSlotState(Player(8)) == PLAYER_SLOT_STATE_PLAYING then
call ForceAddPlayer( Players_Team1, Player(8) )
set NumberOfPlayersTeam1 = NumberOfPlayersTeam1 + 1
endif
if GetPlayerSlotState(Player(9)) == PLAYER_SLOT_STATE_PLAYING then
call ForceAddPlayer( Players_Team1, Player(9) )
set NumberOfPlayersTeam1 = NumberOfPlayersTeam1 + 1
endif
if GetPlayerSlotState(Player(10)) == PLAYER_SLOT_STATE_PLAYING then
call ForceAddPlayer( Players_Team1, Player(10) )
set NumberOfPlayersTeam1 = NumberOfPlayersTeam1 + 1
endif
// Init Team 2
if GetPlayerSlotState(Player(3)) == PLAYER_SLOT_STATE_PLAYING then
call ForceAddPlayer( Players_Team2, Player(3) )
set NumberOfPlayersTeam2 = NumberOfPlayersTeam2 + 1
endif
if GetPlayerSlotState(Player(4)) == PLAYER_SLOT_STATE_PLAYING then
call ForceAddPlayer( Players_Team2, Player(4) )
set NumberOfPlayersTeam2 = NumberOfPlayersTeam2 + 1
endif
if GetPlayerSlotState(Player(5)) == PLAYER_SLOT_STATE_PLAYING then
call ForceAddPlayer( Players_Team2, Player(5) )
set NumberOfPlayersTeam2 = NumberOfPlayersTeam2 + 1
endif
if GetPlayerSlotState(Player(7)) == PLAYER_SLOT_STATE_PLAYING then
call ForceAddPlayer( Players_Team2, Player(7) )
set NumberOfPlayersTeam2 = NumberOfPlayersTeam2 + 1
endif
if GetPlayerSlotState(Player(11)) == PLAYER_SLOT_STATE_PLAYING then
call ForceAddPlayer( Players_Team2, Player(11) )
set NumberOfPlayersTeam2 = NumberOfPlayersTeam2 + 1
endif
// Init AI players
call ForceAddPlayer ( AI_Players, Player(0) )
call ForceAddPlayer ( AI_Players, Player(1) )
call ForceAddPlayer ( AI_Players, Player(PLAYER_NEUTRAL_AGGRESSIVE) )
call ForForce( Players_Team1, function Init_Players_AI_Callback)
call ForForce( Players_Team2, function Init_Players_AI_Callback)
endfunction
function IsUnitTeam1 takes unit u returns boolean
if IsPlayerAlly(GetOwningPlayer(u), Player(1)) == true then
set u = null
return true
endif
set u = null
return false
endfunction
function IsUnitTeam2 takes unit u returns boolean
if IsPlayerAlly(GetOwningPlayer(u), Player(0)) == true then
set u = null
return true
endif
set u = null
return false
endfunction
function Team_Message takes integer teamid, string message returns nothing
local real positionX = 0
local real positionY = 0
local real duration = 10
// Team 1
if teamid == 1 then
call DisplayTimedTextToPlayer(Player(1), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(2), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(6), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(8), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(9), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(10), positionX, positionY, duration, message)
// Team 2
elseif teamid == 2 then
call DisplayTimedTextToPlayer(Player(0), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(3), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(4), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(5), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(7), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(11), positionX, positionY, duration, message)
else
call DisplayTimedTextToPlayer(Player(0), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(1), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(2), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(3), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(4), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(5), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(6), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(7), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(8), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(9), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(10), positionX, positionY, duration, message)
call DisplayTimedTextToPlayer(Player(11), positionX, positionY, duration, message)
endif
endfunction
function IncScoreDamage takes integer id, real d returns nothing
set Score_Damage[id] = Score_Damage[id] + d
endfunction
function IncScoreHealing takes integer id, real d returns nothing
set Score_Healing[id] = Score_Healing[id] + d
endfunction
function GetOnePlayerId takes nothing returns integer
local integer i
local integer id
set i = 2
loop
exitwhen i > 11
if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
set id = i
endif
set i = i + 1
endloop
return id
endfunction
function GetHighestLevelId takes nothing returns integer
local integer i
local integer id = GetOnePlayerId()
set i = 2
loop
exitwhen i > 11
if Score_Levels[i] > Score_Levels[id] and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
set id = i
endif
set i = i + 1
endloop
return id
endfunction
function GetHighestKillsId takes nothing returns integer
local integer i
local integer id = GetOnePlayerId()
set i = 2
loop
exitwhen i > 11
if Score_Kills[i] > Score_Kills[id] and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
set id = i
endif
set i = i + 1
endloop
return id
endfunction
function GetHighestPvPId takes nothing returns integer
local integer i
local integer id = GetOnePlayerId()
set i = 2
loop
exitwhen i > 11
if Score_PvP[i] > Score_PvP[id] and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
set id = i
endif
set i = i + 1
endloop
return id
endfunction
function GetLowestDeathsId takes nothing returns integer
local integer i
local integer id = GetOnePlayerId()
set i = 2
loop
exitwhen i > 11
if Score_Deaths[i] < Score_Deaths[id] and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
set id = i
endif
set i = i + 1
endloop
return id
endfunction
function GetMostDamageId takes nothing returns integer
local integer i
local integer id = GetOnePlayerId()
set i = 2
loop
exitwhen i > 11
if Score_Damage[i] > Score_Damage[id] and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
set id = i
endif
set i = i + 1
endloop
return id
endfunction
function GetMostHealingId takes nothing returns integer
local integer i
local integer id = GetOnePlayerId()
set i = 2
loop
exitwhen i > 11
if Score_Healing[i] > Score_Healing[id] and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
set id = i
endif
set i = i + 1
endloop
return id
endfunction
private function ScorePlayersCallback takes nothing returns nothing
call CreateFogModifierRadiusLocBJ( true, GetEnumPlayer(), FOG_OF_WAR_VISIBLE, Location(57, 2700), 1024 )
call CreateFogModifierRadiusLocBJ( true, GetEnumPlayer(), FOG_OF_WAR_VISIBLE, Location(-5808, 7793), 1024 )
call CreateFogModifierRadiusLocBJ( true, GetEnumPlayer(), FOG_OF_WAR_VISIBLE, Location(-2312, 4384), 1024 )
call CameraSetupApplyForPlayer( true, ScoreCam, GetEnumPlayer(), 0 )
endfunction
private function ScoreDefeatCallback takes nothing returns nothing
call CustomDefeatBJ( GetEnumPlayer(), "The enemy team has defeated you!" )
endfunction
private function ScoreVictoryCallback takes nothing returns nothing
call CustomVictoryBJ( GetEnumPlayer(), true, true )
endfunction
function ShowScores takes integer WinningTeam returns nothing
local real duration = SCORE_DURATION
local integer i = GetRandomInt(0,30)
if i > 20 then
set ScoreCam = gg_cam_Camera_003
elseif i > 10 then
set ScoreCam = gg_cam_Camera_002
else
set ScoreCam = gg_cam_Camera_001
endif
call EnableUserControl(false)
call PauseAllUnitsBJ( true )
call PlayThematicMusicBJ( "Sound\\Music\\mp3Music\\PH1.mp3" )
call TriggerSleepAction(2.0)
call PlaySoundBJ(Sound_Score)
call CinematicFadeBJ( bj_CINEFADETYPE_FADEOUT, 3, "ReplaceableTextures\\CameraMasks\\Black_mask.blp", 0, 0, 0, 0 )
// call TriggerSleepAction(3)
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " ")
if WinningTeam == 1 then
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " |cff2377D5TEAM 1|r WINS!")
elseif WinningTeam == 2 then
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " |cffF32222TEAM 2|r WINS!")
endif
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration, " ")
call TriggerSleepAction(7)
call DisableTrigger( gg_trg_Camera )
call ForForce(bj_FORCE_ALL_PLAYERS, function ScorePlayersCallback)
call CinematicFadeBJ( bj_CINEFADETYPE_FADEIN, 8, "ReplaceableTextures\\CameraMasks\\Black_mask.blp", 0, 0, 0, 0 )
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration*2, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration*2, "|cffDCDCDCThanks for playing |r"+TITLE+" "+VERSION)
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration*2, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration*2, "|cffDCDCDCPlease feel free to report any feedback on this map at|r |cffFFA358hiveworkshop.com|r")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration*2, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration*2, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration*2, " |cffFFDD8DHighest Level|r "+"|cffDCDCDC["+I2S(Score_Levels[GetHighestLevelId()])+"] : |r"+PlayerNames[GetHighestLevelId()])
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration*2, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration*2, " |cffFF974AMost PvP|r "+"|cffDCDCDC["+I2S(Score_PvP[GetHighestPvPId()])+"] : |r"+PlayerNames[GetHighestPvPId()])
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration*2, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration*2, " |cffD60505Most Kills|r "+"|cffDCDCDC["+I2S(Score_Kills[GetHighestKillsId()])+"] : |r"+PlayerNames[GetHighestKillsId()])
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration*2, " ")
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration*2, " |cff7A7878Least Deaths|r "+"|cffDCDCDC["+I2S(Score_Deaths[GetLowestDeathsId()])+"] : |r"+PlayerNames[GetLowestDeathsId()])
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, duration*2, " ")
call TriggerSleepAction(duration)
call CinematicFadeBJ( bj_CINEFADETYPE_FADEOUT, 2, "ReplaceableTextures\\CameraMasks\\Black_mask.blp", 0, 0, 0, 0 )
call TriggerSleepAction(2)
if WinningTeam == 1 then
call ForForce(Players_Team1, function ScoreVictoryCallback)
call ForForce(Players_Team2, function ScoreDefeatCallback)
elseif WinningTeam == 2 then
call ForForce(Players_Team1, function ScoreDefeatCallback)
call ForForce(Players_Team2, function ScoreVictoryCallback)
endif
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
globals
// Map information
constant string TITLE = "|c0054e37cA|c004bd679e|c0043ca77o|c003abd75n |c002aa471o|c0021986ef |c00107f6aW|c00087268a|c00006666r|r"
constant string VERSION = "|cffF7D599v1.03|r"
constant string AUTHOR = "|cff616161by MoCo|r"
// constant boolean DEBUG_RUN = true
constant real CAMERA_RANGE = 640 // 720 // Z offset of game camera
constant integer UNIT_CAP = 100 // currently unused
constant integer START_GOLD = 0
constant integer START_HONOR = 3
constant string SKY_MODEL = "Environment\\Sky\\FelwoodSky\\FelwoodSky.mdl"
// Tags
constant string DEBUG = "|cffEA34DFDebug-Info:|r "
constant string EVENT = "|cffF7A647Game Event:|r "
constant string HINT = "|cff34A3EAHint:|r "
constant string UPGRADE = "|cff9AFDACTeam Upgrade Notice:|r "
constant string TEAM1 = "|cff2377D5Team 1|r "
constant string TEAM2 = "|cffF32222Team 2|r "
constant integer MAX_PLAYERS = 11
constant real TAG_SIZE = 0.02 // // 0.0184
constant real CRIT_TAG_SIZE = 0.03
constant integer INCOME = 20
constant real GENERIC_ASSIST_RANGE = 512
constant real HONOR_RANGE = 800
constant real SCORE_DURATION = 20
unit array Heroes[1]
fogmodifier array Fogs[1]
integer array Score_Kills[1]
integer array Score_PvP[1]
integer array Score_Deaths[1]
integer array Score_Levels[1]
real array Score_Damage[1]
real array Score_Healing[1]
camerasetup ScoreCam
// Various stuff
location array Waypoint_Array[1]
location Spawn_Team1
location Spawn_Team2
unit Base_Team1 = gg_unit_htow_0033
unit Base_Team2 = gg_unit_ogre_0055
sound Sound_General
sound Sound_2
sound Sound_Score
integer Order_Stop
unit Raccoon_Team1
unit Raccoon_Team2
unit Raccoon_Neutral
unit Tavern
unit Tavern_Team1
unit Tavern_Team2
// Player Stuff
force Players = CreateForce()
force Players_Team1 = CreateForce()
force Players_Team2 = CreateForce()
force AI_Players = CreateForce()
force AI_Players_Team1 = CreateForce()
force AI_Players_Team2 = CreateForce()
integer NumberOfPlayers = 0
integer NumberOfPlayersTeam1 = 0
integer NumberOfPlayersTeam2 = 0
boolean AI_Only = false
boolean AI_Only_Team1 = false
boolean AI_Only_Team2 = false
string array PlayerColors[1]
string array PlayerNames[1]
boolean AI_Active = false
unit Shrine1
unit Shrine2
unit array Dragons[1]
// Groups
group AI_Safes_Team1 = CreateGroup()
group AI_Safes_Team2 = CreateGroup()
// Various stuff
unit array Safes[1]
unit array Inactive_Heroes[1]
unit array AI_Safes[1]
unit array AI_Workers[1]
integer array Druid_Str_Mod[1]
// sounds
sound Sound_Bear
sound Sound_Wolf
sound Sound_Falcon
sound Sound_Arrow
endglobals
//TESH.scrollpos=3
//TESH.alwaysfold=0
scope GameInit initializer Init
function Trig_Game_Init_Visibility_Callback takes nothing returns nothing
set bj_lastCreatedFogModifier = CreateFogModifierRect(GetEnumPlayer(), FOG_OF_WAR_VISIBLE, bj_mapInitialPlayableArea, true, false)
call FogModifierStart(bj_lastCreatedFogModifier)
endfunction
function Trig_Game_Init_Selectors_Callback takes nothing returns nothing
local integer id = GetPlayerId(GetEnumPlayer())
if IsPlayerAlly(GetEnumPlayer(), Player(1)) then
set Hero_Selectors[id] = CreateUnitAtLoc(GetEnumPlayer(), 'e006', GetUnitLoc(Tavern_Team1), bj_UNIT_FACING)
else
set Hero_Selectors[id] = CreateUnitAtLoc(GetEnumPlayer(), 'e006', GetUnitLoc(Tavern_Team2), bj_UNIT_FACING)
endif
call SetPlayerState( Player(id), PLAYER_STATE_RESOURCE_GOLD, START_GOLD )
call SetPlayerState( Player(id), PLAYER_STATE_RESOURCE_LUMBER, START_HONOR )
endfunction
function Select_Tavern_Callback takes nothing returns nothing
local unit tavern
if IsPlayerAlly(GetEnumPlayer(), Player(1)) then
set tavern = Tavern_Team1
else
set tavern = Tavern_Team2
endif
call ClearSelectionForPlayer( GetEnumPlayer() )
call SelectUnitForPlayerSingle(tavern, GetEnumPlayer())
call PanCameraToTimedForPlayer(GetEnumPlayer(), GetUnitX(tavern), GetUnitY(tavern), 0)
call DestroyFogModifier(Fogs[GetPlayerId(GetEnumPlayer())])
if GetLocalPlayer() == GetEnumPlayer() then
call SetCameraTargetController(tavern, 0, 0, false)
endif
set tavern = null
endfunction
private function PlayersCallback takes nothing returns nothing
call CameraSetupApplyForPlayer( true, gg_cam_Camera_001, GetEnumPlayer(), 0 )
set Fogs[GetPlayerId(GetEnumPlayer())] = CreateFogModifierRadiusLocBJ( true, GetEnumPlayer(), FOG_OF_WAR_VISIBLE, Location(57, 2700), 1024 )
endfunction
function Init_Game takes nothing returns nothing
call CinematicFadeBJ( bj_CINEFADETYPE_FADEOUT, 0.00, "ReplaceableTextures\\CameraMasks\\Black_mask.blp", 0, 0, 0, 0 )
call EnableUserControl(false)
// Adjust minimap
call EnableMinimapFilterButtons( false, false )
call SetAllyColorFilterState( 0 )
call SetCreepCampFilterState( false )
call SetSkyModel( SKY_MODEL )
// call MeleeStartingHeroLimit() Does not work
// Init units and regions
call TriggerExecute( gg_trg_Init_Units_and_Regions )
// Init Player stuff
call Init_Players()
call AI_Only_Check() // make sure to init players before
call ForForce(Players, function PlayersCallback)
// Creeps are too strong
call SetPlayerHandicap(Player(PLAYER_NEUTRAL_AGGRESSIVE), 0.5)
call SetPlayerState(Player(PLAYER_NEUTRAL_AGGRESSIVE), PLAYER_STATE_GIVES_BOUNTY, 0)
// OrderStop
set Order_Stop = GetUnitCurrentOrder(gg_unit_ngsp_0152)
// Set Master Sound (used for different stuff)
call Preload( "Sound\\Interface\\ArrangedTeamInvitation.wav" )
set Sound_General = CreateSound("Sound\\Interface\\ArrangedTeamInvitation.wav", false, false, true, 12700, 12700, "")
call Preload( "Sound\\Interface\\GameFound.wav" )
set Sound_Score = CreateSound("Sound\\Interface\\GameFound.wav", false, false, true, 12700, 12700, "")
call Preload( "Sound\\Interface\\SecretFound.wav" )
set Sound_2 = CreateSound("Sound\\Interface\\SecretFound.wav", false, false, true, 12700, 12700, "")
call Preload( "Abilities\\Weapons\\Arrow\\ArrowAttack1.wav" )
set Sound_Arrow = CreateSound("Abilities\\Weapons\\Arrow\\ArrowAttack1.wav", false, true, true, 12700, 12700, "")
call Preload( "Units\\Creeps\\GrizzlyBear\\GrizzlyBearReady1.wav" )
set Sound_Bear = CreateSound("Units\\Creeps\\GrizzlyBear\\GrizzlyBearReady1.wav", false, true, true, 12700, 12700, "")
call Preload( "Units\\Orc\\Spiritwolf\\SpiritWolfBirth1.wav" )
set Sound_Wolf = CreateSound("Units\\Orc\\Spiritwolf\\SpiritWolfBirth1.wav", false, true, true, 12700, 12700, "")
call Preload( "Units\\Creeps\\WarEagle\\HawkReady1.wav" )
set Sound_Falcon = CreateSound("Units\\Creeps\\WarEagle\\HawkReady1.wav", false, true, true, 12700, 12700, "")
// Create Hero Selectors
call ForForce(Players, function Trig_Game_Init_Selectors_Callback)
call TriggerSleepAction( 0.1 )
call PlayThematicMusic("Sound\\Music\\mp3Music\\OrcTheme.mp3")
if DEBUG_MODE then
call CinematicFadeBJ( bj_CINEFADETYPE_FADEIN, 1, "ReplaceableTextures\\CameraMasks\\Black_mask.blp", 0, 0, 0, 0 )
else
call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS, 3.00, " " + TITLE + " " + AUTHOR)
call TriggerSleepAction( 1.00 )
// -------------------- Start Fade -----------------------------------
call CinematicFadeBJ( bj_CINEFADETYPE_FADEIN, 2, "ReplaceableTextures\\CameraMasks\\Black_mask.blp", 0, 0, 0, 0 )
call TriggerSleepAction( 3.00 )
endif
// -------------------- Game Startup -----------------------------------
// call CinematicModeBJ( false, GetPlayersAll() )
call StartSound(Sound_2)
call ResetToGameCamera(0)
call EnableTrigger( gg_trg_Camera )
call EnableUserControl(true)
//call TriggerSleepAction( 0.01 )
call CinematicFadeBJ( bj_CINEFADETYPE_FADEOUT, 0.00, "ReplaceableTextures\\CameraMasks\\Black_mask.blp", 0, 0, 0, 0 )
call TriggerSleepAction( 0.5 )
call ForForce(Players, function Select_Tavern_Callback)
call CinematicFadeBJ( bj_CINEFADETYPE_FADEIN, 1, "ReplaceableTextures\\CameraMasks\\Black_mask.blp", 0, 0, 0, 0 )
call DisplayTimedTextToForce( Players, 10, "You may type |cffFFA358help|r for a list of useful commands" )
call DisplayTimedTextToForce( Players, 10, " " )
// If Debug Mode, show whole map
if DEBUG_MODE then
call ForForce(bj_FORCE_ALL_PLAYERS, function Trig_Game_Init_Visibility_Callback)
endif
// Let's spawn AI heroes now
call TriggerSleepAction( 3.00 )
call Spawn_AI_Heroes()
endfunction
//===========================================================================
function Init takes nothing returns nothing
set gg_trg_Initialization = CreateTrigger( )
call TriggerAddAction( gg_trg_Initialization, function Init_Game )
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Camera_Actions takes nothing returns nothing
call SetCameraField(CAMERA_FIELD_ZOFFSET, CAMERA_RANGE, 0)
endfunction
//===========================================================================
function InitTrig_Camera takes nothing returns nothing
set gg_trg_Camera = CreateTrigger( )
call TriggerRegisterTimerEvent(gg_trg_Camera, 0.01, true)
call TriggerAddAction( gg_trg_Camera, function Trig_Camera_Actions )
endfunction
//TESH.scrollpos=51
//TESH.alwaysfold=0
function Trig_Init_Safes_Create_Tag takes unit u returns nothing
local texttag t = CreateTextTag()
local string s = PlayerNames[GetPlayerId(GetOwningPlayer(u))]
call SetTextTagText(t, s, 0.02)
call SetTextTagPos(t, GetUnitX(u), GetUnitY(u), 0.00)
call SetTextTagVisibility(t, true)
call SetTextTagPermanent(t, true)
set t = null
endfunction
function Trig_Init_Units_Actions takes nothing returns nothing
local integer id
local unit u
set Tavern_Team1 = gg_unit_ntav_0085
set Tavern_Team2 = gg_unit_n009_0002
set Base_Team1 = gg_unit_htow_0033
set Base_Team2 = gg_unit_ogre_0055
set Shrine1 = gg_unit_nbse_0013
set Shrine2 = gg_unit_nbse_0014
set Spawn_Team1 = Location(GetRectCenterX(gg_rct_SpawnTeam1M), GetRectCenterY(gg_rct_SpawnTeam1M))
set Spawn_Team2 = Location(GetRectCenterX(gg_rct_SpawnTeam2M), GetRectCenterY(gg_rct_SpawnTeam2M))
// Init The Raccoon of Wisdom - he makes you drunk
set Raccoon_Neutral = gg_unit_n00M_0071
// Bosses
// Init the annoying safes..
// Team 1
set Safes[2] = gg_unit_h001_0126
set Safes[6] = gg_unit_h001_0129
set Safes[8] = gg_unit_h001_0130
set Safes[9] = gg_unit_h001_0131
set Safes[10] = gg_unit_h001_0132
// Team 2
set Safes[3] = gg_unit_h00A_0024
set Safes[4] = gg_unit_h00A_0053
set Safes[5] = gg_unit_h00A_0057
set Safes[7] = gg_unit_h00A_0059
set Safes[11] = gg_unit_h00A_0067
set id = 2
loop
exitwhen id > 11
if GetPlayerSlotState(Player(id)) == PLAYER_SLOT_STATE_PLAYING then
call Trig_Init_Safes_Create_Tag(Safes[id])
call SetUnitUseFood(Safes[id], false)
if IsPlayerAlly(Player(id), Player(1)) then
set u = CreateUnitAtLoc(Player(id), 'hpea', GetUnitLoc(Safes[id]), bj_UNIT_FACING)
else
set u = CreateUnitAtLoc(Player(id), 'opeo', GetUnitLoc(Safes[id]), bj_UNIT_FACING)
endif
if GetPlayerController(Player(id)) == MAP_CONTROL_COMPUTER then
if IsPlayerAlly(Player(id), Player(1)) then
call GroupAddUnit( AI_Safes_Team1, Safes[id] )
else
call GroupAddUnit( AI_Safes_Team2, Safes[id] )
endif
set AI_Workers[id] = u
set AI_Safes[id] = Safes[id]
endif
else
call RemoveUnit( Safes[id] )
endif
set id = id + 1
endloop
set u = null
endfunction
//===========================================================================
function InitTrig_Init_Units_and_Regions takes nothing returns nothing
set gg_trg_Init_Units_and_Regions = CreateTrigger( )
call TriggerAddAction( gg_trg_Init_Units_and_Regions, function Trig_Init_Units_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope Merchants initializer Init
private function Actions takes nothing returns nothing
local effect e
// Let's add some exclamation marks to all merchants
set e = AddSpecialEffectTarget("Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl", gg_unit_ngsp_0152, "overhead")
set e = AddSpecialEffectTarget("Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl", gg_unit_ngsp_0149, "overhead")
set e = AddSpecialEffectTarget("Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl", gg_unit_e00C_0045, "overhead")
set e = AddSpecialEffectTarget("Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl", gg_unit_e00B_0075, "overhead")
set e = AddSpecialEffectTarget("Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl", gg_unit_n002_0061, "overhead")
set e = null
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterTimerEvent(trg, 0.01, false)
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=747
//TESH.alwaysfold=0
library HeroSystem initializer Init requires TimerUtils, BasicFunctions
globals
constant real HERO_DEAD_TIME = 30 // Respawn time for heroes
constant real BASIC_CRIT_CHANCE = 10.0 // 3.0
constant real CRIT_PER_ATTRIBUTE = 0.2
constant real CRIT_FACTOR = 2.0
constant integer HONOR_CAP = 20 // Number of small actions to be done to gain +1 honor
// Heroes Team 1
constant integer WARRIOR_ID = 'O003'
constant integer PRIEST_ID = 'H005'
constant integer MAGE_ID = 'H003'
constant integer DRUID_ID = 'E002'
constant integer DRUIDB_ID = 'E004'
constant integer ROGUE_ID = 'E003'
constant integer HUNTER_ID = 'H004'
constant integer NECRO_ID = 'H00F'
constant integer ENT_ID = 'O002'
constant integer ENTR_ID = 'O00G'
constant integer PALADIN_ID = 'H006'
// Heroes Team 2
constant integer WARRIOR_ID2 = 'O009'
constant integer PRIEST_ID2 = 'O00A'
constant integer MAGE_ID2 = 'H00B'
constant integer DRUID_ID2 = 'E007'
constant integer DRUIDB_ID2 = 'E009'
constant integer ROGUE_ID2 = 'E000'
constant integer HUNTER_ID2 = 'H00C'
constant integer NECRO_ID2 = 'H00G'
constant integer ENT_ID2 = 'O00F'
constant integer SHAMAN_ID = 'O001'
// unit array Heroes[1]
boolean array Players_Selected[1]
timer array Resurrection_Timers[1]
timerdialog array Resurrection_Timer_Windows[1]
string array Kill_Comments[1]
unit array Hero_Selectors[1]
unit array Avatars[1]
group Hero_Group = CreateGroup()
group Dead_Heroes = CreateGroup()
group AI_Heroes = CreateGroup()
group AI_Heroes_Team1 = CreateGroup()
group AI_Heroes_Team2 = CreateGroup()
group Strength_Heroes = CreateGroup()
group Agility_Heroes = CreateGroup()
group Intelligence_Heroes = CreateGroup()
group Melee_Heroes = CreateGroup()
group Ranged_Heroes = CreateGroup()
// pets & summons
unit array Water_Elementals[1]
unit array Pets_Bears[1]
unit array Pets_Wolfs[1]
unit array Pets_Falcons[1]
unit array Pets[1]
unit array UnholySpirits[1]
integer HonorPlayerId
integer Honor1
integer Honor2
integer array HonorStack[1]
endglobals
function IsHero takes unit u returns boolean
return IsUnitInGroup(u, Hero_Group)
endfunction
function IsAIHero takes unit u returns boolean
return IsHero(u) and GetPlayerController(GetOwningPlayer(u)) == MAP_CONTROL_COMPUTER
endfunction
function IsStrHero takes unit u returns boolean
return IsUnitInGroup(u, Strength_Heroes)
endfunction
function IsAgiHero takes unit u returns boolean
return IsUnitInGroup(u, Agility_Heroes)
endfunction
function IsIntHero takes unit u returns boolean
return IsUnitInGroup(u, Intelligence_Heroes)
endfunction
function GetRandomHeroID takes integer team returns integer
local integer i
local integer HeroID
if team == 1 then
set HeroID = WARRIOR_ID
set i = GetRandomInt(10,100)
// call Debug_Message("Random Int: "+I2S(i))
if i >= 10 then
set HeroID = WARRIOR_ID
endif
if i >= 20 then
set HeroID = MAGE_ID
endif
if i >= 30 then
set HeroID = PRIEST_ID
endif
if i >= 40 then
set HeroID = DRUID_ID
endif
if i >= 50 then
set HeroID = ROGUE_ID
endif
if i >= 60 then
set HeroID = HUNTER_ID
endif
if i >= 70 then
set HeroID = NECRO_ID
endif
if i >= 80 then
set HeroID = PALADIN_ID
endif
if i >= 90 then
set HeroID = ENT_ID
endif
elseif team == 2 then
set HeroID = WARRIOR_ID2
set i = GetRandomInt(10,100)
if i >= 10 then
set HeroID = WARRIOR_ID2
endif
if i >= 20 then
set HeroID = MAGE_ID2
endif
if i >= 30 then
set HeroID = PRIEST_ID2
endif
if i >= 40 then
set HeroID = DRUID_ID2
endif
if i >= 50 then
set HeroID = ROGUE_ID2
endif
if i >= 60 then
set HeroID = HUNTER_ID2
endif
if i >= 70 then
set HeroID = NECRO_ID2
endif
if i >= 80 then
set HeroID = SHAMAN_ID
endif
if i >= 90 then
set HeroID = ENT_ID2
endif
endif
return HeroID
endfunction
private function ComputerBuysItems takes unit u returns nothing
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer honor = GetPlayerState(Player(id), PLAYER_STATE_RESOURCE_LUMBER)
// Str Hero
if IsStrHero(u) then
// Buy Weapon
if honor >=7 and not UnitHasItemOfTypeBJ(u, 'I01M') then
call UnitAddItemByIdSwapped( 'I01M', u )
call SetPlayerState(Player(id), PLAYER_STATE_RESOURCE_LUMBER, honor-7)
endif
// Buy Armor
if honor >=9 and not UnitHasItemOfTypeBJ(u, 'I00Q') then
call UnitAddItemByIdSwapped( 'I00Q', u )
call SetPlayerState(Player(id), PLAYER_STATE_RESOURCE_LUMBER, honor-9)
endif
// Agi Hero
elseif IsAgiHero(u) then
// Buy Weapon
if honor >=7 and not UnitHasItemOfTypeBJ(u, 'I01M') then
call UnitAddItemByIdSwapped( 'I01M', u )
call SetPlayerState(Player(id), PLAYER_STATE_RESOURCE_LUMBER, honor-7)
endif
// Buy Armor
if honor >=7 and not UnitHasItemOfTypeBJ(u, 'I011') then
call UnitAddItemByIdSwapped( 'I011', u )
call SetPlayerState(Player(id), PLAYER_STATE_RESOURCE_LUMBER, honor-7)
endif
// Int Hero
elseif IsIntHero(u) then
// Buy Weapon
if honor >=7 and not UnitHasItemOfTypeBJ(u, 'I018') then
call UnitAddItemByIdSwapped( 'I018', u )
call SetPlayerState(Player(id), PLAYER_STATE_RESOURCE_LUMBER, honor-7)
endif
// Buy Armor
if honor >=7 and not UnitHasItemOfTypeBJ(u, 'I003') then
call UnitAddItemByIdSwapped( 'I003', u )
call SetPlayerState(Player(id), PLAYER_STATE_RESOURCE_LUMBER, honor-7)
endif
endif
endfunction
function GetRandomStartWP takes unit u returns integer
local integer i = GetRandomInt(11,40)
local integer j = 0
if IsPlayerAlly(GetOwningPlayer(u), Player(1)) then
if i > 10 then
set j = 1
endif
if i > 20 then
set j = 11
endif
if i > 30 then
set j = 21
endif
else
if i > 10 then
set j = 7
endif
if i > 20 then
set j = 17
endif
if i > 30 then
set j = 27
endif
endif
return j
endfunction
function Revive_Hero takes nothing returns nothing
local integer id = GetTimerData(GetExpiredTimer())
local unit shrine
local unit u = Heroes[id]
local integer i
// Team stuff
if ( ( IsPlayerAlly(GetOwningPlayer(u), Player(1)) == true ) ) then
set shrine = Shrine1
else
set shrine = Shrine2
endif
call SetUnitUseFood(Safes[id], false)
// Revive Hero at Shrine
call ReviveHero( u, GetUnitX(shrine), GetUnitY(shrine), true )
call PanCameraToTimedLocForPlayer( Player(id), GetUnitLoc(shrine), 0 )
call ClearSelectionForPlayer(Player(id))
call SelectUnitAddForPlayer( u, Player(id))
call GroupRemoveUnit(Dead_Heroes, u )
call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MAX_MANA))
call TimerDialogDisplay(Resurrection_Timer_Windows[id], false)
// call ReleaseTimer(Resurrection_Timers[id])
// Roots debug
call SetUnitMoveSpeed( u, GetUnitDefaultMoveSpeed(u) )
// Druid Debug for Bear Form
if Druid_Str_Mod[id] > 0 then
call SetHeroStr(u, GetHeroStr(u, false) - Druid_Str_Mod[id], true)
set Druid_Str_Mod[id] = 0
endif
// Necro
if Avatars[id] != null then
call KillUnit(Avatars[id])
endif
// AI Hero?
if IsAIHero(u) then
call ComputerBuysItems(u)
set i = GetRandomStartWP(u)
// call Debug_Message("Send AI Hero on Way " + GetUnitName(u) + " to point: "+I2S(i))
set waypoint_table[GetUnitId(u)] = i
call Order_Unit_To_Next_WP(u)
endif
set u = null
set shrine = null
endfunction
private function Init_Kill_Comments takes nothing returns nothing
// Init PvP Comments
set Kill_Comments[1] = "Got one!"
set Kill_Comments[2] = "And stay down!"
set Kill_Comments[3] = "Too easy.."
set Kill_Comments[4] = "Starts getting fun!"
set Kill_Comments[5] = "Take it easy!"
set Kill_Comments[6] = "Don't worry be happy!"
set Kill_Comments[7] = "Anyone seen that kill?"
set Kill_Comments[8] = "Bang!"
set Kill_Comments[9] = "Good fight anyway!"
set Kill_Comments[10] = "Nice try!"
set Kill_Comments[11] = "Got ya!"
set Kill_Comments[12] = "Terminated!"
set Kill_Comments[13] = "Fragged!"
set Kill_Comments[14] = "You face the dirt!"
set Kill_Comments[15] = "Got one!"
endfunction
function Add_Honor takes integer id, integer honorPoints returns nothing
local texttag t = CreateTextTag()
local string s = "|cffFFAE5F+" +I2S(honorPoints) + " Honor!|r"
local player PlayerTarget = Player(id)
if id >= 2 and id <= 11 then
call SetPlayerState(Player(id), PLAYER_STATE_RESOURCE_LUMBER, GetPlayerState(Player(id), PLAYER_STATE_RESOURCE_LUMBER)+honorPoints)
call SetTextTagColor(t, 178, 233, 142, 255)
call SetTextTagText(t, s, 0.0184)
call SetTextTagPos(t, GetUnitX(Heroes[id]), GetUnitY(Heroes[id]), 0.00)
call SetTextTagVelocity(t, 0, 0.05)
call SetTextTagVisibility(t, false)
call SetTextTagFadepoint(t, 3)
call SetTextTagLifespan(t, 4)
call SetTextTagPermanent(t, false)
if PlayerTarget == GetLocalPlayer() then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SetTextTagVisibility(t, true)
endif
endif
set t = null
set PlayerTarget = null
endfunction
private function HonorCallback takes nothing returns nothing
call Add_Honor(GetPlayerId(GetOwningPlayer(GetEnumUnit())), Honor2)
endfunction
private function HonorConditionsTeam1 takes nothing returns boolean
return IsHero(GetFilterUnit()) and IsPlayerAlly(GetOwningPlayer(GetFilterUnit()), Player(1)) and GetPlayerId(GetOwningPlayer(GetFilterUnit())) != HonorPlayerId
endfunction
private function HonorConditionsTeam2 takes nothing returns boolean
return IsHero(GetFilterUnit()) and IsPlayerAlly(GetOwningPlayer(GetFilterUnit()), Player(0)) and GetPlayerId(GetOwningPlayer(GetFilterUnit())) != HonorPlayerId
endfunction
function IncHonorStack takes integer id, integer i returns nothing
set HonorStack[id] = HonorStack[id] + i
if HonorStack[id] >= HONOR_CAP then
set HonorStack[id] = 0
call Add_Honor(id, 1)
endif
endfunction
function AddHonorArea takes real x, real y, integer team, integer id, integer a1, integer a2 returns nothing
local group targets = NewGroup()
set HonorPlayerId = id
set Honor1 = a1
set Honor2 = a2
call Add_Honor(id, Honor1)
// Get targets
if team == 1 then
call GroupEnumUnitsInRange(targets, x, y, HONOR_RANGE, Condition(function HonorConditionsTeam1))
elseif team == 2 then
call GroupEnumUnitsInRange(targets, x, y, HONOR_RANGE, Condition(function HonorConditionsTeam2))
endif
call ForGroup( targets, function HonorCallback )
call ReleaseGroup(targets)
set targets = null
endfunction
private function Conditions_A_Hero_Dies takes nothing returns boolean
return IsHero(GetTriggerUnit())
endfunction
private function A_Hero_Dies takes nothing returns nothing
local unit u = GetDyingUnit()
local unit k = GetKillingUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer id2 = GetPlayerId(GetOwningPlayer(k))
call DisplayTextToPlayer( Player(id), 0, 0, "|cffFF2323You died!|r Your Hero is revived in |cffFFA358" + I2S(R2I(HERO_DEAD_TIME)) + "|r seconds." )
call GroupAddUnit(Dead_Heroes, u )
if IsPlayerAlly(Player(id), Player(0)) then
call AddHonorArea(GetUnitX(u), GetUnitY(u), 1, id2, 1, 1)
elseif IsPlayerAlly(Player(id), Player(1)) then
call AddHonorArea(GetUnitX(u), GetUnitY(u), 2, id2, 1, 1)
endif
call SetUnitUseFood(Safes[id], true)
call UnitRemoveItem(u, gg_item_I00H_0097)
// Death Timer
call SetTimerData(Resurrection_Timers[id], id)
call TimerStart(Resurrection_Timers[id], HERO_DEAD_TIME, false, function Revive_Hero)
// Window
set Resurrection_Timer_Windows[id] = CreateTimerDialog(Resurrection_Timers[id])
call TimerDialogSetTitle(Resurrection_Timer_Windows[id], PlayerNames[id])
call TimerDialogDisplayForPlayerBJ(true, Resurrection_Timer_Windows[id], Player(id))
// If Mage, kill water elemental too
if Water_Elementals[id] != null then
call KillUnit(Water_Elementals[id])
endif
// If Hunter, kill Pet too
if Pets[id] != null then
call KillUnit(Pets[id])
endif
// If Necro, kill Unholy Summon
if UnholySpirits[id] != null then
call KillUnit(UnholySpirits[id])
endif
// If Dragon companion, kill it too
if Dragons[id] != null then
call KillUnit(Dragons[id])
endif
set u = null
set k = null
endfunction
private function Conditions_Hero_Kills_Hero takes nothing returns boolean
return IsHero(GetDyingUnit()) == true and IsPlayerInForce(GetOwningPlayer(GetKillingUnit()), Players) == true and IsPlayerEnemy(GetOwningPlayer(GetKillingUnit()), GetOwningPlayer(GetDyingUnit())) == true and not IsUnitType(GetKillingUnit(), UNIT_TYPE_STRUCTURE)
endfunction
private function Hero_Kills_Hero takes nothing returns nothing
local integer id = GetPlayerId(GetOwningPlayer(GetKillingUnit()))
local integer i = GetRandomInt(1, 15)
// +1 Honor Point
//call Add_Honor(id, 1)
//if IsPlayerAlly(Player(id), Player(1)) then
// call AddHonorArea(GetUnitX(GetDyingUnit()), GetUnitY(GetDyingUnit()), 1, id, 1, 1)
//elseif IsPlayerAlly(Player(id), Player(0)) then
// call AddHonorArea(GetUnitX(GetDyingUnit()), GetUnitY(GetDyingUnit()), 2, id, 1, 1)
//endif
// Random PvP comment
call CreateTagOnUnit(Heroes[id], Kill_Comments[i])
endfunction
function Repick takes integer id returns nothing
local force team
local unit tavern
local integer i
// Hero has to be alive and not inactive due to special spells
if GetUnitState(Heroes[id], UNIT_STATE_LIFE) > 0 and Inactive_Heroes[id] == null then
if ( IsPlayerAlly(Player(id), Player(1)) == true ) then
set tavern = Tavern_Team1
set team = Players_Team1
else
set tavern = Tavern_Team2
set team = Players_Team2
endif
// Message
call DisplayTimedTextToForce(team, 10, PlayerNames[id] + " is picking a new hero!")
// drop items
set i = 0
loop
exitwhen i > 5
// if GetItemTypeId(UnitItemInSlot(Heroes[id], i)) == 'stel' then
// call RemoveItem(UnitItemInSlot(Heroes[id], i))
// else
call UnitRemoveItem(Heroes[id], UnitItemInSlot(Heroes[id], i))
// endif
set i = i + 1
endloop
call GroupRemoveUnit(Hero_Group, Heroes[id])
call GroupRemoveUnit(Strength_Heroes, Heroes[id])
call GroupRemoveUnit(Agility_Heroes, Heroes[id])
call GroupRemoveUnit(Intelligence_Heroes, Heroes[id])
call GroupRemoveUnit(Melee_Heroes, Heroes[id])
call GroupRemoveUnit(Ranged_Heroes, Heroes[id])
call RemoveUnit(Heroes[id])
set Heroes[id] = null
if Water_Elementals[id] != null then
call RemoveUnit(Water_Elementals[id])
set Water_Elementals[id] = null
endif
if Pets[id] != null then
call RemoveUnit(Pets[id])
set Pets[id] = null
endif
if Pets_Bears[id] != null then
call RemoveUnit(Pets_Bears[id])
set Pets_Bears[id] = null
endif
if Pets_Wolfs[id] != null then
call RemoveUnit(Pets_Wolfs[id])
set Pets_Wolfs[id] = null
endif
if Pets_Falcons[id] != null then
call RemoveUnit(Pets_Falcons[id])
set Pets_Falcons[id] = null
endif
if UnholySpirits[id] != null then
call RemoveUnit(UnholySpirits[id])
set UnholySpirits[id] = null
endif
if Dragons[id] != null then
call RemoveUnit(Dragons[id])
set Dragons[id] = null
endif
// Mark player as selected
set Players_Selected[id] = false
// Create hero selector
set Hero_Selectors[id] = CreateUnit(Player(id), 'e006' , GetUnitX(tavern), GetUnitY(tavern), bj_UNIT_FACING)
call ClearSelectionForPlayer(Player(id))
call StartSoundForPlayerBJ(Player(id),Sound_2)
call SelectUnitForPlayerSingle(tavern, Player(id))
call PanCameraToForPlayer(Player(id), GetUnitX(tavern), GetUnitY(tavern))
call SetCameraPositionForPlayer(Player(id), GetUnitX(tavern), GetUnitY(tavern))
if not DEBUG_MODE then
if GetLocalPlayer() == Player(id) then
call SetCameraTargetController(tavern, 0, 0, false)
endif
endif
else
call DisplayTimedTextToPlayer(Player(id), 0, 0, 10, "Your hero has to be |cffFFA358alive|r to use this function!")
endif
set tavern = null
set team = null
endfunction
private function Spawn_AI_Heroes_Callback takes nothing returns nothing
local unit u = null
local integer i
local integer HeroID
if GetPlayerController(GetEnumPlayer()) == MAP_CONTROL_COMPUTER then
if IsPlayerAlly(GetEnumPlayer(), Player(1)) then
set HeroID = GetRandomHeroID(1)
else
set HeroID = GetRandomHeroID(2)
endif
endif
set u = CreateUnit(GetEnumPlayer(), HeroID, GetUnitX(Shrine1), GetUnitY(Shrine1), bj_UNIT_FACING)
set u = null
endfunction
function Spawn_AI_Heroes takes nothing returns nothing
call ForForce( Players, function Spawn_AI_Heroes_Callback )
endfunction
private function Conditions_Hero_Init takes nothing returns boolean
// Player has to be unselected, Unit has to be hero, unit has to be lagal
return Players_Selected[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))] == false and IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) == true and Legal_Hero_Check(GetTriggerUnit()) == true
endfunction
private function Hero_Init takes nothing returns nothing
local unit Hero = GetTriggerUnit()
local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
local unit shrine
local force = team
// Mark player as selected
set Players_Selected[id] = true
set Heroes[id] = Hero
call GroupAddUnit( Hero_Group, Hero )
// If AI Hero, then..
if IsAIHero(Hero) then
call GroupAddUnit( AI_Heroes, Hero )
endif
// Class specific stuff
// --------------------
// Warrior
if ( GetUnitTypeId(Hero) == WARRIOR_ID or GetUnitTypeId(Hero) == WARRIOR_ID2 ) then
call GroupAddUnit( Strength_Heroes, Hero )
call GroupAddUnit( Melee_Heroes, Hero )
// Give Shield
if GetUnitTypeId(Hero) == WARRIOR_ID2 then
call AddSpecialEffectTarget("RoundShieldL.mdl", Hero, "left")
endif
endif
// Priest
if ( GetUnitTypeId(Hero) == PRIEST_ID or GetUnitTypeId(Hero) == PRIEST_ID2 ) then
call GroupAddUnit( Intelligence_Heroes, Hero )
call GroupAddUnit( Ranged_Heroes, Hero )
endif
// Mage
if ( GetUnitTypeId(Hero) == MAGE_ID or GetUnitTypeId(Hero) == MAGE_ID2 ) then
call GroupAddUnit( Intelligence_Heroes, Hero )
call GroupAddUnit( Ranged_Heroes, Hero )
endif
// Druid
if ( GetUnitTypeId(Hero) == DRUID_ID or GetUnitTypeId(Hero) == DRUID_ID2 ) then
call GroupAddUnit( Intelligence_Heroes, Hero )
call GroupAddUnit( Ranged_Heroes, Hero )
endif
// Paladin
if ( GetUnitTypeId(Hero) == PALADIN_ID ) then
call GroupAddUnit( Strength_Heroes, Hero )
call GroupAddUnit( Melee_Heroes, Hero )
endif
// Rogue
if ( GetUnitTypeId(Hero) == ROGUE_ID or GetUnitTypeId(Hero) == ROGUE_ID2 ) then
call GroupAddUnit( Agility_Heroes, Hero )
call GroupAddUnit( Melee_Heroes, Hero )
endif
// Hunter
if ( GetUnitTypeId(Hero) == HUNTER_ID or GetUnitTypeId(Hero) == HUNTER_ID2 ) then
call GroupAddUnit( Agility_Heroes, Hero )
call GroupAddUnit( Ranged_Heroes, Hero )
endif
// Necromancer
if ( GetUnitTypeId(Hero) == NECRO_ID or GetUnitTypeId(Hero) == NECRO_ID2 ) then
call GroupAddUnit( Intelligence_Heroes, Hero )
call GroupAddUnit( Ranged_Heroes, Hero )
endif
// Shaman
if ( GetUnitTypeId(Hero) == SHAMAN_ID ) then
call GroupAddUnit( Agility_Heroes, Hero )
call GroupAddUnit( Melee_Heroes, Hero )
endif
// Ancient Protector
if ( GetUnitTypeId(Hero) == ENT_ID or GetUnitTypeId(Hero) == ENT_ID2 ) then
call GroupAddUnit( Strength_Heroes, Hero )
call GroupAddUnit( Melee_Heroes, Hero )
endif
// Remove Hero Selector
call RemoveUnit( Hero_Selectors[id] )
// Move Hero to Shrine
if ( IsPlayerAlly(GetOwningPlayer(Hero), Player(1)) == true ) then
set shrine = Shrine1
set team = Players_Team1
else
set shrine = Shrine2
set team = Players_Team2
endif
call ResetToGameCameraForPlayer(Player(id), 0)
call StartSoundForPlayerBJ(Player(id), Sound_General)
// call DisplayTimedTextToPlayer(Player(id),0,0,10, "Hero selected: "+GetUnitName(Hero))
call DisplayTimedTextToForce(team, 10, PlayerNames[id] + " has chosen the "+GetUnitName(Hero) )
call ClearSelectionForPlayer(Player(id))
call SelectUnitForPlayerSingle(Hero, Player(id))
call SetUnitPositionLoc( Hero, GetUnitLoc(shrine) )
call PanCameraToTimedForPlayer(Player(id), GetUnitX(shrine), GetUnitY(shrine), 0)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Awaken\\Awaken.mdl", Hero, "origin"))
if DEBUG_MODE then
call UnitAddItemByIdSwapped( 'stel', Hero )
endif
// If AI Hero, then go to next waypoint
if IsAIHero(Hero) then
set waypoint_table[GetUnitId(Hero)] = GetRandomStartWP(Hero)
call Order_Unit_To_Next_WP( Hero )
endif
// Ent animation debug
if ( GetUnitTypeId(Hero) == ENT_ID or GetUnitTypeId(Hero) == ENT_ID2 ) then
call SetUnitAnimationByIndex(Hero, 0)
endif
set Hero = null
set shrine = null
set team = null
endfunction
private function Conditions_Pick_Flag takes nothing returns boolean
return IsAIHero(GetTriggerUnit())
endfunction
private function Pick_Flag takes nothing returns nothing
call IssueTargetOrder( GetTriggerUnit(), "smart", gg_item_I00H_0097 )
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local integer i
local trigger trg = CreateTrigger( )
call Init_Kill_Comments()
// Init Heroes
call TriggerRegisterEnterRectSimple( trg, GetPlayableMapRect() )
call TriggerAddCondition( trg, Condition( function Conditions_Hero_Init ) )
call TriggerAddAction( trg, function Hero_Init )
// A Hero dies
set trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( trg, Condition( function Conditions_A_Hero_Dies ) )
call TriggerAddAction( trg, function A_Hero_Dies )
// Hero kills Hero (PvP)
set trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( trg , EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( trg , Condition( function Conditions_Hero_Kills_Hero ) )
call TriggerAddAction( trg , function Hero_Kills_Hero )
// Pick up Flag
set trg = CreateTrigger( )
call TriggerRegisterEnterRectSimple( trg, Rect( GetItemX(gg_item_I00H_0097) - 512, GetItemY(gg_item_I00H_0097) - 512, GetItemX(gg_item_I00H_0097) + 512, GetItemY(gg_item_I00H_0097) + 512 ) )
call TriggerAddCondition( trg , Condition( function Conditions_Pick_Flag ) )
call TriggerAddAction( trg , function Pick_Flag )
// Init Resurrection Timers & Selection stuff
set i = 0
loop
exitwhen i > MAX_PLAYERS
set Resurrection_Timers[i] = NewTimer()
set Players_Selected[i] = false
set Resurrection_Timer_Windows[i] = CreateTimerDialog(Resurrection_Timers[i])
call TimerDialogSetTitle(Resurrection_Timer_Windows[i], PlayerNames[i])
call TimerDialogDisplay(Resurrection_Timer_Windows[i], false)
set i = i + 1
endloop
set trg = null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope Events initializer Init
private function CommanderDeath takes nothing returns nothing
call Game_Message("The Alliance |cff046CB7High Commander|r has been slain!")
endfunction
private function WarchiefDeath takes nothing returns nothing
call Game_Message("The |cffFB2525Great Warchief|r has been slain!")
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterUnitEvent( trg, gg_unit_H00H_0062, EVENT_UNIT_DEATH )
call TriggerAddAction( trg, function CommanderDeath )
set trg = CreateTrigger( )
call TriggerRegisterUnitEvent( trg, gg_unit_O00D_0063, EVENT_UNIT_DEATH )
call TriggerAddAction( trg, function WarchiefDeath )
set trg = null
endfunction
endscope
//TESH.scrollpos=208
//TESH.alwaysfold=0
scope ScoreBoard initializer Init
globals
constant string SCORE_TITLE = TITLE + " " + VERSION // + " " + AUTHOR
private multiboard Score_Table // Don't use "= CreateMultiboard()"! else the game will crash
private integer array ScoreBoard_Positions[1]
// integer array Score_Kills[1]
// integer array Score_Hero_Kills[1]
// integer array Score_Deaths[1]
timer GameTime = CreateTimer()
integer GameTime_Minutes
integer GameTime_Seconds
private integer ClockRow
private integer TempInt
endglobals
private function Update_Callback takes nothing returns nothing
local multiboarditem field
local integer id = GetPlayerId(GetEnumPlayer())
// Name
set field = MultiboardGetItem(Score_Table, ScoreBoard_Positions[id], 0)
call MultiboardSetItemValue( field, " " + PlayerNames[id] )
// Level
set field = MultiboardGetItem(Score_Table, ScoreBoard_Positions[id], 1)
call MultiboardSetItemValue( field, " " + I2S(GetHeroLevel(Heroes[id])) )
set Score_Levels[id] = GetHeroLevel(Heroes[id])
// PvP
set field = MultiboardGetItem(Score_Table, ScoreBoard_Positions[id], 2)
call MultiboardSetItemValue( field, " " + I2S(Score_PvP[id]) )
// Kills
set field = MultiboardGetItem(Score_Table, ScoreBoard_Positions[id], 3)
call MultiboardSetItemValue( field, " " + I2S(Score_Kills[id]) )
// Deaths
set field = MultiboardGetItem(Score_Table, ScoreBoard_Positions[id], 4)
call MultiboardSetItemValue( field, I2S(Score_Deaths[id]) )
set field = null
endfunction
private function Update takes nothing returns nothing
call ForForce( Players, function Update_Callback )
endfunction
private function Conditions_Level_Up takes nothing returns boolean
return IsHero(GetTriggerUnit())
endfunction
private function Conditions_Hero_Kills takes nothing returns boolean
return IsPlayerInForce(GetOwningPlayer(GetKillingUnit()), Players) == true
endfunction
private function A_Hero_Kills takes nothing returns nothing
local integer id = GetPlayerId(GetOwningPlayer(GetKillingUnit()))
set Score_Kills[id] = Score_Kills[id] + 1
if IsHero(GetDyingUnit()) then
set Score_PvP[id] = Score_PvP[id] + 1
endif
call IncHonorStack(id, 2)
call Update()
endfunction
private function Conditions_Hero_Dies takes nothing returns boolean
return IsHero(GetTriggerUnit())
endfunction
private function A_Hero_Dies takes nothing returns nothing
local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
set Score_Deaths[id] = Score_Deaths[id] + 1
call Update()
endfunction
private function Set_Clock takes nothing returns nothing
local multiboarditem clockfield = null
set clockfield = MultiboardGetItem(Score_Table, ClockRow, 2)
set GameTime_Minutes = ( R2I(TimerGetElapsed(GameTime)) / 60 )
set GameTime_Seconds = ModuloInteger(R2I(TimerGetElapsed(GameTime)), 60)
if GameTime_Seconds >= 10 then
call MultiboardSetItemValue( clockfield, I2S(GameTime_Minutes) + ":" + I2S(GameTime_Seconds) )
else
call MultiboardSetItemValue( clockfield, I2S(GameTime_Minutes) + ":0" + I2S(GameTime_Seconds) )
endif
set clockfield = null
endfunction
private function Add_Players takes nothing returns nothing
local multiboarditem field = MultiboardGetItem(Score_Table, TempInt, 0)
local integer id = GetPlayerId(GetEnumPlayer())
set ScoreBoard_Positions[id] = TempInt
call MultiboardSetItemValue(field, " " + PlayerNames[id])
set field = MultiboardGetItem(Score_Table, ScoreBoard_Positions[id], 1)
call MultiboardSetItemValue( field, " 1" )
set TempInt = ( TempInt + 1 )
set field = null
endfunction
private function Init_Score_Board takes nothing returns nothing
local integer i
local integer j
local multiboarditem field = null
call TriggerSleepAction( 1.00 )
call TimerStart( GameTime, 999999.00, false, null )
// Now create the actual Multiboard
set Score_Table = CreateMultiboard()
call MultiboardSetRowCount(Score_Table, 6 + NumberOfPlayers )
call MultiboardSetColumnCount(Score_Table, 5)
call MultiboardSetTitleText(Score_Table, SCORE_TITLE)
call MultiboardDisplay(Score_Table, true)
// Adjust color and display style
set i = 0
loop
exitwhen ( i > MultiboardGetRowCount(Score_Table)-1 )
set j = 0
loop
exitwhen ( j > 4 )
set field = MultiboardGetItem(Score_Table, i, j)
call MultiboardSetItemStyle( field, true, false )
call MultiboardSetItemValueColor( field, 220, 220, 220, 255 )
set j = j + 1
endloop
set i = i + 1
endloop
// Adjust column width
set i = 0
loop
exitwhen ( i > MultiboardGetRowCount(Score_Table)-1 )
set field = MultiboardGetItem(Score_Table, i, 0)
call MultiboardSetItemWidth(field, 0.10)
set field = MultiboardGetItem(Score_Table, i, 1)
call MultiboardSetItemWidth(field, 0.03) // 0.01
set field = MultiboardGetItem(Score_Table, i, 2)
call MultiboardSetItemWidth(field, 0.03)
set field = MultiboardGetItem(Score_Table, i, 3)
call MultiboardSetItemWidth(field, 0.03)
set field = MultiboardGetItem(Score_Table, i, 4)
call MultiboardSetItemWidth(field, 0.01)
set i = i + 1
endloop
// Headline
set field = MultiboardGetItem(Score_Table, 0, 1)
call MultiboardSetItemValue( field, "|cffFFDD8DLv|r" )
call MultiboardSetItemValueColor( field, 255, 255, 255, 255 )
set field = MultiboardGetItem(Score_Table, 0, 2)
call MultiboardSetItemValue( field, "|cffFF974APvP|r" )
call MultiboardSetItemValueColor( field, 255, 255, 255, 255 )
set field = MultiboardGetItem(Score_Table, 0, 3)
call MultiboardSetItemValue( field, "|cffD60505Kills|r" )
call MultiboardSetItemValueColor( field, 255, 255, 255, 255 )
set field = MultiboardGetItem(Score_Table, 0, 4)
call MultiboardSetItemStyle( field, true, true )
call MultiboardSetItemIcon(field, "ReplaceableTextures\\CommandButtons\\BTNPunisher.blp")
// Team 1
set field = MultiboardGetItem(Score_Table, 1, 0)
call MultiboardSetItemValue( field, TEAM1 )
// Team 2
set field = MultiboardGetItem(Score_Table, 3 + NumberOfPlayersTeam1, 0)
call MultiboardSetItemValue( field, TEAM2 )
// Add Players Team 1
set TempInt = 2
call ForForce( Players_Team1, function Add_Players )
// Add Players Team 2
set TempInt = 4 + NumberOfPlayersTeam1
call ForForce( Players_Team2, function Add_Players )
// Game Time
set ClockRow = ( 5 + NumberOfPlayers )
set field = MultiboardGetItem(Score_Table, ClockRow, 0)
call MultiboardSetItemValueColor( field, 100, 100, 100, 255 )
call MultiboardSetItemValue( field, "Game Time:" )
set field = MultiboardGetItem(Score_Table, ClockRow, 2)
call MultiboardSetItemValueColor( field, 180, 180, 180, 255 )
call MultiboardSetItemValue( field, "0:00" )
call MultiboardDisplay( Score_Table, true )
// Update
call Update()
set field = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
// Init
local trigger trg = CreateTrigger( )
call TriggerRegisterTimerEvent(trg, 5.00, false)
call TriggerAddAction( trg, function Init_Score_Board )
// Update Clock
set trg = CreateTrigger()
call TriggerRegisterTimerEvent(trg, 1, true)
call TriggerAddAction(trg, function Set_Clock)
// Hero Dies
set trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( trg, Condition( function Conditions_Hero_Dies ) )
call TriggerAddAction( trg, function A_Hero_Dies )
// Hero Kills
set trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( trg, Condition( function Conditions_Hero_Kills ) )
call TriggerAddAction( trg, function A_Hero_Kills )
// Levelup
set trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_HERO_LEVEL )
call TriggerAddCondition( trg, Condition( function Conditions_Level_Up ) )
call TriggerAddAction( trg, function Update )
set trg = null
endfunction
endscope
//TESH.scrollpos=143
//TESH.alwaysfold=0
scope Troops initializer Init
globals
location Spawn_Team1L
location Spawn_Team1M
location Spawn_Team1R
location Spawn_Team2L
location Spawn_Team2M
location Spawn_Team2R
boolean Sorcerer1 = false
boolean Sorcerer2 = false
endglobals
private function ReActivator_Condition takes nothing returns boolean
return IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO) == false and UnitUsesWP(GetFilterUnit()) and GetUnitCurrentOrder(GetFilterUnit()) == Order_Stop and GetPlayerController(GetOwningPlayer(GetFilterUnit())) == MAP_CONTROL_COMPUTER// and CaptureSystem_Check_Unit(GetFilterUnit()) == false // change order "move" into the order you are giving the units on their way to the waypoints.
endfunction
private function ReActivator_Callback takes nothing returns nothing
call Order_Unit_To_Next_WP(GetEnumUnit())
endfunction
private function ReActivator takes nothing returns nothing
local group TempGroup = NewGroup()
call GroupEnumUnitsInRect(TempGroup, bj_mapInitialPlayableArea, Condition(function ReActivator_Condition)) // store the condition in a global if you have JNGP
call ForGroup( TempGroup, function ReActivator_Callback )
call ReleaseGroup( TempGroup )
set TempGroup = null
endfunction
private function Troops_Team1 takes integer FirstWP returns nothing
local unit CreatedUnit
// local integer FirstWP = 1
// Team 1
if ( GetUnitState(Base_Team1, UNIT_STATE_LIFE) > 0 ) then
// Archer
set CreatedUnit = CreateUnitAtLoc(Player(1), 'earc', Spawn_Team1, bj_UNIT_FACING)
set waypoint_table[GetUnitId(CreatedUnit)] = FirstWP
call Order_Unit_To_Next_WP( CreatedUnit )
// Footman
set CreatedUnit = CreateUnitAtLoc(Player(1), 'hfoo', Spawn_Team1, bj_UNIT_FACING)
set waypoint_table[GetUnitId(CreatedUnit)] = FirstWP
call Order_Unit_To_Next_WP( CreatedUnit )
// Footman
set CreatedUnit = CreateUnitAtLoc(Player(1), 'hfoo', Spawn_Team1, bj_UNIT_FACING)
set waypoint_table[GetUnitId(CreatedUnit)] = FirstWP
call Order_Unit_To_Next_WP( CreatedUnit )
// Tier 2 Units
if ( Team1_Tier >= 2 ) then
// Priest / Mage
if Sorcerer1 == false then
set CreatedUnit = CreateUnitAtLoc(Player(1), 'hmpr', Spawn_Team1, bj_UNIT_FACING)
set Sorcerer1 = true
else
set CreatedUnit = CreateUnitAtLoc(Player(1), 'hsor', Spawn_Team1, bj_UNIT_FACING)
set Sorcerer1 = false
endif
call SetUnitState(CreatedUnit, UNIT_STATE_MANA, 150)
set waypoint_table[GetUnitId(CreatedUnit)] = FirstWP
call Order_Unit_To_Next_WP( CreatedUnit )
// Tier 3 Units
if ( Team1_Tier >= 3 ) then
// Knight
set CreatedUnit = CreateUnitAtLoc(Player(1), 'hkni', Spawn_Team1, bj_UNIT_FACING)
set waypoint_table[GetUnitId(CreatedUnit)] = FirstWP
call Order_Unit_To_Next_WP( CreatedUnit )
endif
endif
endif
set CreatedUnit = null
endfunction
private function Troops_Team2 takes integer FirstWP returns nothing
local unit CreatedUnit
// Team 2
if ( GetUnitState(Base_Team2, UNIT_STATE_LIFE) > 0 ) then
// Archer
set CreatedUnit = CreateUnitAtLoc(Player(0), 'ohun', Spawn_Team2, bj_UNIT_FACING)
set waypoint_table[GetUnitId(CreatedUnit)] = FirstWP
call Order_Unit_To_Next_WP( CreatedUnit )
// Grunt
set CreatedUnit = CreateUnitAtLoc(Player(0), 'ogru', Spawn_Team2, bj_UNIT_FACING)
set waypoint_table[GetUnitId(CreatedUnit)] = FirstWP
call Order_Unit_To_Next_WP( CreatedUnit )
// Grunt
set CreatedUnit = CreateUnitAtLoc(Player(0), 'ogru', Spawn_Team2, bj_UNIT_FACING)
set waypoint_table[GetUnitId(CreatedUnit)] = FirstWP
call Order_Unit_To_Next_WP( CreatedUnit )
// Tier 2 Units
if ( Team2_Tier >= 2 ) then
// Priest / Mage
if Sorcerer2 == false then
set CreatedUnit = CreateUnitAtLoc(Player(0), 'odoc', Spawn_Team2, bj_UNIT_FACING)
set Sorcerer2 = true
else
set CreatedUnit = CreateUnitAtLoc(Player(0), 'oshm', Spawn_Team2, bj_UNIT_FACING)
set Sorcerer2 = false
endif
call SetUnitState(CreatedUnit, UNIT_STATE_MANA, 150)
set waypoint_table[GetUnitId(CreatedUnit)] = FirstWP
call Order_Unit_To_Next_WP( CreatedUnit )
// Tier 3 Units
if ( Team2_Tier >= 3 ) then
// Ogre
set CreatedUnit = CreateUnitAtLoc(Player(0), 'nogo', Spawn_Team2, bj_UNIT_FACING)
set waypoint_table[GetUnitId(CreatedUnit)] = FirstWP
call Order_Unit_To_Next_WP( CreatedUnit )
endif
endif
endif
set CreatedUnit = null
endfunction
private function Spawn_Troops takes nothing returns nothing
set Spawn_Team1 = Spawn_Team1L
set Spawn_Team2 = Spawn_Team2L
call Troops_Team1(21)
call Troops_Team2(27)
call TriggerSleepAction(10.0)
set Spawn_Team1 = Spawn_Team1M
set Spawn_Team2 = Spawn_Team2M
call Troops_Team1(1)
call Troops_Team2(7)
call TriggerSleepAction(10.0)
set Spawn_Team1 = Spawn_Team1R
set Spawn_Team2 = Spawn_Team2R
call Troops_Team1(11)
call Troops_Team2(17)
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterTimerEvent(trg, 30.00, true)
call TriggerAddAction( trg, function Spawn_Troops )
set trg = CreateTrigger( )
call TriggerRegisterTimerEvent(trg, 5.00, true)
call TriggerAddAction(trg, function ReActivator)
set trg = CreateTrigger( )
call TriggerRegisterTimerEvent(trg, 0.01, false)
call TriggerAddAction( trg, function Spawn_Troops )
set Spawn_Team1L = Location(GetRectCenterX(gg_rct_SpawnTeam1L), GetRectCenterY(gg_rct_SpawnTeam1L))
set Spawn_Team1M = Location(GetRectCenterX(gg_rct_SpawnTeam1M), GetRectCenterY(gg_rct_SpawnTeam1M))
set Spawn_Team1R = Location(GetRectCenterX(gg_rct_SpawnTeam1R), GetRectCenterY(gg_rct_SpawnTeam1R))
set Spawn_Team2L = Location(GetRectCenterX(gg_rct_SpawnTeam2L), GetRectCenterY(gg_rct_SpawnTeam2L))
set Spawn_Team2M = Location(GetRectCenterX(gg_rct_SpawnTeam2M), GetRectCenterY(gg_rct_SpawnTeam2M))
set Spawn_Team2R = Location(GetRectCenterX(gg_rct_SpawnTeam2R), GetRectCenterY(gg_rct_SpawnTeam2R))
set trg = null
endfunction
endscope
//TESH.scrollpos=33
//TESH.alwaysfold=0
scope CreepGate initializer Init
globals
location GateSpawn
endglobals
private function Creep_Conditions takes nothing returns boolean
return GetOwningPlayer(GetFilterUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE) and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0
endfunction
private function Spawn_Creeps takes nothing returns nothing
local unit u
local effect e
local group creeps = NewGroup()
call GroupEnumUnitsInRect(creeps, gg_rct_GateSpawn, Condition(function Creep_Conditions))
call Debug_Message("Try to spawn some creeps")
native GetRandomInt takes integer lowBound, integer highBound returns integer
if FirstOfGroup(creeps) == null then
set u = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), ChooseRandomCreep(GetRandomInt(1,2)), GetRandomReal(GetRectMinX(gg_rct_GateSpawn), GetRectMaxX(gg_rct_GateSpawn)), GetRandomReal(GetRectMinY(gg_rct_GateSpawn), GetRectMaxY(gg_rct_GateSpawn)), bj_UNIT_FACING)
set e = AddSpecialEffect("Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl", GetUnitX(u), GetUnitY(u))
call DestroyEffect(e)
set u = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), ChooseRandomCreep(GetRandomInt(2,3)), GetRandomReal(GetRectMinX(gg_rct_GateSpawn), GetRectMaxX(gg_rct_GateSpawn)), GetRandomReal(GetRectMinY(gg_rct_GateSpawn), GetRectMaxY(gg_rct_GateSpawn)), bj_UNIT_FACING)
set e = AddSpecialEffect("Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl", GetUnitX(u), GetUnitY(u))
call DestroyEffect(e)
set u = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), ChooseRandomCreep(GetRandomInt(3,6)), GetRandomReal(GetRectMinX(gg_rct_GateSpawn), GetRectMaxX(gg_rct_GateSpawn)), GetRandomReal(GetRectMinY(gg_rct_GateSpawn), GetRectMaxY(gg_rct_GateSpawn)), bj_UNIT_FACING)
set e = AddSpecialEffect("Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl", GetUnitX(u), GetUnitY(u))
call DestroyEffect(e)
set u = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), ChooseRandomCreep(GetRandomInt(5,7)), GetRandomReal(GetRectMinX(gg_rct_GateSpawn), GetRectMaxX(gg_rct_GateSpawn)), GetRandomReal(GetRectMinY(gg_rct_GateSpawn), GetRectMaxY(gg_rct_GateSpawn)), bj_UNIT_FACING)
set e = AddSpecialEffect("Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl", GetUnitX(u), GetUnitY(u))
call DestroyEffect(e)
set u = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), ChooseRandomCreep(GetRandomInt(8,10)), GetRandomReal(GetRectMinX(gg_rct_GateSpawn), GetRectMaxX(gg_rct_GateSpawn)), GetRandomReal(GetRectMinY(gg_rct_GateSpawn), GetRectMaxY(gg_rct_GateSpawn)), bj_UNIT_FACING)
set e = AddSpecialEffect("Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl", GetUnitX(u), GetUnitY(u))
call DestroyEffect(e)
endif
call ReleaseGroup(creeps)
set creeps = null
call DestroyEffect(e)
set e = null
set u = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterTimerEvent(trg, 60.00, true)
call TriggerAddAction( trg, function Spawn_Creeps )
set trg = CreateTrigger( )
call TriggerRegisterTimerEvent(trg, 0.01, false)
call TriggerAddAction( trg, function Spawn_Creeps )
set GateSpawn = Location(GetRectCenterX(gg_rct_GateSpawn), GetRectCenterY(gg_rct_GateSpawn))
set trg = null
endfunction
endscope
//TESH.scrollpos=547
//TESH.alwaysfold=0
library Itemsystem initializer Init requires HeroSystem
globals
private equipment array Item_Array[1]
private Table ItemTab = 0
private real array ItemSystem_SpellDamageMods[1]
private real array ItemSystem_CritBoni[1]
private integer array ItemSystem_StrBoni[1]
private integer array ItemSystem_AgiBoni[1]
private integer array ItemSystem_IntBoni[1]
private integer ItemCount = 0 // don't touch this
private integer N = 0 // automatically stores the number of items, don't touch this!
endglobals
struct equipment
integer id
integer class // 1 = weapon, 2 = armor, 3 = boots, 4 = ring
boolean usableStr = true
boolean usableAgi = true
boolean usableInt = true
real spell_bonus = 0.0
real crit_bonus = 0.0
integer str_bonus = 0
integer agi_bonus = 0
integer int_bonus = 0
endstruct
function GetCritChance takes unit u returns real
local integer id = GetPlayerId(GetOwningPlayer(u))
local real crit = 0
if IsStrHero(u) then
set crit = BASIC_CRIT_CHANCE + ItemSystem_CritBoni[id] + (GetHeroStr(Heroes[id], true) * CRIT_PER_ATTRIBUTE)
elseif IsAgiHero(u) then
set crit = BASIC_CRIT_CHANCE + ItemSystem_CritBoni[id] + (GetHeroAgi(Heroes[id], true) * CRIT_PER_ATTRIBUTE)
elseif IsIntHero(u) then
set crit = BASIC_CRIT_CHANCE + ItemSystem_CritBoni[id] + (GetHeroInt(Heroes[id], true) * CRIT_PER_ATTRIBUTE)
endif
return crit
endfunction
function Inc takes integer i returns integer
set i = i + 1
return i
endfunction
private function GetN takes integer id returns integer
return ItemTab[id] // probably much faster with table than the old code :)
endfunction
function IsSystemItem takes integer id returns boolean
if GetN(id) != 0 then
return true
endif
return false
endfunction
function GetStrBonus takes integer id returns integer
return ItemSystem_StrBoni[id]
endfunction
function GetAgiBonus takes integer id returns integer
return ItemSystem_AgiBoni[id]
endfunction
function GetIntBonus takes integer id returns integer
return ItemSystem_IntBoni[id]
endfunction
function GetSpellBonus takes integer id returns real
return ItemSystem_SpellDamageMods[id]
endfunction
function GetSpellMod takes integer id returns real
return 1 + ItemSystem_SpellDamageMods[id]
endfunction
function GetCritBonus takes integer id returns real
return ItemSystem_CritBoni[id]
endfunction
function IsStrItem takes integer id returns boolean
return Item_Array[GetN(id)].usableStr
endfunction
function IsAgiItem takes integer id returns boolean
return Item_Array[GetN(id)].usableAgi
endfunction
function IsIntItem takes integer id returns boolean
return Item_Array[GetN(id)].usableInt
endfunction
function IsWeapon takes integer id returns boolean
if Item_Array[GetN(id)].class == 1 then
return true
endif
return false
endfunction
function IsArmor takes integer id returns boolean
set id = GetN(id)
if Item_Array[id].class == 2 then
return true
endif
return false
endfunction
function IsBoots takes integer id returns boolean
set id = GetN(id)
if Item_Array[id].class == 3 then
return true
endif
return false
endfunction
function IsRing takes integer id returns boolean
set id = GetN(id)
if Item_Array[id].class == 4 then
return true
endif
return false
endfunction
function TwoOfSameClass takes integer id, unit Hero returns boolean
local integer i = 0
local integer j = 0
local integer help
local integer class
set id = GetN(id)
if id != 0 then
set class = Item_Array[id].class
loop
exitwhen i > 5
set help = GetItemTypeId(UnitItemInSlot(Hero, i))
if Item_Array[GetN(help)].class == class then
set j = j + 1
endif
set i = i + 1
endloop
if j > 1 then
return true
endif
endif
return false
endfunction
function Show_Stats takes integer id returns nothing
call DisplayTimedTextToPlayer(Player(id),0,0,10, " ")
call DisplayTimedTextToPlayer(Player(id),0,0,10, "Hero stats of "+PlayerNames[id] + " ("+GetUnitName(Heroes[id]) + ") :")
call DisplayTimedTextToPlayer(Player(id),0,0,10, " ")
call DisplayTimedTextToPlayer(Player(id),0,0,10, " |cff449EFBSpell/Ability power : |r |cffA7A7A7+" + R2S(GetSpellBonus(id)*100)+"%|r")
// call DisplayTimedTextToPlayer(Player(id),0,0,10, " |cffCCF389Healing power : |r |cffA7A7A7+" + R2S(GetSpellBonus(id)*100)+"%|r")
call DisplayTimedTextToPlayer(Player(id),0,0,10, " |cff8977F6Crit chance : |r |cffA7A7A7" + R2S(GetCritChance(Heroes[id])) + "%|r")
call DisplayTimedTextToPlayer(Player(id),0,0,10, " |cffE3231EStr : |r |cffA7A7A7+" + I2S(GetStrBonus(id)))
call DisplayTimedTextToPlayer(Player(id),0,0,10, " |cff76DD28Agi : |r |cffA7A7A7+" + I2S(GetAgiBonus(id)))
call DisplayTimedTextToPlayer(Player(id),0,0,10, " |cff3C5CACInt : |r |cffA7A7A7+" + I2S(GetIntBonus(id)))
call DisplayTimedTextToPlayer(Player(id),0,0,10, " ")
endfunction
private function SetMods takes integer id, integer player_id, boolean PickedUp returns nothing
local real life = GetUnitState(Heroes[player_id], UNIT_STATE_LIFE)
set id = GetN(id)
// call Debug_Message("Set Mods with item id: "+I2S(id))
// If aquired
if PickedUp then
set ItemSystem_SpellDamageMods[player_id] = ItemSystem_SpellDamageMods[player_id] + Item_Array[id].spell_bonus
// set ItemSystem_SpellHealingMods[player_id] = ItemSystem_SpellHealingMods[player_id] + Item_Array[id].spell_bonus + Item_Array[id].heal_bonus
set ItemSystem_CritBoni[player_id] = ItemSystem_CritBoni[player_id] + Item_Array[id].crit_bonus
call SetHeroStr( Heroes[player_id], GetHeroStr(Heroes[player_id],false) + Item_Array[id].str_bonus, true)
set ItemSystem_StrBoni[player_id] = ItemSystem_StrBoni[player_id] + Item_Array[id].str_bonus
call SetHeroAgi( Heroes[player_id], GetHeroAgi(Heroes[player_id],false) + Item_Array[id].agi_bonus, true)
set ItemSystem_AgiBoni[player_id] = ItemSystem_AgiBoni[player_id] + Item_Array[id].agi_bonus
call SetHeroInt( Heroes[player_id], GetHeroInt(Heroes[player_id],false) + Item_Array[id].int_bonus, true)
set ItemSystem_IntBoni[player_id] = ItemSystem_IntBoni[player_id] + Item_Array[id].int_bonus
// If dropped, remove multiplier
else
set ItemSystem_SpellDamageMods[player_id] = ItemSystem_SpellDamageMods[player_id] - Item_Array[id].spell_bonus
// set ItemSystem_SpellHealingMods[player_id] = ItemSystem_SpellHealingMods[player_id] - Item_Array[id].spell_bonus - Item_Array[id].heal_bonus
set ItemSystem_CritBoni[player_id] = ItemSystem_CritBoni[player_id] - Item_Array[id].crit_bonus
call SetHeroStr( Heroes[player_id], GetHeroStr(Heroes[player_id],false) - Item_Array[id].str_bonus, true)
set ItemSystem_StrBoni[player_id] = ItemSystem_StrBoni[player_id] - Item_Array[id].str_bonus
call SetHeroAgi( Heroes[player_id], GetHeroAgi(Heroes[player_id],false) - Item_Array[id].agi_bonus, true)
set ItemSystem_AgiBoni[player_id] = ItemSystem_AgiBoni[player_id] - Item_Array[id].agi_bonus
call SetHeroInt( Heroes[player_id], GetHeroInt(Heroes[player_id],false) - Item_Array[id].int_bonus, true)
set ItemSystem_IntBoni[player_id] = ItemSystem_IntBoni[player_id] - Item_Array[id].int_bonus
endif
call SetUnitState(Heroes[player_id], UNIT_STATE_LIFE, life)
endfunction
private function NewEquip takes nothing returns equipment
local equipment equi = equipment.create()
set equi.id = 0
set equi.class = 0
set equi.usableStr = true
set equi.usableAgi = true
set equi.usableInt = true
set equi.spell_bonus = 0.0
// set equi.heal_bonus = 0.0
set equi.crit_bonus = 0.0
set equi.str_bonus = 0
set equi.agi_bonus = 0
set equi.int_bonus = 0
return equi
endfunction
private function RegEquip takes equipment equi returns nothing
set ItemCount = ItemCount + 1
set ItemTab[equi.id] = ItemCount
set Item_Array[ItemCount] = equi
endfunction
private function Init_Items takes nothing returns nothing
local integer i
local equipment equi
set ItemTab = Table.create()
// Init Damage Mods
set i = 0
loop
exitwhen i > 11
set ItemSystem_SpellDamageMods[i] = 0.0
// set ItemSystem_SpellHealingMods[i] = 0.0
set ItemSystem_CritBoni[i] = 0.0
set i = i + 1
endloop
// WEAPONS
// ====================================
// Grandmaster's Sword
set equi = NewEquip()
set equi.id = 'I01M'
set equi.class = 1
set equi.usableInt = false
set equi.spell_bonus = 0.15
set equi.crit_bonus = 3.0
call RegEquip(equi)
// Staff of Dominance
set equi = NewEquip()
set equi.id = 'I018'
set equi.class = 1
set equi.usableStr = false
set equi.usableAgi = false
set equi.spell_bonus = 0.15
set equi.crit_bonus = 3.0
call RegEquip(equi)
// =============================================
// Blade of the Hellwinds
set equi = NewEquip()
set equi.id = 'I00B'
set equi.class = 1
set equi.usableInt = false
set equi.spell_bonus = 0.25
set equi.crit_bonus = 5.0
call RegEquip(equi)
// Staff of the Nether Realms
set equi = NewEquip()
set equi.id = 'I008'
set equi.class = 1
set equi.usableStr = false
set equi.usableAgi = false
set equi.spell_bonus = 0.25
set equi.crit_bonus = 5.0
call RegEquip(equi)
// The Bone Crusher
set equi = NewEquip()
set equi.id = 'I015'
set equi.class = 1
set equi.usableAgi = false
set equi.usableInt = false
set equi.spell_bonus = 0.1
call RegEquip(equi)
// The Blood Drinker
set equi = NewEquip()
set equi.id = 'I01A'
set equi.class = 1
set equi.spell_bonus = 0.1
call RegEquip(equi)
// Staff of the Cobra
set equi = NewEquip()
set equi.id = 'I01D'
set equi.class = 1
set equi.spell_bonus = 0.2
set equi.crit_bonus = 3.0
set equi.str_bonus = 5
set equi.agi_bonus = 5
set equi.int_bonus = 5
call RegEquip(equi)
// Blade of the Underworld
set equi = NewEquip()
set equi.id = 'I00K'
set equi.class = 1
set equi.spell_bonus = 0.15
call RegEquip(equi)
// The Crippler
set equi = NewEquip()
set equi.id = 'I00M'
set equi.class = 1
set equi.usableInt = false
set equi.spell_bonus = 0.1
set equi.crit_bonus = 3.0
call RegEquip(equi)
// Thunderstorm
set equi = NewEquip()
set equi.id = 'I01H'
set equi.class = 1
set equi.usableInt = false
call RegEquip(equi)
// Destroyer of Worlds
set equi = NewEquip()
set equi.id = 'I01B'
set equi.class = 1
set equi.usableAgi = false
set equi.usableInt = false
set equi.crit_bonus = 6.0
set equi.spell_bonus = 0.3
call RegEquip(equi)
// Hattori Hanzo Blade
set equi = NewEquip()
set equi.id = 'I019'
set equi.class = 1
set equi.usableInt = false
set equi.crit_bonus = 10.0
call RegEquip(equi)
// Staff of the Elder Gods
set equi = NewEquip()
set equi.id = 'I00D'
set equi.class = 1
set equi.usableStr = false
set equi.usableAgi = false
set equi.spell_bonus = 0.3
set equi.crit_bonus = 6.0
call RegEquip(equi)
// ARMOR
// ====================================
// Sorcerer's Robes
set equi = NewEquip()
set equi.id = 'I00T'
set equi.class = 2
set equi.str_bonus = 2
set equi.int_bonus = 4
call RegEquip(equi)
// Shroud of the Warmage
set equi = NewEquip()
set equi.id = 'I003'
set equi.class = 2
set equi.str_bonus = 3
set equi.int_bonus = 3
call RegEquip(equi)
// Robes of the Dragonflame
set equi = NewEquip()
set equi.id = 'I00I'
set equi.class = 2
set equi.int_bonus = 6
call RegEquip(equi)
// Vestments of the Wanderer
set equi = NewEquip()
set equi.id = 'I011'
set equi.class = 2
set equi.usableInt = false
set equi.str_bonus = 3
set equi.agi_bonus = 3
set equi.int_bonus = 3
call RegEquip(equi)
// Chestguard of Tenacity
set equi = NewEquip()
set equi.id = 'I00Y'
set equi.class = 2
set equi.usableInt = false
set equi.str_bonus = 3
set equi.agi_bonus = 4
call RegEquip(equi)
// Shadowblood Armor
set equi = NewEquip()
set equi.id = 'I00W'
set equi.class = 2
set equi.usableInt = false
set equi.agi_bonus = 6
call RegEquip(equi)
// Cobaltsteel Armor
set equi = NewEquip()
set equi.id = 'I004'
set equi.class = 2
set equi.usableInt = false
set equi.usableAgi = false
set equi.str_bonus = 4
set equi.int_bonus = 4
call RegEquip(equi)
// Titan's Plate
set equi = NewEquip()
set equi.id = 'I00Q'
set equi.class = 2
set equi.usableInt = false
set equi.usableAgi = false
set equi.str_bonus = 6
call RegEquip(equi)
// ====================================
// BOOTS
// Boots of Speed
set equi = NewEquip()
set equi.id = 'I00S'
set equi.class = 3
call RegEquip(equi)
// Nightwind Boots
set equi = NewEquip()
set equi.id = 'I00F'
set equi.class = 3
call RegEquip(equi)
// ====================================
// RINGS
// Ring of Eagerness
set equi = NewEquip()
set equi.id = 'I01I'
set equi.class = 4
call RegEquip(equi)
// Ring of Balance
set equi = NewEquip()
set equi.id = 'I01J'
set equi.class = 4
set equi.str_bonus = 5
set equi.agi_bonus = 5
set equi.int_bonus = 5
call RegEquip(equi)
// Ring of Domination
set equi = NewEquip()
set equi.id = 'I00U'
set equi.class = 4
set equi.crit_bonus = 5.0
call RegEquip(equi)
// Ring of the Winds
set equi = NewEquip()
set equi.id = 'I01K'
set equi.class = 4
call RegEquip(equi)
// Ring of Protection
set equi = NewEquip()
set equi.id = 'I01L'
set equi.class = 4
call RegEquip(equi)
endfunction
private function Conditions_Item_Manipulate takes nothing returns boolean
return IsSystemItem( GetItemTypeId(GetManipulatedItem()) )
endfunction
private function Item_Manipulate takes nothing returns nothing
local integer player_id = GetPlayerId(GetOwningPlayer(GetManipulatingUnit()))
local integer item_id = GetItemTypeId(GetManipulatedItem())
local item Item = GetManipulatedItem()
local unit Hero = GetManipulatingUnit()
local boolean pickup = false
local boolean usable = true
// Pickup or drop?
if GetTriggerEventId() == EVENT_PLAYER_UNIT_PICKUP_ITEM then
set pickup = true
endif
if pickup then
// call Debug_Message("Item Class: "+
// Apply weapon specific modifications (This has to be called first, even if the weapon is dropped!)
call SetMods(item_id, player_id, true)
// Only one item of each class
if TwoOfSameClass(item_id, Hero) then
call DisplayTimedTextToPlayer(Player(player_id),0,0,5, "|cffF52828You can carry only one item of this type!|r")
call DisplayTimedTextToPlayer(Player(player_id), 0, 0, 10, " ")
call UnitRemoveItem(Hero, Item)
else
// Strength Weapons
if IsStrHero(Hero) and IsStrItem(item_id) == false then
set usable = false
endif
// Agility Weapons
if IsAgiHero(Hero) and IsAgiItem(item_id) == false then
set usable = false
endif
// Intelligence Weapons
if IsIntHero(Hero) and IsIntItem(item_id) == false then
set usable = false
endif
// Drop item if it's not usable
if usable == false then
call DisplayTimedTextToPlayer(Player(player_id), 0, 0, 10, "|cffF52828You cannot use this item!|r")
call DisplayTimedTextToPlayer(Player(player_id), 0, 0, 10, " ")
call UnitRemoveItem(Hero, Item)
else
// OK, if all these things before are passed, let's take the item as successfully picked up
call DisplayTimedTextToPlayer(Player(player_id), 0, 0, 10, "Picked up " + GetItemName(Item) )
call Show_Stats(player_id)
endif
endif
else
// Apply weapon specific modifications
call SetMods(item_id, player_id, false)
call DisplayTimedTextToPlayer(Player(player_id), 0, 0, 10, GetItemName(Item) + " dropped" )
// call Show_Stats(player_id)
endif
set Hero = null
set Item = null
endfunction
// ====================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
// Item Handling
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_PICKUP_ITEM )
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_DROP_ITEM )
call TriggerAddCondition(trg, Condition(function Conditions_Item_Manipulate))
call TriggerAddAction( trg, function Item_Manipulate )
call Init_Items()
set trg = null
endfunction
endlibrary
//TESH.scrollpos=377
//TESH.alwaysfold=0
library UpgradeSystem initializer Init requires HeroSystem
globals
// constant integer UPGRADE_TIME_TIER1
integer array Research_Array[1] // stores all upgrades available
integer Research_Count = 0 // This is the number of available upgrades
integer Team1_Tier = 1
integer Team2_Tier = 1
boolean Team1_TierUpgradeInProgress = false
boolean Team2_TierUpgradeInProgress = false
boolean Full_Upgrades_Team1 = false
boolean Full_Upgrades_Team2 = false
constant integer T2_COST = 2500
constant integer T3_COST = 5000
// integer Team_Gold
integer AI_Team_Gold
integer DecAmount = 0
// currently unused
unit array Towers_Team1[1]
unit array Towers_Team2[1]
rect array Tower_Points_Team1[1]
rect array Tower_Points_Team2[1]
endglobals
function Check_Upgrades takes integer id returns boolean
if ( not ( GetPlayerTechCount(Player(id), 'Rhme', true) == 3 ) ) then
return false
endif
if ( not ( GetPlayerTechCount(Player(id), 'Rhar', true) == 3 ) ) then
return false
endif
if ( not ( GetPlayerTechCount(Player(id), 'Rhpt', true) == 2 ) ) then
return false
endif
if ( not ( GetPlayerTechCount(Player(id), 'Rhst', true) == 2 ) ) then
return false
endif
if ( not ( GetPlayerTechCount(Player(id), 'Resm', true) == 3 ) ) then
return false
endif
if ( not ( GetPlayerTechCount(Player(id), 'Rema', true) == 3 ) ) then
return false
endif
if ( not ( GetPlayerTechCount(Player(id), 'Reib', true) == 2 ) ) then
return false
endif
if ( not ( GetPlayerTechCount(Player(id), 'Rhac', true) >= 3 ) ) then
return false
endif
if ( not ( GetPlayerTechCount(Player(id), 'Rhse', true) >= 1 ) ) then
return false
endif
return true
endfunction
function Update_Upgrades_Status takes nothing returns nothing
// Team 1
if ( Check_Upgrades(1) ) then
set Full_Upgrades_Team1 = true
else
set Full_Upgrades_Team1 = false
endif
// Team 2
if ( Check_Upgrades(0) ) then
set Full_Upgrades_Team2 = true
else
set Full_Upgrades_Team2 = false
endif
endfunction
private function Finish_Research takes nothing returns nothing
local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
local string s
set s = ( UPGRADE + PlayerNames[id] + " just purchased a new Upgrade for your team!" )
// Team 1
if ( IsPlayerAlly(GetOwningPlayer(GetTriggerUnit()), Player(1)) == true ) then
// Set Tech Level for whole team
call SetPlayerTechResearched( Player(1), GetResearched(), GetPlayerTechCount(GetOwningPlayer(GetTriggerUnit()), GetResearched(), true))
call SetPlayerTechResearched( Player(2), GetResearched(), GetPlayerTechCount(GetOwningPlayer(GetTriggerUnit()), GetResearched(), true))
call SetPlayerTechResearched( Player(6), GetResearched(), GetPlayerTechCount(GetOwningPlayer(GetTriggerUnit()), GetResearched(), true))
call SetPlayerTechResearched( Player(8), GetResearched(), GetPlayerTechCount(GetOwningPlayer(GetTriggerUnit()), GetResearched(), true))
call SetPlayerTechResearched( Player(9), GetResearched(), GetPlayerTechCount(GetOwningPlayer(GetTriggerUnit()), GetResearched(), true))
call SetPlayerTechResearched( Player(10), GetResearched(), GetPlayerTechCount(GetOwningPlayer(GetTriggerUnit()), GetResearched(), true))
// Notice Message
call Team_Message(1, s)
// Team 2
else
// Set Tech Level for whole team
call SetPlayerTechResearched( Player(0), GetResearched(), GetPlayerTechCount(GetOwningPlayer(GetTriggerUnit()), GetResearched(), true))
call SetPlayerTechResearched( Player(3), GetResearched(), GetPlayerTechCount(GetOwningPlayer(GetTriggerUnit()), GetResearched(), true))
call SetPlayerTechResearched( Player(4), GetResearched(), GetPlayerTechCount(GetOwningPlayer(GetTriggerUnit()), GetResearched(), true))
call SetPlayerTechResearched( Player(5), GetResearched(), GetPlayerTechCount(GetOwningPlayer(GetTriggerUnit()), GetResearched(), true))
call SetPlayerTechResearched( Player(7), GetResearched(), GetPlayerTechCount(GetOwningPlayer(GetTriggerUnit()), GetResearched(), true))
call SetPlayerTechResearched( Player(11), GetResearched(), GetPlayerTechCount(GetOwningPlayer(GetTriggerUnit()), GetResearched(), true))
// Notice Message
call Team_Message(2, s)
endif
endfunction
private function AI_Buys_Upgrades takes nothing returns nothing
local integer i
local unit u
set i = GetRandomInt(1, Research_Count)
set u = GroupPickRandomUnit(AI_Safes_Team1)
call IssueImmediateOrderById( u, Research_Array[i] )
set i = GetRandomInt(1, Research_Count)
set u = GroupPickRandomUnit(AI_Safes_Team2)
call IssueImmediateOrderById( u, Research_Array[i] )
call Update_Upgrades_Status()
set u = null
if Full_Upgrades_Team1 and Full_Upgrades_Team2 then
call DisableTrigger( GetTriggeringTrigger() )
call DestroyTrigger( GetTriggeringTrigger() )
endif
endfunction
private function Conditions_Demolisher takes nothing returns boolean
return GetItemTypeId(GetManipulatedItem()) == 'I00X'
endfunction
private function Demolisher takes nothing returns nothing
// Team 1
if IsUnitTeam1(GetManipulatingUnit()) then
call CreateUnitAtLoc( GetOwningPlayer(GetManipulatingUnit()), 'ocat', GetUnitLoc(Base_Team1), bj_UNIT_FACING )
// Team 2
else
call CreateUnitAtLoc( GetOwningPlayer(GetManipulatingUnit()), 'ocat', GetUnitLoc(Base_Team2), bj_UNIT_FACING )
endif
call TriggerSleepAction(0.02)
call RemoveItem( GetManipulatedItem() )
endfunction
private function Conditions_Dragon takes nothing returns boolean
return GetItemTypeId(GetManipulatedItem()) == 'I00R' or GetItemTypeId(GetManipulatedItem()) == 'I012'
endfunction
private function Dragon takes nothing returns nothing
local unit u
// Team 1
if IsUnitTeam1(GetManipulatingUnit()) then
set u = CreateUnitAtLoc( Player(1), 'n00A', GetUnitLoc(Base_Team1), bj_UNIT_FACING )
set waypoint_table[GetUnitId(u)] = 1
call Order_Unit_To_Next_WP( u )
set u = CreateUnitAtLoc( Player(1), 'n00A', GetUnitLoc(Base_Team1), bj_UNIT_FACING )
set waypoint_table[GetUnitId(u)] = 11
call Order_Unit_To_Next_WP( u )
set u = CreateUnitAtLoc( Player(1), 'n00A', GetUnitLoc(Base_Team1), bj_UNIT_FACING )
set waypoint_table[GetUnitId(u)] = 21
call Order_Unit_To_Next_WP( u )
// Team 2
else
call CreateUnitAtLoc( Player(0), 'n003', GetUnitLoc(Base_Team2), bj_UNIT_FACING )
set waypoint_table[GetUnitId(u)] = 7
call Order_Unit_To_Next_WP( u )
call CreateUnitAtLoc( Player(0), 'n003', GetUnitLoc(Base_Team2), bj_UNIT_FACING )
set waypoint_table[GetUnitId(u)] = 17
call Order_Unit_To_Next_WP( u )
call CreateUnitAtLoc( Player(0), 'n003', GetUnitLoc(Base_Team2), bj_UNIT_FACING )
set waypoint_table[GetUnitId(u)] = 27
call Order_Unit_To_Next_WP( u )
endif
set u = null
call TriggerSleepAction(0.02)
call RemoveItem( GetManipulatedItem() )
endfunction
private function Conditions_Tier_Upgrade takes nothing returns boolean
// Keep / Stronghold
if ( GetItemTypeId(GetManipulatedItem()) == 'I010' ) or ( GetItemTypeId(GetManipulatedItem()) == 'I014' ) then
return true
endif
// Castle / Fortress
if ( GetItemTypeId(GetManipulatedItem()) == 'I00Z' ) or ( GetItemTypeId(GetManipulatedItem()) == 'I016' ) then
return true
endif
return false
endfunction
private function Tier_Upgrade_Start takes nothing returns nothing
// Team 1
if ( IsPlayerAlly(GetOwningPlayer(GetManipulatingUnit()), Player(1)) == true ) then
if ( GetItemTypeId(GetManipulatedItem()) == 'I010' ) then
call IssueImmediateOrderById( Base_Team1, 'hkee' )
else
call IssueImmediateOrderById( Base_Team1, 'hcas' )
endif
// Team 2
else
// call Debug_Message("Team 2 Tier Upgrade start on "+ GetUnitName(Base_Team2))
if ( GetItemTypeId(GetManipulatedItem()) == 'I014' ) then
call IssueImmediateOrderById( Base_Team2, 'ostr' )
else
call IssueImmediateOrderById( Base_Team2, 'ofrt' )
endif
endif
endfunction
private function Conditions_Tier_Upgrade_Finish takes nothing returns boolean
// Keep / Stronghold
if ( GetUnitTypeId(GetTriggerUnit()) == 'hkee' ) or ( GetUnitTypeId(GetTriggerUnit()) == 'ostr' ) then
return true
endif
// Castle / Fortress
if ( GetUnitTypeId(GetTriggerUnit()) == 'hcas' ) or ( GetUnitTypeId(GetTriggerUnit()) == 'ofrt' )then
return true
endif
return false
endfunction
private function Tier_Upgrade_Finish takes nothing returns nothing
local real x = GetUnitX(GetTriggerUnit())
local real y = GetUnitY(GetTriggerUnit()) //+ 32
// Team 1
if ( IsPlayerAlly(GetOwningPlayer(GetTriggerUnit()), Player(1)) == true ) then
if ( GetUnitTypeId(GetTriggerUnit()) == 'hkee' ) then
call RemoveUnit(GetTriggerUnit())
set Base_Team1 = CreateUnit(Player(1), 'hkee', x, y, bj_UNIT_FACING)
call Team_Message(0, TEAM1 + "just upgraded to |cff9DD2F4Tier 2|r")
set Team1_Tier = 2
set Team1_TierUpgradeInProgress = false
call StartSound(Sound_General)
else
call RemoveUnit(GetTriggerUnit())
set Base_Team1 = CreateUnit(Player(1), 'hcas', x, y, bj_UNIT_FACING)
call Team_Message(0, TEAM1 + "just upgraded to |cffFF9751Tier 3|r")
set Team1_Tier = 3
set Team1_TierUpgradeInProgress = false
call StartSound(Sound_General)
endif
// Team 2
else
if ( GetUnitTypeId(GetTriggerUnit()) == 'ostr' ) then
call RemoveUnit(GetTriggerUnit())
set Base_Team2 = CreateUnit(Player(0), 'ostr', x, y, bj_UNIT_FACING)
call Team_Message(0, TEAM2 + "just upgraded to |cff9DD2F4Tier 2|r")
set Team2_Tier = 2
set Team2_TierUpgradeInProgress = false
call StartSound(Sound_General)
else
call RemoveUnit(GetTriggerUnit())
set Base_Team2 = CreateUnit(Player(0), 'ofrt', x, y, bj_UNIT_FACING)
call Team_Message(0, TEAM2 + "just upgraded to |cffFF9751Tier 3|r")
set Team2_Tier = 3
set Team2_TierUpgradeInProgress = false
call StartSound(Sound_General)
endif
endif
// call KillSoundWhenDone(soundHandle)
endfunction
private function Conditions_AI_Tier_Upgrades takes nothing returns boolean
return AI_Active and ( Team1_Tier < 3 or Team2_Tier < 3 )
endfunction
private function AI_Tier_Upgrades_Team1_Callback takes nothing returns nothing
local integer gold = GetPlayerState(GetEnumPlayer(), PLAYER_STATE_RESOURCE_GOLD)
local integer id = GetPlayerId(GetEnumPlayer())
local item it
local string s
if gold >= T2_COST and Team1_Tier < 2 and GetUnitState(Heroes[id], UNIT_STATE_LIFE) > 0 and not Team1_TierUpgradeInProgress then
set it = CreateItem('I010', GetUnitX(Heroes[id]), GetUnitY(Heroes[id]))
call UnitAddItem(Heroes[id], it)
call SetPlayerState(Player(id), PLAYER_STATE_RESOURCE_GOLD, gold - T2_COST)
set Team1_TierUpgradeInProgress = true
set s = ( UPGRADE + PlayerNames[id] + " just initiated the Tier 2 upgrade!" )
call Team_Message(1, s)
endif
if gold >= T3_COST and Team1_Tier < 3 and GetUnitState(Heroes[id], UNIT_STATE_LIFE) > 0 and not Team1_TierUpgradeInProgress then
set it = CreateItem('I00Z', GetUnitX(Heroes[id]), GetUnitY(Heroes[id]))
call UnitAddItem(Heroes[id], it)
call SetPlayerState(Player(id), PLAYER_STATE_RESOURCE_GOLD, gold - T3_COST)
set s = ( UPGRADE + PlayerNames[id] + " just initiated the Tier 3 upgrade!" )
set Team1_TierUpgradeInProgress = true
call Team_Message(1, s)
endif
set it = null
endfunction
private function AI_Tier_Upgrades_Team2_Callback takes nothing returns nothing
local integer gold = GetPlayerState(GetEnumPlayer(), PLAYER_STATE_RESOURCE_GOLD)
local integer id = GetPlayerId(GetEnumPlayer())
local item it
local string s
if gold >= T2_COST and Team2_Tier < 2 and GetUnitState(Heroes[id], UNIT_STATE_LIFE) > 0 and not Team2_TierUpgradeInProgress then
set it = CreateItem('I014', GetUnitX(Heroes[id]), GetUnitY(Heroes[id]))
call UnitAddItem(Heroes[id], it)
call SetPlayerState(Player(id), PLAYER_STATE_RESOURCE_GOLD, gold - T2_COST)
set Team2_TierUpgradeInProgress = true
set s = ( UPGRADE + PlayerNames[id] + " just initiated the Tier 2 upgrade!" )
call Team_Message(2, s)
endif
if gold >= T3_COST and Team2_Tier < 3 and GetUnitState(Heroes[id], UNIT_STATE_LIFE) > 0 and not Team2_TierUpgradeInProgress then
set it = CreateItem('I016', GetUnitX(Heroes[id]), GetUnitY(Heroes[id]))
call UnitAddItem(Heroes[id], it)
call SetPlayerState(Player(id), PLAYER_STATE_RESOURCE_GOLD, gold - T3_COST)
set s = ( UPGRADE + PlayerNames[id] + " just initiated the Tier 3 upgrade!" )
set Team2_TierUpgradeInProgress = true
call Team_Message(2, s)
endif
set it = null
endfunction
private function AI_Tier_Upgrades takes nothing returns nothing
// Team 1
if Team1_Tier < 3 then
call ForForce( AI_Players_Team1, function AI_Tier_Upgrades_Team1_Callback )
endif
// Team 2
if Team2_Tier < 3 then
call ForForce( AI_Players_Team2, function AI_Tier_Upgrades_Team2_Callback )
endif
endfunction
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
// Tier Upgrades
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_PICKUP_ITEM )
call TriggerAddCondition( trg, Condition( function Conditions_Tier_Upgrade ) )
call TriggerAddAction( trg, function Tier_Upgrade_Start )
set trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_UPGRADE_FINISH )
call TriggerAddCondition( trg, Condition( function Conditions_Tier_Upgrade_Finish ) )
call TriggerAddAction( trg, function Tier_Upgrade_Finish )
// AI players buy Upgrades
set trg = CreateTrigger()
call TriggerRegisterTimerEvent(trg, 20.00, true)
call TriggerAddAction( trg, function AI_Buys_Upgrades )
// AI Tier Upgrades
set trg = CreateTrigger()
call TriggerRegisterTimerEvent(trg, 40.00, true)
call TriggerAddCondition( trg, Condition( function Conditions_AI_Tier_Upgrades ) )
call TriggerAddAction( trg, function AI_Tier_Upgrades )
// Finish Research
set trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_RESEARCH_FINISH )
call TriggerAddAction( trg, function Finish_Research )
// Demolisher
set trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_PICKUP_ITEM )
call TriggerAddCondition( trg, Condition( function Conditions_Demolisher ) )
call TriggerAddAction( trg, function Demolisher )
// Dragon
set trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_PICKUP_ITEM )
call TriggerAddCondition( trg, Condition( function Conditions_Dragon ) )
call TriggerAddAction( trg, function Dragon )
// Iron Forged Swords
set Research_Array[1] = 'Rhme'
// Iron Plating
set Research_Array[2] = 'Rhar'
// Priest Adept Training
set Research_Array[3] = 'Rhpt'
// Caster Adept Training
set Research_Array[4] = 'Rhst'
// Strength of the Moon (Archers)
set Research_Array[5] = 'Resm'
// Moon Armor
set Research_Array[6] = 'Rema'
// Improved Bows
set Research_Array[7] = 'Reib'
// Improved Masonary
set Research_Array[8] = 'Rhac'
// Magic Sentry
set Research_Array[9] = 'Rhse'
set Research_Count = 9
set trg = null
endfunction
endlibrary
//TESH.scrollpos=15
//TESH.alwaysfold=0
scope PlayerLeavesGame initializer Init
private function Actions takes nothing returns nothing
local integer id = GetPlayerId(GetTriggerPlayer())
local unit u = Heroes[id]
call Game_Message("A player has left the game. AI will now take over control")
call SetPlayerController(GetTriggerPlayer(), MAP_CONTROL_COMPUTER)
call ForceAddPlayer( AI_Players, GetTriggerPlayer() )
set AI_Active = true
// Team 1
if ( IsPlayerAlly(GetTriggerPlayer(), Player(1)) == true ) then
call ForceAddPlayer( AI_Players_Team1, GetTriggerPlayer() )
call GroupAddUnit( AI_Heroes_Team1, u )
// Team 2
else
call ForceAddPlayer( AI_Players_Team2, GetTriggerPlayer() )
call GroupAddUnit( AI_Heroes_Team2, u )
endif
call GroupAddUnit( AI_Heroes, u )
// If AI Hero, then go to next waypoint
set waypoint_table[GetUnitId(u)] = 5
call Order_Unit_To_Next_WP( u )
set u = null
// Check, if we have an AI only team now
call AI_Only_Check()
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterPlayerEvent(trg, Player(2), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(trg, Player(3), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(trg, Player(4), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(trg, Player(5), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(trg, Player(6), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(trg, Player(7), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(trg, Player(8), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(trg, Player(9), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(trg, Player(10), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(trg, Player(11), EVENT_PLAYER_LEAVE)
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=3
//TESH.alwaysfold=0
scope Victory initializer Init
private function Conditions takes nothing returns boolean
return ( GetDyingUnit() == Base_Team1 or GetDyingUnit() == Base_Team2 )
endfunction
private function Defeat_Callback takes nothing returns nothing
call CustomDefeatBJ( GetEnumPlayer(), "The enemy team has defeated you!" )
endfunction
private function Victory_Callback takes nothing returns nothing
call CustomVictoryBJ( GetEnumPlayer(), true, true )
endfunction
private function Actions takes nothing returns nothing
// Team 1 wins
if GetDyingUnit() == Base_Team2 then
call ShowScores(1)
// call ForForce(Players_Team1, function Victory_Callback)
// call ForForce(Players_Team2, function Defeat_Callback)
endif
// Team 2 wins
if GetDyingUnit() == Base_Team1 then
call ShowScores(2)
// call ForForce(Players_Team1, function Defeat_Callback)
// call ForForce(Players_Team2, function Victory_Callback)
endif
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=16
//TESH.alwaysfold=0
scope HonorSystem initializer Init
private function CreepConditions takes nothing returns boolean
return GetOwningPlayer(GetTriggerUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE) and GetUnitLevel(GetTriggerUnit()) >= 6
endfunction
private function CreepHonor takes nothing returns nothing
local integer id = GetPlayerId(GetOwningPlayer(GetKillingUnit()))
local integer i = 1
if GetUnitLevel(GetTriggerUnit()) >= 9 then
set i = 2
endif
call Debug_Message("Creep Honor "+I2S(i))
if IsPlayerAlly( Player(id), Player(1)) then
call AddHonorArea(GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 1, id, i, i)
elseif IsPlayerAlly( Player(id), Player(0)) then
call AddHonorArea(GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 2, id, i, i)
endif
endfunction
private function BuildingConditions takes nothing returns boolean
return IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE)
endfunction
private function BuildingHonor takes nothing returns nothing
local integer id = GetPlayerId(GetOwningPlayer(GetKillingUnit()))
if IsPlayerAlly( GetOwningPlayer(GetTriggerUnit()), Player(0)) == true then
call AddHonorArea(GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 1, id, 1, 1)
elseif IsPlayerAlly(GetOwningPlayer(GetTriggerUnit()), Player(1)) == true then
call AddHonorArea(GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 2, id, 1, 1)
endif
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( trg, Condition( function BuildingConditions ) )
call TriggerAddAction( trg, function BuildingHonor )
// Creeps
set trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( trg, Condition( function CreepConditions ) )
call TriggerAddAction( trg, function CreepHonor )
set trg = null
endfunction
endscope
//TESH.scrollpos=338
//TESH.alwaysfold=0
library CaptureSystem initializer Init requires HeroSystem
globals
private constant real CAP_TIME = 15.0
private constant integer CAP_TICKS = 15
constant integer CAP_INCOME = 15
private constant integer CAP_POINTS = 3
private constant real CAP_TICK_TIME = 0.75
integer array CaptureProgress[1]
boolean array CaptureInProgress[1]
unit array CaptureUnits[1]
timer array CaptureTimers[1]
unit array CaptureBuildings[1]
unit array CaptureFlags[1]
unit array CaptureCircles[1]
string array CaptureCaptions[1]
// timerdialog array CaptureTimerWindows[1]
sound CaptureSound
sound CaptureSound_Done
endglobals
function PointIsHostile takes integer i, unit u returns boolean
if GetOwningPlayer(CaptureBuildings[i]) == Player(PLAYER_NEUTRAL_PASSIVE) then
return true
endif
if IsPlayerEnemy(GetOwningPlayer(CaptureBuildings[i]), GetOwningPlayer(u)) then
return true
endif
return false
endfunction
private function CreateCaptions takes nothing returns nothing
// Floating Text
call CreateTextTagLocBJ( CaptureCaptions[1], GetUnitLoc(CaptureBuildings[1]), 0, 14, 100.00, 100.00, 100.00, 0 )
call CreateTextTagLocBJ( CaptureCaptions[2], GetUnitLoc(CaptureBuildings[2]), 0, 14, 100.00, 100.00, 100.00, 0 )
call CreateTextTagLocBJ( CaptureCaptions[3], GetUnitLoc(CaptureBuildings[3]), 0, 14, 100.00, 100.00, 100.00, 0 )
endfunction
private function Hero_Reactivator_Callback takes nothing returns nothing
if GetUnitCurrentOrder(GetEnumUnit()) == Order_Stop and GetEnumUnit() != CaptureUnits[1] and GetEnumUnit() != CaptureUnits[2] and GetEnumUnit() != CaptureUnits[3] then
call Order_Unit_To_Next_WP(GetEnumUnit())
endif
endfunction
private function Hero_Reactivator takes nothing returns nothing
call ForGroup( AI_Heroes, function Hero_Reactivator_Callback )
endfunction
private function Gold_Tag takes unit TargetUnit, string Text returns nothing
local texttag t = CreateTextTag()
local string value
set Text = "|c00FFE57F" + Text + "|r"
call SetTextTagColor(t, 182, 91, 234, 255)
call SetTextTagText(t, Text, 0.03)
call SetTextTagPos(t, GetUnitX(TargetUnit), GetUnitY(TargetUnit), 0.00)
call SetTextTagVelocity(t, 0, 0.03)
call SetTextTagVisibility(t, true)
call SetTextTagFadepoint(t, 3)
call SetTextTagLifespan(t, 4)
call SetTextTagPermanent(t, false)
set t = null
endfunction
private function CreateCaptureTag takes unit u, string Text returns nothing
// local integer id = GetPlayerId(GetOwningPlayer(CaptureUnits[i]))
local texttag t = CreateTextTag()
call SetTextTagColor(t, 182, 91, 234, 255)
call SetTextTagText(t, Text, 0.03)
call SetTextTagPos(t, GetUnitX(u), GetUnitY(u), 0.00)
call SetTextTagVelocity(t, 0, 0.1)
call SetTextTagVisibility(t, true)
call SetTextTagFadepoint(t, 3)
call SetTextTagLifespan(t, 3)
call SetTextTagPermanent(t, false)
set t = null
endfunction
private function Income_Team1 takes integer i returns nothing
call SetPlayerState(Player(1), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(1), PLAYER_STATE_RESOURCE_GOLD) + i )
call SetPlayerState(Player(2), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(2), PLAYER_STATE_RESOURCE_GOLD) + i )
call SetPlayerState(Player(6), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(6), PLAYER_STATE_RESOURCE_GOLD) + i )
call SetPlayerState(Player(8), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(8), PLAYER_STATE_RESOURCE_GOLD) + i )
call SetPlayerState(Player(9), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(9), PLAYER_STATE_RESOURCE_GOLD) + i )
call SetPlayerState(Player(10), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(10), PLAYER_STATE_RESOURCE_GOLD) + i )
endfunction
private function Income_Team2 takes integer i returns nothing
call SetPlayerState(Player(0), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(0), PLAYER_STATE_RESOURCE_GOLD) + i )
call SetPlayerState(Player(3), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(3), PLAYER_STATE_RESOURCE_GOLD) + i )
call SetPlayerState(Player(4), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(4), PLAYER_STATE_RESOURCE_GOLD) + i )
call SetPlayerState(Player(5), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(5), PLAYER_STATE_RESOURCE_GOLD) + i )
call SetPlayerState(Player(7), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(7), PLAYER_STATE_RESOURCE_GOLD) + i )
call SetPlayerState(Player(11), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(11), PLAYER_STATE_RESOURCE_GOLD) + i )
endfunction
private function Income takes nothing returns nothing
local integer i
// Cycle through all points
set i = 1
loop
exitwhen i > CAP_POINTS
// call Debug_Message("Cap Building :"+I2S(i))
// Team 1
if ( GetOwningPlayer(CaptureBuildings[i]) == Player(1)) then
call Income_Team1(CAP_INCOME)
call Gold_Tag(CaptureBuildings[i], "+" + I2S(CAP_INCOME)) // NumberOfPlayersTeam1
endif
if ( GetOwningPlayer(CaptureBuildings[i]) == Player(0)) then
call Income_Team2(CAP_INCOME)
call Gold_Tag(CaptureBuildings[i], "+" + I2S(CAP_INCOME))
endif
set i = i + 1
endloop
// Give Gold for Bases
call Income_Team1(CAP_INCOME)
call Gold_Tag(Base_Team1, "+" + I2S(CAP_INCOME))
call Income_Team2(CAP_INCOME)
call Gold_Tag(Base_Team2, "+" + I2S(CAP_INCOME))
endfunction
function Capture_Abort takes integer i returns boolean
local integer id = GetPlayerId(GetOwningPlayer(CaptureUnits[i]))
call CreateCaptureTag(CaptureUnits[i], "|c00F83232Capture aborted!|r" )
call ReleaseTimer(CaptureTimers[i])
set CaptureInProgress[i] = false
set CaptureProgress[i] = CAP_TICKS
set CaptureUnits[i] = null
call StartSoundForPlayerBJ(Player(id), CaptureSound)
return true
endfunction
private function Check_Unit takes unit u returns boolean
local integer id
set id = 1
loop
exitwhen id > CAP_POINTS
if ( u == CaptureUnits[id] ) then
set u = null
return true
endif
set id = id + 1
endloop
set u = null
return false
endfunction
private function Get_Waypoint_After_Capture takes unit u, integer id returns integer
local integer i = 0
// Tavern
if id == 1 then
set i = 4
endif
// Lumber Mill
if id == 2 then
set i = 14
endif
// Farm
if id == 3 then
set i = 24
endif
return i
endfunction
private function Assist_Conditions takes nothing returns boolean
return ( IsUnitType(GetEnumUnit(), UNIT_TYPE_STRUCTURE) == true )
endfunction
private function GiveHonor takes nothing returns nothing
local integer id = GetPlayerId(GetOwningPlayer(GetEnumUnit()))
call Add_Honor(id, 1)
endfunction
private function Capture_Success takes integer i returns nothing
local unit u = CaptureUnits[i]
local integer id = GetPlayerId(GetOwningPlayer(CaptureUnits[i]))
local group allies = NewGroup()
// call ReleaseTimer(CaptureTimers[i])
call Debug_Message("Capture done "+I2S(i))
set CaptureInProgress[i] = false
if ( IsPlayerAlly(GetOwningPlayer(CaptureUnits[i]), Player(1)) == true ) then
call SetUnitOwner( CaptureBuildings[i], Player(1), true )
call SetUnitOwner( CaptureFlags[i], Player(1), true )
call AddHonorArea(GetUnitX(CaptureUnits[i]), GetUnitY(CaptureUnits[i]), 1, id, 1, 1)
else
call SetUnitOwner( CaptureBuildings[i], Player(0), true )
call SetUnitOwner( CaptureFlags[i], Player(0), true )
call AddHonorArea(GetUnitX(CaptureUnits[i]), GetUnitY(CaptureUnits[i]), 2, id, 1, 1)
endif
// +1 Honor Point
// call Add_Honor(id, 1)
// Get allies in range and give honor
call GroupEnumUnitsInRange(allies, GetUnitX(u), GetUnitY(u), GENERIC_ASSIST_RANGE, Condition(function Assist_Conditions))
call ForGroup( allies, function GiveHonor )
call CreateCaptureTag(u, "|c00BDF1A9Point captured!|r" )
// + XP
// call DES_MOCO_AddDirectXP(CaptureUnits[id], 75)
// Team 1
if ( IsPlayerAlly(GetOwningPlayer(CaptureUnits[i]), Player(1)) == true ) then
call Team_Message(1, TEAM1 + "captured the " + CaptureCaptions[i])
// Team 2
else
call Team_Message(2, TEAM2 + "captured the " + CaptureCaptions[i])
endif
// AI
if ( IsUnitInGroup(CaptureUnits[i], AI_Heroes) == true ) then
set waypoint_table[GetUnitId(CaptureUnits[i])] = Get_Waypoint_After_Capture(CaptureUnits[i], i)
call Order_Unit_To_Next_WP(CaptureUnits[i])
endif
call StartSound(CaptureSound_Done)
set CaptureUnits[i] = null
call ReleaseGroup(allies)
set allies = null
set u = null
endfunction
private function Capture_Callback takes nothing returns nothing
local integer i = GetTimerData(GetExpiredTimer())
local integer id = GetPlayerId(GetOwningPlayer(CaptureUnits[i]))
if CaptureProgress[i] <= 0 then
call ReleaseTimer(GetExpiredTimer())
call Capture_Success(i)
else
call CreateCaptureTag(CaptureUnits[i], "|c00" + PlayerColors[id] + I2S(CaptureProgress[i]) + "|r" )
set CaptureProgress[i] = CaptureProgress[i] - 1
endif
endfunction
function Capture_AI takes integer i returns nothing
call TriggerSleepAction(.5)
// call IssuePointOrder( CaptureUnits[i], "patrol", GetUnitX(CaptureCircles[i])-16, GetUnitY(CaptureCircles[i])-16 )
// set waypoint_table[GetUnitId(CaptureUnits[i])] = 60+i
call IssueImmediateOrder( CaptureUnits[i], "holdposition" )
call Debug_Message("Capture AI: "+I2S(i)+" "+GetUnitName(CaptureUnits[i]))
endfunction
private function Capture_Start takes integer i, unit u returns nothing
local integer id = GetPlayerId(GetOwningPlayer(u))
set CaptureInProgress[i] = true
set CaptureUnits[i] = u
set CaptureProgress[i] = CAP_TICKS
call CreateCaptureTag(u, "|c00FDD484Capture started!|r" )
// If Capture Unit is AI, then make it hold position
if ( IsUnitInGroup(u, AI_Heroes) == true ) then
call Capture_AI(i)
endif
// Team 1
if ( IsPlayerAlly(GetOwningPlayer(CaptureUnits[i]), Player(0)) == true ) and ( GetOwningPlayer(CaptureBuildings[i]) == Player(1)) then
call Team_Message(1, "The |cffFF1C1Cenemy|r is capturing your points! (" + CaptureCaptions[i] + ")")
endif
// Team 2
if ( IsPlayerAlly(GetOwningPlayer(CaptureUnits[i]), Player(1)) == true ) and ( GetOwningPlayer(CaptureBuildings[i]) == Player(0)) then
call Team_Message(2, "The |cffFF1C1Cenemy|r is capturing your points! (" + CaptureCaptions[i] + ")")
endif
// Start timer
set CaptureTimers[i] = NewTimer()
call SetTimerData(CaptureTimers[i], i)
call TimerStart(CaptureTimers[i], CAP_TICK_TIME, true, function Capture_Callback)
call StartSoundForPlayerBJ(Player(id), CaptureSound)
endfunction
function Capture_Enter takes integer i returns boolean
// call Debug_Message("On enter "+I2S(i))
// Triggering unit has to be a hero
if IsHero(GetTriggerUnit()) == false then
return false
endif
// Only works if point neutral or hostile
if PointIsHostile(i, GetTriggerUnit()) == false then
return false
endif
if UnitHasBuff(GetTriggerUnit(), BUFF_TYPE_STEALTH) then
call DisplayTimedTextToPlayer(GetOwningPlayer(GetTriggerUnit()),0,0,5,"|cffFF6A6AYou cannot capture while in stealth mode!|r")
return false
endif
// No capturing in progess
if ( CaptureInProgress[i] == false ) then
call Capture_Start(i,GetTriggerUnit())
endif
return true
endfunction
// =====================================================
private function Init takes nothing returns nothing
local integer i = 1
local trigger trg = CreateTrigger( )
call TriggerRegisterTimerEvent(trg, 5.00, true)
call TriggerAddAction( trg, function Income )
// Hero Reactivator
set trg = CreateTrigger( )
call TriggerRegisterTimerEvent(trg, 5.00, true)
call TriggerAddAction(trg, function Hero_Reactivator)
// Init Capture Timers
set i = 1
loop
exitwhen i > CAP_POINTS
set CaptureTimers[i] = NewTimer()
set i = i + 1
endloop
// init Sound
call Preload( "Sound\\Interface\\QuestLog.wav" )
call Preload( "Sound\\Interface\\ArrangedTeamInvitation.wav" )
set CaptureSound = CreateSound("Sound\\Interface\\QuestLog.wav", false, false, true, 12700, 12700, "")
set CaptureSound_Done = CreateSound("Sound\\Interface\\ArrangedTeamInvitation.wav", false, false, true, 12700, 12700, "")
// Tavern
set CaptureCaptions[1] = "|cffCFEE93Tavern|r"
set CaptureBuildings[1] = gg_unit_n004_0021
set CaptureFlags[1] = gg_unit_h000_0011
set CaptureCircles[1] = gg_unit_ncp2_0003
// Lumber mill
set CaptureCaptions[2] = "|cffBBA48FLumber Mill|r"
set CaptureBuildings[2] = gg_unit_hlum_0037
set CaptureFlags[2] = gg_unit_h000_0019
set CaptureCircles[2] = gg_unit_ncp2_0020
// Farm
set CaptureCaptions[3] = "|cffFF9A40Farm|r"
set CaptureBuildings[3] = gg_unit_hhou_0015
set CaptureFlags[3] = gg_unit_h000_0016
set CaptureCircles[3] = gg_unit_ncp2_0001
set trg = CreateTrigger( )
call TriggerRegisterTimerEvent(trg, 5.00, false)
call TriggerAddAction( trg, function CreateCaptions )
set trg = null
endfunction
endlibrary
//TESH.scrollpos=36
//TESH.alwaysfold=0
scope Tavern initializer Init
globals
private constant integer ID = 1
endglobals
private function Conditions_AI takes nothing returns boolean
// AI Hero
if not IsUnitInGroup(GetTriggerUnit(), AI_Heroes) == true then
return false
endif
// Building already taken?
if IsPlayerAlly(GetOwningPlayer(CaptureBuildings[ID]), GetOwningPlayer(GetTriggerUnit())) == true then
if ( not (GetOwningPlayer(CaptureBuildings[ID]) == Player(PLAYER_NEUTRAL_PASSIVE)) ) then
return false
endif
endif
return true
endfunction
private function AI_Actions takes nothing returns nothing
call Debug_Message("Tavern AI in range..")
call IssuePointOrderLoc( GetTriggerUnit(), "move", GetUnitLoc(CaptureCircles[ID]) )
endfunction
private function Conditions_Break takes nothing returns boolean
if not (GetTriggerUnit() == CaptureUnits[ID] )then
return false
endif
if not ( CaptureInProgress[ID] ) then
return false
endif
return true
endfunction
private function Break takes nothing returns nothing
call Capture_Abort(ID)
endfunction
private function Enter takes nothing returns nothing
call Capture_Enter(ID)
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
// Enter
call TriggerRegisterEnterRectSimple( trg, gg_rct_Tavern )
call TriggerAddAction( trg, function Enter )
// Break
set trg = CreateTrigger()
call TriggerRegisterLeaveRectSimple( trg, gg_rct_Tavern )
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( trg, Condition( function Conditions_Break ) )
call TriggerAddAction( trg, function Break )
// AI
// set trg = CreateTrigger()
// call TriggerRegisterUnitInRangeSimple( trg, 2400.00, gg_unit_ncp2_0003 )
// call TriggerAddCondition( trg, Condition( function Conditions_AI ) )
// call TriggerAddAction( trg, function AI_Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=35
//TESH.alwaysfold=0
scope LumberMill initializer Init
globals
private constant integer ID = 2
endglobals
private function Conditions_AI takes nothing returns boolean
// AI Hero
if not IsUnitInGroup(GetTriggerUnit(), AI_Heroes) == true then
return false
endif
// Building already taken?
if IsPlayerAlly(GetOwningPlayer(CaptureBuildings[ID]), GetOwningPlayer(GetTriggerUnit())) == true then
if ( not (GetOwningPlayer(CaptureBuildings[ID]) == Player(PLAYER_NEUTRAL_PASSIVE)) ) then
return false
endif
endif
return true
endfunction
private function AI_Actions takes nothing returns nothing
call IssuePointOrderLoc( GetTriggerUnit(), "move", GetUnitLoc(CaptureCircles[ID]) )
endfunction
private function Conditions_Break takes nothing returns boolean
if not (GetTriggerUnit() == CaptureUnits[ID] )then
return false
endif
if not ( CaptureInProgress[ID] ) then
return false
endif
return true
endfunction
private function Break takes nothing returns nothing
call Capture_Abort(ID)
endfunction
private function Enter takes nothing returns nothing
call Capture_Enter(ID)
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
// Enter
call TriggerRegisterEnterRectSimple( trg, gg_rct_LumberMill )
call TriggerAddAction( trg, function Enter )
// Break
set trg = CreateTrigger()
call TriggerRegisterLeaveRectSimple( trg, gg_rct_LumberMill )
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( trg, Condition( function Conditions_Break ) )
call TriggerAddAction( trg, function Break )
// AI
// set trg = CreateTrigger()
// call TriggerRegisterUnitInRangeSimple( trg, 2400.00, gg_unit_ncp2_0020 )
// call TriggerAddCondition( trg, Condition( function Conditions_AI ) )
// call TriggerAddAction( trg, function AI_Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=40
//TESH.alwaysfold=0
scope Farm initializer Init
globals
private constant integer ID = 3
endglobals
private function Conditions_AI takes nothing returns boolean
// AI Hero
if not IsUnitInGroup(GetTriggerUnit(), AI_Heroes) == true then
return false
endif
// Building already taken?
if IsPlayerAlly(GetOwningPlayer(CaptureBuildings[ID]), GetOwningPlayer(GetTriggerUnit())) == true then
if ( not (GetOwningPlayer(CaptureBuildings[ID]) == Player(PLAYER_NEUTRAL_PASSIVE)) ) then
return false
endif
endif
return true
endfunction
private function AI_Actions takes nothing returns nothing
call IssuePointOrderLoc( GetTriggerUnit(), "move", GetUnitLoc(CaptureCircles[ID]) )
endfunction
private function Conditions_Break takes nothing returns boolean
if not (GetTriggerUnit() == CaptureUnits[ID] )then
return false
endif
if not ( CaptureInProgress[ID] ) then
return false
endif
return true
endfunction
private function Break takes nothing returns nothing
call Capture_Abort(ID)
endfunction
private function Conditions_Enter takes nothing returns boolean
return GetTriggerUnit() != CaptureUnits[ID]
endfunction
private function Enter takes nothing returns nothing
call Capture_Enter(ID)
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
// Enter
call TriggerRegisterEnterRectSimple( trg, gg_rct_Farm )
call TriggerAddCondition( trg, Condition( function Conditions_Enter ) )
call TriggerAddAction( trg, function Enter )
// Break
set trg = CreateTrigger()
call TriggerRegisterLeaveRectSimple( trg, gg_rct_Farm )
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( trg, Condition( function Conditions_Break ) )
call TriggerAddAction( trg, function Break )
// AI
// set trg = CreateTrigger()
// call TriggerRegisterUnitInRangeSimple( trg, 2400.00, gg_unit_ncp2_0001 )
// call TriggerAddCondition( trg, Condition( function Conditions_AI ) )
// call TriggerAddAction( trg, function AI_Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=268
//TESH.alwaysfold=0
library SpellTable initializer Init requires TimerUtils
globals
private constant integer SPELL_MAX = 256
private integer Spell_Count = 0
spell array spells[1]
Table SpellTab
integer EFFECT_ID = 0
constant integer MAX_EFFECTS = 256
effect array EffectTable[1]
// Shared
constant real RANDOM_DAMAGE_MIN = 0.95
constant real RANDOM_DAMAGE_MAX = 1.05
constant real GENERIC_AOE_RANGE = 400.00
constant real GENERIC_DOT_INTERVAL = 1.3 // 1.2
constant real GENERIC_BUFF_DURATION = 20.00
constant real DISPEL_RADIUS = 256.00 // area dispel
// Warrior
constant real CHARGE_DAMAGE = 4.00
constant real SHIELD_SLAM_DAMAGE = 1.75
constant real SLAM_RANGE = 300.00
// Mage
constant real FROST_BOLT_DAMAGE = 3.00
constant real FREEZING_CHANCE = 30
constant real FREEZE_DURATION = 3.00
constant real FIRE_NOVA_DAMAGE = 2.25
constant real ICE_BARRIER_HEALTH = 8.00
constant real ICE_BARRIER_DURATION = 30.00
constant real SHEEP_DURATION = 5.00
// Druid
constant real MOON_FIRE_DAMAGE = 3.00
constant real REJUVENATION_HEALTH_PER_TICK = 1.0
constant real REJUVENATION_TICKS = 8.00
constant real MARKOFTHEWILD_HEALTH_BONUS = 10.00
constant real MARKOFTHEWILD_MANA_BONUS = 10.00
constant real MARKOFTHEWILD_ARMOR_BONUS = 1.00 // 0.20
constant real ROOTS_DAMAGE = 1.00
constant real ROOTS_TICKS = 3.00
constant real CLAW_STRIKE_DAMAGE = 3.00
constant real BASH_DAMAGE = 1.50
// Priest
constant real SHIELD_LIFE = 7.50
constant real SHIELD_DURATION = 30.00
constant real HOLY_NOVA_POWER = 2.50
constant real FEAR_TICKS = 5.00
constant real HEALING_TOUCH_POWER = 4.50
constant real MANA_BURN_DAMAGE = 2.00
constant real SHADOW_WORD_TICKS = 8.00
constant real SHADOW_WORD_DAMAGE = 0.75
constant real FEAR_MAX_TARGETS = 5
// Paladin
constant real HOLY_LIGHT_POWER = 5.00
constant real PURGE_POWER = 2.75
constant real PURGE_MOVEMENT_FACTOR = 0.50
constant real PURGE_DURATION = 3.00
constant real CALL_OF_JUSTICE_DAMAGE = 2.0
// Shaman
constant real EARTH_SHOCK_DAMAGE = 3.0
constant real HEALING_WAVE_POWER = 4.5
constant integer HEALING_WAVE_MAX_TARGETS = 4
constant real HEALING_WAVE_LOSS_FACTOR = 0.75
constant real FIRE_AND_ICE_FACTOR = 0.15
constant real FIRE_AND_ICE_DURATION = 30.00
constant real TOTEM_DURATION = 15.00
// Rogue
constant real FAN_OF_KNIVES_DAMAGE = 1.50
constant real DEADLY_STRIKE_DAMAGE = 2.00
constant real DEADLY_STRIKE_TICKS = 5.00
constant real DEADLY_STRIKE_TICK_FACTOR = 0.3 // tick damage is multiplied with this factor
constant real BACKSTAB_DAMAGE = 3.25
constant real STEALTH_DURATION = 30.00
// Hunter
constant real CRITICAL_SHOT_DAMAGE = 3.00
constant real CRITICAL_SHOT_TICKS = 3.00
constant real CRITICAL_SHOT_TICK_FACTOR = 0.30
constant real CRITICAL_SHOT_MOVEMENT_FACTOR = 0.7
constant real MULTI_SHOT_DAMAGE = 2.00
constant real MULTI_SHOT_RANGE = 200
// Necromancer
constant real SOUL_SHIELD_HEALTH = 5.00
constant real SOUL_SHIELD_DURATION = 30.00
constant real SOUL_SHIELD_HARVEST_PERCENT = 25.00
constant real VAMPIRIC_CURSE_TICKS = 7.00
constant real VAMPIRIC_CURSE_DAMAGE = 1.00
constant real VAMPIRIC_CURSE_HEALTH_FACTOR = 0.5
constant real DARK_CONSUMPTION_DAMAGE = 1.00
constant integer DARK_CONSUMPTION_TICKS = 5
constant real DARK_CONSUMPTION_RANGE = 200
// constant real BRUTAL_STRIKE_DAMAGE = 2.50
// constant real BRUTAL_STRIKE_TICKS = 3.00
// constant real BRUTAL_STRIKE_TICK_FACTOR = 0.3
constant real BEYOND_DEATH_DAMAGE = 2.00
constant real BEYOND_DEATH_DURATION = 15.00
// Ent
constant real ROCK_DAMAGE = 3.0
constant real BEAM_DAMAGE = 2.5
// Other
constant real FLAME_SHOCK_DAMAGE = 5.00
endglobals
struct spell
integer id = 0
unit caster = null
unit target = null
real x = 0
real y = 0
location loc = null
real damage = 0.0
boolean isCrit = false
real health = 0.0
real mana = 0.0
real armor = 0.0
real speed = 0.0
integer ticks = 0
integer effect_id = 0
method onDestroy takes nothing returns nothing
call RemoveLocation(.loc)
endmethod
endstruct
function GetSpellCaster takes integer id returns unit
return spells[id].caster
endfunction
function GetSpellTarget takes integer id returns unit
return spells[id].target
endfunction
function GetSpellDamage takes integer id returns real
return spells[id].damage
endfunction
function GetSpellLocation takes integer id returns location
return spells[id].loc
endfunction
function GetSpellHealth takes integer id returns real
return spells[id].health
endfunction
function GetSpellMana takes integer id returns real
return spells[id].mana
endfunction
function GetSpellCrit takes integer id returns boolean
return spells[id].isCrit
endfunction
function GetSpellTicks takes integer id returns integer
return spells[id].ticks
endfunction
function GetSpellEffectId takes integer id returns integer
return spells[id].effect_id
endfunction
function SetSpellEffectId takes integer id, integer value returns nothing
set spells[id].effect_id = value
endfunction
function GetRandomSpellMod takes nothing returns real
return GetRandomReal(RANDOM_DAMAGE_MIN, RANDOM_DAMAGE_MAX)
endfunction
function GetSpell takes integer id returns spell
return spells[id]
endfunction
function IncSpellTicks takes integer id returns nothing
set spells[id].ticks = spells[id].ticks + 1
endfunction
function ReleaseEffect takes integer id returns nothing
if EffectTable[id ] != null then
call DestroyEffect(EffectTable[id ])
set EffectTable[id ] = null
// call Debug_Message("Destroy Effect id "+I2S(id))
endif
endfunction
function SetMoveSpeed takes unit u returns nothing
local real normal_speed = GetUnitDefaultMoveSpeed(u)
call SetUnitMoveSpeed(u, normal_speed)
// Purge
if UnitHasBuff(u, BUFF_TYPE_PURGE) then
call SetUnitMoveSpeed( u, GetUnitDefaultMoveSpeed(u)*PURGE_MOVEMENT_FACTOR )
endif
// Critical Shot
if UnitHasBuff(u, BUFF_TYPE_CRITICAL_SHOT) then
call SetUnitMoveSpeed( u, GetUnitDefaultMoveSpeed(u)*CRITICAL_SHOT_MOVEMENT_FACTOR )
endif
// Roots
if UnitHasBuff(u, BUFF_TYPE_ROOTS) then
call SetUnitMoveSpeed(u, 0)
endif
// Frozen
if UnitHasBuff(u, BUFF_TYPE_FROZEN) then
call SetUnitMoveSpeed(u, 0)
endif
endfunction
private function RegisterEffectTimerCallback takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
// call Debug_Message("Release Effect Timer Callback id "+I2S(id))
call ReleaseTimer(t)
call ReleaseEffect(id)
set t = null
endfunction
// Effects with timed life are automatically destroyed
function RegisterEffect takes effect e, real lifespan returns integer
local timer t
local integer id = EFFECT_ID
// If an old effect hasn't cleaned up -> destroy
if EffectTable[id] != null then
call DestroyEffect(EffectTable[id])
endif
// Store Effect and inc ID
set EffectTable[id] = e
if EFFECT_ID < MAX_EFFECTS - 1 then
set EFFECT_ID = EFFECT_ID + 1
else
set EFFECT_ID = 0
endif
// Timed life?
if lifespan > 0 then
set t = NewTimer()
call SetTimerData(t, id)
call TimerStart(t, lifespan, false, function RegisterEffectTimerCallback)
endif
// call Debug_Message("Effect registered, id: "+I2S(id))
set t = null
return id
endfunction
function ReleaseSpell takes integer id returns nothing
call spell.destroy(spells[id])
// call Debug_Message("Spell released: "+I2S(id))
endfunction
function RegisterSpell takes unit caster, unit target, location loc, real damage, boolean crit, real health, real mana, real armor, real speed, integer ticks, integer effect_id returns integer
local spell thisSpell = spell.create()
set thisSpell.id = Spell_Count // SetSpellId()
set thisSpell.caster = caster
set thisSpell.target = target
set thisSpell.loc = loc
set thisSpell.damage = damage
set thisSpell.isCrit = crit
set thisSpell.health = health
set thisSpell.mana = mana
set thisSpell.armor = armor
set thisSpell.speed = speed
set thisSpell.ticks = ticks
set thisSpell.effect_id = effect_id
if Spell_Count >= SPELL_MAX-1 then
set Spell_Count = 0
else
set Spell_Count = Spell_Count + 1
endif
set spells[thisSpell.id] = thisSpell
// call Debug_Message("Spell registered: "+I2S(thisSpell.id))
return thisSpell.id
endfunction
private function Init takes nothing returns nothing
set SpellTab = Table.create()
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Preload_Actions takes nothing returns nothing
endfunction
//===========================================================================
function InitTrig_Preload takes nothing returns nothing
set gg_trg_Preload = CreateTrigger( )
call TriggerAddAction( gg_trg_Preload, function Trig_Preload_Actions )
call Debug_Message("Preload Abilities")
call AbilityPreload('A04T')
call AbilityPreload('A05G')
call AbilityPreload('A043')
call AbilityPreload('A03J')
call AbilityPreload('A03R')
call AbilityPreload('A04K')
call AbilityPreload('A022')
call AbilityPreload('A04L')
call AbilityPreload('A00H')
call AbilityPreload('A02H')
call AbilityPreload('S001')
call AbilityPreload('A011')
call AbilityPreload('A004')
call AbilityPreload('A01O')
call AbilityPreload('A077')
call AbilityPreload('A06Z')
call AbilityPreload('A00J')
call AbilityPreload('A04H')
call AbilityPreload('A04D')
call AbilityPreload('A01A')
call AbilityPreload('A00W')
call AbilityPreload('A05N')
call AbilityPreload('A07E')
call AbilityPreload('A054')
call AbilityPreload('A008')
call AbilityPreload('A066')
call AbilityPreload('A00T')
call AbilityPreload('A02I')
call AbilityPreload('A03Q')
call AbilityPreload('A02K')
call AbilityPreload('A06K')
call AbilityPreload('A020')
call AbilityPreload('A07A')
call AbilityPreload('A04Q')
call AbilityPreload('A03Z')
call AbilityPreload('A00K')
call AbilityPreload('A03O')
call AbilityPreload('A016')
call AbilityPreload('A013')
call AbilityPreload('A007')
call AbilityPreload('A03D')
call AbilityPreload('A04V')
call AbilityPreload('A03W')
call AbilityPreload('A026')
call AbilityPreload('A044')
call AbilityPreload('A03V')
call AbilityPreload('A01F')
call AbilityPreload('A03H')
call AbilityPreload('A03E')
call AbilityPreload('A03B')
call AbilityPreload('A063')
call AbilityPreload('A030')
call AbilityPreload('A039')
call AbilityPreload('A04E')
call AbilityPreload('A00U')
call AbilityPreload('A02V')
call AbilityPreload('A04R')
call AbilityPreload('A074')
call AbilityPreload('A04A')
call AbilityPreload('A04B')
call AbilityPreload('A02Y')
call AbilityPreload('A00F')
call AbilityPreload('A02J')
call AbilityPreload('A04O')
call AbilityPreload('A04M')
call AbilityPreload('A03L')
call AbilityPreload('A00E')
call AbilityPreload('A031')
call AbilityPreload('A025')
call AbilityPreload('A00Y')
call AbilityPreload('A03A')
call AbilityPreload('A00Z')
call AbilityPreload('A037')
call AbilityPreload('A04X')
call AbilityPreload('A049')
call AbilityPreload('A03G')
call AbilityPreload('A03K')
call AbilityPreload('A03I')
call AbilityPreload('A03C')
call AbilityPreload('A018')
call AbilityPreload('A04S')
call AbilityPreload('A03M')
call AbilityPreload('A040')
call AbilityPreload('A051')
call AbilityPreload('A056')
call AbilityPreload('A06E')
call AbilityPreload('A069')
call AbilityPreload('A05H')
call AbilityPreload('A04Y')
call AbilityPreload('A005')
call AbilityPreload('A02S')
call AbilityPreload('A033')
call AbilityPreload('A032')
call AbilityPreload('A05L')
call AbilityPreload('A06G')
call AbilityPreload('A02Z')
call AbilityPreload('A064')
call AbilityPreload('A06D')
call AbilityPreload('A00V')
call AbilityPreload('A04P')
call AbilityPreload('A019')
endfunction
//TESH.scrollpos=49
//TESH.alwaysfold=0
scope CriticalStrike initializer Init
globals
private constant integer MAX_HANDLE_NO = 8190
private constant integer MIN_HANDLE_ID = 0x100000
private boolean array Flag[MAX_HANDLE_NO]
endglobals
private function H2I takes handle h returns integer
return GetHandleId(h)
endfunction
private function Conditions takes nothing returns boolean
return GetTriggerDamageType() == DAMAGE_TYPE_ATTACK and IsPlayerInForce(GetOwningPlayer(GetTriggerDamageSource()), Players) == true
//IsUnitType(GetTriggerDamageSource(), UNIT_TYPE_HERO) == true
endfunction
private function Actions takes nothing returns nothing
local unit u = GetTriggerDamageSource()
local unit t = GetTriggerDamageTarget()
local real d = GetTriggerDamage()
local integer id = GetPlayerId(GetOwningPlayer(u))
// call Debug_Message("Damage_Event")
// crit
if Flag[H2I(GetTriggerDamageSource())-MIN_HANDLE_ID] or UnitHasBuff(u, BUFF_TYPE_STEALTH) then
//Deals +100%/200%/300%/etc damage
// debug call BJDebugMsg("Critical Strike has a |cff00ffff"+I2S(pr)+"|r priority which should fire a |cff00ffff5|r-PR trigger!")
call CreateDamageTag(u, t, d*CRIT_FACTOR, true, false)
call UnitDamageTargetEx(u, t, ((d*CRIT_FACTOR)-d), ATTACK_TYPE_HERO, DAMAGE_TYPE_EXTRA, true, true)
// call IncScoreDamage(id, d*CRIT_FACTOR)
set Flag[H2I(u)-MIN_HANDLE_ID] = false
else
call CreateDamageTag(u, t, d, false, false)
// call IncScoreDamage(id, d)
endif
// set te = null
set u = null
set t = null
endfunction
private function Atk_Conditions takes nothing returns boolean
return IsUnitType(GetAttacker(), UNIT_TYPE_HERO) == true
endfunction
private function Atk_Actions takes nothing returns nothing
local unit u = GetAttacker()
// Crit
//call CoreSystem_Debug_Message("Atk_actions")
if GetRandomReal(1, 100) <= GetCritChance(u) then
set Flag[H2I(u)-MIN_HANDLE_ID] = true
else
set Flag[H2I(u)-MIN_HANDLE_ID] = false
endif
if UnitHasBuff(u, BUFF_TYPE_STEALTH) then
call UnitRemoveBuff(u, BUFF_TYPE_STEALTH)
set Flag[H2I(u)-MIN_HANDLE_ID] = true
endif
set u = null
endfunction
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerAddAction(trg, function Actions)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerRegisterDamageEvent(trg, 1)
set trg = CreateTrigger()
call TriggerAddAction(trg, function Atk_Actions)
call TriggerAddCondition(trg, Condition(function Atk_Conditions))
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_ATTACKED)
set trg = null
endfunction
endscope
//TESH.scrollpos=9
//TESH.alwaysfold=0
scope StaffOfTeleportation initializer Init
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'AImt'
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local location t = GetSpellTargetLoc()
local integer id = GetPlayerId(GetOwningPlayer(u))
call TriggerSleepAction(3.1)
set t = GetUnitLoc(u)
if Water_Elementals[id] != null then
call SetUnitPositionLoc( Water_Elementals[id], t )
endif
if Pets[id] != null then
call SetUnitPositionLoc( Pets[id], t )
endif
if UnholySpirits[id] != null then
call SetUnitPositionLoc( UnholySpirits[id], t )
endif
if Dragons[id] != null then
call SetUnitPositionLoc( Dragons[id], t )
endif
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=97
//TESH.alwaysfold=0
scope FrostBolt initializer Init
globals
private constant integer AbilID = 'A00U'
//Buff stuff
integer BUFF_TYPE_FROZEN
private integer AuraID = 'A02V'
private integer BuffID = 'B014'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
local unit t = db.target
local integer spell_id = db.data
local integer effect_id = GetSpellEffectId(spell_id)
// Release effect
call ReleaseEffect(effect_id)
// ReleaseSpell
call ReleaseSpell(spell_id)
// Reset Movement speed
call SetMoveSpeed(t)
set t = null
endfunction
private function Damage_Callback takes nothing returns nothing
local timer ti = GetExpiredTimer()
local dbuff db = 0
// Get Spell Data
local integer spell_id = GetTimerData(ti)
local unit u = GetSpellCaster(spell_id)
local unit t = GetSpellTarget(spell_id)
local boolean crit = GetSpellCrit(spell_id)
local real d = GetSpellDamage(spell_id)
local effect e
local integer effect_id
// Release Timer
call ReleaseTimer(ti)
set ti = null
if GetUnitState(t, UNIT_STATE_LIFE) > 0 then
// Damage
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
// Frost buff
if Chance(FREEZING_CHANCE) and GetUnitState(t, UNIT_STATE_LIFE)>0 then
// Remove old buff
if UnitHasBuff(t, BUFF_TYPE_FROZEN) then
call UnitRemoveBuff(t, BUFF_TYPE_FROZEN)
endif
// Apply the buff
set db = UnitAddBuff(u, t, BUFF_TYPE_FROZEN, FREEZE_DURATION, 1)
set db.data = spell_id
call SetMoveSpeed(t)
set e = AddSpecialEffectTarget("FrostNova.mdl", t, "origin")
set effect_id = RegisterEffect(e, 0)
call SetSpellEffectId(spell_id, effect_id)
else
call ReleaseSpell(spell_id)
endif
endif
set e = null
set u = null
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local integer spell_id
local real dx = GetUnitX(u) - GetUnitX(t)
local real dy = GetUnitY(u) - GetUnitY(t)
local real dist = SquareRoot(dx * dx + dy * dy)
local real projectile_time = dist * 0.0005
local timer ti = NewTimer()
// Spell damage
set d = FROST_BOLT_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Register spell
set spell_id = RegisterSpell(u, t, null, d, crit, 0,0,0,0,0,0)
// Damage Callback
call SetTimerData(ti, spell_id)
call TimerStart(ti, projectile_time, false, function Damage_Callback)
// Cleanup
set u = null
set t = null
set ti = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
set BUFF_TYPE_FROZEN = DefineBuffType(AuraID, BuffID, 0, false, false, 0, 0, OnEnd)
// takes integer AbilId, integer BuffId, real period, boolean isPeriodic, boolean isPositive, callback onAdd, callback onPeriodic, callback onEnd returns integer
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=27
//TESH.alwaysfold=0
scope FireNova initializer Init
globals
private constant integer AbilID = 'A00J'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Target_Conditions takes nothing returns boolean
return IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(GetSpellAbilityUnit())) == true and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local group targets = NewGroup()
// Spell damage
set d = FIRE_NOVA_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Get targets
call GroupEnumUnitsInRange(targets, GetUnitX(u), GetUnitY(u), GENERIC_AOE_RANGE, Condition(function Target_Conditions))
// Burn them
loop
set t = FirstOfGroup(targets)
exitwhen t == null
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
call GroupRemoveUnit(targets, t)
endloop
// Cleanup
call ReleaseGroup(targets)
set targets = null
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=13
//TESH.alwaysfold=0
scope IceBarrier initializer Init
globals
private constant integer AbilID = 'A00F'
//Buff stuff
integer BUFF_TYPE_ICE_BARRIER
private integer AuraID = 'A02Y'
private integer BuffID = 'B00F'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
if UnitHasShield(db.target) then
call DestroyShield(db.target)
endif
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local dbuff db = 0
local real ShieldLife = ICE_BARRIER_HEALTH*lvl*GetSpellMod(id)
// If unit already has old buff, remove it
if UnitHasBuff(u, BUFF_TYPE_ICE_BARRIER) then
call UnitRemoveBuff(u, BUFF_TYPE_ICE_BARRIER)
endif
call AddShield(u,ShieldLife,0,0,1,"|cff97C1E8", true, true,0,"FreezingPrison.mdl")
set db = UnitAddBuff(u, u, BUFF_TYPE_ICE_BARRIER, ICE_BARRIER_DURATION, lvl)
set u = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
set BUFF_TYPE_ICE_BARRIER = DefineBuffType(AuraID, BuffID, 0, false, true, 0, 0, OnEnd)
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=9
//TESH.alwaysfold=0
scope WaterElemental initializer Init
globals
private constant integer AbilID = 'A00K'
private constant real AC_ORDER_DELAY = 0.5
private location array TargetLocation[1]
private unit array TargetUnit[1]
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Conditions_AutoControl takes nothing returns boolean
return GetUnitTypeId(GetTriggerUnit()) == MAGE_ID or GetUnitTypeId(GetTriggerUnit()) == MAGE_ID2
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local real x = GetUnitX(u) + GetRandomReal(-128, 128 )
local real y = GetUnitY(u) + GetRandomReal(-128, 128 )
local integer level = GetHeroLevel(u)
local effect e1
local effect e2
// Create/revive water elemental
if Water_Elementals[id] == null then
set Water_Elementals[id] = CreateUnit(GetOwningPlayer(GetSpellAbilityUnit()), 'H008', x, y, bj_UNIT_FACING)
else
call KillUnit(Water_Elementals[id])
call ReviveHero(Water_Elementals[id], x, y, false)
endif
set e1 = AddSpecialEffectTarget("WaterMagic.mdl", Water_Elementals[id], "origin")
set e2 = AddSpecialEffectTarget("WaterBuff.mdl", Water_Elementals[id], "overhead")
// Set to hero level
call SuspendHeroXP(Water_Elementals[id], false)
if level > 1 then
call SetHeroLevel(Water_Elementals[id], level, false)
endif
call SuspendHeroXP(Water_Elementals[id], true)
call DestroyEffect(e1)
call DestroyEffect(e2)
set e1 = null
set e2 = null
set u = null
endfunction
private function AutoControl_Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
call ReleaseTimer(t)
call IssueTargetOrder( Water_Elementals[id], "smart", TargetUnit[id] )
call IssuePointOrderLoc( Water_Elementals[id], "smart", TargetLocation[id] )
set TargetUnit[id] = null
set TargetLocation[id] = null
set t = null
endfunction
private function AutoControl_Actions takes nothing returns nothing
local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
local timer t = NewTimer()
call SetTimerData(t, id)
set TargetUnit[id] = GetOrderTargetUnit()
set TargetLocation[id] = GetOrderPointLoc()
call TimerStart(t, AC_ORDER_DELAY, false, function AutoControl_Callback)
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
// Auto Control
set trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
call TriggerAddCondition( trg, Condition( function Conditions_AutoControl ) )
call TriggerAddAction( trg, function AutoControl_Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=28
//TESH.alwaysfold=0
scope ShieldSlamMulti initializer Init
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A04X'
endfunction
private function Target_Conditions takes nothing returns boolean
return IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(GetSpellAbilityUnit())) == true and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)
endfunction
private function Callback takes nothing returns nothing
local unit t = GetEnumUnit()
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroStr(u, true)
local boolean crit = false
local real d = 0
local group targets = NewGroup()
// Spell damage
set d = SHIELD_SLAM_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Get targets
call GroupEnumUnitsInRange(targets, GetUnitX(u), GetUnitY(u), SLAM_RANGE, Condition(function Target_Conditions))
// Burn them
loop
set t = FirstOfGroup(targets)
exitwhen t == null
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
call GroupRemoveUnit(targets, t)
endloop
// Cleanup
call ReleaseGroup(targets)
set targets = null
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=45
//TESH.alwaysfold=0
scope Moonfire initializer Init
globals
private constant integer AbilID = 'A04Y'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Damage_Callback takes nothing returns nothing
local timer ti = GetExpiredTimer()
// Get Spell Data
local integer spell_id = GetTimerData(ti)
local unit u = GetSpellCaster(spell_id)
local unit t = GetSpellTarget(spell_id)
local boolean crit = GetSpellCrit(spell_id)
local real d = GetSpellDamage(spell_id)
// Release Timer
call ReleaseTimer(ti)
set ti = null
if GetUnitState(t, UNIT_STATE_LIFE) > 0 then
// Damage
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
// ReleaseSpell
call ReleaseSpell(spell_id)
endif
set u = null
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local integer spell_id
local timer ti = NewTimer()
// Spell damage
set d = MOON_FIRE_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Register spell
set spell_id = RegisterSpell(u, t, null, d, crit, 0,0,0,0,0,0)
// Damage Callback
call SetTimerData(ti, spell_id)
call TimerStart(ti, 0.65, false, function Damage_Callback)
// Cleanup
set u = null
set t = null
set ti = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=72
//TESH.alwaysfold=0
scope Rejuvenation initializer Init
globals
private constant integer AbilID = 'A064'
//Buff stuff
integer BUFF_TYPE_REJUVENATION
private integer AuraID = 'A02Z'
private integer BuffID = 'B00K'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
local integer spell_id = db.data
local integer effect_id = GetSpellEffectId(spell_id)
// Release
call ReleaseEffect(effect_id)
call ReleaseSpell(spell_id)
endfunction
private function HealTick takes integer spell_id returns nothing
local unit u = GetSpellCaster(spell_id)
local unit t = GetSpellTarget(spell_id)
local boolean crit = GetSpellCrit(spell_id)
local real d = GetSpellDamage(spell_id)
if GetUnitState(t, UNIT_STATE_LIFE) < GetUnitState(t, UNIT_STATE_MAX_LIFE) then
call CreateDamageTag(u, t, d, crit, true)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_HEALING, false, crit)
endif
set u = null
set t = null
endfunction
private function Callback takes nothing returns nothing
local dbuff db = GetEventBuff()
local integer spell_id = db.data
call HealTick(spell_id)
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local dbuff db = 0
local integer spell_id
local effect e
local integer effect_id
// Damage
set d = -REJUVENATION_HEALTH_PER_TICK * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Remove old buff
if UnitHasBuff(t, BUFF_TYPE_REJUVENATION) then
call UnitRemoveBuff(t, BUFF_TYPE_REJUVENATION)
endif
// Honor
if u != t then
call IncHonorStack(id, 1)
endif
// Effect
set e = AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Rejuvenation\\RejuvenationTarget.mdl", t, "chest")
set effect_id = RegisterEffect(e, 0)
// Register spell
set spell_id = RegisterSpell(u, t, null, d, crit, 0,0,0,0,0, effect_id)
// Apply the buff
set db = UnitAddBuff(u, t, BUFF_TYPE_REJUVENATION, (REJUVENATION_TICKS * GENERIC_DOT_INTERVAL)-GENERIC_DOT_INTERVAL, lvl )
set db.data = spell_id
// and make it work first time
call HealTick(spell_id)
set u = null
set t = null
set e = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
set BUFF_TYPE_REJUVENATION = DefineBuffType(AuraID, BuffID, GENERIC_DOT_INTERVAL, true, true, 0, Callback, OnEnd)
// takes integer AbilId, integer BuffId, real period, boolean isPeriodic, boolean isPositive, callback onAdd, callback onPeriodic, callback onEnd returns integer
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=72
//TESH.alwaysfold=0
scope Roots initializer Init
globals
private constant integer AbilID = 'A05H'
//Buff stuff
integer BUFF_TYPE_ROOTS
private integer AuraID = 'A033'
private integer BuffID = 'B00O'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
local integer spell_id = db.data
local integer effect_id = GetSpellEffectId(spell_id)
local unit t = GetSpellTarget(spell_id)
// Reset Movement speed
call SetMoveSpeed(t)
// Release
call ReleaseEffect(effect_id)
call ReleaseSpell(spell_id)
set t = null
endfunction
private function RootsDamage takes integer spell_id returns nothing
local unit u = GetSpellCaster(spell_id)
local unit t = GetSpellTarget(spell_id)
local boolean crit = GetSpellCrit(spell_id)
local real d = GetSpellDamage(spell_id)
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
call SetMoveSpeed(t)
set u = null
set t = null
endfunction
private function Callback takes nothing returns nothing
local dbuff db = GetEventBuff()
local integer spell_id = db.data
call RootsDamage(spell_id)
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local dbuff db = 0
local integer spell_id
local integer effect_id
local effect e
// Calculate spell damage
set d = ROOTS_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Remove old buff
if UnitHasBuff(t, BUFF_TYPE_ROOTS) then
call UnitRemoveBuff(t, BUFF_TYPE_ROOTS)
endif
// Effect
set e = AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\EntanglingRoots\\EntanglingRootsTarget.mdl", t, "origin")
set effect_id = RegisterEffect(e, 0)
// Register spell
set spell_id = RegisterSpell(u, t, null, d, crit, 0,0,0,0,0,effect_id)
// Apply the buff
set db = UnitAddBuff(u, t, BUFF_TYPE_ROOTS, (ROOTS_TICKS * GENERIC_DOT_INTERVAL)-GENERIC_DOT_INTERVAL, lvl)
set db.data = spell_id
// and make it work first time
call RootsDamage(spell_id)
set u = null
set t = null
set e = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
set BUFF_TYPE_ROOTS = DefineBuffType(AuraID, BuffID, GENERIC_DOT_INTERVAL, true, false, 0, Callback, OnEnd)
// takes integer AbilId, integer BuffId, real period, boolean isPeriodic, boolean isPositive, callback onAdd, callback onPeriodic, callback onEnd returns integer
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=98
//TESH.alwaysfold=0
scope MarkOfTheWild initializer Init
globals
private constant integer AbilID = 'A05L'
//Buff stuff
integer BUFF_TYPE_MARKOFTHEWILD
private integer AuraID = 'A032'
private integer BuffID = 'B00M'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Target_Conditions takes nothing returns boolean
return IsPlayerAlly(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(GetSpellAbilityUnit())) == true and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
local integer spell_id = db.data
local unit t = db.target
local integer effect_id = GetSpellEffectId(spell_id)
local real unit_max_life = GetUnitState(t, UNIT_STATE_MAX_LIFE)
local real unit_max_mana = GetUnitState(t, UNIT_STATE_MAX_MANA)
local real life_bonus = R2I(GetSpellHealth(spell_id))
local real mana_bonus = R2I(GetSpellMana(spell_id))
call Debug_Message(R2S(unit_max_life)+" | "+R2S(unit_max_mana))
// set unit_max_life = unit_max_life - life_bonus
// set unit_max_mana = unit_max_mana - mana_bonus
// call Debug_Message(R2S(unit_max_life)+" | "+R2S(unit_max_mana))
// call SetUnitMaxState(t, UNIT_STATE_MAX_LIFE, unit_max_life )
// call SetUnitMaxState(t, UNIT_STATE_MAX_MANA, unit_max_mana )
// set unit_max_life = GetUnitState(t, UNIT_STATE_MAX_LIFE)
// set unit_max_mana = GetUnitState(t, UNIT_STATE_MAX_MANA)
call AddUnitMaxState(t, UNIT_STATE_MAX_LIFE, -life_bonus)
call AddUnitMaxState(t, UNIT_STATE_MAX_MANA, -mana_bonus)
call Debug_Message("OnEnd: "+R2S(GetUnitState(t, UNIT_STATE_MAX_LIFE))+" | "+R2S(GetUnitState(t, UNIT_STATE_MAX_MANA)))
// Release
call ReleaseEffect(effect_id)
call ReleaseSpell(spell_id)
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = null
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroLevel(u)
local group targets = NewGroup()
local integer i = 0
local dbuff db = 0
local integer spell_id
local effect e
local integer effect_id
local integer mana_bonus
local integer life_bonus
// Get targets
call GroupEnumUnitsInRange(targets, GetUnitX(u), GetUnitY(u), GENERIC_AOE_RANGE, Condition(function Target_Conditions))
// Honor
if CountUnitsInGroup(targets) >= 2 then
call IncHonorStack(id, 1)
endif
// Buff'em!
loop
set t = FirstOfGroup(targets)
exitwhen t == null
// If unit already has old buff, remove it
if UnitHasBuff(t, BUFF_TYPE_MARKOFTHEWILD) then
call UnitRemoveBuff(t, BUFF_TYPE_MARKOFTHEWILD)
endif
// Effect
set e = AddSpecialEffectTarget("MOTWTarget.mdl", t, "overhead")
set effect_id = RegisterEffect(e, 0)
// Bonus
set life_bonus = R2I(GetUnitState(t, UNIT_STATE_MAX_LIFE)*0.1)
set mana_bonus = R2I(GetUnitState(t, UNIT_STATE_MAX_MANA)*0.1)
// call Debug_Message("MoW Bonus: "+R2S(life_bonus)+" | "+R2S(mana_bonus))
// Register spell
set spell_id = RegisterSpell(u, t, null, 0, false,I2R(life_bonus),I2R(mana_bonus),0,0,0,effect_id)
// Apply new buff
set db = UnitAddBuff(u, t, BUFF_TYPE_MARKOFTHEWILD, GENERIC_BUFF_DURATION, lvl)
set db.data = spell_id
// Buff effect
// call SetUnitMaxState(t, UNIT_STATE_MAX_LIFE, GetUnitState(t, UNIT_STATE_MAX_LIFE) + life_bonus )
// call SetUnitMaxState(t, UNIT_STATE_MAX_MANA, GetUnitState(t, UNIT_STATE_MAX_MANA) + mana_bonus )
call AddUnitMaxState(t, UNIT_STATE_MAX_LIFE, I2R(life_bonus))
call AddUnitMaxState(t, UNIT_STATE_MAX_MANA, I2R(mana_bonus))
call Debug_Message("OnAdd: "+R2S(GetUnitState(t, UNIT_STATE_MAX_LIFE))+" | "+R2S(GetUnitState(t, UNIT_STATE_MAX_MANA)))
call GroupRemoveUnit(targets, t)
endloop
// Cleanup
call ReleaseGroup(targets)
set targets = null
set u = null
set t = null
set e = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
set BUFF_TYPE_MARKOFTHEWILD = DefineBuffType(AuraID, BuffID, 0, false, true, 0, 0, OnEnd)
// takes integer AbilId, integer BuffId, real period, boolean isPeriodic, boolean isPositive, callback onAdd, callback onPeriodic, callback onEnd returns integer
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=36
//TESH.alwaysfold=0
scope ClawStrike initializer Init
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A069'
endfunction
private function Target_Conditions takes nothing returns boolean
return IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(GetSpellAbilityUnit())) == true and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroStr(u, true)
local boolean crit = false
local effect e
local effect e2
local real d = 0
local group targets = NewGroup()
// Spell damage
set d = CLAW_STRIKE_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Get targets
call GroupEnumUnitsInRange(targets, GetUnitX(t), GetUnitY(t), 128, Condition(function Target_Conditions))
call TriggerSleepAction( 0.3)
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
call GroupRemoveUnit(targets, t)
set d = d*0.75
// Damage them
loop
set t = FirstOfGroup(targets)
exitwhen t == null
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
call GroupRemoveUnit(targets, t)
endloop
set e = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Incinerate\\IncinerateBuff.mdl", u, "weapon")
set e2 = AddSpecialEffectTarget("Abilities\\Spells\\Orc\\SpiritLink\\SpiritLinkZapTarget.mdl", u, "overhead")
call DestroyEffect(e)
call DestroyEffect(e2)
call ReleaseGroup(targets)
set targets = null
set e = null
set e2 = null
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=3
//TESH.alwaysfold=0
scope Bash initializer Init
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A06E'
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroStr(u, true)
local boolean crit = false
local real d = 0
// Spell damage
set d = BASH_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=35
//TESH.alwaysfold=0
scope BearForm initializer Init
private function Conditions_BearForm takes nothing returns boolean
return ( GetSpellAbilityId() == 'A005' and GetUnitTypeId(GetSpellAbilityUnit()) == DRUID_ID ) or ( GetSpellAbilityId() == 'A02S' and GetUnitTypeId(GetSpellAbilityUnit()) == DRUID_ID2 )
endfunction
private function Conditions_DruidForm takes nothing returns boolean
return ( GetSpellAbilityId() == 'A005' and GetUnitTypeId(GetSpellAbilityUnit()) == DRUIDB_ID ) or ( GetSpellAbilityId() == 'A02S' and GetUnitTypeId(GetSpellAbilityUnit()) == DRUIDB_ID2 )
endfunction
private function BearForm takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local effect e
local real r
local real lifepercent
set lifepercent = GetUnitState(u, UNIT_STATE_LIFE) / GetUnitState(u, UNIT_STATE_MAX_LIFE) * 100.0
set Druid_Str_Mod[id] = GetHeroStr(u, false) / 2
call Debug_Message("Add Str: "+I2S(Druid_Str_Mod[id]))
call SetHeroStr(u, GetHeroStr(u, false) + Druid_Str_Mod[id], true)
set r = ( GetUnitState(u, UNIT_STATE_MAX_LIFE) / 100 ) * lifepercent
call SetUnitState(u, UNIT_STATE_LIFE, r)
set e = AddSpecialEffectTarget("EarthFlare.mdl", u, "origin")
call DestroyEffect(e)
set e = null
set u = null
endfunction
private function DruidForm takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local effect e
local real r
local real lifepercent
call Debug_Message("Rem Str: "+I2S(Druid_Str_Mod[id]))
set r = GetUnitState(u, UNIT_STATE_LIFE)
set lifepercent = r / GetUnitState(u, UNIT_STATE_MAX_LIFE) * 100.0
call SetHeroStr(u, GetHeroStr(u, false) - Druid_Str_Mod[id], true)
set r = ( GetUnitState(u, UNIT_STATE_MAX_LIFE) / 100 ) * lifepercent
call SetUnitState(u, UNIT_STATE_LIFE, r)
set Druid_Str_Mod[id] = 0
set e = AddSpecialEffectTarget("EarthFlare.mdl", u, "origin")
call DestroyEffect(e)
set e = null
set u = null
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition( trg, Condition( function Conditions_BearForm ) )
call TriggerAddAction( trg, function BearForm )
set trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition( trg, Condition( function Conditions_DruidForm ) )
call TriggerAddAction( trg, function DruidForm )
set trg = null
endfunction
endscope
//TESH.scrollpos=8
//TESH.alwaysfold=0
scope HealingTouch initializer Init
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A04A' //'A05N'
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
// Spell healing
set d = -HEALING_TOUCH_POWER * lvl * GetSpellMod * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
call CreateDamageTag(u, t, d, crit, true)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
// Honor
if u != t then
call IncHonorStack(id, 1)
endif
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=72
//TESH.alwaysfold=0
scope Fear initializer Init
globals
private constant integer AbilID = 'A06Z'
//Buff stuff
integer BUFF_TYPE_FEAR
private integer AuraID = 'A039'
private integer BuffID = 'B00N'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Target_Conditions takes nothing returns boolean
return IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(GetSpellAbilityUnit())) == true and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 and GetFilterUnit() != GetSpellAbilityUnit() and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
local integer spell_id = db.data
local integer effect_id = GetSpellEffectId(spell_id)
// Release
call ReleaseEffect(effect_id)
call ReleaseSpell(spell_id)
endfunction
private function Run_Away takes unit u returns nothing
local real x = GetUnitX(u) + 1024.00 * Cos(GetRandomReal(0, 360) * bj_DEGTORAD)
local real y = GetUnitY(u) + 1024.00 * Sin(GetRandomReal(0, 360) * bj_DEGTORAD)
// Make unit move around
call IssuePointOrder(u, "move", x, y )
call ClearSelectionForPlayer(GetOwningPlayer(u))
set u = null
endfunction
private function Callback takes nothing returns nothing
local dbuff db = GetEventBuff()
local unit t = db.target
call Run_Away(t)
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = null
local integer lvl = GetHeroLevel(u)
local group targets = NewGroup()
local dbuff db = 0
local integer spell_id
local effect e
local integer effect_id
// Get targets
call GroupEnumUnitsInRange(targets, GetUnitX(u), GetUnitY(u), GENERIC_AOE_RANGE, Condition(function Target_Conditions))
// Target Number is limited
loop
exitwhen CountUnitsInGroup(targets) <= FEAR_MAX_TARGETS
call GroupRemoveUnit(targets, FirstOfGroup(targets))
endloop
// Buff'em!
loop
set t = FirstOfGroup(targets)
exitwhen t == null
// If unit already has old buff, remove it
if UnitHasBuff(t, BUFF_TYPE_FEAR) then
call UnitRemoveBuff(t, BUFF_TYPE_FEAR)
endif
// Effect
set e = AddSpecialEffectTarget("FearTargetNew.mdl", t, "overhead")
set effect_id = RegisterEffect(e, 0)
// Register spell
set spell_id = RegisterSpell(u, t, null, 0, false,0,0,0,0,0,effect_id)
// Apply new buff
set db = UnitAddBuff(u, t, BUFF_TYPE_FEAR, (FEAR_TICKS * GENERIC_DOT_INTERVAL)-GENERIC_DOT_INTERVAL, lvl)
set db.data = spell_id
// Make 'em run
call Run_Away(t)
call GroupRemoveUnit(targets, t)
endloop
// Cleanup
call ReleaseGroup(targets)
set targets = null
set u = null
set t = null
set e = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
set BUFF_TYPE_FEAR = DefineBuffType(AuraID, BuffID, GENERIC_DOT_INTERVAL, true, false, 0, Callback, OnEnd)
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=22
//TESH.alwaysfold=0
scope Shield initializer Init
globals
private constant integer AbilID = 'A00T'
//Buff stuff
integer BUFF_TYPE_SHIELD
private integer AuraID = 'A037'
private integer BuffID = 'B00P'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
if UnitHasShield(db.target) then
call DestroyShield(db.target)
endif
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local dbuff db = 0
local real ShieldLife = lvl * SHIELD_LIFE * GetSpellMod(id)
// If unit already has old buff, remove it
if UnitHasBuff(t, BUFF_TYPE_SHIELD) then
call UnitRemoveBuff(t, BUFF_TYPE_SHIELD)
endif
call AddShield(t,ShieldLife,0,0,1,"|cffFFC742", true, true,0,"Abilities\\Spells\\Items\\StaffOfSanctuary\\Staff_Sanctuary_Target.mdl")
set db = UnitAddBuff(u, t, BUFF_TYPE_SHIELD, SHIELD_DURATION, lvl)
// Honor
if u != t then
call IncHonorStack(id, 1)
endif
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
set BUFF_TYPE_SHIELD = DefineBuffType(AuraID, BuffID, 0, false, true, 0, 0, OnEnd)
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=30
//TESH.alwaysfold=0
scope HolyNova initializer Init
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A066'
endfunction
private function Target_Conditions takes nothing returns boolean
return IsPlayerAlly(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(GetSpellAbilityUnit())) == true and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local group targets = NewGroup()
local boolean honor = false
// Spell damage
set d = -HOLY_NOVA_POWER * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Get targets
call GroupEnumUnitsInRange(targets, GetUnitX(u), GetUnitY(u), GENERIC_AOE_RANGE, Condition(function Target_Conditions))
// Hit'em
loop
set t = FirstOfGroup(targets)
exitwhen t == null
// Honor
if u != t and honor == false then
call IncHonorStack(id, 1)
set honor = true
endif
call CreateDamageTag(u, t, d, crit, true)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_HEALING, false, crit)
call GroupRemoveUnit(targets, t)
endloop
// Cleanup
call ReleaseGroup(targets)
set targets = null
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=10
//TESH.alwaysfold=0
scope ManaBurn initializer Init
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A02I'
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local real mana = GetUnitState(t, UNIT_STATE_MANA)
if mana > 0 then
// Spell damage
set mana = mana*0.3
set d = mana*2
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_SPELL, false, crit)
call SetUnitState(t, UNIT_STATE_MANA, GetUnitState(t, UNIT_STATE_MANA) - mana)
endif
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=65
//TESH.alwaysfold=0
scope ShadowWordPain initializer Init
globals
private constant integer AbilID = 'A06K'
//Buff stuff
integer BUFF_TYPE_SHADOW_WORD_PAIN
private integer AuraID = 'A03A'
private integer BuffID = 'B00T'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
local integer spell_id = db.data
local integer effect_id = GetSpellEffectId(spell_id)
// Release
call ReleaseEffect(effect_id)
call ReleaseSpell(spell_id)
endfunction
private function CurseDamage takes integer spell_id returns nothing
local unit u = GetSpellCaster(spell_id)
local unit t = GetSpellTarget(spell_id)
local boolean crit = GetSpellCrit(spell_id)
local real d = GetSpellDamage(spell_id)
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
set u = null
set t = null
endfunction
private function Callback takes nothing returns nothing
local dbuff db = GetEventBuff()
local integer spell_id = db.data
call CurseDamage(spell_id)
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local dbuff db = 0
local integer spell_id
local effect e
local integer effect_id
// Calculate spell damage
set d = SHADOW_WORD_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Remove old buff
if UnitHasBuff(t, BUFF_TYPE_SHADOW_WORD_PAIN) then
call UnitRemoveBuff(t, BUFF_TYPE_SHADOW_WORD_PAIN)
endif
// Effect
set e = AddSpecialEffectTarget("Abilities\\Spells\\Other\\HowlOfTerror\\HowlTarget.mdl", t, "overhead")
set effect_id = RegisterEffect(e, 0)
// Register spell
set spell_id = RegisterSpell(u, t, null, d, crit, 0,0,0,0,0, effect_id)
// Apply the buff
set db = UnitAddBuff(u, t, BUFF_TYPE_SHADOW_WORD_PAIN, (SHADOW_WORD_TICKS * GENERIC_DOT_INTERVAL)-GENERIC_DOT_INTERVAL, lvl)
set db.data = spell_id
// and make it work first time
call CurseDamage(spell_id)
set u = null
set t = null
set e = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
set BUFF_TYPE_SHADOW_WORD_PAIN = DefineBuffType(AuraID, BuffID, GENERIC_DOT_INTERVAL, true, false, 0, Callback, OnEnd)
// takes integer AbilId, integer BuffId, real period, boolean isPeriodic, boolean isPositive, callback onAdd, callback onPeriodic, callback onEnd returns integer
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=93
//TESH.alwaysfold=0
scope DeadlyStrike initializer Init
globals
private constant integer AbilID = 'A011'
//Buff stuff
integer BUFF_TYPE_DEADLY_STRIKE
private integer AuraID = 'A03B'
private integer BuffID = 'B00Q'
private effect array Effects
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
local unit u = db.source
local unit t = db.target
// Destroy effect
if Effects[GetUnitId(t)] != null then
call DestroyEffect( Effects[GetUnitId(t)] )
endif
// Destroy spell instance
call Debug_Message("Attempt to destroy spell id: "+I2S(db.data))
call spell.destroy(spells[db.data])
set u = null
set t = null
endfunction
private function Callback takes nothing returns nothing
local dbuff db = GetEventBuff()
local unit u = db.source
local unit t = db.target
local boolean crit = false
local real d = 0
set d = spells[db.data].damage
set crit = spells[db.data].isCrit
set d = d * DEADLY_STRIKE_TICK_FACTOR
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
set Effects[GetUnitId(t)] = AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodFootman.mdl", t, "origin")
// Destroy effect
if Effects[GetUnitId(t)] != null then
call DestroyEffect( Effects[GetUnitId(t)] )
endif
set u = null
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroAgi(u, true)
local boolean crit = false
local real d = 0
local dbuff db = 0
local integer Spell_ID
// Calculate spell damage
set d = DEADLY_STRIKE_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Always crit when attack is out of stealth
if UnitHasBuff(u, BUFF_TYPE_STEALTH) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Register spell
set Spell_ID = RegisterSpell(u, t, null, d, crit, 0,0,0,0,0,0)
// Remove old buff
if UnitHasBuff(t, BUFF_TYPE_DEADLY_STRIKE) then
call UnitRemoveBuff(t, BUFF_TYPE_DEADLY_STRIKE)
endif
// Apply the buff
set db = UnitAddBuff(u, t, BUFF_TYPE_DEADLY_STRIKE, (DEADLY_STRIKE_TICKS * GENERIC_DOT_INTERVAL), lvl)
set db.data = Spell_ID
// Create effect on target
set Effects[GetUnitId(t)] = AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodFootman.mdl", t, "origin")
// Initial damage
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
call IssueTargetOrder( u, "attack", t )
// Destroy effect
if Effects[GetUnitId(t)] != null then
call DestroyEffect( Effects[GetUnitId(t)] )
endif
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
set BUFF_TYPE_DEADLY_STRIKE = DefineBuffType(AuraID, BuffID, GENERIC_DOT_INTERVAL, true, false, 0, Callback, OnEnd)
// takes integer AbilId, integer BuffId, real period, boolean isPeriodic, boolean isPositive, callback onAdd, callback onPeriodic, callback onEnd returns integer
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=35
//TESH.alwaysfold=0
scope FanOfKnives initializer Init
globals
private unit caster
private real damage = 0
private boolean crit = false
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A077'
endfunction
private function Target_Conditions takes nothing returns boolean
return IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(GetSpellAbilityUnit())) == true and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroAgi(u, true)
local group targets = NewGroup()
local real d = 0
set caster = GetSpellAbilityUnit()
// Spell damage
set d = FAN_OF_KNIVES_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set damage = damage * CRIT_FACTOR
endif
// Always crit when attack is out of stealth
if UnitHasBuff(u, BUFF_TYPE_STEALTH) then
set crit = true
set damage = damage * CRIT_FACTOR
endif
// Get targets
call GroupEnumUnitsInRange(targets, GetUnitX(u), GetUnitY(u), GENERIC_AOE_RANGE, Condition(function Target_Conditions))
// Burn them
loop
set t = FirstOfGroup(targets)
exitwhen t == null
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
call GroupRemoveUnit(targets, t)
endloop
// Cleanup
call ReleaseGroup(targets)
set targets = null
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=11
//TESH.alwaysfold=0
scope Backstab initializer Init
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A013'
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroAgi(u, true)
local boolean crit = false
local real d = 0
// Spell damage
set d = BACKSTAB_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Always crit when attack is out of stealth
if UnitHasBuff(u, BUFF_TYPE_STEALTH) then
set crit = true
set d = d * CRIT_FACTOR
endif
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
call IssueTargetOrder( u, "attack", t )
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=43
//TESH.alwaysfold=0
scope Stealth initializer Init
globals
private constant integer AbilID = 'A07A'
//Buff stuff
integer BUFF_TYPE_STEALTH
private integer AuraID = 'A03C'
private integer BuffID = 'B00U'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Stealth_Break_Conditions takes nothing returns boolean
return UnitHasBuff(GetSpellAbilityUnit(), BUFF_TYPE_STEALTH) and GetSpellAbilityId() != AbilID
endfunction
private function Stealth_Break_Conditions2 takes nothing returns boolean
return UnitHasBuff(GetAttacker(), BUFF_TYPE_STEALTH)
endfunction
private function Stealth_Break_Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
call TriggerSleepAction(0.2)
if UnitHasBuff(u, BUFF_TYPE_STEALTH) then
call UnitRemoveBuff(u, BUFF_TYPE_STEALTH)
endif
endfunction
private function Stealth_Break_Actions2 takes nothing returns nothing
call UnitRemoveBuff(GetAttacker(), BUFF_TYPE_STEALTH)
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
call UnitRemoveAbility(db.target, 'Agho')
call UnitRemoveType(db.target, UNIT_TYPE_PEON)
// call SetUnitPathing( db.target, true )
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local dbuff db = 0
// If unit already has old buff, remove it
if UnitHasBuff(u, BUFF_TYPE_STEALTH) then
call UnitRemoveBuff(u, BUFF_TYPE_STEALTH)
endif
set db = UnitAddBuff(u, u, BUFF_TYPE_STEALTH, STEALTH_DURATION, lvl)
call UnitAddAbility(u, 'Agho')
call UnitAddType(u, UNIT_TYPE_PEON)
// call SetUnitPathing( u, false )
set u = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
local trigger trg2 = CreateTrigger()
local trigger trg3 = CreateTrigger()
set BUFF_TYPE_STEALTH = DefineBuffType(AuraID, BuffID, 0, false, true, 0, 0, OnEnd)
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
call TriggerRegisterAnyUnitEventBJ(trg2, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg2, Condition(function Stealth_Break_Conditions))
call TriggerAddAction(trg2, function Stealth_Break_Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=105
//TESH.alwaysfold=0
scope CriticalShot initializer Init
globals
private constant integer AbilID = 'A02H'
//Buff stuff
integer BUFF_TYPE_CRITICAL_SHOT
private integer AuraID = 'A03H'
private integer BuffID = 'B00R'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
local unit u = db.source
local unit t = db.target
local integer spell_id = db.data
// Reset Movement speed
call SetMoveSpeed(t)
// Release spell
call ReleaseSpell(spell_id)
set u = null
set t = null
endfunction
private function Callback takes nothing returns nothing
local dbuff db = GetEventBuff()
local unit u = db.source
local unit t = db.target
local boolean crit = false
local real d = 0
set d = spells[db.data].damage
set crit = spells[db.data].isCrit
set d = d * CRITICAL_SHOT_TICK_FACTOR
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
set u = null
set t = null
endfunction
private function Damage_Callback takes nothing returns nothing
local timer ti = GetExpiredTimer()
local dbuff db = 0
// Get Spell Data
local integer spell_id = GetTimerData(ti)
local unit u = GetSpellCaster(spell_id)
local unit t = GetSpellTarget(spell_id)
local boolean crit = GetSpellCrit(spell_id)
local real d = GetSpellDamage(spell_id)
// Release Timer
call ReleaseTimer(ti)
set ti = null
if GetUnitState(t, UNIT_STATE_LIFE) > 0 then
// Remove old buff
if UnitHasBuff(t, BUFF_TYPE_CRITICAL_SHOT) then
call UnitRemoveBuff(t, BUFF_TYPE_CRITICAL_SHOT)
endif
// Apply the buff
set db = UnitAddBuff(u, t, BUFF_TYPE_CRITICAL_SHOT, (CRITICAL_SHOT_TICKS * GENERIC_DOT_INTERVAL), 0)
set db.data = spell_id
// Reset Movement speed
call SetMoveSpeed(t)
// Initial damage
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
endif
set u = null
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroAgi(u, true)
local boolean crit = false
local real d = 0
local dbuff db = 0
local integer spell_id
local real dx = GetUnitX(u) - GetUnitX(t)
local real dy = GetUnitY(u) - GetUnitY(t)
local real Range = SquareRoot(dx * dx + dy * dy)
local real RangeFactor = 0.3 + Range*0.001
local timer ti = NewTimer()
local real arrow_time = Range * 0.0005
local effect e
// Spell damage
set d = CRITICAL_SHOT_DAMAGE * lvl * GetSpellMod(id) * RangeFactor * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Register spell
set spell_id = RegisterSpell(u, t, null, d, crit, 0,0,0,0,0,0)
call PlaySoundOnUnitBJ(Sound_Arrow, 100, u)
call SetTimerData(ti, spell_id)
call TimerStart(ti, arrow_time, false, function Damage_Callback)
set u = null
set e = null
set t = null
set ti = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
set BUFF_TYPE_CRITICAL_SHOT = DefineBuffType(AuraID, BuffID, GENERIC_DOT_INTERVAL, true, false, 0, Callback, OnEnd)
// takes integer AbilId, integer BuffId, real period, boolean isPeriodic, boolean isPositive, callback onAdd, callback onPeriodic, callback onEnd returns integer
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=63
//TESH.alwaysfold=0
scope MultiShot initializer Init
globals
private constant integer AbilID = 'A03Q'
private unit Caster = null
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Target_Conditions takes nothing returns boolean
return IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(Caster)) == true and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)
endfunction
private function DamageCallback takes nothing returns nothing
local timer ti = GetExpiredTimer()
local integer spell_id = GetTimerData(ti)
local group targets = NewGroup()
local unit u = GetSpellCaster(spell_id)
local unit t
local location loc = GetSpellLocation(spell_id)
local boolean crit = GetSpellCrit(spell_id)
local real d = GetSpellDamage(spell_id)
call ReleaseTimer(ti)
set ti = null
set Caster = u
call Debug_Message("Damage: "+R2S(d))
// Get targets
call GroupEnumUnitsInRange(targets, GetLocationX(loc), GetLocationY(loc), MULTI_SHOT_RANGE, Condition(function Target_Conditions))
// Burn them
loop
set t = FirstOfGroup(targets)
exitwhen t == null
if GetUnitState(t, UNIT_STATE_LIFE) > 0 then
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
endif
call GroupRemoveUnit(targets, t)
endloop
// Cleanup
call ReleaseGroup(targets)
set targets = null
set u = null
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local location loc = GetSpellTargetLoc()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroAgi(u, true)
local boolean crit = false
local real d = 0
local integer spell_id
local timer ti = NewTimer()
// Spell damage
set d = MULTI_SHOT_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Register spell
set spell_id = RegisterSpell(u, t, loc, d, crit, 0,0,0,0,0,0)
call SetTimerData(ti, spell_id)
call TimerStart(ti, 0.5, false, function DamageCallback )
// Cleanup
set u = null
set t = null
set ti = null
set loc = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=79
//TESH.alwaysfold=0
scope Pets initializer Init
globals
// boolean array PetFix[1]
private integer array BearsXP[1]
private integer array WolfsXP[1]
private integer array FalconsXP[1]
endglobals
private function Callback_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A00E'
endfunction
private function Callback_Actions takes nothing returns nothing
local integer id = GetPlayerId(GetOwningPlayer(GetSpellAbilityUnit()))
call IssuePointOrderLoc( Pets[id], "move", GetUnitLoc(GetSpellAbilityUnit()) )
endfunction
private function Attack_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A03L'
endfunction
private function Attack_Actions takes nothing returns nothing
local integer id = GetPlayerId(GetOwningPlayer(GetSpellAbilityUnit()))
call IssueTargetOrder( Pets[id], "attack", GetSpellTargetUnit() )
endfunction
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A03J' or GetSpellAbilityId() == 'A03R' or GetSpellAbilityId() == 'A03V'
endfunction
private function Conditions_AutoControl takes nothing returns boolean
return GetUnitTypeId(GetTriggerUnit()) == HUNTER_ID or GetUnitTypeId(GetTriggerUnit()) == HUNTER_ID2
endfunction
private function AutoControl_Actions takes nothing returns nothing
local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
call TriggerSleepAction(0.3)
call IssueTargetOrder( Pets[id], "smart", GetOrderTargetUnit() )
call IssuePointOrderLoc( Pets[id], "smart", GetOrderPointLoc() )
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local real x = GetUnitX(GetSpellAbilityUnit()) + GetRandomReal(-128, 128 )
local real y = GetUnitY(GetSpellAbilityUnit()) + GetRandomReal(-128, 128 )
// Remove old pet
if Pets[id] != null then
call KillUnit(Pets[id])
endif
// Bear
if GetSpellAbilityId() == 'A03J' then
if Pets_Bears[id] == null then
set Pets_Bears[id] = CreateUnit(GetOwningPlayer(GetSpellAbilityUnit()), 'H007', x, y, bj_UNIT_FACING)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl", Pets_Bears[id], "origin") )
else
call ReviveHero(Pets_Bears[id], x, y, true)
endif
set Pets[id] = Pets_Bears[id]
call PlaySoundOnUnitBJ(Sound_Bear, 100, Pets[id])
// Wolf
elseif GetSpellAbilityId() == 'A03R' then
if Pets_Wolfs[id] == null then
set Pets_Wolfs[id] = CreateUnit(GetOwningPlayer(GetSpellAbilityUnit()), 'H00D', x, y, bj_UNIT_FACING)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl", Pets_Wolfs[id], "origin") )
else
call ReviveHero(Pets_Wolfs[id], x, y, true)
endif
set Pets[id] = Pets_Wolfs[id]
call PlaySoundOnUnitBJ(Sound_Wolf, 100, Pets[id])
// Falcon
elseif GetSpellAbilityId() == 'A03V' then
if Pets_Falcons[id] == null then
set Pets_Falcons[id] = CreateUnit(GetOwningPlayer(GetSpellAbilityUnit()), 'H00E', x, y, bj_UNIT_FACING)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl", Pets_Falcons[id], "origin") )
else
call ReviveHero(Pets_Falcons[id], x, y, true)
endif
set Pets[id] = Pets_Falcons[id]
call PlaySoundOnUnitBJ(Sound_Falcon, 100, Pets[id])
endif
call IndieSummon_SetMaster(Pets[id], u)
call SetUnitState(Pets[id], UNIT_STATE_MANA, GetUnitState(Pets[id], UNIT_STATE_MAX_MANA))
set u = null
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
// Order: Attack Target
set trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition( trg, Condition( function Attack_Conditions ) )
call TriggerAddAction( trg, function Attack_Actions )
// Order: Callback
set trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition( trg, Condition( function Callback_Conditions ) )
call TriggerAddAction( trg, function Callback_Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=36
//TESH.alwaysfold=0
scope ThrowRocks initializer Init
globals
private constant integer AbilID = 'A04Q'
private unit caster
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Target_Conditions takes nothing returns boolean
return IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(GetSpellAbilityUnit())) == true and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local location loc = GetSpellTargetLoc()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroStr(u, true)
local boolean crit = false
local real d = 0
local group targets = NewGroup()
// Spell damage
set d = MULTI_SHOT_DAMAGE*lvl*GetSpellMod(id)
set d = GetRandomSpellMod(d)
set d = GetRandomSpellMod(MULTI_SHOT_DAMAGE*lvl*GetSpellMod(id))
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Get targets
call GroupEnumUnitsInRange(targets, GetLocationX(loc), GetLocationY(loc), 200, Condition(function Target_Conditions))
call TriggerSleepAction(0.5)
// Burn them
loop
set t = FirstOfGroup(targets)
exitwhen t == null
if GetUnitState(t, UNIT_STATE_LIFE) > 0 then
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
endif
call GroupRemoveUnit(targets, t)
endloop
// Cleanup
call ReleaseGroup(targets)
set targets = null
set u = null
set t = null
set loc = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=78
//TESH.alwaysfold=0
scope VampiricCurse initializer Init
globals
private constant integer AbilID = 'A03Z'
//Buff stuff
integer BUFF_TYPE_VAMPIRIC_CURSE
private integer AuraID = 'A040'
private integer BuffID = 'B011'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
local integer spell_id = db.data
local integer effect_id = GetSpellEffectId(spell_id)
// Release
call ReleaseEffect(effect_id)
call ReleaseSpell(spell_id)
endfunction
private function CurseDamage takes integer spell_id returns nothing
local unit u = GetSpellCaster(spell_id)
local unit t = GetSpellTarget(spell_id)
local boolean crit = GetSpellCrit(spell_id)
local real d = GetSpellDamage(spell_id)
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
// Healing for caster
if GetUnitState(u, UNIT_STATE_LIFE) > 0 and GetUnitState(u, UNIT_STATE_LIFE) < GetUnitState(u, UNIT_STATE_MAX_LIFE) then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIre\\AIreTarget.mdl", u, "origin") )
set d = d * VAMPIRIC_CURSE_HEALTH_FACTOR
call CreateDamageTag(u, u, -d, crit, true)
call UnitDamageTargetEx(u, u, -d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
endif
set u = null
set t = null
endfunction
private function Callback takes nothing returns nothing
local dbuff db = GetEventBuff()
local integer spell_id = db.data
call CurseDamage(spell_id)
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local dbuff db = 0
local integer spell_id
local integer effect_id
local effect e
// Calculate spell damage
set d = VAMPIRIC_CURSE_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Remove old buff
if UnitHasBuff(t, BUFF_TYPE_VAMPIRIC_CURSE) then
call UnitRemoveBuff(t, BUFF_TYPE_VAMPIRIC_CURSE)
endif
// Effect
set e = AddSpecialEffectTarget("Abilities\\Spells\\Undead\\Curse\\CurseTarget.mdl", t, "overhead")
set effect_id = RegisterEffect(e, 0)
// Register spell
set spell_id = RegisterSpell(u, t, null, d, crit, 0,0,0,0,0,effect_id)
// Apply the buff
set db = UnitAddBuff(u, t, BUFF_TYPE_VAMPIRIC_CURSE, (VAMPIRIC_CURSE_TICKS * GENERIC_DOT_INTERVAL)-GENERIC_DOT_INTERVAL, lvl)
set db.data = spell_id
// and make it work first time
call CurseDamage(spell_id)
set u = null
set t = null
set e = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
set BUFF_TYPE_VAMPIRIC_CURSE = DefineBuffType(AuraID, BuffID, GENERIC_DOT_INTERVAL, true, false, 0, Callback, OnEnd)
// takes integer AbilId, integer BuffId, real period, boolean isPeriodic, boolean isPositive, callback onAdd, callback onPeriodic, callback onEnd returns integer
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=57
//TESH.alwaysfold=0
scope DarkConsumption initializer Init
globals
private constant integer AbilID = 'S001'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Target_Conditions takes nothing returns boolean
return IsUnitType(GetFilterUnit(), UNIT_TYPE_UNDEAD) == false and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)
endfunction
private function DamageTargets takes integer id returns nothing
local integer spell_id = id
local group targets = NewGroup()
local location loc = GetSpellLocation(spell_id)
local unit u = GetSpellCaster(spell_id)
local unit t
local real d = GetSpellDamage(spell_id)
local boolean crit = GetSpellCrit(spell_id)
// Get targets
call GroupEnumUnitsInRange(targets, GetLocationX(loc), GetLocationY(loc), DARK_CONSUMPTION_RANGE, Condition(function Target_Conditions))
// Burn them
loop
set t = FirstOfGroup(targets)
exitwhen t == null
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
call DestroyEffect( AddSpecialEffectTarget("Abilities\\Spells\\Undead\\DeathandDecay\\DeathandDecayDamage.mdl", t, "origin"))
call GroupRemoveUnit(targets, t)
endloop
call ReleaseGroup(targets)
set targets = null
set loc = null
set u = null
set t = null
endfunction
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer spell_id = GetTimerData(t)
local integer spell_ticks = GetSpellTicks(spell_id)
local integer effect_id = GetSpellEffectId(spell_id)
call DamageTargets(spell_id)
call IncSpellTicks(spell_id)
if GetSpellTicks(spell_id) >= DARK_CONSUMPTION_TICKS then
call ReleaseTimer(t)
call ReleaseEffect(effect_id)
call ReleaseSpell(spell_id)
endif
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local location loc = GetSpellTargetLoc()
local location loc1
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local timer DarkTimer = NewTimer()
local integer spell_id
local integer effect_id
local effect e
// Spell damage
set d = DARK_CONSUMPTION_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Effect
set e = AddSpecialEffectLoc("NewDarkPillar.mdl", loc)
set effect_id = RegisterEffect(e, 0)
// Register spell
set spell_id = RegisterSpell(u, null, loc, d, crit, 0,0,0,0,0,effect_id)
call DamageTargets(spell_id)
call SetTimerData(DarkTimer, spell_id)
call TimerStart(DarkTimer, GENERIC_DOT_INTERVAL, true, function Callback)
// Cleanup
set DarkTimer = null
set u = null
set e = null
set loc = null
set loc1 = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=154
//TESH.alwaysfold=0
scope Zombies initializer Init
globals
private constant integer AbilID = 'A02K'
private constant integer ZOMBIE_ID = 'U000'
constant integer ZOMBIES_MAX = 5
private unit caster
private integer array Zombie_Count[1]
private Table ZombieTable
private Stack array ZombieStack[1]
private integer N = 0
private constant integer MAX_N = ZOMBIES_MAX*10
private unit array Zombies[1]
endglobals
private function ReleaseZombie takes unit u returns nothing
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer i = GetUnitId(u)
call ZombieTable.flush(i)
call ZombieStack[id].remove(i)
call Debug_Message("Release Zombie id: "+I2S(i))
endfunction
private function KillZombie takes integer i returns nothing
local integer n = ZombieTable[i]
call KillUnit(Zombies[n])
endfunction
private function RegisterZombie takes unit u returns nothing
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer i
// Clear Stack?
if ZombieStack[id].size >= ZOMBIES_MAX then
call Debug_Message("Size bigger MAX")
// kill oldest zombie of list
set i = ZombieStack[id].last // i = unit id
call KillZombie(i)
endif
set i = GetUnitId(u)
set N = N + 1
set Zombies[N] = u
set ZombieTable[i] = N
call ZombieStack[id].add(i)
call Debug_Message("Register Zombie id: "+I2S(i)+" on slot "+I2S(N))
if N > MAX_N then
set N = 0
endif
endfunction
private function Conditions_Zombie_Dies takes nothing returns boolean
return GetUnitTypeId(GetTriggerUnit()) == ZOMBIE_ID
endfunction
private function Zombie_Dies takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local location loc = GetUnitLoc(u)
call ReleaseZombie(u)
call RemoveUnit(u)
call DestroyEffect(AddSpecialEffectLoc("Objects\\Spawnmodels\\Undead\\UndeadLargeDeathExplode\\UndeadLargeDeathExplode.mdl", loc ) )
set loc = null
set u = null
endfunction
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Target_Conditions takes nothing returns boolean
return GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) <= 0 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)
endfunction
private function RaiseAnimation2 takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
local unit u = Zombies[ZombieTable[id]]
call ReleaseTimer(t)
call SetUnitInvulnerable( u, false )
call PauseUnit(u, false)
call SetUnitAnimation(u, "stand")
set t = null
set u = null
endfunction
private function RaiseAnimation takes unit u returns nothing
local timer t = NewTimer()
call SetTimerData(t, GetUnitId(u))
call SetUnitAnimation(u, "birth")
call PauseUnit(u, true)
call SetUnitInvulnerable( u, true )
call TimerStart(t, 2, false, function RaiseAnimation2)
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local unit zombie
local location loc = GetSpellTargetLoc()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroLevel(u)
local group targets = NewGroup()
local integer i = 0
local effect e
// Get targets
call GroupEnumUnitsInRange(targets, GetLocationX(loc), GetLocationY(loc), 200, Condition(function Target_Conditions))
set e = AddSpecialEffectLoc("Abilities\\Spells\\Undead\\RegenerationAura\\ObsidianRegenAura.mdl", loc)
call RegisterEffect(e, 2)
// Rise corpses
loop
set t = FirstOfGroup(targets)
exitwhen t == null or i >= ZOMBIES_MAX
set zombie = CreateUnitAtLoc(Player(id), ZOMBIE_ID, GetUnitLoc(t), GetUnitFacing(t))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\RaiseSkeletonWarrior\\RaiseSkeleton.mdl", zombie, "origin") )
call SetHeroLevelBJ(zombie, lvl, false)
call SuspendHeroXP(zombie, true)
call SetUnitExploded(zombie, true)
call GroupRemoveUnit(targets, t)
call IndieSummon_SetMaster(zombie, u)
call RegisterZombie(zombie)
// Raise animation
// call RaiseAnimation(zombie)
call SetUnitAnimation(zombie, "birth")
call PauseUnit(zombie, true)
call SetUnitInvulnerable( zombie, true )
call TriggerSleepAction(2.0)
call SetUnitInvulnerable( zombie, false )
call PauseUnit(zombie, false)
call SetUnitAnimation(zombie, "stand")
call RemoveUnit(t)
set i = i + 1
endloop
// Cleanup
call ReleaseGroup(targets)
set targets = null
set u = null
set t = null
set e = null
set zombie = null
set loc = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local integer i
local trigger trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition( trg, Condition( function Conditions_Zombie_Dies ) )
call TriggerAddAction( trg, function Zombie_Dies )
// Zombie stack
set ZombieTable = Table.create()
set i = 2
loop
exitwhen i > 11
set ZombieStack[i] = Stack.create()
set i = i + 1
endloop
set trg = null
endfunction
endscope
//TESH.scrollpos=107
//TESH.alwaysfold=0
scope BeyondDeath initializer Init
globals
private constant integer AbilID = 'A026' // 'A04G' // 'A048'
//Buff stuff
integer BUFF_TYPE_BEYOND_DEATH
private integer AuraID = 'A03W'
private integer BuffID = 'B013'
private effect array Effects
private effect array Effects2
private constant integer SPAWN_ID = 'U003'
private unit array Summons[1]
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function CursedUnitDeath takes integer id, unit t, unit u returns nothing
local location loc = GetUnitLoc(t)
local unit spawn
local integer lvl = GetHeroLevel(u)
// Hero
if not IsUnitType(t, UNIT_TYPE_HERO) then
call RemoveUnit(t)
endif
// Splatter
call DestroyEffect(AddSpecialEffectLoc("Objects\\Spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl", loc))
if Summons[id] != null then
call KillUnit(Summons[id])
endif
set spawn = CreateUnitAtLoc(Player(id), SPAWN_ID, loc, bj_UNIT_FACING)
set UnholySpirits[id] = spawn
set Summons[id] = spawn
// Set to hero level
call SuspendHeroXP(spawn, false)
if lvl > 1 then
call SetHeroLevel(spawn, lvl, false)
endif
call SuspendHeroXP(spawn, true)
call IndieSummon_SetMaster(spawn, Heroes[id])
call SetUnitAnimation(spawn, "spell")
call PauseUnit(spawn, true)
call SetUnitInvulnerable( spawn, true )
call TriggerSleepAction(2.0)
call SetUnitInvulnerable( spawn, false )
call PauseUnit(spawn, false)
call SetUnitAnimation(spawn, "stand")
if not ( GetUnitState(Heroes[id], UNIT_STATE_LIFE) > 0 ) then
call KillUnit(spawn)
endif
set spawn = null
set loc = null
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
local unit u = db.source
local unit t = db.target
local integer id = GetPlayerId(GetOwningPlayer(u))
// Destroy effect
if Effects[GetUnitId(t)] != null then
call DestroyEffect( Effects[GetUnitId(t)] )
endif
if Effects2[GetUnitId(t)] != null then
call DestroyEffect( Effects2[GetUnitId(t)] )
endif
// Dying?
if GetUnitState(t, UNIT_STATE_LIFE) <= 0 then
call CursedUnitDeath(id, t, u)
endif
set u = null
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local dbuff db = 0
// Calculate spell damage
set d = BEYOND_DEATH_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Remove old buff
if UnitHasBuff(t, BUFF_TYPE_BEYOND_DEATH) then
call UnitRemoveBuff(t, BUFF_TYPE_BEYOND_DEATH)
endif
// Apply the buff
set db = UnitAddBuff(u, t, BUFF_TYPE_BEYOND_DEATH, BEYOND_DEATH_DURATION, lvl)
// Create effect on target (always before damage!)
set Effects[GetUnitId(t)] = AddSpecialEffectTarget("CurseofAgony.mdl", t, "overhead")
set Effects2[GetUnitId(t)] = AddSpecialEffectTarget("Abilities\\Spells\\Items\\VampiricPotion\\VampPotionCaster.mdl", t, "origin")
// Apply damage
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
set BUFF_TYPE_BEYOND_DEATH = DefineBuffType(AuraID, BuffID, 0, false, false, 0, 0, OnEnd)
// takes integer AbilId, integer BuffId, real period, boolean isPeriodic, boolean isPositive, callback onAdd, callback onPeriodic, callback onEnd returns integer
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=41
//TESH.alwaysfold=0
scope SoulShield initializer Init
globals
private constant integer AbilID = 'A03I'
//Buff stuff
integer BUFF_TYPE_SOUL_SHIELD
private integer AuraID = 'A03K'
private integer BuffID = 'B00Y'
endglobals
private function Conditions_SoulHarvest takes nothing returns boolean
return GetKillingUnit() != null and UnitHasBuff(GetKillingUnit(), BUFF_TYPE_SOUL_SHIELD)
endfunction
private function SoulHarvest takes nothing returns nothing
local unit u = GetKillingUnit()
local real r = GetShieldHpPercent(u) + SOUL_SHIELD_HARVEST_PERCENT
call Debug_Message("ShieldPercent "+R2S(r))
if r > 100 then
set r = 100
endif
call SetShieldHpPercent(u, r)
call Debug_Message("ShieldPercent "+R2S(r))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIre\\AIreTarget.mdl", u, "origin") )
set u = null
endfunction
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
if UnitHasShield(db.target) then
call DestroyShield(db.target)
endif
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local dbuff db = 0
local real ShieldLife = ( lvl * SOUL_SHIELD_HEALTH * GetSpellMod(id))
// If unit already has old buff, remove it
if UnitHasBuff(u, BUFF_TYPE_SOUL_SHIELD) then
call UnitRemoveBuff(u, BUFF_TYPE_SOUL_SHIELD)
endif
call AddShield(u,ShieldLife,0,0,1,"|cff97C1E8", true, true,0,"SoulArmor.mdl")
set db = UnitAddBuff(u, u, BUFF_TYPE_SOUL_SHIELD, SOUL_SHIELD_DURATION, lvl)
set u = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
set BUFF_TYPE_SOUL_SHIELD = DefineBuffType(AuraID, BuffID, 0, false, true, 0, 0, OnEnd)
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
// Unit dying
set trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( trg, Condition( function Conditions_SoulHarvest ) )
call TriggerAddAction( trg, function SoulHarvest )
set trg = null
endfunction
endscope
//TESH.scrollpos=41
//TESH.alwaysfold=0
scope Purge initializer Init
globals
private constant integer AbilID = 'A054'
//Buff stuff
integer BUFF_TYPE_PURGE
private integer AuraID = 'A04J'
private integer BuffID = 'B017'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
local unit t = db.target
// Reset Movement speed
call SetMoveSpeed(t)
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local dbuff db = 0
local effect e
local integer effect_id
// Spell damage
set d = PURGE_POWER * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Remove all buffs!
call UnitRemoveAllBuffs(t)
// Effect
set e = AddSpecialEffectTarget("Abilities\\Spells\\Orc\\Purge\\PurgeBuffTarget.mdl", t, "origin")
set effect_id = RegisterEffect(e, PURGE_DURATION)
// Apply the buff
set db = UnitAddBuff(u, t, BUFF_TYPE_PURGE, PURGE_DURATION, lvl)
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
call SetMoveSpeed(t)
set u = null
set t = null
set e = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
set BUFF_TYPE_PURGE = DefineBuffType(AuraID, BuffID, 0, false, false, 0, 0, OnEnd)
// takes integer AbilId, integer BuffId, real period, boolean isPeriodic, boolean isPositive, callback onAdd, callback onPeriodic, callback onEnd returns integer
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=16
//TESH.alwaysfold=0
scope HolyLight initializer Init
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A008'
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local boolean isHealing = true
// Damage
if IsUnitType(t, UNIT_TYPE_UNDEAD) then
set isHealing = false
set d = HOLY_LIGHT_POWER * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Healing
else
set isHealing = true
set d = -HOLY_LIGHT_POWER * lvl * GetSpellMod(id) * GetRandomSpellMod()
endif
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
call CreateDamageTag(u, t, d, crit, isHealing)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
// Honor
if u != t then
call IncHonorStack(id, 1)
endif
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=42
//TESH.alwaysfold=0
scope CallOfJustice initializer Init
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A04K'
endfunction
private function Target_Conditions takes nothing returns boolean
return IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(GetSpellAbilityUnit())) == true and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)
endfunction
private function Callback takes nothing returns nothing
local unit t = GetEnumUnit()
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local group targets = NewGroup()
local real d1 = 0
// Spell damage
set d = CALL_OF_JUSTICE_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Get targets
call GroupEnumUnitsInRange(targets, GetUnitX(u), GetUnitY(u), GENERIC_AOE_RANGE+200, Condition(function Target_Conditions))
call SetUnitAnimation(u, "channel")
// Burn them
loop
set t = FirstOfGroup(targets)
exitwhen t == null
if GetUnitState(t, UNIT_STATE_LIFE) > 0 then
call DestroyEffect(AddSpecialEffectTarget("TheHolyBomb.mdl", t, "origin") )
call TriggerSleepAction(0.25)
if IsUnitType(t, UNIT_TYPE_UNDEAD) then
set d1 = d*2
else
set d1 = d
endif
call CreateDamageTag(u, t, d1, crit, false)
call UnitDamageTargetEx(u, t, d1, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
endif
call GroupRemoveUnit(targets, t)
call TriggerSleepAction(0.1)
endloop
// Cleanup
call ReleaseGroup(targets)
set targets = null
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=12
//TESH.alwaysfold=0
scope EarthShock initializer Init
globals
private constant integer AbilID = 'A01O'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
// Spell damage
set d = EARTH_SHOCK_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
call TriggerSleepAction(0.01)
if GetUnitState(t, UNIT_STATE_LIFE) > 0 then
call IssueTargetOrder( u, "attack", t )
endif
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=82
//TESH.alwaysfold=0
scope HealingWave initializer Init
globals
private constant integer AbilID = 'A04B'
private constant real WAVE_DELAY = 0.2
private integer array TargetCount[1]
private unit TargetCheck = null
private sound SOUND_HEALING_WAVE
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Target_Conditions takes nothing returns boolean
return GetFilterUnit() != TargetCheck and IsPlayerAlly(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(TargetCheck)) == true and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) < GetUnitState(GetFilterUnit(), UNIT_STATE_MAX_LIFE)
endfunction
private function GetNextTartget takes integer sid, unit u returns unit
local group targets = NewGroup()
set TargetCheck = null
// Get targets
set TargetCheck = u
call GroupEnumUnitsInRange(targets, GetUnitX(u), GetUnitY(u), GENERIC_AOE_RANGE, Condition(function Target_Conditions))
set TargetCheck = GroupPickRandomUnit(targets)
call ReleaseGroup(targets)
set targets = null
if TargetCheck != null then
return TargetCheck
endif
return null
endfunction
private function HealTarget takes integer id, unit t1, unit t2, integer sid, boolean honor returns nothing
local lightning l
local unit u = GetSpellCaster(sid)
local real d = GetSpellDamage(sid)
local boolean crit = GetSpellCrit(sid)
local boolean honor1 = honor
set TargetCount[id] = TargetCount[id] + 1
set d = d * Pow(HEALING_WAVE_LOSS_FACTOR, I2R(TargetCount[id]))
//call Debug_Message("Healing Wave on unit " + GetUnitName(t2))
if TargetCount[id] == 1 then
set l = AddLightning("HWPB", true, GetUnitX(t1), GetUnitY(t1), GetUnitX(t2), GetUnitY(t2))
else
set l = AddLightning("HWSB", true, GetUnitX(t1), GetUnitY(t1), GetUnitX(t2), GetUnitY(t2))
endif
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Orc\\HealingWave\\HealingWaveTarget.mdl", t2, "origin"))
call CreateDamageTag(u, t2, d, crit, true)
call UnitDamageTargetEx(u, t2, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
// Honor
if honor1 == false and t2 != u then
call IncHonorStack(id,1)
set honor1 = true
endif
call TriggerSleepAction(WAVE_DELAY)
call DestroyLightning(l)
set l = null
set u = null
if TargetCount[id] < HEALING_WAVE_MAX_TARGETS then
set t1 = t2
set t2 = GetNextTartget(sid, t2)
if t2 != null then
call HealTarget(id, t1, t2, sid, honor1)
endif
endif
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local integer Spell_ID
// Spell healing
set d = -HEALING_WAVE_POWER * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Register spell
set Spell_ID = RegisterSpell(u, t, null, d, crit, 0,0,0,0,0,0)
set TargetCount[id] = 0
call PlaySoundOnUnitBJ(SOUND_HEALING_WAVE, 100, t)
call HealTarget(id, u, t, Spell_ID, false)
// Crit
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
call Preload( "Abilities\\Spells\\Orc\\HealingWave\\HealingWave.wav" )
set SOUND_HEALING_WAVE = CreateSound("Abilities\\Spells\\Orc\\HealingWave\\HealingWave.wav", false, true, true, 12700, 12700, "")
set trg = null
endfunction
endscope
//TESH.scrollpos=110
//TESH.alwaysfold=0
scope FireAndIce initializer Init
globals
private constant integer AbilID = 'A01D' // 'A04D'
//Buff stuff
integer BUFF_TYPE_FIRE_AND_ICE
private integer AuraID = 'A04E'
private integer BuffID = 'B015'
private effect array Effects
private real TAG_SPACE = 16
private sound SOUND_FIRE_ICE
private effect array Fire[1]
private effect array Ice[1]
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function CreateBonusTag takes unit source, unit target, real value, boolean isFire returns nothing
local texttag t = CreateTextTag()
local string s
local integer id = GetPlayerId(GetOwningPlayer(source))
set s = I2S(R2I(value))
// Let's only display damage/healing if it's not 0
if value > 0 then
call SetTextTagVisibility(t, false)
call SetTextTagText(t, s, TAG_SIZE) // 0.0184
if isFire then
call SetTextTagColor(t, 248, 161, 91, 255)
call SetTextTagPos(t, GetUnitX(target)+TAG_SPACE, GetUnitY(target)+TAG_SPACE, 0.00)
else
call SetTextTagColor(t, 168, 217, 237, 255)
call SetTextTagPos(t, GetUnitX(target)-TAG_SPACE, GetUnitY(target)-TAG_SPACE, 0.00)
endif
call SetTextTagVelocity(t, 0, 0.05)
call SetTextTagFadepoint(t, 1)
call SetTextTagLifespan(t, 2)
call SetTextTagPermanent(t, false)
endif
if Player(id) == GetLocalPlayer() then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SetTextTagVisibility(t, true)
endif
set t = null
endfunction
private function Conditions_BonusDamage takes nothing returns boolean
return GetTriggerDamageType() == DAMAGE_TYPE_ATTACK and UnitHasBuff(GetTriggerDamageSource(), BUFF_TYPE_FIRE_AND_ICE)
endfunction
private function BonusDamage takes nothing returns nothing
local unit u = GetTriggerDamageSource()
local unit t = GetTriggerDamageTarget()
local real d = GetTriggerDamage()
local real d1
local real d2
local dbuff db = GetUnitBuff(u, BUFF_TYPE_FIRE_AND_ICE)
// Fire damage
set d1 = d * FIRE_AND_ICE_FACTOR * GetRandomSpellMod()
call CreateBonusTag(u, t, d1, true)
call UnitDamageTargetEx(u, t, d1, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, false)
// Ice damage
set d2 = d * FIRE_AND_ICE_FACTOR * GetRandomSpellMod()
call CreateBonusTag(u, t, d2, false)
call UnitDamageTargetEx(u, t, d2, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, false)
set u = null
set t = null
endfunction
private function OnEnd takes nothing returns nothing
local dbuff db = GetEventBuff()
local unit u = db.source
local unit t = db.target
local integer id = GetPlayerId(GetOwningPlayer(u))
// Destroy effect
if Fire[id] != null then
call DestroyEffect( Fire[id] )
endif
if Ice[id] != null then
call DestroyEffect( Ice[id] )
endif
// Destroy spell instance
// call Debug_Message("Attempt to destroy spell id: "+I2S(db.data))
// call spell.destroy(spells[db.data])
set u = null
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
// Remove old buff
if UnitHasBuff(u, BUFF_TYPE_FIRE_AND_ICE) then
call UnitRemoveBuff(u, BUFF_TYPE_FIRE_AND_ICE)
endif
// call DestroyEffect(AddSpecialEffectLoc("Objects\\Spawnmodels\\Undead\\UndeadLargeDeathExplode\\UndeadLargeDeathExplode.mdl", loc ) )
// Add effect
set Fire[id] = AddSpecialEffectTarget("FireHands.mdl", u, "right hand")
set Ice[id] = AddSpecialEffectTarget("FrostHands.mdl", u, "left hand")
call UnitAddBuff(u, u, BUFF_TYPE_FIRE_AND_ICE, FIRE_AND_ICE_DURATION, lvl)
call PlaySoundOnUnitBJ(SOUND_FIRE_ICE, 100, u)
// call KillSoundWhenDone(SOUND_FIRE_ICE)
// Cleanup
set u = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
set BUFF_TYPE_FIRE_AND_ICE = DefineBuffType(AuraID, BuffID, 0, false, true, 0, 0, OnEnd)
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = CreateTrigger()
call TriggerRegisterDamageEvent(trg, 1)
call TriggerAddCondition(trg, Condition(function Conditions_BonusDamage))
call TriggerAddAction(trg, function BonusDamage)
call Preload( "Abilities\\Spells\\Orc\\Shockwave\\Shockwave.wav" )
set SOUND_FIRE_ICE = CreateSound("Abilities\\Spells\\Orc\\Shockwave\\Shockwave.wav", false, true, true, 12700, 12700, "")
set trg = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope FireTotem initializer Init
globals
private constant integer AbilID = 'A04H'
private unit array Totems
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local location loc = GetSpellTargetLoc()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroLevel(u)
call KillUnit(Totems[id])
set Totems[id] = CreateUnitAtLoc(Player(id), 'H00J', loc, bj_UNIT_FACING )
call SetUnitAnimationByIndex(Totems[id], 1)
call SetHeroLevelBJ(Totems[id], lvl, false)
call UnitApplyTimedLife(Totems[id], 'BOwd', TOTEM_DURATION)
set u = null
set loc = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope WaterTotem initializer Init
globals
private constant integer AbilID = 'A056'
private unit array Totems
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local location loc = GetSpellTargetLoc()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroLevel(u)
call KillUnit(Totems[id])
set Totems[id] = CreateUnitAtLoc(Player(id), 'H00K', loc, bj_UNIT_FACING )
call SetUnitAnimationByIndex(Totems[id], 1)
call SetHeroLevelBJ(Totems[id], lvl, false)
call UnitApplyTimedLife(Totems[id], 'BOwd', TOTEM_DURATION)
set u = null
set loc = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=11
//TESH.alwaysfold=0
scope FlameShock initializer Init
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A01A'
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local effect e = null
// Spell damage
set d = FLAME_SHOCK_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
set e = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl", t, "origin")
call DestroyEffect(e)
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
call IssueTargetOrder( u, "attack", t )
set e = null
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=9
//TESH.alwaysfold=0
scope BeamJustice initializer Init
globals
private constant integer AbilID = 'A024' // 'A04V'
private constant integer POINTS = 10
private constant real RANGE = 1600
private constant real WIDTH = 140
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Target_Conditions takes nothing returns boolean
return GetFilterUnit() != GetSpellAbilityUnit() and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local location loc = GetSpellTargetLoc()
local location EndPoint
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroInt(u, true)
local boolean crit = false
local real d = 0
local group targets = NewGroup()
local group targetsFinal = NewGroup()
local effect e
local real angle
local real EndX
local real EndY
local real cos
local real sin
local integer i = 0
local boolean honor = false
local real x1 = GetUnitX(u)
local real y1 = GetUnitY(u)
set e = AddSpecialEffectTarget("Kaiserbreath.mdl", u, "origin")
// Calculate Angle
set angle = Atan2(GetLocationY(loc) - y1, GetLocationX(loc) - x1) // * bj_RADTODEG
set cos = Cos(angle)
set sin = Sin(angle)
// call Debug_Message("Caster Pos: "+R2S(x1)+" "+R2S(y1)+" Angle: "+R2S(angle))
// Final end point of spell
set EndX = x1 + RANGE * cos
set EndY = y1 + RANGE * sin
// call Debug_Message("End Point: "+R2S(x2)+" "+R2S(y2)+ "cos: "+R2S(cos)+" sin: "+R2S(sin))
// set e2 = AddSpecialEffect("EarthFlare.mdl", EndX, EndY)
call SetUnitMoveSpeed(u, 0)
call SetUnitTurnSpeed(u, 0)
call SetUnitFacing(u, bj_RADTODEG*angle)
// call PauseUnit(u, true)
// Spell damage
set d = BEAM_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
// Get targets
// Zerlege Beam in einzelne Punkte und prüfe, ob Unit in Nähe ist
loop
exitwhen i >= POINTS
call GroupEnumUnitsInRange(targets, x1, y1, WIDTH, Condition(function Target_Conditions))
set x1 = x1 + (RANGE/POINTS) * cos
set y1 = y1 + (RANGE/POINTS) * sin
// Burn them
loop
set t = FirstOfGroup(targets)
exitwhen t == null
if not IsUnitInGroup(t, targetsFinal) then
call GroupAddUnit(targetsFinal, t)
endif
call GroupRemoveUnit(targets, t)
endloop
set i = i + 1
endloop
// Burn them
loop
set t = FirstOfGroup(targetsFinal)
exitwhen t == null
if IsPlayerEnemy(GetOwningPlayer(u), GetOwningPlayer(t)) then
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
elseif IsPlayerAlly(GetOwningPlayer(u), GetOwningPlayer(t)) then
// Honor
if u != t and honor == false then
call IncHonorStack(id, 1)
set honor = true
endif
call CreateDamageTag(u, t, d, crit, true)
call UnitDamageTargetEx(u, t, -d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_HEALING, false, crit)
endif
call GroupRemoveUnit(targetsFinal, t)
endloop
call TriggerSleepAction(1.75)
call SetUnitMoveSpeed(u, GetUnitDefaultMoveSpeed(u) )
call SetUnitTurnSpeed(u, GetUnitDefaultTurnSpeed(u))
// Cleanup
call DestroyEffect(e)
set e = null
call ReleaseGroup(targets)
call ReleaseGroup(targetsFinal)
set targets = null
set targetsFinal = null
set u = null
set t = null
set loc = null
set EndPoint = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=12
//TESH.alwaysfold=0
scope ThrowRock initializer Init
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A04S'
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroStr(u, true)
local boolean crit = false
local real dx = GetUnitX(u) - GetUnitX(t)
local real dy = GetUnitY(u) - GetUnitY(t)
local real dist = SquareRoot(dx * dx + dy * dy)
local effect e
local real d = 0
// Spell damage
set d = ROCK_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
call TriggerSleepAction( (dist/800) * 0.7)
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
// function KnockbackTarget takes unit source, unit targ, real angle, real startspeed, real decrement, boolean killDestructables, boolean knockAdjacent, boolean chainAdjacent returns boolean
set e = AddSpecialEffect("BloodbathTarget.mdl", GetUnitX(t), GetUnitY(t))
call KnockbackTarget(u,t, GetUnitFacing(u), 800, 1400, false, false, false)
call DestroyEffect(e)
set e = null
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=39
//TESH.alwaysfold=0
scope Thunderstorm initializer Init
globals
private constant integer AbilID = 'A04D'
private real TAG_SPACE = 16
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function CreateBonusTag takes unit source, unit target, real value, boolean isFire returns nothing
local texttag t = CreateTextTag()
local string s
local integer id = GetPlayerId(GetOwningPlayer(source))
set s = I2S(R2I(value))
// Let's only display damage/healing if it's not 0
if value > 0 then
call SetTextTagVisibility(t, false)
call SetTextTagText(t, s, TAG_SIZE) // 0.0184
call SetTextTagColor(t, 175, 220, 255, 255)
call SetTextTagPos(t, GetUnitX(target)+TAG_SPACE, GetUnitY(target)+TAG_SPACE, 0.00)
call SetTextTagVelocity(t, 0, 0.05)
call SetTextTagFadepoint(t, 1)
call SetTextTagLifespan(t, 2)
call SetTextTagPermanent(t, false)
endif
if Player(id) == GetLocalPlayer() then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SetTextTagVisibility(t, true)
endif
set t = null
endfunction
private function Conditions_BonusDamage takes nothing returns boolean
return GetTriggerDamageType() == DAMAGE_TYPE_ATTACK and UnitHasItemOfTypeBJ(GetTriggerDamageSource(), 'I01H')
endfunction
private function BonusDamage takes nothing returns nothing
local unit u = GetTriggerDamageSource()
local unit t = GetTriggerDamageTarget()
local real d = GetTriggerDamage()
local real d1
call Debug_Message("Thunderstorm Damage")
// Lightning damage
set d1 = d * 0.3 * GetRandomSpellMod()
call CreateBonusTag(u, t, d1, true)
call UnitDamageTargetEx(u, t, d1, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, false)
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterDamageEvent(trg, 1)
call TriggerAddCondition(trg, Condition(function Conditions_BonusDamage))
call TriggerAddAction(trg, function BonusDamage)
set trg = null
endfunction
endscope
//TESH.scrollpos=97
//TESH.alwaysfold=0
scope BladeKilJaeden initializer Init
globals
private constant integer DEMON = 'N006'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A00X'
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit Demon
local integer id = GetPlayerId(GetOwningPlayer(u))
local location TempPoint = GetUnitLoc(u)
local effect e1
local effect e2
local effect e3
local integer i = GetHeroLevel(u)
local player p = GetOwningPlayer(u)
// call RemoveItem( GetManipulatedItem() )
call SetUnitExploded( u, true )
call CreateTagOnUnit(u, "|cffA68BFFThis feels ... |cffF30505strange!|r")
if UnitHasAnyBuff(u) then
call UnitRemoveAllBuffs(u)
endif
call SetUnitInvulnerable( u, true )
call SetUnitMoveSpeed( u, 0.00 )
call TriggerSleepAction(1.0)
set e1 = AddSpecialEffectLoc("Abilities\\Spells\\Human\\FlameStrike\\FlameStrike1.mdl", TempPoint)
call TriggerSleepAction(1.0)
set e2 = AddSpecialEffectLoc("Firaga.mdl", TempPoint)
call TriggerSleepAction(1.5)
set e3 = AddSpecialEffectLoc("Objects\\Spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl", TempPoint)
call GroupRemoveUnit( Hero_Group, u )
set Inactive_Heroes[id] = u
call SetUnitInvulnerable( u, false )
call SetUnitMoveSpeed( u, GetUnitDefaultMoveSpeed(u) )
call KillUnit( u )
if ( Water_Elementals[id] != null ) then
call KillUnit( Water_Elementals[id])
endif
if ( Pets_Bears[id] != null ) then
call KillUnit( Pets_Bears[id])
endif
call TriggerSleepAction(0.2)
set Demon = CreateUnitAtLoc( p, DEMON, TempPoint, bj_UNIT_FACING )
call SetHeroLevelBJ(Demon, i , false)
call SelectUnitForPlayerSingle(Demon, Player(id))
call GroupAddUnit( Hero_Group, Demon )
set Heroes[id] = Demon
call RemoveLocation(TempPoint)
set TempPoint = null
set u = null
set Demon = null
call DestroyEffect(e1)
call DestroyEffect(e2)
call DestroyEffect(e3)
set e1 = null
set e2 = null
set e3 = null
set p = null
endfunction
private function Demon_Dies_Conditions takes nothing returns boolean
return GetUnitTypeId(GetDyingUnit()) == DEMON
endfunction
private function Demon_Dies_Actions takes nothing returns nothing
local unit Demon = GetDyingUnit()
local integer id = GetPlayerId(GetOwningPlayer(Demon))
local unit OldHero = Inactive_Heroes[id]
local effect e
set e = AddSpecialEffectLoc("ChaosExplosion.mdl", GetUnitLoc(Demon))
call GroupAddUnit( Hero_Group, OldHero )
set Heroes[id] = OldHero
call GroupRemoveUnit( Hero_Group, Demon )
call RemoveUnit(Demon)
set Inactive_Heroes[id] = null
call DestroyEffect(e)
set e = null
// Death Timer
// call SetTimerData(Resurrection_Timers[id], id)
// call TimerStart(Resurrection_Timers[id], HERO_DEAD_TIME, false, function Revive_Hero)
// Window
// set Resurrection_Timer_Windows[id] = CreateTimerDialog(Resurrection_Timers[id])
// call TimerDialogSetTitle(Resurrection_Timer_Windows[id], PlayerNames[id])
// call TimerDialogDisplayForPlayerBJ(true, Resurrection_Timer_Windows[id], Player(id))
set OldHero = null
set Demon = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition(trg, Condition( function Conditions ) )
call TriggerAddAction(trg, function Actions )
set trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( trg, Condition( function Demon_Dies_Conditions ) )
call TriggerAddAction( trg, function Demon_Dies_Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=3
//TESH.alwaysfold=0
function Trig_Wrath_of_Nature_Conditions takes nothing returns boolean
return GetUnitTypeId(GetTriggerUnit()) == 'o005'
endfunction
function Trig_Wrath_of_Nature_Actions takes nothing returns nothing
local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
local integer i = 0
local unit u
local effect e
local boolean switch = false
loop
exitwhen i > 4
call TriggerSleepAction(5.0)
if switch then
set u = CreateUnitAtLoc(Player(id), 'n00F', GetUnitLoc(GetTriggerUnit()), bj_UNIT_FACING)
set switch = false
else
set u = CreateUnitAtLoc(Player(id), 'n00D', GetUnitLoc(GetTriggerUnit()), bj_UNIT_FACING)
set switch = true
endif
call UnitApplyTimedLife(u, 'BTLF', 120)
set e = AddSpecialEffectLoc("CenarionFury.mdl", GetUnitLoc(GetTriggerUnit()))
set i = i + 1
call DestroyEffect(e)
endloop
// call DestroyEffect(e)
set e = null
set u = null
endfunction
//===========================================================================
function InitTrig_Wrath_of_Nature takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterEnterRectSimple( trg, bj_mapInitialPlayableArea )
call TriggerAddCondition( trg, Condition( function Trig_Wrath_of_Nature_Conditions ) )
call TriggerAddAction( trg, function Trig_Wrath_of_Nature_Actions )
set trg = null
endfunction
//TESH.scrollpos=35
//TESH.alwaysfold=0
scope TheCrippler initializer Init
globals
//Buff stuff
private real TAG_SPACE = 16
endglobals
private function CreateBonusTag takes unit source, unit target, real value, boolean isFire returns nothing
local texttag t = CreateTextTag()
local string s
local integer id = GetPlayerId(GetOwningPlayer(source))
set s = I2S(R2I(value))
// Let's only display damage/healing if it's not 0
if value > 0 then
call SetTextTagVisibility(t, false)
call SetTextTagText(t, s, TAG_SIZE) // 0.0184
call SetTextTagColor(t, 206, 40, 40, 255)
call SetTextTagPos(t, GetUnitX(target)+TAG_SPACE, GetUnitY(target)+TAG_SPACE, 0.00)
call SetTextTagVelocity(t, 0, 0.05)
call SetTextTagFadepoint(t, 1)
call SetTextTagLifespan(t, 2)
call SetTextTagPermanent(t, false)
endif
if Player(id) == GetLocalPlayer() then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SetTextTagVisibility(t, true)
endif
set t = null
endfunction
private function Conditions takes nothing returns boolean
return GetTriggerDamageType() == DAMAGE_TYPE_ATTACK and UnitHasItemOfTypeBJ(GetTriggerDamageSource(), 'I00M')
endfunction
private function Actions takes nothing returns nothing
local unit u = GetTriggerDamageSource()
local unit t = GetTriggerDamageTarget()
local real d = GetTriggerDamage()
local real d1
local integer id = GetPlayerId(GetOwningPlayer(u))
local dbuff db = 0
local integer Spell_ID
// Crippling damage
set d1 = d * 0.2
// set d1 = GetRandomSpellMod(d1)
call CreateBonusTag(u, t, d1, true)
call UnitDamageTargetEx(u, t, d1, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, false)
set u = null
set t = null
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterDamageEvent(trg, 1)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope DragonCompanion initializer Init
globals
private constant integer AbilID = 'A057'
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilID
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local integer id = GetPlayerId(GetOwningPlayer(u))
local real x = GetUnitX(GetSpellAbilityUnit()) + GetRandomReal(-128, 128 )
local real y = GetUnitY(GetSpellAbilityUnit()) + GetRandomReal(-128, 128 )
if Dragons[id] != null then
call KillUnit(Dragons[id])
endif
set Dragons[id] = CreateUnit(Player(id), 'n00J', x, y, bj_UNIT_FACING)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl", Dragons[id], "origin") )
call IndieSummon_SetMaster(Dragons[id], u)
set u = null
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerAddAction(trg, function Actions)
set trg = null
endfunction
endscope
//TESH.scrollpos=60
//TESH.alwaysfold=0
// **************************************************************************
// ** **
// ** Charge **
// ** ————————————— **
// ** **
// ** A simple Charge Spell **
// ** **
// ** By: Majin **
// **
// ** **
// **************************************************************************
library ChargeConfig
globals
//CHECK THE CHARGEEXEC TRIGGER FOR MORE OPTIONS
//ID CONFIGURATIONS FOR SPELLS AND DUMMY UNITS
//ID of the Charge spell
constant integer SPELLID = 'A022'
//ID of the dummy unit used for the attack at the end of the charge. Set this to 0 for no unit
constant integer DUMMYID = 'e008'
//ID of the spell to be casted by the dummy unit once the charge is complete (Has to be a spell with
//a Target). Set this to 0 for no spell. The Spell effect depends on the level of the Charge Spell
//So it's advisable to set the number of levels of this spell at the same value of the level of the
//Charge Spell
constant integer DUMMYSPELLID = 'A04L'
//Order String for the spell to be casted by the dummy unit
constant string SPELLORDERID = "thunderbolt"
//SPECIAL EFFECTS CONFIGURATION
//You can set this to a non existand model (or change the code of the spell) if you don't want that
//effect
//Special Effect attached on the unit (in this example it will look like a red trail)
constant string ATTACHEDEFFECT = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl"
//Special Effect created by the unit while walking
constant string WALKEFFECT = "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl"
//Special Effect used at the end of the Charge
constant string ENDINGEFFECT = "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"
//NUMERICAL SETTINGS
//Charge Starting Speed
constant real STARTSPEED = 20.00
//Max Speed that can be reached by the Caster unit while charging
constant real MAXSPEED = 100.00
//Damage Dealt at the end of the Charge (0 for no damage). DEPENDS ON LEVEL
constant real CHARGEDAMAGE = 5.00
//Minimum Distance at where a unit can Charge (0 for no min distance)
//Make sure the dummy spell has a longer distance than this
constant real MINDISTANCE = 300.00
//Maximum Distance at where a unit can Charge (0 for no max distance)
//This is mainly used to interrupt the charge if the target unit gets teleported somewhere else
//Make sure the dummy spell has a distance equal or less than this number
constant real MAXDISTANCE = 2000.00
//KNOCKBACK SETTINGS
//Theese settings refer to the Knock trigger which is not made by me but by Silvenon. If you want
//to know more about this script, got to
//http://www.hiveworkshop.com/forums/jass-functions-413/knockback-unit-35545/
//Special Effect created by the knockback
constant string KNOCKEFFECT = "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl"
//The Distance of the Knockback effect. DEPENDS ON LEVEL
constant real KNOCKDISTANCE = 50.00
//The Duration of the Knockback effect
constant real KNOCKDURATION = 1.5
//Tree Destroying effect
//If you want trees destroyed behind your target while he's knocked back, then set this to true
//Otherwise set this to false. See the Knock Trigger for more configuration options
constant boolean KNOCKTREECHECK = true
//Knockback Effect
//This is the effect played on the Knocked Back Unit. If you set this to 0 then no effect will be played
//If you set this to 1 then the effect set on the KnockEffect() function is played as a periodic effect
//If you set this to 2 then the effect will be attached on the unit and destroyed once the knocback ends
constant integer KNOCKPLAYEFFECT = 1
//Attachement point of the effect played during the knockback. Default is "chest"
constant string KNOCKATTACH = "Foot"
//You may want to check the ChargeExec trigger for more Configuration Options
//PATCCHECKER SETTINGS
//ID of the dummy unit used for the path checker function (has to be an invulnerable locusted unit with No model)
constant integer PATHCHECKERID = 'e00A'
//ID of the permanent windwalk spell used for the path checker function
constant integer SPELLPATHID = 'A04M'
endglobals
function KnockTree takes nothing returns real
if (KNOCKTREECHECK==true) then
return 150.00
endif
return 0.00
endfunction
endlibrary
//TESH.scrollpos=73
//TESH.alwaysfold=0
// **************************************************************************
// ** **
// ** Charge **
// ** ————————————— **
// ** **
// ** A simple Charge Spell **
// ** **
// ** By: Majin **
// **
// ** **
// **************************************************************************
library ChargeExec requires Knockback, Itemsystem
struct ChargeLoop
private real ChargeTargetx
private real ChargeTargety
private real ChargeEndx
private real ChargeEndy
private real ChargeLocx
private real ChargeLocy
private real ChargeNextx
private real ChargeNexty
private unit ChargeTarget
private unit ChargeCaster
private real ChargeAngle
private real ChargeDistance
private effect ChargeEffect
private timer ChargeTimer
private boolean ChargeCond = false
private integer SpellLvl
//START OF CONFIGURATION METHODS
//With this method you can set the "acceleration rate" (Physicists Forgive me) of the charge.
//You can use any kind of numeric function (for example this.ChargeDistance * 2.00 will double
//The speed at every loop)
private method ChangeDistance takes nothing returns real
return this.ChargeDistance + 1.00
endmethod
//END OF CONFIGURATION METHODS
//START OF CUSTOMIZABLE METHODS
//This method sets the conditions when to activate the AlmostCharge method. In particular
//You may be interested in changing the distance at where the condition is true.
//In this Example it will be activated when the Caster is 16x times the Charge Speed Far away
//From the target
private method AlmostChargeCond takes nothing returns boolean
return ((GetDistance(this.ChargeLocx, this.ChargeLocy, this.ChargeEndx, this.ChargeEndy) < ( this.ChargeDistance * 16.00 )) and this.ChargeCond == false)
endmethod
//Actions to take when the Charge is almost completed. In this example the caster will play
//The slam animation (Being a Blademaster, it will jump in the air while attacking)
private method AlmostCharge takes nothing returns nothing
set this.ChargeCond = true
call SetUnitTimeScale( this.ChargeCaster, 2.00 )
call SetUnitAnimation( this.ChargeCaster, "slam" )
call QueueUnitAnimation( this.ChargeCaster, "stand")
endmethod
//Actions to take when the Caster reaches its target and the charge is completed.
//In this example the target unit will be stunned and you will see a Thunderclap effect on the ground
private method CompleteCharge takes nothing returns nothing
local effect tempEffect
local unit dummy
local real angle=GetAngle(this.ChargeLocx, this.ChargeLocy, this.ChargeEndx, this.ChargeEndy)
// MoCo
local unit u = this.ChargeCaster
local unit t = this.ChargeTarget
local integer id = GetPlayerId(GetOwningPlayer(u))
local integer lvl = GetHeroStr(u, true)
local boolean crit = false
local effect e
local effect e2
local real d = 0
set this.ChargeLocx = this.ChargeNextx
set this.ChargeLocy = this.ChargeNexty
set this.ChargeNextx = PolarProjectionx(this.ChargeLocx, this.ChargeDistance, this.ChargeAngle)
set this.ChargeNexty = PolarProjectiony(this.ChargeLocy, this.ChargeDistance, this.ChargeAngle)
call DestroyEffect(AddSpecialEffect( WALKEFFECT, this.ChargeLocx, this.ChargeLocy ))
call SetUnitX( this.ChargeCaster, this.ChargeEndx )
call SetUnitY( this.ChargeCaster, this.ChargeEndy )
set dummy = CreateUnit( GetOwningPlayer(this.ChargeCaster), DUMMYID, this.ChargeLocx, this.ChargeLocy, 0 )
call UnitAddAbility( dummy, DUMMYSPELLID )
call SetUnitAbilityLevel(dummy, DUMMYSPELLID, this.SpellLvl)
call IssueTargetOrder( dummy, SPELLORDERID, this.ChargeTarget )
call UnitApplyTimedLife( dummy, 'BTLF', 1.00)
call DestroyEffect(AddSpecialEffect( ENDINGEFFECT, this.ChargeLocx, this.ChargeLocy ))
// MoCo
// Spell damage
set d = CHARGE_DAMAGE * lvl * GetSpellMod(id) * GetRandomSpellMod()
// Crit
if GetRandomReal(1,100) <= GetCritChance(u) then
set crit = true
set d = d * CRIT_FACTOR
endif
set e = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Incinerate\\IncinerateBuff.mdl", u, "weapon")
set e2 = AddSpecialEffectTarget("Abilities\\Spells\\Orc\\SpiritLink\\SpiritLinkZapTarget.mdl", u, "overhead")
call CreateDamageTag(u, t, d, crit, false)
call UnitDamageTargetEx(u, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPELL, false, crit)
call IssueTargetOrder( u, "attack", t )
// call UnitDamageTarget( this.ChargeCaster, this.ChargeTarget, CHARGEDAMAGE*this.SpellLvl, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS )
call PauseUnit( this.ChargeCaster, false )
//This is the Knockback effect, see the Knock Trigger for more customization options
call KnockbackEx(this.ChargeTarget, KNOCKDISTANCE*this.SpellLvl, angle, KNOCKDURATION, KnockTree(), KNOCKPLAYEFFECT, KNOCKEFFECT, KNOCKATTACH)
call IssueTargetOrder( this.ChargeCaster, "attack", this.ChargeTarget )
// MoCo
call DestroyEffect(e)
call DestroyEffect(e2)
set e = null
set e2 = null
set u = null
set t = null
set dummy = null
endmethod
//What to do during the charge, the unit is moved, an effect is placed on the ground and
//the charging speed is increased
private method ContinueCharge takes nothing returns nothing
call DestroyEffect(AddSpecialEffect( WALKEFFECT, this.ChargeLocx, this.ChargeLocy ))
call SetUnitX(this.ChargeCaster, this.ChargeNextx)
call SetUnitY(this.ChargeCaster, this.ChargeNexty)
call SetUnitFacing(this.ChargeCaster, bj_RADTODEG * GetAngle(this.ChargeNextx, this.ChargeNexty, this.ChargeTargetx, this.ChargeTargety))
set this.ChargeLocx = this.ChargeNextx
set this.ChargeLocy = this.ChargeNexty
set this.ChargeNextx = PolarProjectionx(this.ChargeLocx, this.ChargeDistance, this.ChargeAngle)
set this.ChargeNexty = PolarProjectiony(this.ChargeLocy, this.ChargeDistance, this.ChargeAngle)
if (this.ChargeDistance <= MAXSPEED) then
set this.ChargeDistance = this.ChangeDistance()
endif
endmethod
//END OF CUSTOMIZABLE METHODS
//START OF OTHER METHODS
//This is the main method executed during the charge
public static method ChargeActions takes nothing returns nothing
local ChargeLoop l=GetTimerInt(GetExpiredTimer())
set l.ChargeTargetx = GetUnitX(l.ChargeTarget)
set l.ChargeTargety = GetUnitY(l.ChargeTarget)
set l.ChargeEndx = PolarProjectionx(l.ChargeTargetx, 100.00, GetAngle(l.ChargeTargetx, l.ChargeTargety, l.ChargeLocx, l.ChargeLocy))
set l.ChargeEndy = PolarProjectiony(l.ChargeTargety, 100.00, GetAngle(l.ChargeTargetx, l.ChargeTargety, l.ChargeLocx, l.ChargeLocy))
set l.ChargeAngle = GetAngle(l.ChargeLocx, l.ChargeLocy, l.ChargeEndx, l.ChargeEndy)
if ( l.AlmostChargeCond() ) then
//What to do when the caster is about to reach the target
call l.AlmostCharge()
endif
//If the Target gets too far away (by teleportation, for example) then stops the Charge
if ( GetDistance(l.ChargeLocx, l.ChargeLocy, l.ChargeEndx, l.ChargeEndy) >= MAXDISTANCE and (MAXDISTANCE != 0.00) ) then
call l.StopCharge()
endif
if ( l.ChargeConditions() ) then
//If the unit hasn't reached the target yet, then execute this
call l.ContinueCharge()
call TimerAttach(l.ChargeTimer,0.03,l,function ChargeLoop.ChargeActions)
else
if ( l.ChargeCompleted() ) then
//What to do if the charge is succesfully completed
call l.CompleteCharge()
endif
call l.StopCharge()
endif
endmethod
//Actions to take once the Charge is being stopped (either because it wasn't possible to complete
//the charge or because the caster reached its target)
private method StopCharge takes nothing returns nothing
set this.ChargeCond = false
call SetUnitPathing(this.ChargeCaster, true)
call PauseUnit(this.ChargeCaster, false)
call SetUnitAnimation(this.ChargeCaster, "stand")
call SetUnitTimeScale(this.ChargeCaster, 1.00)
call DestroyEffect(this.ChargeEffect)
call this.destroy()
endmethod
private method ChargeCompleted takes nothing returns boolean
if ((GetDistance(this.ChargeLocx, this.ChargeLocy, this.ChargeEndx, this.ChargeEndy) <= this.ChargeDistance*1.10) and IsPointWalkable(this.ChargeNextx, this.ChargeNexty)) then
if ((IsTerrainPathable(this.ChargeNextx, this.ChargeNexty, PATHING_TYPE_WALKABILITY) == false ) and ( (GetUnitState(this.ChargeTarget, UNIT_STATE_LIFE)<=0) == false )) then
if(((GetUnitState(this.ChargeCaster, UNIT_STATE_LIFE) <= 0) == false)) then
return true
endif
endif
endif
return false
endmethod
private method ChargeConditions takes nothing returns boolean
if ((GetDistance(this.ChargeLocx, this.ChargeLocy, this.ChargeEndx, this.ChargeEndy) > this.ChargeDistance*1.10) and IsPointWalkable(this.ChargeNextx, this.ChargeNexty)) then
if ((IsTerrainPathable(this.ChargeNextx, this.ChargeNexty, PATHING_TYPE_WALKABILITY) == false ) and ( (GetUnitState(this.ChargeTarget, UNIT_STATE_LIFE)<=0) == false )) then
if(((GetUnitState(this.ChargeCaster, UNIT_STATE_LIFE) <= 0) == false)) then
return true
endif
endif
endif
return false
endmethod
private method onDestroy takes nothing returns nothing
call ReleaseTimer2(this.ChargeTimer)
set this.ChargeTarget = null
set this.ChargeCaster = null
set this.ChargeEffect = null
endmethod
static method create takes real pChargeTargetx, real pChargeTargety, real pChargeEndx, real pChargeEndy, real pChargeLocx, real pChargeLocy, real pChargeNextx, real pChargeNexty, unit pChargeTarget, unit pChargeCaster, real pChargeAngle, real pChargeDistance, effect pChargeEffect, timer pChargeTimer returns ChargeLoop
local ChargeLoop l = ChargeLoop.allocate()
set l.ChargeTargetx = pChargeTargetx
set l.ChargeTargety = pChargeTargety
set l.ChargeEndx = pChargeEndx
set l.ChargeEndy = pChargeEndy
set l.ChargeLocx = pChargeLocx
set l.ChargeLocy = pChargeLocy
set l.ChargeNextx = pChargeNextx
set l.ChargeNexty = pChargeNexty
set l.ChargeTarget = pChargeTarget
set l.ChargeCaster = pChargeCaster
set l.ChargeAngle = pChargeAngle
set l.ChargeDistance = pChargeDistance
set l.ChargeEffect = pChargeEffect
set l.ChargeTimer = pChargeTimer
set l.SpellLvl = GetUnitAbilityLevel(l.ChargeCaster, SPELLID)
return l
endmethod
//END OF OTHER METHODS
endstruct
endlibrary
//TRIGGER OF THE CHARGE SPELL
scope Charge initializer InitTrig
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SPELLID
endfunction
private function CheckActions takes nothing returns nothing
local real ChargeLocx = GetUnitX(GetTriggerUnit())
local real ChargeLocy = GetUnitY(GetTriggerUnit())
local real ChargeEndx = GetUnitX(GetSpellTargetUnit())
local real ChargeEndy = GetUnitY(GetSpellTargetUnit())
// local sound s
if ( GetDistance(ChargeLocx, ChargeLocy, ChargeEndx, ChargeEndy) <= (MINDISTANCE) ) then
call DisplayTextToPlayer( GetOwningPlayer(GetTriggerUnit()), 0, 0, "|cffFFCC00Target is too close!|r" )
// set s = CreateSound("Sound\\Interface\\Error.wav", false, false, true, 12700, 12700, "")
// call StartSound(s)
// call KillSoundWhenDone(s)
// set s = null
call IssueImmediateOrder( GetTriggerUnit(), "stop" )
endif
endfunction
private function InitActions takes nothing returns nothing
local timer ChargeTimer = NewTimer2()
local effect ChargeEffect
local unit ChargeCaster = GetTriggerUnit()
local unit ChargeTarget = GetSpellTargetUnit()
local real ChargeDistance = STARTSPEED
local real ChargeLocx = GetUnitX(ChargeCaster)
local real ChargeLocy = GetUnitY(ChargeCaster)
local real ChargeTargetx = GetUnitX(ChargeTarget)
local real ChargeTargety = GetUnitY(ChargeTarget)
local real ChargeEndx = PolarProjectionx(ChargeTargetx, 100.00, GetAngle(ChargeTargetx, ChargeTargety, ChargeLocx, ChargeLocy))
local real ChargeEndy = PolarProjectiony(ChargeTargety, 100.00, GetAngle(ChargeTargetx, ChargeTargety, ChargeLocx, ChargeLocy))
local real ChargeAngle = GetAngle(ChargeLocx, ChargeLocy, ChargeEndx, ChargeEndy)
local real ChargeNextx = PolarProjectionx(ChargeLocx, ChargeDistance, ChargeAngle)
local real ChargeNexty = PolarProjectiony(ChargeLocy, ChargeDistance, ChargeAngle)
local ChargeLoop stru
set ChargeEffect = AddSpecialEffectTarget(ATTACHEDEFFECT, ChargeCaster, "chest" )
set stru = ChargeLoop.create(ChargeTargetx, ChargeTargety, ChargeEndx, ChargeEndy, ChargeLocx, ChargeLocy, ChargeNextx, ChargeNexty, ChargeTarget, ChargeCaster, ChargeAngle, ChargeDistance, ChargeEffect, ChargeTimer)
call SetUnitPathing(ChargeCaster, false)
call SetUnitTimeScale(ChargeCaster, 3)
call IssueImmediateOrder(ChargeCaster, "stop" )
call PauseUnit(ChargeCaster, true)
if GetUnitTypeId(ChargeCaster) == 'O009' then
call SetUnitAnimationByIndex(ChargeCaster,6) // 6 Orc
else
call SetUnitAnimationByIndex(ChargeCaster,6) // 3 Human
endif
call TimerAttach(ChargeTimer,0,stru,function ChargeLoop.ChargeActions)
set ChargeTimer = null
set ChargeEffect = null
set ChargeCaster = null
set ChargeTarget = null
endfunction
private function InitTrig takes nothing returns nothing
local trigger ChargeCheck = CreateTrigger()
local trigger ChargeInit = CreateTrigger()
local filterfunc f = Filter(function AntiLeak)
local integer i = 0
loop
exitwhen i == 16
call TriggerRegisterPlayerUnitEvent(ChargeCheck,Player(i),EVENT_PLAYER_UNIT_SPELL_CAST,truefilter)
call TriggerRegisterPlayerUnitEvent(ChargeInit,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,truefilter)
set i = i + 1
endloop
call TriggerAddCondition(ChargeCheck, Condition(function Conditions))
call TriggerAddAction(ChargeCheck, function CheckActions)
call TriggerAddCondition(ChargeInit, Condition(function Conditions))
call TriggerAddAction(ChargeInit, function InitActions)
set ChargeCheck = null
set ChargeInit = null
set f = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Knockback initializer Init requires Walkable
// **************************************************************************
// ** **
// ** Knockback(Ex) **
// ** ————————————— **
// ** **
// ** A function made for efficient knockbacking **
// ** **
// ** By: Silvenon **
// ** **
// **************************************************************************
//=======================================//
//Credits to PitzerMike for this function//
//=======================================//
private function TreeFilter takes nothing returns boolean
local destructable d = GetFilterDestructable()
local boolean i = IsDestructableInvulnerable(d)
local unit u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMYID, GetWidgetX(d), GetWidgetY(d), 0)
local boolean result = false
call UnitAddAbility(u, 'Ahrl')
if i then
call SetDestructableInvulnerable(d, false)
endif
set result = IssueTargetOrder(u, "harvest", d)
call RemoveUnit(u)
if i then
call SetDestructableInvulnerable(d, true)
endif
set u = null
set d = null
return result
endfunction
//===========================================================================
globals
private timer Tim = CreateTimer()
private integer Total = 0
private boolexpr Cond = null
private integer array Ar
private boolean array BoolAr
private real MAX_X
private real MAX_Y
private real MIN_X
private real MIN_Y
endglobals
private constant function Interval takes nothing returns real
return 0.04
endfunction
private function KillTree takes nothing returns nothing
if BoolAr[0] then
call KillDestructable(GetEnumDestructable())
else
set BoolAr[1] = true
endif
endfunction
public struct Data
unit u
real d1
real d2
real sin
real cos
real r
string s = ""
effect e = null
static method create takes unit u, integer q, real d, real a, real r, integer t, string s, string p returns Data
local Data dat = Data.allocate()
set dat.u = u
set dat.d1 = 2 * d / (q + 1)
set dat.d2 = dat.d1 / q
set dat.sin = Sin(a)
set dat.cos = Cos(a)
set dat.r = r
if s != "" and s != null then
if t == 2 then
if p != "" and p != null then
set dat.e = AddSpecialEffectTarget(s, u, p)
else
set dat.e = AddSpecialEffectTarget(s, u, "chest")
endif
elseif t == 1 then
set dat.s = s
endif
endif
call SetUnitPosition(u, GetUnitX(u), GetUnitY(u))
call PauseUnit(u, true)
if Total == 0 then
call TimerStart(Tim, Interval(), true, function Data.Execute)
endif
set Total = Total + 1
set Ar[Total - 1] = dat
return dat
endmethod
static method Execute takes nothing returns nothing
local Data dat
local integer i = 0
local real x
local real y
local rect r
local real rad
loop
exitwhen i >= Total
set dat = Ar[i]
if dat.s != "" and dat.s != null then
set x = GetUnitX(dat.u)
set y = GetUnitY(dat.u)
call DestroyEffect(AddSpecialEffect(dat.s, x, y))
set x = x + dat.d1 * dat.cos
set y = y + dat.d1 * dat.sin
else
set x = GetUnitX(dat.u) + dat.d1 * dat.cos
set y = GetUnitY(dat.u) + dat.d1 * dat.sin
endif
if dat.r != 0 then
set BoolAr[0] = dat.r > 0
set rad = dat.r
if not BoolAr[0] then
set rad = rad * (-1)
endif
set r = Rect(x - rad, y - rad, x + rad, y + rad)
call EnumDestructablesInRect(r, Cond, function KillTree)
call RemoveRect(r)
set r = null
endif
if (x < MAX_X and y < MAX_Y and x > MIN_X and y > MIN_Y) and not BoolAr[1] and (IsPointWalkable(x, y)) then
call SetUnitX(dat.u, x)
call SetUnitY(dat.u, y)
endif
set dat.d1 = dat.d1 - dat.d2
if dat.d1 <= 0 or (x > MAX_X or y > MAX_Y or x < MIN_X or y < MIN_Y) or BoolAr[1] or not(IsPointWalkable(x, y)) then
set Ar[i] = Ar[Total - 1]
set Total = Total - 1
call dat.destroy()
endif
set i = i + 1
endloop
if Total == 0 then
call PauseTimer(Tim)
endif
endmethod
method onDestroy takes nothing returns nothing
if .e != null then
call DestroyEffect(.e)
endif
call PauseUnit(.u, false)
set BoolAr[0] = false
set BoolAr[1] = false
endmethod
endstruct
function KnockbackEx takes unit u, real d, real a, real w, real r, integer t, string s, string p returns nothing
call Data.create(u, R2I(w / Interval()), d, a, r, t, s, p)
endfunction
function Knockback takes unit u, real d, real a, real w returns nothing
call Data.create(u, R2I(w / Interval()), d, a, 0, 0, "", "")
endfunction
private function Init takes nothing returns nothing
set Cond = Filter(function TreeFilter)
set BoolAr[0] = false
set BoolAr[1] = false
set MAX_X = GetRectMaxX(bj_mapInitialPlayableArea) - 64
set MAX_Y = GetRectMaxY(bj_mapInitialPlayableArea) - 64
set MIN_X = GetRectMinX(bj_mapInitialPlayableArea) + 64
set MIN_Y = GetRectMinY(bj_mapInitialPlayableArea) + 64
endfunction
endlibrary
//TESH.scrollpos=3
//TESH.alwaysfold=0
// **************************************************************************
// ** **
// ** Check Pathability Function **
// ** ————————————— **
// ** **
// ** A Function that checks if a unit can walk over a certain area **
// ** (Ignores other units but not buildings, trees and other obstacles) **
// ** **
// ** By: Majin **
// **
// ** **
// **************************************************************************
library Walkable initializer init requires ChargeConfig, Math
globals
unit pathchecker
rect pathrect
filterfunc truefilter
endglobals
function HideItems takes nothing returns nothing
call SetItemVisible(GetEnumItem(), false)
endfunction
function UnHideItems takes nothing returns nothing
call SetItemVisible(GetEnumItem(), true)
endfunction
function IsPointWalkable takes real x, real y returns boolean
local boolean b
call SetUnitPosition(pathchecker,x,y)
set b=((GetUnitX(pathchecker)-x)*(GetUnitX(pathchecker)-x)+((GetUnitY(pathchecker)-y)*(GetUnitY(pathchecker)-y))<=1)
if (b==false) then
call MoveRectTo(pathrect, x, y)
call EnumItemsInRect(pathrect,truefilter,function HideItems)
call SetUnitPosition(pathchecker,x,y)
set b=((GetUnitX(pathchecker)-x)*(GetUnitX(pathchecker)-x)+((GetUnitY(pathchecker)-y)*(GetUnitY(pathchecker)-y))<=1)
call EnumItemsInRect(pathrect,truefilter,function UnHideItems)
endif
return b
endfunction
function init takes nothing returns nothing
local real x = GetRectMinX(bj_mapInitialPlayableArea)
local real y = GetRectMinY(bj_mapInitialPlayableArea)
set pathrect=Rect(x,y,x+200.00,y+200.00)
set pathchecker=CreateUnit( Player(PLAYER_NEUTRAL_PASSIVE), PATHCHECKERID, 0, 0, 0)
set truefilter=Filter(function AntiLeak)
call UnitAddAbility(pathchecker, SPELLPATHID)
call IssueImmediateOrder( pathchecker, "windwalk" )
endfunction
endlibrary
//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 NewTimer2 takes nothing returns timer
if (N==0) then
return CreateTimer()
endif
set N=N-1
return timers[N]
endfunction
function ReleaseTimer2 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
// **************************************************************************
// ** **
// ** Mathematical Functions **
// ** ————————————— **
// ** **
// ** Functions used instead of BJs to calculate some values **
// ** **
// ** By: Majin **
// **
// ** **
// **************************************************************************
library Math
function GetDistance takes real ax, real ay, real bx, real by returns real
return SquareRoot((bx-ax)*(bx-ax)+(by-ay)*(by-ay))
endfunction
function PolarProjectionx takes real ax, real dist, real angle returns real
return ax + dist * Cos(angle)
endfunction
function PolarProjectiony takes real ay, real dist, real angle returns real
return ay + dist * Sin(angle)
endfunction
function GetAngle takes real ax, real ay, real bx, real by returns real
return Atan2(by-ay, bx-ax)
endfunction
function RAbs takes real a returns real
if (a >= 0) then
return a
else
return -a
endif
endfunction
function AntiLeak takes nothing returns boolean
return true
endfunction
endlibrary
//TESH.scrollpos=67
//TESH.alwaysfold=0
scope Hints initializer Init
globals
private integer i = 0
private string array Hints[1]
private constant integer MAX_HINTS = 14
private boolean array HintsActive[1]
endglobals
private function ActivateHints takes nothing returns nothing
set HintsActive[GetPlayerId(GetTriggerPlayer())] = true
endfunction
private function ToggleHints takes nothing returns nothing
local string s = GetEventPlayerChatString()
if SubString(s, 5, 8) == "-1 " or SubString(s, 5, 8) == " -1" or SubString(s, 5, 8) == "-1" then
set HintsActive[GetPlayerId(GetTriggerPlayer())] = true
call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 5.00, "Hints |cffFFA358ON|r" )
endif
if SubString(s, 5, 8) == "-0 " or SubString(s, 5, 8) == " -0" or SubString(s, 5, 8) == "-0" then
set HintsActive[GetPlayerId(GetTriggerPlayer())] = false
call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 5.00, "Hints |cffFFA358OFF|r" )
endif
endfunction
private function Callback takes nothing returns nothing
local integer id = GetPlayerId(GetEnumPlayer())
if HintsActive[id] then
call DisplayTimedTextToPlayer( Player(id), 0, 0, 10.00, " " )
call DisplayTimedTextToPlayer( Player(id), 0, 0, 10.00, HINT + Hints[i] )
call DisplayTimedTextToPlayer( Player(id), 0, 0, 10.00, " " )
endif
endfunction
private function Conditions takes nothing returns boolean
return i <= MAX_HINTS
endfunction
private function Actions takes nothing returns nothing
set i = i + 1
call ForForce(Players, function Callback)
if i >= MAX_HINTS then
set i = 0
endif
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterTimerEvent(trg, 120.00, true)
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set Hints[1] = "You may disable/enable automatic hints by typing |cffFFA358hints -0|r or |cffFFA358hints -1|r."
set Hints[2] = "You will always find the newest version of this map on |cffFFA358hiveworkshop.com|r."
set Hints[3] = "Gold is a team resource that is used to buy upgrades and research for your team."
set Hints[4] = "Honor is a personal resource that can be used to buy items for your hero."
set Hints[5] = "The following actions reward you with honor: PvP, creeping, capturing points, destroying buildings, killing enemies, healin/buffing allies."
set Hints[6] = "The power of spells and abilities scales with your heroes attributes."
set Hints[7] = "The Spell/ability power defines the multiplier that is used to calculate the spell damage. However, there is a small random factor."
set Hints[8] = "Select your castle to upgrade it. There are 2 more tiers available. A higher tier provides additional troops."
set Hints[9] = "You can do research in your safe which is located in your base."
set Hints[10] = "It is your tactical choice which upgrades to do first. However, one Player should safe money to do the tier upgrades."
set Hints[11] = "There are two neutral shops along the map that sell powerful items."
set Hints[12] = "You can only carry one item of these item types: weapon, armor, boots, ring."
set Hints[13] = "You may build workers in your safe. They can be used for building towers and repairing buildings."
set Hints[14] = "Feedback on the map is welcome and appreciated. You'll find contact info in the quest log."
set HintsActive[2] = true
set HintsActive[3] = true
set HintsActive[4] = true
set HintsActive[5] = true
set HintsActive[6] = true
set HintsActive[7] = true
set HintsActive[8] = true
set HintsActive[9] = true
set HintsActive[10] = true
set HintsActive[11] = true
set trg = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( trg, Player(2), "hints", false )
call TriggerRegisterPlayerChatEvent( trg, Player(3), "hints", false )
call TriggerRegisterPlayerChatEvent( trg, Player(4), "hints", false )
call TriggerRegisterPlayerChatEvent( trg, Player(5), "hints", false )
call TriggerRegisterPlayerChatEvent( trg, Player(6), "hints", false )
call TriggerRegisterPlayerChatEvent( trg, Player(7), "hints", false )
call TriggerRegisterPlayerChatEvent( trg, Player(8), "hints", false )
call TriggerRegisterPlayerChatEvent( trg, Player(9), "hints", false )
call TriggerRegisterPlayerChatEvent( trg, Player(10), "hints", false )
call TriggerRegisterPlayerChatEvent( trg, Player(11), "hints", false )
call TriggerAddAction( trg, function ToggleHints )
set trg = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope Repick initializer Init
private function Actions takes nothing returns nothing
call Repick(GetPlayerId(GetTriggerPlayer()))
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( trg, Player(2), "repick", true )
call TriggerRegisterPlayerChatEvent( trg, Player(3), "repick", true )
call TriggerRegisterPlayerChatEvent( trg, Player(4), "repick", true )
call TriggerRegisterPlayerChatEvent( trg, Player(5), "repick", true )
call TriggerRegisterPlayerChatEvent( trg, Player(6), "repick", true )
call TriggerRegisterPlayerChatEvent( trg, Player(7), "repick", true )
call TriggerRegisterPlayerChatEvent( trg, Player(8), "repick", true )
call TriggerRegisterPlayerChatEvent( trg, Player(9), "repick", true )
call TriggerRegisterPlayerChatEvent( trg, Player(10), "repick", true )
call TriggerRegisterPlayerChatEvent( trg, Player(11), "repick", true )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope ShowStats initializer Init
private function Actions takes nothing returns nothing
call Show_Stats(GetPlayerId(GetTriggerPlayer()))
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( trg, Player(2), "stats", true )
call TriggerRegisterPlayerChatEvent( trg, Player(3), "stats", true )
call TriggerRegisterPlayerChatEvent( trg, Player(4), "stats", true )
call TriggerRegisterPlayerChatEvent( trg, Player(5), "stats", true )
call TriggerRegisterPlayerChatEvent( trg, Player(6), "stats", true )
call TriggerRegisterPlayerChatEvent( trg, Player(7), "stats", true )
call TriggerRegisterPlayerChatEvent( trg, Player(8), "stats", true )
call TriggerRegisterPlayerChatEvent( trg, Player(9), "stats", true )
call TriggerRegisterPlayerChatEvent( trg, Player(10), "stats", true )
call TriggerRegisterPlayerChatEvent( trg, Player(11), "stats", true )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope ScoreDamage initializer Init
private function Actions takes nothing returns nothing
local integer id = GetPlayerId(GetTriggerPlayer())
call DisplayTimedTextToPlayer(Player(id),0,0,15, " Damage Score: "+R2S(Score_Damage[id]))
call DisplayTimedTextToPlayer(Player(id),0,0,15, " Healing Score: "+R2S(Score_Healing[id]))
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( trg, Player(2), "scd", true )
call TriggerRegisterPlayerChatEvent( trg, Player(3), "scd", true )
call TriggerRegisterPlayerChatEvent( trg, Player(4), "scd", true )
call TriggerRegisterPlayerChatEvent( trg, Player(5), "scd", true )
call TriggerRegisterPlayerChatEvent( trg, Player(6), "scd", true )
call TriggerRegisterPlayerChatEvent( trg, Player(7), "scd", true )
call TriggerRegisterPlayerChatEvent( trg, Player(8), "scd", true )
call TriggerRegisterPlayerChatEvent( trg, Player(9), "scd", true )
call TriggerRegisterPlayerChatEvent( trg, Player(10), "scd", true )
call TriggerRegisterPlayerChatEvent( trg, Player(11), "scd", true )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope GameInfo initializer Init
private function Actions takes nothing returns nothing
local integer id = GetPlayerId(GetTriggerPlayer())
call DisplayTimedTextToPlayer( GetTriggerPlayer(), 0, 0, 15, " " )
call DisplayTimedTextToPlayer( GetTriggerPlayer(), 0, 0, 15, "|cff88BD78List of commands:" )
call DisplayTimedTextToPlayer( GetTriggerPlayer(), 0, 0, 15, " " )
call DisplayTimedTextToPlayer( GetTriggerPlayer(), 0, 0, 15, " |cffFFA358info|r basic information about the map" )
call DisplayTimedTextToPlayer( GetTriggerPlayer(), 0, 0, 15, " |cffFFA358stats|r displays hero statistics" )
call DisplayTimedTextToPlayer( GetTriggerPlayer(), 0, 0, 15, " |cffFFA358repick|r choose another hero (but you'll lose your level and drop all items)" )
call DisplayTimedTextToPlayer( GetTriggerPlayer(), 0, 0, 15, " |cffFFA358hints -0/1|r enable/disable hints" )
call DisplayTimedTextToPlayer(Player(id),0,0,15, " ")
call DisplayTimedTextToPlayer(Player(id),0,0,15, "|cffF7D599Gold|r is a pro-team resource that may be used for upgrades and research. Your team receives additional gold for controlling |cffF7D599strategic points|r.")
call DisplayTimedTextToPlayer(Player(id),0,0,15, " ")
call DisplayTimedTextToPlayer(Player(id),0,0,15, "Spend your |cff7882DEhonor points|r to acquire powerful items! You and nearby allies receive honor for different events like killing heroes & creeps, for capturing strategic points or destroying enemy buildings.")
call DisplayTimedTextToPlayer(Player(id),0,0,15, " ")
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( trg, Player(2), "info", true )
call TriggerRegisterPlayerChatEvent( trg, Player(3), "info", true )
call TriggerRegisterPlayerChatEvent( trg, Player(4), "info", true )
call TriggerRegisterPlayerChatEvent( trg, Player(5), "info", true )
call TriggerRegisterPlayerChatEvent( trg, Player(6), "info", true )
call TriggerRegisterPlayerChatEvent( trg, Player(7), "info", true )
call TriggerRegisterPlayerChatEvent( trg, Player(8), "info", true )
call TriggerRegisterPlayerChatEvent( trg, Player(9), "info", true )
call TriggerRegisterPlayerChatEvent( trg, Player(10), "info", true )
call TriggerRegisterPlayerChatEvent( trg, Player(11), "info", true )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope GiveGold initializer Init
private function Conditions takes nothing returns boolean
return DEBUG_MODE
endfunction
private function Actions takes nothing returns nothing
local integer id = GetPlayerId(GetTriggerPlayer())
local integer amount = S2I(SubString( GetEventPlayerChatString(), 8, 7 ))
call Debug_Message(PlayerNames[id] + " has been given " + I2S(amount) + " gold.")
call SetPlayerState( GetTriggerPlayer(), PLAYER_STATE_RESOURCE_GOLD, ( GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_GOLD) + amount ) )
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( trg, Player(2), "givegold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(3), "givegold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(4), "givegold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(5), "givegold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(6), "givegold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(7), "givegold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(8), "givegold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(9), "givegold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(10), "givegold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(11), "givegold", false )
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=4
//TESH.alwaysfold=0
scope ShowGold initializer Init
private function Conditions takes nothing returns boolean
return DEBUG_MODE
endfunction
private function Actions takes nothing returns nothing
local integer id = GetPlayerId(GetTriggerPlayer())
call Debug_Message(PlayerNames[2] + " (ID:"+I2S(2)+") gold: " + I2S(GetPlayerState(Player(2), PLAYER_STATE_RESOURCE_GOLD)))
call Debug_Message(PlayerNames[6] + " (ID:"+I2S(6)+") gold: " + I2S(GetPlayerState(Player(6), PLAYER_STATE_RESOURCE_GOLD)))
call Debug_Message(PlayerNames[8] + " (ID:"+I2S(8)+") gold: " + I2S(GetPlayerState(Player(8), PLAYER_STATE_RESOURCE_GOLD)))
call Debug_Message(PlayerNames[9] + " (ID:"+I2S(9)+") gold: " + I2S(GetPlayerState(Player(9), PLAYER_STATE_RESOURCE_GOLD)))
call Debug_Message(PlayerNames[10] + " (ID:"+I2S(10)+") gold: " + I2S(GetPlayerState(Player(10), PLAYER_STATE_RESOURCE_GOLD)))
call Debug_Message(" ")
call Debug_Message(PlayerNames[3] + " (ID:"+I2S(3)+") gold: " + I2S(GetPlayerState(Player(3), PLAYER_STATE_RESOURCE_GOLD)))
call Debug_Message(PlayerNames[4] + " (ID:"+I2S(4)+") gold: " + I2S(GetPlayerState(Player(4), PLAYER_STATE_RESOURCE_GOLD)))
call Debug_Message(PlayerNames[5] + " (ID:"+I2S(5)+") gold: " + I2S(GetPlayerState(Player(5), PLAYER_STATE_RESOURCE_GOLD)))
call Debug_Message(PlayerNames[7] + " (ID:"+I2S(7)+") gold: " + I2S(GetPlayerState(Player(7), PLAYER_STATE_RESOURCE_GOLD)))
call Debug_Message(PlayerNames[11] + " (ID:"+I2S(11)+") gold: " + I2S(GetPlayerState(Player(11), PLAYER_STATE_RESOURCE_GOLD)))
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( trg, Player(2), "showgold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(3), "showgold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(4), "showgold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(5), "showgold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(6), "showgold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(7), "showgold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(8), "showgold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(9), "showgold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(10), "showgold", false )
call TriggerRegisterPlayerChatEvent( trg, Player(11), "showgold", false )
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope ShowScores initializer Init
private function Conditions takes nothing returns boolean
return DEBUG_MODE
endfunction
private function Actions takes nothing returns nothing
call ShowScores(1)
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( trg, Player(2), "score", false )
call TriggerRegisterPlayerChatEvent( trg, Player(3), "score", false )
call TriggerRegisterPlayerChatEvent( trg, Player(4), "score", false )
call TriggerRegisterPlayerChatEvent( trg, Player(5), "score", false )
call TriggerRegisterPlayerChatEvent( trg, Player(6), "score", false )
call TriggerRegisterPlayerChatEvent( trg, Player(7), "score", false )
call TriggerRegisterPlayerChatEvent( trg, Player(8), "score", false )
call TriggerRegisterPlayerChatEvent( trg, Player(9), "score", false )
call TriggerRegisterPlayerChatEvent( trg, Player(10), "score", false )
call TriggerRegisterPlayerChatEvent( trg, Player(11), "score", false )
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope Animation initializer Init
private function Conditions takes nothing returns boolean
return DEBUG_MODE
endfunction
private function Actions takes nothing returns nothing
local integer id = GetPlayerId(GetTriggerPlayer())
local integer index = S2I(SubString( GetEventPlayerChatString(), 9, 7 ))
call Debug_Message("Hero animation: " + I2S(index))
call SetUnitAnimationByIndex(Heroes[id], index)
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( trg, Player(2), "animation", false )
call TriggerRegisterPlayerChatEvent( trg, Player(3), "animation", false )
call TriggerRegisterPlayerChatEvent( trg, Player(4), "animation", false )
call TriggerRegisterPlayerChatEvent( trg, Player(5), "animation", false )
call TriggerRegisterPlayerChatEvent( trg, Player(6), "animation", false )
call TriggerRegisterPlayerChatEvent( trg, Player(7), "animation", false )
call TriggerRegisterPlayerChatEvent( trg, Player(8), "animation", false )
call TriggerRegisterPlayerChatEvent( trg, Player(9), "animation", false )
call TriggerRegisterPlayerChatEvent( trg, Player(10), "animation", false )
call TriggerRegisterPlayerChatEvent( trg, Player(11), "animation", false )
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope GiveGoldAll initializer Init
private function Conditions takes nothing returns boolean
return DEBUG_MODE
endfunction
private function Callback takes nothing returns nothing
call SetPlayerState( GetEnumPlayer(), PLAYER_STATE_RESOURCE_GOLD, ( GetPlayerState(GetEnumPlayer(), PLAYER_STATE_RESOURCE_GOLD) + 10000 ) )
endfunction
private function Actions takes nothing returns nothing
local integer id = GetPlayerId(GetTriggerPlayer())
call Debug_Message("All players have been given 10000 gold.")
call ForForce(Players, function Callback)
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( trg, Player(2), "givegoldall", false )
call TriggerRegisterPlayerChatEvent( trg, Player(3), "givegoldall", false )
call TriggerRegisterPlayerChatEvent( trg, Player(4), "givegoldall", false )
call TriggerRegisterPlayerChatEvent( trg, Player(5), "givegoldall", false )
call TriggerRegisterPlayerChatEvent( trg, Player(6), "givegoldall", false )
call TriggerRegisterPlayerChatEvent( trg, Player(7), "givegoldall", false )
call TriggerRegisterPlayerChatEvent( trg, Player(8), "givegoldall", false )
call TriggerRegisterPlayerChatEvent( trg, Player(9), "givegoldall", false )
call TriggerRegisterPlayerChatEvent( trg, Player(10), "givegoldall", false )
call TriggerRegisterPlayerChatEvent( trg, Player(11), "givegoldall", false )
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope GiveLumber initializer Init
private function Conditions takes nothing returns boolean
return DEBUG_MODE
endfunction
private function Actions takes nothing returns nothing
local integer id = GetPlayerId(GetTriggerPlayer())
local integer amount = S2I(SubString( GetEventPlayerChatString(), 9, 7 ))
call Debug_Message(PlayerNames[id] + " has been given " + I2S(amount) + " honor points.")
call SetPlayerState( GetTriggerPlayer(), PLAYER_STATE_RESOURCE_LUMBER, ( GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_LUMBER) + amount ) )
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( trg, Player(2), "givehonor", false )
call TriggerRegisterPlayerChatEvent( trg, Player(3), "givehonor", false )
call TriggerRegisterPlayerChatEvent( trg, Player(4), "givehonor", false )
call TriggerRegisterPlayerChatEvent( trg, Player(5), "givehonor", false )
call TriggerRegisterPlayerChatEvent( trg, Player(6), "givehonor", false )
call TriggerRegisterPlayerChatEvent( trg, Player(7), "givehonor", false )
call TriggerRegisterPlayerChatEvent( trg, Player(8), "givehonor", false )
call TriggerRegisterPlayerChatEvent( trg, Player(9), "givehonor", false )
call TriggerRegisterPlayerChatEvent( trg, Player(10), "givehonor", false )
call TriggerRegisterPlayerChatEvent( trg, Player(11), "givehonor", false )
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope SetLevel initializer Init
private function Conditions takes nothing returns boolean
return DEBUG_MODE
endfunction
private function Actions takes nothing returns nothing
local integer id = GetPlayerId(GetTriggerPlayer())
local integer level = S2I(SubString( GetEventPlayerChatString(), 8, 3 ))
call SetHeroLevelBJ(Heroes[id], level , true)
call Debug_Message(PlayerNames[id] + " has set his hero to level " + I2S(level))
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( trg, Player(2), "setlevel", false )
call TriggerRegisterPlayerChatEvent( trg, Player(3), "setlevel", false )
call TriggerRegisterPlayerChatEvent( trg, Player(4), "setlevel", false )
call TriggerRegisterPlayerChatEvent( trg, Player(5), "setlevel", false )
call TriggerRegisterPlayerChatEvent( trg, Player(6), "setlevel", false )
call TriggerRegisterPlayerChatEvent( trg, Player(7), "setlevel", false )
call TriggerRegisterPlayerChatEvent( trg, Player(8), "setlevel", false )
call TriggerRegisterPlayerChatEvent( trg, Player(9), "setlevel", false )
call TriggerRegisterPlayerChatEvent( trg, Player(10), "setlevel", false )
call TriggerRegisterPlayerChatEvent( trg, Player(11), "setlevel", false )
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=73
//TESH.alwaysfold=0
scope Weather initializer Init
globals
constant real RAIN_CHECK_TIME = 60
constant real RAIN_CHANCE = 15
boolean isRaining = false
weathereffect Rays
weathereffect Rain
boolean daytime =true
endglobals
private function RemoveRaysCallback takes nothing returns nothing
local timer t = GetExpiredTimer()
call ReleaseTimer(t)
call RemoveWeatherEffect(Rays)
set t = null
if daytime then
set Rays = AddWeatherEffect(gg_rct_ForestMiddle, 'LRaa')
else
set Rays = AddWeatherEffect(gg_rct_ForestMiddle, 'LRma')
endif
call EnableWeatherEffect( Rays, true )
endfunction
private function RemoveRays takes nothing returns nothing
local timer t = NewTimer()
call EnableWeatherEffect( Rays, false )
call TimerStart(t, 3, false, function RemoveRaysCallback )
set t = null
endfunction
private function Daytime takes nothing returns nothing
set daytime = true
call RemoveRays()
endfunction
private function Nighttime takes nothing returns nothing
set daytime = false
call RemoveRays()
endfunction
private function Rain_Over takes nothing returns nothing
local timer t = GetExpiredTimer()
call ReleaseTimer(t)
call EnableWeatherEffect( Rain, false )
set isRaining = false
set t = null
endfunction
private function Check_Raining takes nothing returns nothing
local real r = GetRandomReal(1,100)
local timer t
local real rain_time
if r <= RAIN_CHANCE and not isRaining then
set isRaining = true
set rain_time = GetRandomReal(60,300)
call EnableWeatherEffect( Rain, true )
set t = NewTimer()
call TimerStart(t, rain_time, false, function Rain_Over)
endif
set t = null
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg
set Rays = AddWeatherEffect(gg_rct_ForestMiddle, 'LRaa')
call EnableWeatherEffect( Rays, true )
set Rain = AddWeatherEffect(bj_mapInitialPlayableArea, 'RAhr')
call EnableWeatherEffect( Rain, false )
set trg = CreateTrigger()
call TriggerRegisterGameStateEvent(trg, GAME_STATE_TIME_OF_DAY, EQUAL, 6.00)
call TriggerAddAction( trg, function Daytime )
set trg = CreateTrigger()
call TriggerRegisterGameStateEvent(trg, GAME_STATE_TIME_OF_DAY, EQUAL, 18.00)
call TriggerAddAction( trg, function Nighttime )
set trg = CreateTrigger()
call TriggerRegisterTimerEvent(trg, RAIN_CHECK_TIME, true)
call TriggerAddAction( trg, function Check_Raining )
// Fog in swamp
call AddWeatherEffectSaveLast( gg_rct_Swamp1, 'FDbh' )
call EnableWeatherEffect( GetLastCreatedWeatherEffect(), true )
call AddWeatherEffectSaveLast( gg_rct_Swamp2, 'FDbh' )
call EnableWeatherEffect( GetLastCreatedWeatherEffect(), true )
// call AddWeatherEffectSaveLast( gg_rct_Swamp1, 'RAlr' )
// call EnableWeatherEffect( GetLastCreatedWeatherEffect(), true )
// call AddWeatherEffectSaveLast( gg_rct_Swamp2, 'RAlr' )
// call EnableWeatherEffect( GetLastCreatedWeatherEffect(), true )
// set trg = CreateTrigger( )
// call TriggerRegisterPlayerChatEvent( trg, Player(2), "rain", true )
// call TriggerAddAction( trg, function Check_Raining )
// set trg = CreateTrigger( )
// call TriggerRegisterPlayerChatEvent( trg, Player(2), "weather", true )
// call TriggerAddAction( trg, function Weather )
set trg = null
endfunction
endscope
//TESH.scrollpos=106
//TESH.alwaysfold=0
// =======================================================================
// FOG FADING SYSTEM | v1.3 | by MoCo, please give credit if you use this)
// =======================================================================
library FFS initializer Init
globals
// I recommend tu use 1.0 here for final maps
private constant real TIME_OF_DAY_SPEED = 1.0 // 10 makes a good timelapse for testing
private constant real SECONDS_PER_HOUR = 20.0 // Only change this, if you also change it in the game constants!
private constant real START_TIME = 12 // Time at game start
private constant integer FOG_STYLE = 0 // 0 = linear, 1 & 2 are expon. functions
// Fog #1: noon time, 12 p.m.
private constant real NOON_FOG_START = 1500 // Start distance of fog 1800
private constant real NOON_FOG_END = 4500 // End distance of fog 400
private constant real NOON_DENSITY = 0.1 // 1.0 Fog density 0.5
// Color values
private real NOON_RED = 156//118// 211 // 0.7 // 0.78 // 0.34 // 0.74
private real NOON_GREEN = 220//166//244 // 0.92 // 0.88 // 0.51 // 0.83
private real NOON_BLUE = 173//118//204 // 0.65 // 0.62 // 0.39 // 0.6
// Fog #2: night time, 24 p.m.
private constant real NIGHT_FOG_START = 1500 // Start distance of fog
private constant real NIGHT_FOG_END = 4000 // End distance of fog
private constant real NIGHT_DENSITY = 1.0 // Fog density
// Color values
private constant real NIGHT_RED = 0.411 // 0.27 // 0.74
private constant real NIGHT_GREEN = 0.47 // 0.45 // 0.83
private constant real NIGHT_BLUE = 0.66 // 0.41 // 0.9
// ============================================================
// Don't touch the code below unless you know what you're doing
// ============================================================
// variables used by the system
private real fog_density
private real fog_start
private real fog_end
private real fog_red
private real fog_green
private real fog_blue
private real fog_fade_ticks
private real fog_fade_amount_start
private real fog_fade_amount_end
private real fog_fade_amount_density
private real fog_fade_amount_red
private real fog_fade_amount_green
private real fog_fade_amount_blue
private real time_dif
endglobals
private function Start takes nothing returns nothing
// Time of day speed
call SetTimeOfDayScale(TIME_OF_DAY_SPEED)
// Set Starting Time
call SetFloatGameState(GAME_STATE_TIME_OF_DAY, START_TIME )
set NOON_RED = NOON_RED/255
set NOON_GREEN = NOON_GREEN/255
set NOON_BLUE = NOON_BLUE/255
// Fading is processed every second
// and we got 12 hours to fade between 2 fog colors
set fog_fade_ticks = ( 12 * SECONDS_PER_HOUR ) / TIME_OF_DAY_SPEED
// Density amounts to be faded every second
set fog_fade_amount_start = ( NIGHT_FOG_START - NOON_FOG_START ) / fog_fade_ticks
set fog_fade_amount_end = ( NIGHT_FOG_END - NOON_FOG_END ) / fog_fade_ticks
set fog_fade_amount_density = ( NIGHT_DENSITY - NOON_DENSITY ) / fog_fade_ticks
// Color amounts to be faded every second
set fog_fade_amount_red = ( NIGHT_RED - NOON_RED ) / fog_fade_ticks
set fog_fade_amount_green = ( NIGHT_GREEN - NOON_GREEN ) / fog_fade_ticks
set fog_fade_amount_blue = ( NIGHT_BLUE - NOON_BLUE ) / fog_fade_ticks
// Calculate Fog Color for starting time
// between noon and midnight
if START_TIME > 12 and START_TIME <= 24 then
set time_dif = ( ( START_TIME - 12 ) * SECONDS_PER_HOUR ) / TIME_OF_DAY_SPEED
set fog_start = NOON_FOG_START + fog_fade_amount_start * time_dif
set fog_end = NOON_FOG_END + fog_fade_amount_end * time_dif
set fog_density = NOON_DENSITY + fog_fade_amount_density * time_dif
set fog_red = NOON_RED + fog_fade_amount_red * time_dif
set fog_green = NOON_GREEN + fog_fade_amount_green * time_dif
set fog_blue = NOON_BLUE + fog_fade_amount_blue * time_dif
// after midnight, before noon
else
set time_dif = ( START_TIME * SECONDS_PER_HOUR ) / TIME_OF_DAY_SPEED
set fog_start = NIGHT_FOG_START - fog_fade_amount_start * time_dif
set fog_end = NIGHT_FOG_END - fog_fade_amount_end * time_dif
set fog_density = NIGHT_DENSITY - fog_fade_amount_density * time_dif
set fog_red = NIGHT_RED - fog_fade_amount_red * time_dif
set fog_green = NIGHT_GREEN - fog_fade_amount_green * time_dif
set fog_blue = NIGHT_BLUE - fog_fade_amount_blue * time_dif
endif
call SetTerrainFogEx(FOG_STYLE, fog_start, fog_red, fog_density, fog_red, fog_green, fog_blue)
endfunction
private function Timer takes nothing returns nothing
local real time = GetFloatGameState(GAME_STATE_TIME_OF_DAY)
// between noon and midnight
if time > 12 and time <= 24 then
set fog_start = fog_start + fog_fade_amount_start
set fog_end = fog_end + fog_fade_amount_end
set fog_density = fog_density + fog_fade_amount_density
set fog_red = fog_red + fog_fade_amount_red
set fog_green = fog_green + fog_fade_amount_green
set fog_blue = fog_blue + fog_fade_amount_blue
// after midnight, before noon
else
set fog_start = fog_start - fog_fade_amount_start
set fog_end = fog_end - fog_fade_amount_end
set fog_density = fog_density - fog_fade_amount_density
set fog_red = fog_red - fog_fade_amount_red
set fog_green = fog_green - fog_fade_amount_green
set fog_blue = fog_blue - fog_fade_amount_blue
endif
// Apply fog values
call SetTerrainFogEx(FOG_STYLE, fog_start, fog_end, fog_density, fog_red, fog_green, fog_blue)
// Below is a debug display that shows raw values each update tick
// call DisplayTextToPlayer(GetLocalPlayer(),0,0, "FOG - start: "+R2S(fog_start)+", end: "+R2S(fog_end)+", dens: "+R2S(fog_density)+", R: "+R2S(fog_red)+", G: "+R2S(fog_green)+", B: "+R2S(fog_blue))
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterTimerEvent(trg, 0.01, false)
call TriggerAddAction(trg, function Start)
set trg = CreateTrigger()
call TriggerRegisterTimerEvent(trg, 1, true)
call TriggerAddAction(trg, function Timer)
set trg = null
endfunction
endlibrary
//TESH.scrollpos=18
//TESH.alwaysfold=0
scope WaypointArray initializer Init
globals
Table waypoint_table = 0
endglobals
public function Init takes nothing returns nothing
set waypoint_table = Table.create()
set Waypoint_Array[0] = Location(GetRectCenterX(gg_rct_WPM05_Middle), GetRectCenterY(gg_rct_WPM05_Middle))
// Middle
set Waypoint_Array[1] = Location(GetRectCenterX(gg_rct_WPM01), GetRectCenterY(gg_rct_WPM01))
set Waypoint_Array[2] = Location(GetRectCenterX(gg_rct_WPM02), GetRectCenterY(gg_rct_WPM02))
set Waypoint_Array[3] = Location(GetRectCenterX(gg_rct_WPM03), GetRectCenterY(gg_rct_WPM03))
set Waypoint_Array[4] = Location(GetRectCenterX(gg_rct_WPM04), GetRectCenterY(gg_rct_WPM04))
set Waypoint_Array[5] = Location(GetRectCenterX(gg_rct_WPM05_Middle), GetRectCenterY(gg_rct_WPM05_Middle))
set Waypoint_Array[6] = Location(GetRectCenterX(gg_rct_WPM06), GetRectCenterY(gg_rct_WPM06))
set Waypoint_Array[7] = Location(GetRectCenterX(gg_rct_WPM07), GetRectCenterY(gg_rct_WPM07))
set Waypoint_Array[8] = Location(GetRectCenterX(gg_rct_WPM08), GetRectCenterY(gg_rct_WPM08))
set Waypoint_Array[9] = Location(GetRectCenterX(gg_rct_WPM09), GetRectCenterY(gg_rct_WPM09))
// Right
set Waypoint_Array[11] = Location(GetRectCenterX(gg_rct_WPR01), GetRectCenterY(gg_rct_WPR01))
set Waypoint_Array[12] = Location(GetRectCenterX(gg_rct_WPR02), GetRectCenterY(gg_rct_WPR02))
set Waypoint_Array[13] = Location(GetRectCenterX(gg_rct_WPR03), GetRectCenterY(gg_rct_WPR03))
set Waypoint_Array[14] = Location(GetRectCenterX(gg_rct_WPR04), GetRectCenterY(gg_rct_WPR04))
set Waypoint_Array[15] = Location(GetRectCenterX(gg_rct_WPR05), GetRectCenterY(gg_rct_WPR05))
set Waypoint_Array[16] = Location(GetRectCenterX(gg_rct_WPR06), GetRectCenterY(gg_rct_WPR06))
set Waypoint_Array[17] = Location(GetRectCenterX(gg_rct_WPR07), GetRectCenterY(gg_rct_WPR07))
set Waypoint_Array[18] = Location(GetRectCenterX(gg_rct_WPR08), GetRectCenterY(gg_rct_WPR08))
set Waypoint_Array[19] = Location(GetRectCenterX(gg_rct_WPR09), GetRectCenterY(gg_rct_WPR09))
// Left
set Waypoint_Array[21] = Location(GetRectCenterX(gg_rct_WPL01), GetRectCenterY(gg_rct_WPL01))
set Waypoint_Array[22] = Location(GetRectCenterX(gg_rct_WPL02), GetRectCenterY(gg_rct_WPL02))
set Waypoint_Array[23] = Location(GetRectCenterX(gg_rct_WPL03), GetRectCenterY(gg_rct_WPL03))
set Waypoint_Array[24] = Location(GetRectCenterX(gg_rct_WPL04), GetRectCenterY(gg_rct_WPL04))
set Waypoint_Array[25] = Location(GetRectCenterX(gg_rct_WPL05), GetRectCenterY(gg_rct_WPL05))
set Waypoint_Array[26] = Location(GetRectCenterX(gg_rct_WPL06), GetRectCenterY(gg_rct_WPL06))
set Waypoint_Array[27] = Location(GetRectCenterX(gg_rct_WPL07), GetRectCenterY(gg_rct_WPL07))
set Waypoint_Array[50] = Location(GetRectCenterX(gg_rct_Base1), GetRectCenterY(gg_rct_Base1))
set Waypoint_Array[51] = Location(GetRectCenterX(gg_rct_Base2), GetRectCenterY(gg_rct_Base2))
// Capture Points
set Waypoint_Array[61] = Location(GetRectCenterX(gg_rct_Tavern), GetRectCenterY(gg_rct_Tavern))
set Waypoint_Array[62] = Location(GetRectCenterX(gg_rct_LumberMill), GetRectCenterY(gg_rct_LumberMill))
set Waypoint_Array[63] = Location(GetRectCenterX(gg_rct_Farm), GetRectCenterY(gg_rct_Farm))
// set Waypoint_Array[64] = Location(GetRectCenterX(gg_rct_Tavern), GetRectCenterY(gg_rct_Tavern))
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP01_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP01_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 2
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 50
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP01 takes nothing returns nothing
set gg_trg_WP01 = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP01, gg_rct_WPM01 )
call TriggerAddCondition( gg_trg_WP01, Condition( function Trig_WP01_Conditions ) )
call TriggerAddAction( gg_trg_WP01, function Trig_WP01_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP02_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP02_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 3
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 1
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP02 takes nothing returns nothing
set gg_trg_WP02 = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP02, gg_rct_WPM02 )
call TriggerAddCondition( gg_trg_WP02, Condition( function Trig_WP02_Conditions ) )
call TriggerAddAction( gg_trg_WP02, function Trig_WP02_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP03_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP03_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 4
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 2
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP03 takes nothing returns nothing
set gg_trg_WP03 = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP03, gg_rct_WPM03 )
call TriggerAddCondition( gg_trg_WP03, Condition( function Trig_WP03_Conditions ) )
call TriggerAddAction( gg_trg_WP03, function Trig_WP03_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP04_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP04_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 5
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 3
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP04 takes nothing returns nothing
set gg_trg_WP04 = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP04, gg_rct_WPM04 )
call TriggerAddCondition( gg_trg_WP04, Condition( function Trig_WP04_Conditions ) )
call TriggerAddAction( gg_trg_WP04, function Trig_WP04_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP05_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP05_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 6
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 4
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
if IsHero(GetTriggerUnit()) then
if PointIsHostile(1, GetTriggerUnit()) then
call Order_Unit_Move_To_Direct_WP(GetTriggerUnit(), 61)
endif
endif
endfunction
//===========================================================================
function InitTrig_WP05 takes nothing returns nothing
set gg_trg_WP05 = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP05, gg_rct_WPM05_Middle )
call TriggerAddCondition( gg_trg_WP05, Condition( function Trig_WP05_Conditions ) )
call TriggerAddAction( gg_trg_WP05, function Trig_WP05_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP06_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP06_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 7
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 5
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP06 takes nothing returns nothing
set gg_trg_WP06 = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP06, gg_rct_WPM06 )
call TriggerAddCondition( gg_trg_WP06, Condition( function Trig_WP06_Conditions ) )
call TriggerAddAction( gg_trg_WP06, function Trig_WP06_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP07_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP07_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 8
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 6
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP07 takes nothing returns nothing
set gg_trg_WP07 = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP07, gg_rct_WPM07 )
call TriggerAddCondition( gg_trg_WP07, Condition( function Trig_WP07_Conditions ) )
call TriggerAddAction( gg_trg_WP07, function Trig_WP07_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP08_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP08_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 9
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 7
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP08 takes nothing returns nothing
set gg_trg_WP08 = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP08, gg_rct_WPM08 )
call TriggerAddCondition( gg_trg_WP08, Condition( function Trig_WP08_Conditions ) )
call TriggerAddAction( gg_trg_WP08, function Trig_WP08_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP09_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP09_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 51
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 8
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP09 takes nothing returns nothing
set gg_trg_WP09 = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP09, gg_rct_WPM09 )
call TriggerAddCondition( gg_trg_WP09, Condition( function Trig_WP09_Conditions ) )
call TriggerAddAction( gg_trg_WP09, function Trig_WP09_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP01_R_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP01_R_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 12
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 50
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP01_R takes nothing returns nothing
set gg_trg_WP01_R = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP01_R, gg_rct_WPR01 )
call TriggerAddCondition( gg_trg_WP01_R, Condition( function Trig_WP01_R_Conditions ) )
call TriggerAddAction( gg_trg_WP01_R, function Trig_WP01_R_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP02_R_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP02_R_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 13
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 11
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP02_R takes nothing returns nothing
set gg_trg_WP02_R = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP02_R, gg_rct_WPR02 )
call TriggerAddCondition( gg_trg_WP02_R, Condition( function Trig_WP02_R_Conditions ) )
call TriggerAddAction( gg_trg_WP02_R, function Trig_WP02_R_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP03_R_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP03_R_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 14
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 12
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP03_R takes nothing returns nothing
set gg_trg_WP03_R = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP03_R, gg_rct_WPR03 )
call TriggerAddCondition( gg_trg_WP03_R, Condition( function Trig_WP03_R_Conditions ) )
call TriggerAddAction( gg_trg_WP03_R, function Trig_WP03_R_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP04_R_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP04_R_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 15
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 13
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP04_R takes nothing returns nothing
set gg_trg_WP04_R = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP04_R, gg_rct_WPR04 )
call TriggerAddCondition( gg_trg_WP04_R, Condition( function Trig_WP04_R_Conditions ) )
call TriggerAddAction( gg_trg_WP04_R, function Trig_WP04_R_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP05_R_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP05_R_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 16
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 14
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
if IsHero(GetTriggerUnit()) then
if PointIsHostile(2, GetTriggerUnit()) then
call Order_Unit_Move_To_Direct_WP(GetTriggerUnit(), 62)
endif
endif
endfunction
//===========================================================================
function InitTrig_WP05_R takes nothing returns nothing
set gg_trg_WP05_R = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP05_R, gg_rct_WPR05 )
call TriggerAddCondition( gg_trg_WP05_R, Condition( function Trig_WP05_R_Conditions ) )
call TriggerAddAction( gg_trg_WP05_R, function Trig_WP05_R_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP06_R_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP06_R_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 17
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 15
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP06_R takes nothing returns nothing
set gg_trg_WP06_R = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP06_R, gg_rct_WPR06 )
call TriggerAddCondition( gg_trg_WP06_R, Condition( function Trig_WP06_R_Conditions ) )
call TriggerAddAction( gg_trg_WP06_R, function Trig_WP06_R_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP07_R_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP07_R_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 18
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 16
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP07_R takes nothing returns nothing
set gg_trg_WP07_R = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP07_R, gg_rct_WPR07 )
call TriggerAddCondition( gg_trg_WP07_R, Condition( function Trig_WP07_R_Conditions ) )
call TriggerAddAction( gg_trg_WP07_R, function Trig_WP07_R_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP08_R_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP08_R_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 19
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 17
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP08_R takes nothing returns nothing
set gg_trg_WP08_R = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP08_R, gg_rct_WPR08 )
call TriggerAddCondition( gg_trg_WP08_R, Condition( function Trig_WP08_R_Conditions ) )
call TriggerAddAction( gg_trg_WP08_R, function Trig_WP08_R_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP09_R_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP09_R_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 51
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 18
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP09_R takes nothing returns nothing
set gg_trg_WP09_R = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP09_R, gg_rct_WPR09 )
call TriggerAddCondition( gg_trg_WP09_R, Condition( function Trig_WP09_R_Conditions ) )
call TriggerAddAction( gg_trg_WP09_R, function Trig_WP09_R_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP01_L_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP01_L_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 22
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 50
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP01_L takes nothing returns nothing
set gg_trg_WP01_L = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP01_L, gg_rct_WPL01 )
call TriggerAddCondition( gg_trg_WP01_L, Condition( function Trig_WP01_L_Conditions ) )
call TriggerAddAction( gg_trg_WP01_L, function Trig_WP01_L_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP02_L_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP02_L_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 23
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 21
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP02_L takes nothing returns nothing
set gg_trg_WP02_L = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP02_L, gg_rct_WPL02 )
call TriggerAddCondition( gg_trg_WP02_L, Condition( function Trig_WP02_L_Conditions ) )
call TriggerAddAction( gg_trg_WP02_L, function Trig_WP02_L_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP03_L_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP03_L_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 24
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 22
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP03_L takes nothing returns nothing
set gg_trg_WP03_L = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP03_L, gg_rct_WPL03 )
call TriggerAddCondition( gg_trg_WP03_L, Condition( function Trig_WP03_L_Conditions ) )
call TriggerAddAction( gg_trg_WP03_L, function Trig_WP03_L_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP04_L_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP04_L_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 25
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 23
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
if IsHero(GetTriggerUnit()) then
if PointIsHostile(3, GetTriggerUnit()) then
call Order_Unit_Move_To_Direct_WP(GetTriggerUnit(), 63)
endif
endif
endfunction
//===========================================================================
function InitTrig_WP04_L takes nothing returns nothing
set gg_trg_WP04_L = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP04_L, gg_rct_WPL04 )
call TriggerAddCondition( gg_trg_WP04_L, Condition( function Trig_WP04_L_Conditions ) )
call TriggerAddAction( gg_trg_WP04_L, function Trig_WP04_L_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP05_L_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP05_L_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 26
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 24
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP05_L takes nothing returns nothing
set gg_trg_WP05_L = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP05_L, gg_rct_WPL05 )
call TriggerAddCondition( gg_trg_WP05_L, Condition( function Trig_WP05_L_Conditions ) )
call TriggerAddAction( gg_trg_WP05_L, function Trig_WP05_L_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP06_L_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP06_L_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 27
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 25
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP06_L takes nothing returns nothing
set gg_trg_WP06_L = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP06_L, gg_rct_WPL06 )
call TriggerAddCondition( gg_trg_WP06_L, Condition( function Trig_WP06_L_Conditions ) )
call TriggerAddAction( gg_trg_WP06_L, function Trig_WP06_L_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_WP07_L_Conditions takes nothing returns boolean
return UnitUsesWP(GetTriggerUnit())
endfunction
function Trig_WP07_L_Actions takes nothing returns nothing
if IsUnitTeam1(GetTriggerUnit()) then
set waypoint_table[GetUnitId(GetTriggerUnit())] = 51
else
set waypoint_table[GetUnitId(GetTriggerUnit())] = 26
endif
call Order_Unit_To_Next_WP_Delay(GetTriggerUnit())
endfunction
//===========================================================================
function InitTrig_WP07_L takes nothing returns nothing
set gg_trg_WP07_L = CreateTrigger( )
call TriggerRegisterEnterRectSimple( gg_trg_WP07_L, gg_rct_WPL07 )
call TriggerAddCondition( gg_trg_WP07_L, Condition( function Trig_WP07_L_Conditions ) )
call TriggerAddAction( gg_trg_WP07_L, function Trig_WP07_L_Actions )
endfunction
//TESH.scrollpos=172
//TESH.alwaysfold=0
scope DEXP initializer Init
//Configuration globals
globals
private constant real RADIUS = 1400. //Radius to consider heroes for exp gain
private constant real CLOSE = 600. //Determines "Close" for distance effect. Gives full exp
private constant real MEDIUM = 1000. //Determines the "Middle" for distance effect. Gives less exp
private constant real FAR = 1400. //Determines the "Far" for distance effect. Gives even less exp
//Should probably be the same as Radius.
private constant real CLOSE_FACTOR = 1. //Determines what % of exp heroes in the "close" range get. (1 == 100%)
private constant real MEDIUM_FACTOR = .5 //Determines what % of exp heroes in the "medium" range get. (.5 == 50%)
private constant real FAR_FACTOR = .25 //Determines what % of exp heroes in the "far" range get. (.25 == 25%)
private constant integer UNIT_EXP = 30 // 10 //How much exp per level (of the unit) units give.
private constant integer HERO_EXP = 60 // 30 //How much exp per level (of the dying hero) heroes give.
private constant integer BONUS_EXP = 0 //How much exp is granted per allies hero nearby.
//If this value is positive, more heroes == more exp each
//if this value is negative, more heroes == less exp each ('Blizzard' method)
//If this value is 0, the number of heroes effects nothing.
//This is for the displaying of exp in textag format
private constant real DURATION = 5. //How long the message will last
private constant integer SIZE = 12 //Font size
private constant integer RED = 0 //Red value (of 255) for the text
private constant integer GREEN = 74 //Green value (of 255) for the text
private constant integer BLUE = 255 //Blue value (of 255) for the text
private constant boolean SHOW_TEXT = true //Set this to false to stop texttags
private constant boolean SPLIT = false //Set to true to divide the final exp by the number of heroes
private constant boolean DISTANCE_EFFECT = true //Set to false if you do not want the
//distance from the kill to determine how much exp the heroes get.
endglobals
private constant function Formula takes integer XPfactor, integer unitlevel, integer heroesinradius, integer bonus returns integer
return (XPfactor * unitlevel) + (heroesinradius * bonus)
//This is the function that determines how XP is calculted.
//Unless you have a different method, don't touch this.
endfunction
private function CreateXPTag takes unit TargetUnit, string message returns nothing
local unit u = TargetUnit
local string s = message
local texttag t = CreateTextTag()
call SetTextTagColor(t, 182, 91, 234, 255)
call SetTextTagText(t, s, 0.0184)
call SetTextTagPos(t, GetUnitX(u), GetUnitY(u), 0.00)
call SetTextTagVelocity(t, 0, 0.08)
call SetTextTagVisibility(t, true)
call SetTextTagFadepoint(t, 1)
call SetTextTagLifespan(t, 2)
call SetTextTagPermanent(t, false)
set u = null
set t = null
endfunction
//This is the filter that picks up heroes in the radius of the killer.
//To modify it, simply add more booleans.
private function filter takes nothing returns boolean
local unit u = GetFilterUnit()
local boolean b1 = IsUnitType(u, UNIT_TYPE_DEAD) == false
local boolean b2 = IsUnitType(u, UNIT_TYPE_HERO) == true
local boolean b3 = IsUnitAlly(u, GetOwningPlayer(GetKillingUnit())) == true
//local boolean b4 = IsHero(u) == true
local boolean b4 = GetUnitTypeId(u) != 'H008'
local boolean b5 = GetUnitTypeId(u) != 'U000'
local boolean b6 = GetUnitTypeId(u) != 'U002'
local boolean b7 = GetUnitTypeId(u) != 'U004'
set u = null
return b1 and b2 and b3 and b4 and b5 and b6 and b7
endfunction
//Use this filter to modify the exp given for certain conditions.
//For example, say you didn't want units from player 3 to give exp.
//See example below.
//Of course, if you don't want this then remove all the contents inside except "return exp"
private function ExpFilter takes integer exp, unit u returns integer
// local boolean b1 = IsUnitInGroup(u, udg_Heroes) == false
// if b1 then
// return exp * 0
// endif
return exp
endfunction
//This applies the XP accordingly.
private function GiveXP takes nothing returns nothing
local unit u = GetDyingUnit()
local unit f
local unit Killer = GetKillingUnit()
local player p = GetOwningPlayer(Killer)
local integer add = 0
local integer KilledUnitLevel
local integer unitNum = 0
local group g = CreateGroup()
local real x = GetUnitX(Killer)
local real y = GetUnitY(Killer)
local real distance
set bj_groupCountUnits = 0
call GroupEnumUnitsInRange(g, x, y, RADIUS, Condition(function filter))
call ForGroup(g, function CountUnitsInGroupEnum)
set unitNum = bj_groupCountUnits
//============================================================
if IsUnitAlly(u, p) == false then
if IsHero(u) then //if IsUnitType(u, UNIT_TYPE_HERO) == true then
set KilledUnitLevel = GetHeroLevel(u)
set add = Formula(HERO_EXP, KilledUnitLevel, unitNum, BONUS_EXP)
else
set KilledUnitLevel = GetUnitLevel(u)
set add = Formula(UNIT_EXP, KilledUnitLevel, unitNum, BONUS_EXP)
endif
endif
if SPLIT then
set add = R2I(add / unitNum)
endif
//============================================================
if DISTANCE_EFFECT then
set add = ExpFilter(add, u)
loop
set f = FirstOfGroup(g)
exitwhen f == null
set distance = ((GetUnitX(Killer)-GetUnitX(f)) * (GetUnitX(Killer)-GetUnitX(f))) + ((GetUnitY(Killer)-GetUnitY(f)) * (GetUnitY(Killer)-GetUnitY(f)))
if SHOW_TEXT and add > 0 and GetLocalPlayer() == GetOwningPlayer(f) then
call CreateXPTag(f, "+" + I2S(add) + "xp")
endif
//Far Away Units
if distance > MEDIUM*MEDIUM and distance <= FAR*FAR then
call SetPlayerHandicapXP(GetOwningPlayer(f), 1.00)
call AddHeroXP(f, R2I(add * FAR_FACTOR), true)
call SetPlayerHandicapXP(GetOwningPlayer(f), 0.00)
//Medium Distance Units
elseif distance > CLOSE*CLOSE and distance <= MEDIUM*MEDIUM then
call SetPlayerHandicapXP(GetOwningPlayer(f), 1.00)
call AddHeroXP(f, R2I(add * MEDIUM_FACTOR), true)
call SetPlayerHandicapXP(GetOwningPlayer(f), 0.00)
//Close Range Units
elseif distance <= CLOSE*CLOSE then
call SetPlayerHandicapXP(GetOwningPlayer(f), 1.00)
call AddHeroXP(f, R2I(add * CLOSE_FACTOR), true)
call SetPlayerHandicapXP(GetOwningPlayer(f), 0.00)
endif
call GroupRemoveUnit(g, f)
endloop
else
set add = ExpFilter(add, u)
loop
set f = FirstOfGroup(g)
exitwhen f == null
if SHOW_TEXT and add > 0 and GetLocalPlayer() == GetOwningPlayer(f) then
call CreateXPTag(f, "+" + I2S(add))
// call Debug_Message("add XP")
// call CreateTextTagEX("+ " + I2S(add), SIZE, f, DURATION, RED, GREEN, BLUE)
endif
call SetPlayerHandicapXP(GetOwningPlayer(f), 1.00)
call AddHeroXP(f, add, true)
call SetPlayerHandicapXP(GetOwningPlayer(f), 0.00)
call GroupRemoveUnit(g, f)
endloop
endif
call DestroyGroup(g)
set g = null
set u = null
set Killer = null
set f = null
endfunction
//This trigger stops players from gaining XP when they shouldn't be.
private function Cut_XP_Gain takes nothing returns nothing
local integer i = 0
loop
exitwhen i > 12
call SetPlayerHandicapXP(Player(i), 0.00)
set i = i + 1
endloop
call DestroyTimer(GetExpiredTimer())
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddAction(t, function GiveXP )
call TimerStart(CreateTimer(), .04, false, function Cut_XP_Gain)
set t = null
endfunction
//private function InitTrig_DEXP takes nothing returns nothing
// local trigger t = CreateTrigger( )
// call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH )
// call TriggerAddAction(t, function GiveXP )
// call TimerStart(CreateTimer(), .04, false, function Cut_XP_Gain)
// set t = null
//endfunction
endscope
//TESH.scrollpos=54
//TESH.alwaysfold=0
library Table
//***************************************************************
//* Table object 3.0
//* ------------
//*
//* set t=Table.create() - instanceates a new table object
//* call t.destroy() - destroys it
//* t[1234567] - Get value for key 1234567
//* (zero if not assigned previously)
//* set t[12341]=32 - Assigning it.
//* call t.flush(12341) - Flushes the stored value, so it
//* doesn't use any more memory
//* t.exists(32) - Was key 32 assigned? Notice
//* that flush() unassigns values.
//* call t.reset() - Flushes the whole contents of the
//* Table.
//*
//* call t.destroy() - Does reset() and also recycles the id.
//*
//* If you use HandleTable instead of Table, it is the same
//* but it uses handles as keys, the same with StringTable.
//*
//* You can use Table on structs' onInit if the struct is
//* placed in a library that requires Table or outside a library.
//*
//* You can also do 2D array syntax if you want to touch
//* mission keys directly, however, since this is shared space
//* you may want to prefix your mission keys accordingly:
//*
//* set Table["thisstring"][ 7 ] = 2
//* set Table["thisstring"][ 5 ] = Table["thisstring"][7]
//*
//***************************************************************
//=============================================================
globals
private constant integer MAX_INSTANCES=8100 //400000
//Feel free to change max instances if necessary, it will only affect allocation
//speed which shouldn't matter that much.
//=========================================================
private hashtable ht
endglobals
private struct GTable[MAX_INSTANCES]
method reset takes nothing returns nothing
call FlushChildHashtable(ht, integer(this) )
endmethod
private method onDestroy takes nothing returns nothing
call this.reset()
endmethod
//=============================================================
// initialize it all.
//
private static method onInit takes nothing returns nothing
set ht = InitHashtable()
endmethod
endstruct
//Hey: Don't instanciate other people's textmacros that you are not supposed to, thanks.
//! textmacro Table__make takes name, type, key
struct $name$ extends GTable
method operator [] takes $type$ key returns integer
return LoadInteger(ht, integer(this), $key$)
endmethod
method operator []= takes $type$ key, integer value returns nothing
call SaveInteger(ht, integer(this) ,$key$, value)
endmethod
method flush takes $type$ key returns nothing
call RemoveSavedInteger(ht, integer(this), $key$)
endmethod
method exists takes $type$ key returns boolean
return HaveSavedInteger( ht, integer(this) ,$key$)
endmethod
static method flush2D takes string firstkey returns nothing
call $name$(- StringHash(firstkey)).reset()
endmethod
static method operator [] takes string firstkey returns $name$
return $name$(- StringHash(firstkey) )
endmethod
endstruct
//! endtextmacro
//! runtextmacro Table__make("Table","integer","key" )
//! runtextmacro Table__make("StringTable","string", "StringHash(key)" )
//! runtextmacro Table__make("HandleTable","handle","GetHandleId(key)" )
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library TimerUtils initializer init
//*********************************************************************
//* TimerUtils (red+blue+orange flavors for 1.24b+)
//* ----------
//*
//* To implement it , create a custom text trigger called TimerUtils
//* and paste the contents of this script there.
//*
//* To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass) More scripts: htt://www.wc3c.net
//*
//* For your timer needs:
//* * Attaching
//* * Recycling (with double-free protection)
//*
//* set t=NewTimer() : Get a timer (alternative to CreateTimer)
//* ReleaseTimer(t) : Relese a timer (alt to DestroyTimer)
//* SetTimerData(t,2) : Attach value 2 to timer
//* GetTimerData(t) : Get the timer's value.
//* You can assume a timer's value is 0
//* after NewTimer.
//*
//* Multi-flavor:
//* Set USE_HASH_TABLE to true if you don't want to complicate your life.
//*
//* If you like speed and giberish try learning about the other flavors.
//*
//********************************************************************
//================================================================
globals
//How to tweak timer utils:
// USE_HASH_TABLE = true (new blue)
// * SAFEST
// * SLOWEST (though hash tables are kind of fast)
//
// USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = true (orange)
// * kinda safe (except there is a limit in the number of timers)
// * ALMOST FAST
//
// USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = false (red)
// * THE FASTEST (though is only faster than the previous method
// after using the optimizer on the map)
// * THE LEAST SAFE ( you may have to tweak OFSSET manually for it to
// work)
//
private constant boolean USE_HASH_TABLE = true
private constant boolean USE_FLEXIBLE_OFFSET = false
private constant integer OFFSET = 0x100000
private integer VOFFSET = OFFSET
//Timers to preload at map init:
private constant integer QUANTITY = 256
//Changing this to something big will allow you to keep recycling
// timers even when there are already AN INCREDIBLE AMOUNT of timers in
// the stack. But it will make things far slower so that's probably a bad idea...
private constant integer ARRAY_SIZE = 8190
endglobals
//==================================================================================================
globals
private integer array data[ARRAY_SIZE]
private hashtable ht
endglobals
//It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
function SetTimerData takes timer t, integer value returns nothing
static if (USE_HASH_TABLE) then
// new blue
call SaveInteger(ht,0,GetHandleId(t), value)
elseif (USE_FLEXIBLE_OFFSET) then
// orange
static if (DEBUG_MODE) then
if (GetHandleId(t)-VOFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
set data[GetHandleId(t)-VOFFSET]=value
else
// new red
static if (DEBUG_MODE) then
if (GetHandleId(t)-OFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
set data[GetHandleId(t)-OFFSET]=value
endif
endfunction
function GetTimerData takes timer t returns integer
static if(USE_HASH_TABLE) then
// new blue
return LoadInteger(ht,0,GetHandleId(t) )
elseif (USE_FLEXIBLE_OFFSET) then
// orange
static if (DEBUG_MODE) then
if(GetHandleId(t)-VOFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
return data[GetHandleId(t)-VOFFSET]
else
// new red
static if (DEBUG_MODE) then
if(GetHandleId(t)-OFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
return data[GetHandleId(t)-OFFSET]
endif
endfunction
//==========================================================================================
globals
private timer array tT[ARRAY_SIZE]
private integer tN = 0
private constant integer HELD=0x28829022
//use a totally random number here, the more improbable someone uses it, the better.
endglobals
//==========================================================================================
function NewTimer takes nothing returns timer
if (tN==0) then
//If this happens then the QUANTITY rule has already been broken, try to fix the
// issue, else fail.
debug call BJDebugMsg("NewTimer: Warning, Exceeding TimerUtils_QUANTITY, make sure all timers are getting recycled correctly")
static if( not USE_HASH_TABLE) then
debug call BJDebugMsg("In case of errors, please increase it accordingly, or set TimerUtils_USE_HASH_TABLE to true")
set tT[0]=CreateTimer()
static if( USE_FLEXIBLE_OFFSET) then
if (GetHandleId(tT[0])-VOFFSET<0) or (GetHandleId(tT[0])-VOFFSET>=ARRAY_SIZE) then
//all right, couldn't fix it
call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
return null
endif
else
if (GetHandleId(tT[0])-OFFSET<0) or (GetHandleId(tT[0])-OFFSET>=ARRAY_SIZE) then
//all right, couldn't fix it
call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
return null
endif
endif
endif
else
set tN=tN-1
endif
call SetTimerData(tT[tN],0)
return tT[tN]
endfunction
//==========================================================================================
function ReleaseTimer takes timer t returns nothing
if(t==null) then
debug call BJDebugMsg("Warning: attempt to release a null timer")
return
endif
if (tN==ARRAY_SIZE) 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
call PauseTimer(t)
if(GetTimerData(t)==HELD) then
debug call BJDebugMsg("Warning: ReleaseTimer: Double free!")
return
endif
call SetTimerData(t,HELD)
set tT[tN]=t
set tN=tN+1
endif
endfunction
private function init takes nothing returns nothing
local integer i=0
local integer o=-1
local boolean oops = false
static if( USE_HASH_TABLE ) then
set ht = InitHashtable()
loop
exitwhen(i==QUANTITY)
set tT[i]=CreateTimer()
call SetTimerData(tT[i], HELD)
set i=i+1
endloop
set tN = QUANTITY
else
loop
set i=0
loop
exitwhen (i==QUANTITY)
set tT[i] = CreateTimer()
if(i==0) then
set VOFFSET = GetHandleId(tT[i])
static if(USE_FLEXIBLE_OFFSET) then
set o=VOFFSET
else
set o=OFFSET
endif
endif
if (GetHandleId(tT[i])-o>=ARRAY_SIZE) then
exitwhen true
endif
if (GetHandleId(tT[i])-o>=0) then
set i=i+1
endif
endloop
set tN = i
exitwhen(tN == QUANTITY)
set oops = true
exitwhen not USE_FLEXIBLE_OFFSET
debug call BJDebugMsg("TimerUtils_init: Failed a initialization attempt, will try again")
endloop
if(oops) then
static if ( USE_FLEXIBLE_OFFSET) then
debug call BJDebugMsg("The problem has been fixed.")
//If this message doesn't appear then there is so much
//handle id fragmentation that it was impossible to preload
//so many timers and the thread crashed! Therefore this
//debug message is useful.
elseif(DEBUG_MODE) then
call BJDebugMsg("There were problems and the new timer limit is "+I2S(i))
call BJDebugMsg("This is a rare ocurrence, if the timer limit is too low:")
call BJDebugMsg("a) Change USE_FLEXIBLE_OFFSET to true (reduces performance a little)")
call BJDebugMsg("b) or try changing OFFSET to "+I2S(VOFFSET) )
endif
endif
endif
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library GroupUtils initializer Init requires optional xebasic
//******************************************************************************
//* BY: Rising_Dusk
//*
//* This library is a combination of several features relevant to groups. First
//* and foremost, it contains a group stack that you can access dynamic groups
//* from. It also provides means to refresh groups and clear any shadow
//* references within them. The included boolexprs are there for backwards
//* compatibility with maps that happen to use them. Since the 1.24c patch,
//* null boolexprs used in GroupEnumUnits* calls no longer leak, so there is no
//* performance gain to using the BOOLEXPR_TRUE constant.
//*
//* Instead of creating/destroying groups, we have moved on to recycling them.
//* NewGroup pulls a group from the stack and ReleaseGroup adds it back. Always
//* remember to call ReleaseGroup on a group when you are done using it. If you
//* fail to do so enough times, the stack will overflow and no longer work.
//*
//* GroupRefresh cleans a group of any shadow references which may be clogging
//* its hashtable. If you remove a unit from the game who is a member of a unit
//* group, it will 'effectively' remove the unit from the group, but leave a
//* shadow in its place. Calling GroupRefresh on a group will clean up any
//* shadow references that may exist within it. It is only worth doing this on
//* groups that you plan to have around for awhile.
//*
//* Constants that can be used from the library:
//* [group] ENUM_GROUP As you might expect, this group is good for
//* when you need a group just for enumeration.
//* [boolexpr] BOOLEXPR_TRUE This is a true boolexpr, which is important
//* because a 'null' boolexpr in enumeration
//* calls results in a leak. Use this instead.
//* [boolexpr] BOOLEXPR_FALSE This exists mostly for completeness.
//*
//* This library also includes a simple implementation of a group enumeration
//* call that factors collision of units in a given area of effect. This is
//* particularly useful because GroupEnumUnitsInRange doesn't factor collision.
//*
//* In your map, you can just replace all instances of GroupEnumUnitsInRange
//* with GroupEnumUnitsInArea with identical arguments and your spells will
//* consider all units colliding with the area of effect. After calling this
//* function as you would normally call GroupEnumUnitsInRange, you are free to
//* do anything with the group that you would normally do.
//*
//* If you don't use xebasic in your map, you may edit the MAX_COLLISION_SIZE
//* variable below and the library will use that as the added radius to check.
//* If you use xebasic, however, the script will automatically use xe's
//* collision size variable.
//*
//* You are also able to use GroupUnitsInArea. This function returns all units
//* within the area, no matter what they are, which can be convenient for those
//* instances where you actually want that.
//*
//* Example usage:
//* local group MyGroup = NewGroup()
//* call GroupRefresh(MyGroup)
//* call ReleaseGroup(MyGroup)
//* call GroupEnumUnitsInArea(ENUM_GROUP, x, y, 350., BOOLEXPR_TRUE)
//* call GroupUnitsInArea(ENUM_GROUP, x, y, 350.)
//*
globals
//If you don't have xebasic in your map, this value will be used instead.
//This value corresponds to the max collision size of a unit in your map.
private constant real MAX_COLLISION_SIZE = 197.
//If you are insane and don't care about any of the protection involved in
//this library, but want this script to be really fast, set this to true.
private constant boolean LESS_SAFETY = false
endglobals
globals
//* Constants that are available to the user
group ENUM_GROUP = CreateGroup()
boolexpr BOOLEXPR_TRUE = null
boolexpr BOOLEXPR_FALSE = null
endglobals
globals
//* Hashtable for debug purposes
private hashtable ht = InitHashtable()
//* Temporary references for GroupRefresh
private boolean Flag = false
private group Refr = null
//* Arrays and counter for the group stack
private group array Groups
private integer Count = 0
//* Variables for use with the GroupUnitsInArea function
private real X = 0.
private real Y = 0.
private real R = 0.
private hashtable H = InitHashtable()
endglobals
private function HookDestroyGroup takes group g returns nothing
if g == ENUM_GROUP then
call BJDebugMsg(SCOPE_PREFIX+"Warning: ENUM_GROUP destroyed")
endif
endfunction
debug hook DestroyGroup HookDestroyGroup
private function AddEx takes nothing returns nothing
if Flag then
call GroupClear(Refr)
set Flag = false
endif
call GroupAddUnit(Refr, GetEnumUnit())
endfunction
function GroupRefresh takes group g returns nothing
set Flag = true
set Refr = g
call ForGroup(Refr, function AddEx)
if Flag then
call GroupClear(g)
endif
endfunction
function NewGroup takes nothing returns group
if Count == 0 then
set Groups[0] = CreateGroup()
else
set Count = Count - 1
endif
static if not LESS_SAFETY then
call SaveInteger(ht, 0, GetHandleId(Groups[Count]), 1)
endif
return Groups[Count]
endfunction
function ReleaseGroup takes group g returns boolean
local integer id = GetHandleId(g)
static if LESS_SAFETY then
if g == null then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Null groups cannot be released")
return false
elseif Count == 8191 then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Max groups achieved, destroying group")
call DestroyGroup(g)
return false
endif
else
if g == null then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Null groups cannot be released")
return false
elseif not HaveSavedInteger(ht, 0, id) then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Group not part of stack")
return false
elseif LoadInteger(ht, 0, id) == 2 then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Groups cannot be multiply released")
return false
elseif Count == 8191 then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Max groups achieved, destroying group")
call DestroyGroup(g)
return false
endif
call SaveInteger(ht, 0, id, 2)
endif
call GroupClear(g)
set Groups[Count] = g
set Count = Count + 1
return true
endfunction
private function Filter takes nothing returns boolean
return IsUnitInRangeXY(GetFilterUnit(), X, Y, R)
endfunction
private function HookDestroyBoolExpr takes boolexpr b returns nothing
local integer bid = GetHandleId(b)
if HaveSavedHandle(H, 0, bid) then
//Clear the saved boolexpr
call DestroyBoolExpr(LoadBooleanExprHandle(H, 0, bid))
call RemoveSavedHandle(H, 0, bid)
endif
endfunction
hook DestroyBoolExpr HookDestroyBoolExpr
private constant function GetRadius takes real radius returns real
static if LIBRARY_xebasic then
return radius+XE_MAX_COLLISION_SIZE
else
return radius+MAX_COLLISION_SIZE
endif
endfunction
function GroupEnumUnitsInArea takes group whichGroup, real x, real y, real radius, boolexpr filter returns nothing
local real prevX = X
local real prevY = Y
local real prevR = R
local integer bid = 0
//Set variables to new values
set X = x
set Y = y
set R = radius
if filter == null then
//Adjusts for null boolexprs passed to the function
set filter = Condition(function Filter)
else
//Check for a saved boolexpr
set bid = GetHandleId(filter)
if HaveSavedHandle(H, 0, bid) then
//Set the filter to use to the saved one
set filter = LoadBooleanExprHandle(H, 0, bid)
else
//Create a new And() boolexpr for this filter
set filter = And(Condition(function Filter), filter)
call SaveBooleanExprHandle(H, 0, bid, filter)
endif
endif
//Enumerate, if they want to use the boolexpr, this lets them
call GroupEnumUnitsInRange(whichGroup, x, y, GetRadius(radius), filter)
//Give back original settings so nested enumerations work
set X = prevX
set Y = prevY
set R = prevR
endfunction
function GroupUnitsInArea takes group whichGroup, real x, real y, real radius returns nothing
local real prevX = X
local real prevY = Y
local real prevR = R
//Set variables to new values
set X = x
set Y = y
set R = radius
//Enumerate
call GroupEnumUnitsInRange(whichGroup, x, y, GetRadius(radius), Condition(function Filter))
//Give back original settings so nested enumerations work
set X = prevX
set Y = prevY
set R = prevR
endfunction
private function True takes nothing returns boolean
return true
endfunction
private function False takes nothing returns boolean
return false
endfunction
private function Init takes nothing returns nothing
set BOOLEXPR_TRUE = Condition(function True)
set BOOLEXPR_FALSE = Condition(function False)
endfunction
endlibrary
//TESH.scrollpos=55
//TESH.alwaysfold=0
library ShieldSystem initializer Init requires IntuitiveBuffSystem
// The_Witcher's Shield System
//
// This is an easy to use shield system.
// it allows you to add shield points to a unit
// the shield works like in the game halo:
// the attacked unit doesn't receive any dmg, the shield gets it
// when the shield is down the unit is damaged
// the shield can reload constantly or after some seconds of not beeing attacked
//
// to give a unit a shield just use (if duration is 0 the shield will stay without a time limit)
//
// call AddShield( towhichunit, hitpoints, RegPerSec, TimeTillReg, damage factor, colorcode, destroy when shieldhp = 0, show the bar, Duration )
// unit real real real real string boolean boolean real
//
// you can check whether a unit has already a shield with (it will return a boolean)
// UnitHasShield( yourunit)
// unit
//
// to implement this system, just copy this trigger in your map
// it requires jngp to be edited/saved
//
// To get rid of a shield just use
// call DestroyShield( which unit's)
// unit
//
// to show or hide the shield bar use
// call ShowShield( WhichUnits, Show? )
// unit boolean
//
// to get information about an existing shield use:
// HP: GetShieldHp( unit )
// maxHP: GetShieldMaxHp( unit )
// percentHP: GetShieldHpPercent( unit )
// regeneration: GetShieldReg( unit )
// TimeTillReg: GetShieldTimeTillReg( unit )
// DamageFactor: GetShieldDamageFactor( unit )
//
// to change the values of an existing shield use:
// HP: SetShieldHp( unit, NewValue )
// maxHP: SetShieldMaxHp( unit, NewValue )
// percentHP: SetShieldHpPercent( unit, NewValue )
// regeneration: SetShieldReg( unit, NewValue )
// TimeTillReg: SetShieldTimeTillReg( unit, NewValue )
// DamageFactor: SetShieldDamageFactor( unit, NewValue )
//
// have fun^^
// The (very small^^) Setup part
globals
// the shieldbar's size (should be (7.5 * 0.023 / 10 - 0.00625) or 0.01(which isn't working for everyone) for a good result)
private constant real size = 7.5 * 0.023 / 10 - 0.00625
// A ability which gives a high instant life bonus
private constant integer lifeabi = 'A001'
// the timer interval (should be 0.01 but if laggy then just change it)
private constant real interval = 0.01
//the path of the special effect for untis with a shield
//another good effect: "Abilities\\Spells\\Human\\DivineShield\\DivineShieldTarget.mdl"
// private constant string sfx = "Abilities\\Spells\\NightElf\\Rejuvenation\\RejuvenationTarget.mdl"
//the attachement point for sfx
private constant string AtPoint = "chest"
endglobals
// end of Setup!!
private struct shield
unit u
real hp
real fullhp
real reg
real f
string code
texttag t
real r
effect fx
real remain
timer time
boolean kill
integer i
real damage = 0
boolean show
endstruct
globals
private trigger trg = CreateTrigger()
private group g = CreateGroup()
private hashtable h = InitHashtable()
private integer total = 0
private unit array units
private timer tim = CreateTimer()
endglobals
function UnitHasShield takes unit u returns boolean
return LoadInteger(h,GetHandleId(u),0) != 0
endfunction
function DestroyShield takes unit whichunits returns nothing
local shield dat = LoadInteger(h,GetHandleId(whichunits),0)
local shield dat2 = LoadInteger(h,GetHandleId(units[total-1]),0)
call Debug_Message("Destroy Shield")
if dat != 0 then
call DestroyTextTag(dat.t)
// add by Moco
set dat.t = null
call DestroyTimer(dat.time)
call DestroyEffect(dat.fx)
call FlushChildHashtable(h,GetHandleId(whichunits))
set total = total - 1
set units[dat.i] = units[total]
set dat2.i = dat.i
call dat.destroy()
// If unit already has old buff, remove it
if UnitHasBuff(whichunits, BUFF_TYPE_ICE_BARRIER) then
call UnitRemoveBuff(whichunits, BUFF_TYPE_ICE_BARRIER)
endif
if UnitHasBuff(whichunits, BUFF_TYPE_SHIELD) then
call UnitRemoveBuff(whichunits, BUFF_TYPE_SHIELD)
endif
// if UnitHasBuff(whichunits, BUFF_TYPE_SOUL_SHIELD) then
// call UnitRemoveBuff(whichunits, BUFF_TYPE_SOUL_SHIELD)
// endif
endif
if total == 0 then
call PauseTimer(tim)
endif
endfunction
private function regeneration takes nothing returns nothing
local shield dat
local string s = "''''''''''''''''''''''''''''''''''''''''''''''''''"
local integer k
local integer i = 0
loop
exitwhen i >= total
set dat = LoadInteger(h,GetHandleId(units[i]),0)
if TimerGetRemaining(dat.time) == 0 then
if dat.hp < dat.fullhp then
set dat.hp = dat.hp + dat.reg
else
set dat.hp = dat.fullhp
endif
endif
if dat.remain > 0 then
set dat.remain = dat.remain - interval
elseif dat.remain != -100 then
call DestroyShield(dat.u)
endif
set k = R2I(50 * (dat.hp / dat.fullhp))
call SetTextTagText(dat.t, dat.code + SubString(s,0, k ) + "|r" + SubString(s,k + 1,StringLength(s)) , size)
call SetTextTagPos(dat.t,GetUnitX(dat.u) -40, GetUnitY(dat.u),-100)
// changed by MoCo for healin
if dat.damage > 0 then
// if dat.damage != 0 then
if dat.hp > (dat.damage * dat.f) then
set dat.hp = dat.hp - (dat.damage * dat.f)
call SetWidgetLife( dat.u,GetWidgetLife(dat.u) + dat.damage)
else
call SetWidgetLife( dat.u,GetWidgetLife(dat.u) + dat.hp)
set dat.hp = 0
endif
set dat.damage = 0
endif
call UnitRemoveAbility(dat.u,lifeabi)
if dat.hp <= 0 and dat.kill == true then
call DestroyShield(dat.u)
set i = i - 1
endif
set i = i + 1
endloop
set s = null
endfunction
private function attack takes nothing returns nothing
local shield dat = LoadInteger(h,GetHandleId(GetTriggerUnit()),0)
local timer t
if dat != 0 then
if dat.hp > 0 then
if GetEventDamage() > 0 then// add by MoCo
set dat.damage = dat.damage + GetEventDamage()
endif
endif
call TimerStart(dat.time,dat.r,false,null)
endif
endfunction
function AddShield takes unit towhich, real hp, real RegPerSec, real TimeTillReg, real dmgfactor, string colorcode, boolean destroy, boolean ShowBar, real Duration, string sfx returns nothing
local shield dat
if LoadInteger(h,GetHandleId(towhich),0) != 0 then
call DestroyShield(towhich)
endif
set dat = shield.create()
set dat.u = towhich
set dat.fullhp = hp
set dat.hp = hp
set dat.reg = RegPerSec / 100
set dat.f = dmgfactor
set dat.code = colorcode
set dat.r = TimeTillReg
set dat.kill = destroy
set dat.time = CreateTimer()
set dat.t = CreateTextTag()
set dat.show = ShowBar
set dat.fx = AddSpecialEffectTarget(sfx, dat.u, AtPoint)
set dat.remain = Duration
if dat.remain == 0 then
set dat.remain = -100
endif
call SetTextTagVisibility(dat.t,ShowBar)
set dat.i = total
if not IsUnitInGroup(dat.u,g) then
call GroupAddUnit(g,dat.u)
call TriggerRegisterUnitEvent( trg, towhich, EVENT_UNIT_DAMAGED )
endif
set units[total] = dat.u
set total = total + 1
call SaveInteger(h,GetHandleId(dat.u),0,dat)
if total == 1 then
call TimerStart(tim,interval,true,function regeneration)
endif
endfunction
private function kill takes nothing returns nothing
call DestroyShield(GetTriggerUnit())
endfunction
function ShowShield takes unit u, boolean flag returns nothing
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
set dat.show = flag
call SetTextTagVisibility(dat.t,flag)
endif
endfunction
function GetShieldHpPercent takes unit u returns real
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
return dat.hp / dat.fullhp * 100.0
endif
return .0
endfunction
function GetShieldHp takes unit u returns real
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
return dat.hp
endif
return .0
endfunction
function GetShieldMaxHp takes unit u returns real
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
return dat.fullhp
endif
return .0
endfunction
function GetShieldReg takes unit u returns real
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
return dat.reg*100
endif
return .0
endfunction
function GetShieldTimeTillReg takes unit u returns real
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
return dat.r
endif
return .0
endfunction
function GetShieldDamageFactor takes unit u returns real
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
return dat.f
endif
return .0
endfunction
function SetShieldHpPercent takes unit u, real new returns nothing
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
set dat.hp = dat.fullhp * new/100
if dat.fullhp < dat.hp then
set dat.hp = dat.fullhp
endif
endif
endfunction
function SetShieldHp takes unit u, real new returns nothing
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
set dat.hp = new
if dat.fullhp < dat.hp then
set dat.hp = dat.fullhp
endif
endif
endfunction
function SetShieldMaxHp takes unit u, real new returns nothing
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
set dat.fullhp = new
if dat.fullhp < dat.hp then
set dat.hp = dat.fullhp
endif
endif
endfunction
function SetShieldReg takes unit u, real new returns nothing
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
set dat.reg = new/100
endif
endfunction
function SetShieldTimeTillReg takes unit u, real new returns nothing
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
set dat.r = new
call TimerStart(dat.time,dat.r,false,null)
endif
endfunction
function SetShieldDamageFactor takes unit u, real new returns nothing
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
set dat.f = new
endif
endfunction
private function Init takes nothing returns nothing
// local trigger tt = CreateTrigger()
// call TriggerAddAction(tt, function kill)
// call TriggerRegisterAnyUnitEventBJ( tt, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddAction(trg, function attack)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library IntuitiveBuffSystem initializer Init requires Stack, TimerUtils, AutoIndex, AbilityPreload
//******************************************************************************
//* BY: Rising_Dusk
//* (Intuitive) Buff System 1.05
//*
//* This library is a simple and easy to understand implementation of custom
//* buff handling in JASS. I call it the Intuitive Buff System because anyone
//* should be able to pick it up and use it right away. It uses a callback
//* driven style where the user specifies which callbacks run either
//* periodically over a buff's duration or when the buff is removed. This covers
//* all possible types of buffs that one might want to create.
//*
//******************************************************************************
//*
//* In order to make a buff work, one must first create a custom aura ability in
//* the Object Editor and a custom buff for that aura. The raw ids for these
//* objects need to be supplied to the IBS via the DefineBuffType function.
//*
//* function DefineBuffType takes integer AbilId, integer BuffId, ...
//* ... real period, boolean isPeriodic, boolean isPositive, callback onAdd, ...
//* ... callback onPeriodic, callback onEnd returns integer
//*
//* The arguments for this function are as follows:
//* [integer] AbilId Owner of the buff being applied
//* [integer] BuffId Target for the buff to be applied to
//* [real] period Type of the buff from DefineBuffType
//* [boolean] isPeriodic Whether the buff is periodic or not
//* [boolean] isPositive Whether the buff is positive or not
//* [callback] onAdd Callback to run when a buff is added
//* [callback] onPeriodic Callback to run every buff iteration
//* [callback] onEnd Callback to run when a buff ends
//*
//* NOTE: All callbacks must follow the below structural convention
//* function MyCallback takes nothing returns nothing
//*
//* The callback functions may be private, public, or whatever. When using them
//* in the DefineBuffType function call, simply put the function's name for the
//* respective argument (no function keyword). If you do not want any function
//* to be called for one of the callbacks, simply use 0 for that argument.
//*
//* Once the bufftype is registered with the system, you are free to use it
//* whenever you want to. It returns an integer, which you should set to a
//* global integer in a scope initializer or some initialization function. To
//* apply a buff to a unit, simple call the function. All of these
//* values are effectively constant for any buff created of the given bufftype.
//*
//* The period argument tells the system the interval for running the
//* onPeriodic callback function. The period and onPeriodic arguments only
//* matter if the isPeriodic argument is true. The onEnd argument runs when a
//* buff is removed either manually, by it expiring, or by the unit it is on
//* dying. The onAdd argument runs when a buff is either applied or refreshed.
//* Please do not destroy the dbuff struct inside your callback functions; that
//* will cause doublefrees. The system automatically cleans them up.
//*
//* Inside the callbacks, you get one event response:
//* function GetEventBuff takes nothing returns dbuff
//*
//* Usage:
//* local dbuff db = GetEventBuff()
//*
//* Within the above struct, the following information can be retrieved (or
//* modified, but I recommend not changing most of the parameters). At any given
//* time during the buff's existence, these values can also be retrieved with a
//* call to GetUnitBuff, GetRandomBuff, or GetRandomBuffSigned on the unit.
//*
//* [unit] .source Owning unit of the buff
//* [unit] .target Unit the buff is applied to
//* [real] .duration Total duration for buff expiration
//* [real] .timeElapsed() Total elapsed time of the buff
//* [real] .timeRemaining() Remaining time before buff expiration
//* .setDuration(NewDur) Sets the current buff duration to NewDur
//* .addDuration(ModDur) Adds ModDur to the current buff duration
//* [integer] .btype.period Periodicity for the buff
//* [integer] .level Level of the buff used on the unit
//* [integer] .data An integer the user can store data to
//* [boolean] .isPeriodic Whether the buff is periodic or not
//* [boolean] .isExpired Whether the buff expired naturally or not
//* Can only return true in the 'OnEnd' callback
//* [boolean] .isRemoved Whether the buff was purged or removed by death or not
//* Can only return true in the 'OnEnd' callback
//* [boolean] .isRefreshed Whether the buff was refreshed or not
//* Can only return true in the 'OnAdd' callback
//*
//******************************************************************************
//*
//* function UnitAddBuff takes unit source, unit target, integer btype, ...
//* ... real dur, integer lvl returns dbuff
//*
//* The arguments for this function are as follows:
//* [unit] source The 'owner' of the buff being applied
//* [unit] target The target for the buff to be applied to
//* [integer] btype The type of the buff from DefineBuffType
//* [real] dur The total duration of the buff
//* [integer] lvl The 'level' of the buff
//*
//* Constants usable in this function call:
//* [real] BUFF_PERMANENT This is the value you should use for the
//* duration argument if you want a buff
//* that never ends.
//*
//* Additional options of note:
//* set mybuff.data = SomeInteger This allows you to attach an integer to
//* a buff that you can get in the event
//* callbacks.
//*
//* The lvl argument is there for reapplication of buff purposes. A buff being
//* applied of a higher level than the old buff will always overwrite the old
//* one, it doesn't matter if duration is higher or not. This way, if you want a
//* buff to get shorter per level, the system will support that.
//*
//******************************************************************************
//*
//* Available system functions:
//*
//* > function GetUnitBuff takes unit target, integer whichType returns dbuff
//*
//* This function allows the user to get a specific buff on a unit at any point
//* if the user knows the bufftype they want. Will return 0 if the buff does not
//* exist.
//*
//* > function GetRandomBuff takes unit target returns dbuff
//*
//* This function allows the user to get a random buff on a unit at any point.
//* Getting a random buff is most useful for stealing or moving of arbitrary
//* buffs on a unit. Will return 0 if the unit has no buffs.
//*
//* > function GetRandomBuffSigned takes unit target, boolean isPos returns dbuff
//*
//* This function, like GetRandomBuff, returns a random buff on a unit given a
//* 'sign'. The isPos argument lets you specify to either get a random positive
//* buff if true or a random negative buff if false. Will return 0 if the unit
//* has no buffs of the desired alignment.
//*
//* > function GetLastAppliedBuff takes unit target returns dbuff
//*
//* This function returns the most recently applied buff on a unit. Will return
//* 0 if the unit has no buffs.
//*
//* > function GetFirstAppliedBuff takes unit target returns dbuff
//*
//* This function returns the first buff in a user's bufflist that is still
//* active. Will return 0 if the unit has no buffs.
//*
//* > function UnitHasBuff takes unit target, integer whichType returns boolean
//*
//* This function will return true if the given unit has the specified buff.
//*
//* > function UnitHasAnyBuff takes unit target returns boolean
//*
//* This function will return true if the given unit has any buff managed by
//* the system.
//*
//* > function UnitRemoveBuff takes unit target, integer whichType returns boolean
//*
//* This function removes a buff of a specified type from a given unit. Will
//* return false if the buff did not exist to be removed.
//*
//* > function UnitRemoveAllBuffs takes unit target returns nothing
//*
//* This function removes all buffs of any type from a given unit.
//*
//******************************************************************************
//*
//* Finally, there is the inherent limit that you can only have 8192 buffs and
//* 8192 bufftypes at once. If you ever get this high, your map will have worse
//* problems than this system working improperly.
//*
//* I hope you find this library as useful as I do. Thanks for reading the
//* documentation. If you have any questions for me about the IBS, how it works,
//* or if you have suggestions for it, please contact me at WC3C by private
//* message. This system is only authorized for release at Warcraft 3 Campaigns.
//*
//* Enjoy!
//*
globals
//Constant for use with infinite duration buffs
constant real BUFF_PERMANENT = 0x800000
endglobals
private keyword TimeOut
private keyword TempBuff
private function interface callback takes nothing returns nothing
globals
private hashtable ht = InitHashtable() //Hashtable for all data attachment
private integer array lists
endglobals
private struct bufftype
//All readonly so the user doesn't mess with them
integer abilid
integer buffid
real period
boolean isPeriodic
boolean isPositive
//All of the callback behavior for the bufftype
callback onAdd
callback onPeriodic
callback onEnd
static method create takes integer abilid, integer buffid, real period, boolean isPeriodic, boolean isPositive, callback onAdd, callback onPeriodic, callback onEnd returns bufftype
local bufftype bt = bufftype.allocate()
set bt.abilid = abilid
set bt.buffid = buffid
set bt.period = period
set bt.isPeriodic = isPeriodic
set bt.onAdd = onAdd
set bt.onPeriodic = onPeriodic
set bt.onEnd = onEnd
return bt
endmethod
endstruct
private struct bufflist
Stack sta
unit target
static method create takes unit target returns bufflist
local bufflist bl = bufflist.allocate()
set bl.target = target
set bl.sta = Stack.create()
//Attach it to the unit
set lists[GetUnitId(target)] = integer(bl)
return bl
endmethod
private method onDestroy takes nothing returns nothing
call .sta.destroy() //Destroy the stack
set lists[GetUnitId(.target)] = 0 //Remove array value
endmethod
endstruct
struct dbuff
unit source
unit target
real elapsed = 0.
real duration
integer level
integer data = 0
bufftype btype
timer tmr
//Behavior variables inside the struct
boolean isPeriodic
boolean isExpired = false
boolean isRemoved = false
boolean isRefreshed = false
//Handy methods that save the user math they don't want to do
method timeElapsed takes nothing returns real
if .btype.isPeriodic then
return .elapsed+TimerGetElapsed(.tmr)
else
return TimerGetElapsed(.tmr)
endif
endmethod
method timeRemaining takes nothing returns real
if .btype.isPeriodic then
return .duration-.elapsed-TimerGetElapsed(.tmr)
else
return TimerGetRemaining(.tmr)
endif
endmethod
method setDuration takes real newDur returns nothing
local real oldDur = .duration
if .timeElapsed() >= newDur then
//This is equivalent to force removing the buff, so kill it
set .isExpired = false
set .isRemoved = true
set .isRefreshed = false
call .destroy() //Timer gets recycled in here!
else
if .isPeriodic then
if .timeElapsed() + .btype.period > newDur then
//Update timeout to cover last segment of buff duration
call TimerStart(.tmr, newDur-.timeElapsed(), false, TimeOut)
//Since it won't clear a full period, we don't let it run onPeriodic
set .isPeriodic = false
endif
else
//Run for however long you have to so total duration is the new duration
call TimerStart(.tmr, newDur-.timeElapsed() , false, TimeOut)
endif
set .duration = newDur
endif
endmethod
method addDuration takes real modDur returns nothing
//Just calls the setDuration method
call .setDuration(.duration+modDur)
endmethod
//Some callback running methods
method runAdd takes nothing returns nothing
set .isExpired = false
set .isRemoved = false
set .isRefreshed = false
call .btype.onAdd.execute()
endmethod
method runRefreshed takes nothing returns nothing
set .isRefreshed = true
set .isExpired = false
set .isRemoved = false
call .btype.onAdd.execute()
endmethod
method runPeriodic takes nothing returns nothing
set .isExpired = false
set .isRemoved = false
set .isRefreshed = false
call .btype.onPeriodic.execute()
endmethod
method runExpired takes nothing returns nothing
//This destroys the dbuff
set .isExpired = true
set .isRemoved = false
set .isRefreshed = false
call .destroy() //Timer gets recycled in here!
endmethod
method runRemoved takes nothing returns nothing
//This destroys the dbuff
set .isExpired = false
set .isRemoved = true
set .isRefreshed = false
call .destroy() //Timer gets recycled in here!
endmethod
static method create takes unit source, unit target, bufftype btype, real dur, integer lvl returns dbuff
local dbuff db = dbuff.allocate()
local integer id = GetUnitId(target)
set db.source = source
set db.target = target
set db.duration = dur
set db.btype = btype
set db.isPeriodic = btype.isPeriodic
set db.level = lvl
set db.tmr = NewTimer()
//Hook the dbuff to the timer
call SetTimerData(db.tmr, integer(db))
//Add ability to the target of the buff
call UnitAddAbility(target, db.btype.abilid)
call UnitMakeAbilityPermanent(target, true, db.btype.abilid)
//Load to table for future referencing
call SaveInteger(ht, btype, id, integer(db))
//Push the buff into the bufflist stack on the target
call bufflist(lists[id]).sta.add(integer(db))
return db
endmethod
private method onDestroy takes nothing returns nothing
local integer id = GetUnitId(.target)
//Clear the table value so the system knows it's done
//Done before the onRemove call to prevent potential double frees with death trigger
call RemoveSavedInteger(ht, .btype, id)
//Remove the buff from the bufflist stack on the target
call bufflist(lists[id]).sta.remove(integer(this))
//Set up and run the onRemove callback
set TempBuff = this
call .btype.onEnd.execute()
//Clear stuff inside the struct and on the unit
call UnitRemoveAbility(.target, .btype.abilid)
call UnitRemoveAbility(.target, .btype.buffid)
call ReleaseTimer(.tmr)
endmethod
endstruct
globals
private code TimeOut = null //Code callback for buff timeouts
private integer BuffTypeCount = 0 //Counter for how many buff types exist
private bufftype array BuffTypes //Array for all defined buff types
private dbuff TempBuff = 0 //Temp buff for callback data
endglobals
private function BuffTimeout takes nothing returns nothing
local timer t = GetExpiredTimer()
local dbuff db = dbuff(GetTimerData(t))
//Different behavior for periodic buffs than one-timers
if db.isPeriodic then
//Run the onPeriod callback no matter what
set TempBuff = db
call db.runPeriodic()
//Check if this iteration kills the buff
set db.elapsed = db.elapsed + db.btype.period
if db.elapsed >= db.duration and not db.isRemoved then
//Kill the buff completely if it hasn't been cleared elsewhere
call db.runExpired()
elseif db.elapsed + db.btype.period > db.duration and not db.isRemoved then
//Update timeout to cover last segment of buff duration
call TimerStart(db.tmr, db.duration-db.elapsed, false, function BuffTimeout)
//Since it won't clear a full period, we don't let it run onPeriodic
set db.isPeriodic = false
elseif TimerGetElapsed(db.tmr) < db.btype.period then
//Update period of timer to normal value
call TimerStart(db.tmr, db.btype.period, true, function BuffTimeout)
endif
elseif not db.isRemoved then
//Kill the buff completely, set it to expired naturally
//Shouldn't run if it was force removed by the on-death trigger
call db.runExpired()
endif
set t = null
endfunction
//******************************************************************************
function GetEventBuff takes nothing returns dbuff
return TempBuff
endfunction
//******************************************************************************
function UnitHasBuff takes unit target, integer whichType returns boolean
return HaveSavedInteger(ht, whichType, GetUnitId(target))
endfunction
function UnitHasAnyBuff takes unit target returns boolean
return bufflist(lists[GetUnitId(target)]).sta.size > 0
endfunction
function UnitRemoveBuff takes unit target, integer whichType returns boolean
local dbuff db = 0
if HaveSavedInteger(ht, whichType, GetUnitId(target)) then
set db = dbuff(LoadInteger(ht, whichType, GetUnitId(target)))
//Buff exists, clear it
call db.runRemoved()
return true
endif
return false
endfunction
private function RemoveAllBuffsEnum takes integer value returns nothing
call dbuff(value).runRemoved()
endfunction
function UnitRemoveAllBuffs takes unit target returns nothing
call bufflist(lists[GetUnitId(target)]).sta.enum(RemoveAllBuffsEnum, true)
endfunction
function GetUnitBuff takes unit target, integer whichType returns dbuff
return dbuff(LoadInteger(ht, whichType, GetUnitId(target)))
endfunction
function GetRandomBuff takes unit target returns dbuff
local bufflist bl = bufflist(lists[GetUnitId(target)])
if bl.sta.size > 0 then
return dbuff(bl.sta.random)
endif
return 0 //No buff to return
endfunction
function GetRandomBuffSigned takes unit target, boolean isPos returns dbuff
local bufflist bl = bufflist(lists[GetUnitId(target)])
local Stack s1 = 0
local Stack s2 = 0
local integer v = 0
//Only do this stuff if the unit has any buffs at all
if bl.sta.size > 0 then
//Build the needed stacks
set s1 = bl.sta.copy()
set s2 = Stack.create()
//Loop through and build a new stack of buffs of desired type
loop
exitwhen s1.size == 0
set v = s1.first
if dbuff(v).btype.isPositive == isPos then
//Found one, add to #2 stack
call s2.add(v)
endif
call s1.remove(v)
endloop
if s2.size > 0 then
//Get random member of generated stack
set v = s2.random
else
set v = 0
endif
//Destroy the generated stacks
call s1.destroy()
call s2.destroy()
//Return our buff or 0
if v > 0 then
return dbuff(v) //Return our buff
endif
endif
return 0 //No buff to return
endfunction
function GetLastAppliedBuff takes unit target returns dbuff
local bufflist bl = bufflist(lists[GetUnitId(target)])
if bl.sta.size > 0 then
return dbuff(bl.sta.first)
endif
return 0 //No buff to return
endfunction
function GetFirstAppliedBuff takes unit target returns dbuff
local bufflist bl = bufflist(lists[GetUnitId(target)])
local Stack s = 0
local integer v = 0
//Only do this stuff if the unit has any buffs at all
if bl.sta.size > 0 then
//Build the stack we need
set s = bl.sta.copy()
//Loop through until you find the bottom of the stack
loop
exitwhen s.size == 0
set v = s.first
call s.remove(v)
endloop
return dbuff(v)
endif
return 0 //No buff to return
endfunction
function UnitAddBuff takes unit source, unit target, integer btype, real dur, integer lvl returns dbuff
local timer t = null
local integer id = GetUnitId(target)
local bufftype bt = bufftype(btype)
local integer d = 0
local dbuff db = 0
//Standard debugging procedure
if source == null or target == null or btype < 0 or lvl < 0 or dur <= 0. then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Invalid buff creation parameters")
return 0
endif
//Find if this previous instance exists in the Table
if HaveSavedInteger(ht, btype, id) then
//Exists, use its data
set db = dbuff(LoadInteger(ht, btype, id))
if (lvl == db.level and db.timeRemaining() < dur) or lvl > db.level then
//Update all applicable values to the newly supplied ones if new instance overwrites
//Elapsed goes to 0 because it's as if a new buff has been cast, run timer again
set db.source = source
set db.target = target
set db.elapsed = 0.
set db.duration = dur
set db.level = lvl
if not db.isPeriodic and db.btype.isPeriodic then
//If it was on the last segment of a periodic timer, reset periodicity
set db.isPeriodic = true
endif
//Run the onAdd callback
set TempBuff = db
//It becomes a refreshed buff now
call db.runRefreshed()
if db.isPeriodic then
call TimerStart(db.tmr, db.btype.period-TimerGetElapsed(db.tmr), true , function BuffTimeout)
else
call TimerStart(db.tmr, dur , false, function BuffTimeout)
endif
endif
else
//Doesn't exist, create it
set db = dbuff.create(source, target, bt, dur, lvl)
//Run the onAdd callback
set TempBuff = db
call db.runAdd()
if db.isPeriodic then
call TimerStart(db.tmr, db.btype.period, true , function BuffTimeout)
else
call TimerStart(db.tmr, dur , false, function BuffTimeout)
endif
endif
return db
endfunction
function DefineBuffType takes integer AbilId, integer BuffId, real period, boolean isPeriodic, boolean isPositive, callback onAdd, callback onPeriodic, callback onEnd returns integer
local bufftype bt = bufftype.create(AbilId, BuffId, period, isPeriodic, isPositive, onAdd, onPeriodic, onEnd)
//Preload abilities to prevent first-buff lag
call AbilityPreload(AbilId)
set BuffTypeCount = BuffTypeCount + 1
set BuffTypes[BuffTypeCount] = bt
return integer(bt)
endfunction
//******************************************************************************
private function DeathActions takes nothing returns nothing
call UnitRemoveAllBuffs(GetDyingUnit())
endfunction
//******************************************************************************
private function UnitEntersMap takes unit u returns nothing
call bufflist.create(u)
endfunction
private function UnitLeavesMap takes unit u returns nothing
if lists[GetUnitId(u)] != 0 then
call bufflist(lists[GetUnitId(u)]).destroy()
endif
endfunction
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
//Trigger for removing buffs on death
call TriggerAddAction(trg, function DeathActions)
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_DEATH)
//Indexing callback to create bufflists for indexed units
call OnUnitIndexed(UnitEntersMap)
//Removal callback to remove bufflists for indexed units
call OnUnitDeindexed(UnitLeavesMap)
//Initialize the callback code var
set TimeOut = function BuffTimeout
endfunction
endlibrary
//TESH.scrollpos=240
//TESH.alwaysfold=0
library IntuitiveDamageSystem initializer Init requires Table, HeroSystem
//******************************************************************************
//* BY: Rising_Dusk
//* (Intuitive) Damage Detection System 1.13
//*
//* This library is the core for what has come to be known as the Intuitive
//* Damage Detection System, or IDDS for short. Simply by copying this library
//* into your map somewhere, you will have access to all of its features and
//* options. Below this documentation are some global variables that can be
//* edited to make the system more useful for your map, whatever it might be.
//* Please note that you should only change those globals listed under
//* configuration constants and damage type constants.
//*
//* An important note for the system is that all non-attack damage in your map
//* MUST BE TRIGGERED using the special function call included in this system,
//* UnitDamageTargetEx. This is how the system works to detect attacks, because
//* if the only non-triggered damage in your map originates from attacks, you
//* clearly know which damage packets are attacks. This allows users to use
//* orb abilities in their maps for whatever they want.
//*
//* function UnitDamageTargetEx takes unit source, unit target, real damage, ...
//* ...attacktype attackType, integer damageType, boolean ConsiderArmor returns boolean
//*
//* This is the function with which you will deal all triggered damage in your
//* map. The damageType argument is one of the predefined integer constants that
//* you can edit or add below. Default values for this with the system are
//* DAMAGE_TYPE_ATTACK, DAMAGE_TYPE_SPELL, and DAMAGE_TYPE_EXTRA. You can
//* trigger the system to treat triggered damage like it is an attack if you
//* want to by using DAMAGE_TYPE_ATTACK. It is very easy to make new damage
//* types in the system, just follow the instructions in the configuration
//* constants area. In addition, be sure that the constants you define do not
//* conflict with the predefined Blizzard constants. (ie. DAMAGE_TYPE_FIRE) If
//* these conflicts do exist, you will encounter multiply defined syntax errors.
//* The AttackType argument is the same as in the regular UnitDamageTarget
//* native. Also, the system allows you to consider armor when dealing damage or
//* not. Set the ConsiderArmor boolean argument to false if you want to ignore
//* armor for that damage, or true if you want to factor it in.
//*
//* function TriggerUnregisterDamageEvent takes trigger trg returns boolean
//* function TriggerRegisterDamageEvent takes trigger trg, integer priority returns boolean
//*
//* The TriggerRegisterDamageEvent function is used when initializing a damage
//* detection response trigger. By using this, it allows you to use a syntax
//* structure nigh-identical to the standard JASS2. It returns a boolean for
//* your convenience that is false if you pass it a null trigger. The system
//* also allows you to pass a positive, zero-inclusive integer to it as that
//* trigger's priority. The higher the number you pass, the later on in the
//* trigger executions it will fire. This is useful if you want shield
//* abilities, as you will want their priorities low so that they can block the
//* damage before it gets to other things. You are also allowed to unregister
//* a trigger from the system at any time if you want; this will likely never
//* have to be done for most maps.
//*
//* function SetDamage takes real dmg returns nothing
//* function SetDamageType takes integer dmgtype returns boolean
//*
//* With this function, you can modify the damage the system interprets for its
//* triggers. This function DOES NOT ACTUALLY CHANGE THE DAMAGE BEING DEALT, it
//* is merely a tool for users to use to change the internal variables. The user
//* will need to modify the damage himself by some other means. Similarly, the
//* SetDamageType function internally changes the damage type of a given packet
//* of damage. This can be useful if you want to convert DAMAGE_TYPE_ATTACK into
//* something else or if you want dynamic damagetypes in-game.
//*
//* function SetTriggerPriority takes trigger trg, integer priority returns boolean
//* function GetTriggerPriority takes trigger trg returns integer
//*
//* These functions let you set or get a given trigger's priority at will. These
//* functions both require that the trigger being passed to it is registered to
//* the IDDS system. If you pass an unregistered trigger to GetTriggerPriority,
//* it will return -1. If you pass a similar trigger to SetTriggerPriority, it
//* will return false.
//*
//* function IgnoreHigherPriority takes nothing returns boolean
//*
//* This function is one of the most important reasons for priorities to exist.
//* With it, you can tell the system to ignore higher priority triggers. This
//* is useful, for instance, if you have a triggered evasion ability and don't
//* want anything else to be done with that damage because it was dodged. Other,
//* similar damage-preventing routines will also find this function useful.
//*
//* function RegisterDamageType takes nothing returns integer
//*
//* This function is useful for declaring your own DAMAGE_TYPE_ETC constants
//* external to the system. By declaring your global variable and then calling
//* this on it as follows, you can register new damage types on the fly. This
//* is very useful if you want other systems or spells to introduce new damage
//* types that are either ignored or do special things for that application.
//*
//* function GetTriggerDamageType takes nothing returns integer
//* function GetTriggerDamageSource takes nothing returns unit
//* function GetTriggerDamageTarget takes nothing returns unit
//* function GetTriggerDamageBase takes nothing returns real
//* function GetTriggerDamage takes nothing returns real
//*
//* Like normal WC3 damage detection, the system has event responses for the
//* damage source, the target of the damage, the amount of damage dealt, and
//* other things. It also permits the detection of damage type, which is
//* something standard WC3 does not have. This lets you create on-attack spells
//* very easily whereas without the system it would be very difficult and
//* computationally costly. GetTriggerDamageBase returns the amount of damage
//* the unit was dealt at the beginning of a given trigger series, whereas
//* GetTriggerDamage returns whatever damage the unit has left to receive, if
//* it has been modified in any way with the SetDamage function mentioned
//* earlier.
//*
//* Once you understand all of the aforementioned aspects of the system, you're
//* ready to put it to use. I know it can be tricky to require all spells be
//* triggered, but this is the way of many great maps anyways, so such a
//* requirement is not so unreasonable. If you have any questions regarding the
//* system, please go to [url]www.wc3c.net[/url] and send a private message to the account
//* Rising_Dusk and I will respond as soon as I can. This system may only be
//* released at [url]www.wc3c.net[/url] and its existence on any other website is against
//* the author's will.
//*
//* Enjoy!
//*
globals
//* Configuration constants
private integer DamageTypeCount = 4
//* These are the damagetype constant globals for ease of use
constant integer DAMAGE_TYPE_ATTACK = 0
constant integer DAMAGE_TYPE_SPELL = 1
constant integer DAMAGE_TYPE_EXTRA = 2
constant integer DAMAGE_TYPE_IGNORED = 3
constant integer DAMAGE_TYPE_HEALING = 4
//* To add new constants, simply follow the naming convention and increment
//* the number accordingly. You shouldn't change or remove the first of the
//* damage types, since it is a special case, but you can change the others
//* however you'd like.
//* These are static constants used by the system and shouldn't be changed
private trigger RunTrigger = CreateTrigger()
private trigger AddTrigger = CreateTrigger()
private integer Count = 0
private Table TrigTable = 0
private Table RegiTable = 0
private boolean IgnPrior = false
private integer array NewDamageType
private real array NewDamage
private trigger array Trg
private integer array Priority
//* Temporary variables used by the system
private unit DamageSource = null
private unit DamageTarget = null
private integer DamageType = 0
private integer DamageId = 0
private real DamageBase = 0.
private real Damage = 0.
endglobals
//******************************************************************************
//******************************************************************************
//* Returns the integer index of a given handle object (Updated for 1.24)
private function H2I takes handle h returns integer
return GetHandleId(h)
endfunction
//* Use an insertion sort algorithm to sort the trigger stack based on priority
private function TriggerSort takes nothing returns boolean
local integer i = 1
local integer j = 0
local integer p = 0
local trigger t = null
loop
exitwhen i >= Count
set t = Trg[i]
set p = Priority[i]
set j = i-1
loop
exitwhen j < 0 or Priority[j] <= p
set Priority[j+1] = Priority[j]
set Trg[j+1] = Trg[j]
set TrigTable[H2I(Trg[j])] = j+1
set j = j - 1
endloop
set Priority[j+1] = p
set Trg[j+1] = t
set TrigTable[H2I(t)] = j+1
set i = i + 1
endloop
set t = null
return true
endfunction
//******************************************************************************
//******************************************************************************
//* The function to call when you want to end a damage's trigger series
function IgnoreHigherPriority takes nothing returns boolean
if DamageSource != null then
//Make sure it was called in the right place
set IgnPrior = true
endif
return IgnPrior
endfunction
//* Changes the base damage for a trigger series on the fly
function SetDamage takes real dmg returns boolean
if DamageSource != null and dmg >= 0 then
//Make sure it was called in the right place
set NewDamage[DamageId] = dmg
set Damage = dmg
return true
endif
return false
endfunction
//* Changes the base damage type of the series
function SetDamageType takes integer dmgtype returns boolean
if DamageSource != null and dmgtype >= 0 then
//Make sure it was called in the right place
set NewDamageType[DamageId] = dmgtype
set DamageType = dmgtype
return true
endif
return false
endfunction
//* Returns the given trigger's priority if it's loaded to the system
function GetTriggerPriority takes trigger trg returns integer
if RegiTable[H2I(trg)] == 0 then
return -1
endif
return Priority[TrigTable[H2I(trg)]]
endfunction
//* Sets the given trigger's priority if it's loaded to the system
function SetTriggerPriority takes trigger trg, integer priority returns boolean
if RegiTable[H2I(trg)] == 0 or priority < 0 then
return false
endif
set Priority[TrigTable[H2I(trg)]] = priority
return TriggerSort()
endfunction
//******************************************************************************
//******************************************************************************
//* The new damage function used by the system
function UnitDamageTargetEx takes unit source, unit target, real damage, attacktype attackType, integer damageType, boolean ConsiderArmor, boolean isCrit returns boolean
local boolean b = false
set DamageType = damageType
set DamageSource = source
if ConsiderArmor then
set b = UnitDamageTarget(source, target, damage, false, false, attackType, DAMAGE_TYPE_NORMAL, null)
else
set b = UnitDamageTarget(source, target, damage, false, false, attackType, DAMAGE_TYPE_UNIVERSAL, null)
endif
if not b then
set DamageType = 0
set DamageSource = null
endif
return b
endfunction
//* The method by which one registers a trigger with the system
function TriggerRegisterDamageEvent takes trigger trg, integer priority returns boolean
if trg == null or priority < 0 then
return false
endif
if RegiTable[H2I(trg)] == 0 then
set RegiTable[H2I(trg)] = 1
endif
set Trg[Count] = trg
set Priority[Count] = priority
set TrigTable[H2I(trg)] = Count
set Count = Count + 1
return TriggerSort()
endfunction
//* The method by which one unregisters a trigger from the system
function TriggerUnregisterDamageEvent takes trigger trg returns boolean
local integer i = 0
if trg == null then
return false
endif
set i = TrigTable[H2I(trg)]
if trg != Trg[i] then
return false
endif
set Trg[i] = Trg[Count]
set Priority[i] = Priority[Count]
set TrigTable[H2I(Trg[i])] = i
set RegiTable[H2I(trg)] = 0
set Count = Count - 1
return TriggerSort()
endfunction
//* Initialization shorthand to register a new damage type externally
function RegisterDamageType takes nothing returns integer
local integer i = DamageTypeCount
set DamageTypeCount = DamageTypeCount + 1
return i
endfunction
//******************************************************************************
//******************************************************************************
//* Wrappers for the system that can get inlined anyways
function GetTriggerDamageType takes nothing returns integer
return DamageType
endfunction
function GetTriggerDamageSource takes nothing returns unit
return DamageSource
endfunction
function GetTriggerDamageTarget takes nothing returns unit
return DamageTarget
endfunction
function GetTriggerDamageBase takes nothing returns real
return DamageBase
endfunction
function GetTriggerDamage takes nothing returns real
return Damage
endfunction
//******************************************************************************
//******************************************************************************
private function RunConditions takes nothing returns boolean
//* The conditions for what must be true for damage detection to run
return GetEventDamage() >= 0.0001 and DamageType != DAMAGE_TYPE_IGNORED
endfunction
private function AddConditions takes nothing returns boolean
//* The conditions for registering a unit with the damage system
return true
endfunction
private function PreloadConditions takes unit u returns boolean
//* The conditions for preloading a unit to the damage system
return true
endfunction
//******************************************************************************
//******************************************************************************
globals
private integer array IDStack
private integer IDC = 0
private integer IDN = 0
endglobals
private function Run takes nothing returns nothing
local unit u = GetEventDamageSource()
local unit s = DamageSource
local unit t = GetTriggerUnit()
local integer i = 0
local integer id = 0
local integer d = DamageType
local real r = GetEventDamage()
local real b = r
//Allocate an id for this damage packet
if IDN > 0 then
set id = IDStack[IDN]
set IDN = IDN - 1
else
set id = IDC
set IDC = IDC + 1
endif
if DamageSource == null then
//Damage is of type attack
set d = DAMAGE_TYPE_ATTACK
set s = u
endif
loop
exitwhen i > Count or IgnPrior
//Ensure all variables are correct for nesting
set Damage = r
set DamageBase = b
set DamageTarget = t
set DamageSource = s
set DamageType = d
set DamageId = id
set NewDamage[id] = 0.
set NewDamageType[id] = -1
if IsTriggerEnabled(Trg[i]) and TriggerEvaluate(Trg[i]) then
call TriggerExecute(Trg[i])
endif
if NewDamage[id] > 0. then
//Update damage if it was changed
set r = NewDamage[id]
endif
if NewDamageType[id] >= 0 then
//Update damagetype if it was changed
set d = NewDamageType[id]
endif
set i = i + 1
endloop
set Damage = 0.
set DamageBase = 0.
set DamageTarget = null
set DamageSource = null
set DamageType = 0
set DamageId = 0
set IgnPrior = false
set NewDamage[id] = 0.
//Return id to the stack
set IDN = IDN + 1
set IDStack[IDN] = id
set u = null
set s = null
set t = null
endfunction
private function Load takes nothing returns nothing
call TriggerRegisterUnitEvent(RunTrigger, GetEnteringUnit(), EVENT_UNIT_DAMAGED)
endfunction
//******************************************************************************
//******************************************************************************
private function PreloadUnits takes nothing returns boolean
if PreloadConditions(GetFilterUnit()) then
call TriggerRegisterUnitEvent(RunTrigger, GetFilterUnit(), EVENT_UNIT_DAMAGED)
endif
return false
endfunction
private function Init takes nothing returns nothing
local rect r = GetWorldBounds()
local region re = CreateRegion()
local boolexpr b = Condition(function PreloadUnits)
local group g = CreateGroup()
//* Create the tables for use with the system
set TrigTable = Table.create()
set RegiTable = Table.create()
call TriggerAddAction(RunTrigger, function Run)
call TriggerAddCondition(RunTrigger, Condition(function RunConditions))
call GroupEnumUnitsInRect(g, r, b)
call RegionAddRect(re, r)
call TriggerRegisterEnterRegion(AddTrigger, re, null)
call TriggerAddAction(AddTrigger, function Load)
call TriggerAddCondition(AddTrigger, Condition(function AddConditions))
call RemoveRect(r)
call DestroyGroup(g)
call DestroyBoolExpr(b)
set re = null
set g = null
set b = null
set r = null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Stack
//*****************************************************************
//* STACK
//*
//* written by: Anitarf
//*
//* This is an efficient implementation of a stack in vJass. Since
//* it is based on a linked list, I decided to add common list
//* methods to the data structure so it can function both as
//* a stack and a simple linked list.
//*
//* As a linked list, it has less functionality than Ammorth's
//* LinkedList, but is considerably faster. Note only that most of
//* the list methods have O(n) time complexity so they may not be
//* suitable for operations on very large lists, however due to
//* their simplicity the list would need to be really large for
//* this to become a problem.
//*
//* All stack methods are of course O(1) and as fast as possible.
//* If you just need a stack, this is definitely the best choice.
//*
//* set s=Stack.create() - Instanceates a new Stack object.
//* call s.destroy() - Destroys the Stack.
//*
//* Stack syntax:
//* call s.push(123) - Pushes the value 123 on the stack.
//* A stack may contain multiple
//* instances of the same value.
//* set i=s.peek() - Reads the top value of the stack
//* and stores it to the variable i.
//* set i=s.pop() - Removes the top value from the stack
//* and stores it to the variable i.
//* s.peek()==Stack.EMPTY - Checks if the stack is empty.
//*
//* List syntax:
//* call s.add(123) - Adds the value 123 to the list.
//* A list may contain multiple
//* instances of the same value.
//* s.size - The total number of values on the list.
//* s.contains(123) - Checks if the value 123 is on the list.
//* set n=s.count(123) - Stores the number of times the value
//* 123 is on the list to the variable n.
//* call s.remove(123) - Removes one instance of the value 123
//* from the list. Returns false if
//* the value was not found on the list.
//* call s.purge(123) - Removes all instances of the value 123
//* from the list. Returns the number of
//* values that were removed.
//* set i=s.first - Reads the first value from the list
//* and stores it to the variable i.
//* set i=s.random - Reads a random value from the list
//* and stores it to the variable i.
//* set s2=s.copy() - Makes a copy of the list and stores
//* it to the variable s2.
//* call s.enum(Func,b) - Calls function Func for all values
//* on the list. The function must follow
//* the Enum function interface.
//* b is a boolean value, if it is true
//* then the values will be enumerated
//* top to bottom, if false then bottom
//* to top.
//*****************************************************************
public function interface Enum takes integer value returns nothing
struct Stack
// Use a totally random number here, the more improbable someone uses it, the better.
// This is the value that is returned by .pop and .peek methods and .first and .random operators when called on an empty stack.
public static constant integer EMPTY=0x28829022
// End of calibration.
readonly integer size = 0
private integer top = 0
private static integer free = 1
private static integer array next
private static integer array value
method push takes integer i returns nothing
// Get an index from the list of free indexes.
local integer n=Stack.free
set Stack.free=Stack.next[n]
// Extend the list of free indexes if needed.
if Stack.free==0 then
set Stack.free=n+1
endif
// Store the value to the index.
set Stack.value[n]=i
// Add index to the top of the stack.
set Stack.next[n]=.top
set .top=n
set .size=.size+1
endmethod
method pop takes nothing returns integer
// Get the top index of stack.
local integer n=.top
// Safety check in case a user pops an empty stack.
if n==0 then
debug call BJDebugMsg("stack warning: .pop called on an empty stack!")
return Stack.EMPTY
endif
// Remove the top index from stack.
set .top=Stack.next[n]
set .size=.size-1
// Add the index to the list of free indexes.
set Stack.next[n]=Stack.free
set Stack.free=n
// Return the value.
return Stack.value[n]
endmethod
method peek takes nothing returns integer
// Read the value of the top index.
return Stack.value[.top]
endmethod
method add takes integer value returns nothing
call .push(value)
endmethod
method contains takes integer value returns boolean
// Get the first index of the list.
local integer i=.top
// Search through the list.
loop
// Stop the search when the end of the list is reached.
exitwhen i==0
// Stop the search if the value is found.
if Stack.value[i]==value then
return true
endif
// Get the next index of the list.
set i=Stack.next[i]
endloop
return false
endmethod
method count takes integer value returns integer
local integer count=0
// Get the first index of the list.
local integer i=.top
// Search through the list.
loop
// Stop the search when the end of the list is reached.
exitwhen i==0
// Increase the count if the value is found.
if Stack.value[i]==value then
set count=count+1
endif
// Get the next index of the list.
set i=Stack.next[i]
endloop
return count
endmethod
method operator first takes nothing returns integer
return .peek()
endmethod
method operator last takes nothing returns integer
local integer r=.size
// Get the first index of the list.
local integer i=.top
// Loop through the list.
loop
// Stop the loop after a random amount of repeats.
set r=r-1
exitwhen r==0 or i==0
// Get the next index of the list.
set i=Stack.next[i]
endloop
return Stack.value[i]
endmethod
method operator random takes nothing returns integer
local integer r=GetRandomInt(1,.size)
// Get the first index of the list.
local integer i=.top
// Loop through the list.
loop
// Stop the loop after a random amount of repeats.
set r=r-1
exitwhen r==0 or i==0
// Get the next index of the list.
set i=Stack.next[i]
endloop
return Stack.value[i]
endmethod
method remove takes integer value returns boolean
// Get the first index of the list.
local integer i1=.top
local integer i2
// Check if the first index holds the value.
if Stack.value[i1]==value then
call .pop()
return true
endif
// Search through the rest of the list.
loop
set i2=Stack.next[i1]
// Stop the search when the end of the list is reached.
exitwhen i2==0
// Check if the next index holds the value.
if Stack.value[i2]==value then
// Remove the index from the stack.
set Stack.next[i1]=Stack.next[i2]
// Add the removed index to the list of free indexes.
set Stack.next[i2]=Stack.free
set Stack.free=i2
set .size=.size-1
return true
endif
set i1=i2
endloop
return false
endmethod
method purge takes integer value returns integer
local integer count=0
local integer i1
local integer i2
// If the first index holds the value, pop it.
loop
// If the list is empty, return.
if .top==0 then
return count
endif
// Repeat until the first index doesn't hold the value.
exitwhen Stack.value[.top]!=value
call .pop()
set count=count+1
endloop
// Get the first index of the list.
set i1=.top
// Search through the rest of the list.
loop
set i2=Stack.next[i1]
// Stop the search when the end of the list is reached.
exitwhen i2==0
// Check if the next index holds the value.
if Stack.value[i2]==value then
// Remove the index from the stack.
set Stack.next[i1]=Stack.next[i2]
// Add the removed index to the list of free indexes.
set Stack.next[i2]=Stack.free
set Stack.free=i2
set .size=.size-1
set count=count+1
else
set i1=i2
endif
endloop
return count
endmethod
method enum takes Enum f, boolean top2bottom returns nothing
local integer array value
// Get the first index of the list.
local integer i1=.top
local integer i2=0
// Populate the array.
loop
exitwhen i1==0
set value[i2]=Stack.value[i1]
set i2=i2+1
set i1=Stack.next[i1]
endloop
// Call the Enum function for each value in the array.
set i1=i2-1
loop
exitwhen i2==0
set i2=i2-1
// Enumerate in which direction?
if top2bottom then
call f.evaluate(value[i1-i2])
else
call f.evaluate(value[i2])
endif
endloop
endmethod
method copy takes nothing returns Stack
local Stack that=Stack.create()
// Get the first index of the list.
local integer i1=.top
local integer i2
// Add a dummy index to the top of the new list.
call that.push(0)
set i2=that.top
loop
exitwhen i1==0
// Get an index from the list of free indexes and add it at the end of the list.
set Stack.next[i2]=Stack.free
set i2=Stack.next[i2]
set Stack.free=Stack.next[i2]
// Extend the list of free indexes if needed.
if Stack.free==0 then
set Stack.free=i2+1
endif
// Copy the value to the new index.
set Stack.value[i2]=Stack.value[i1]
set i1=Stack.next[i1]
endloop
// End the new list correctly.
set Stack.next[i2]=0
// Remove the dummy index.
call that.pop()
// Copy the size value to the new list.
set that.size=this.size
return that
endmethod
method onDestroy takes nothing returns nothing
local integer n
// Remove all remaining indexes from the stack.
loop
// Get the top index.
set n=.top
exitwhen n==0
// Remove it from the stack.
set .top=Stack.next[n]
// Add it to the list of free indexes.
set Stack.next[n]=Stack.free
set Stack.free=n
endloop
endmethod
static method onInit takes nothing returns nothing
// Store the EMPTY value to index 0 to make .peek inline friendly.
set Stack.value[0]=Stack.EMPTY
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library AutoIndex
//===========================================================================
// Information:
//==============
//
// AutoIndex is a very simple script to utilize. Just call GetUnitId(unit)
// to get get the unique value assigned to a particular unit. The GetUnitId
// function is extremely fast because it inlines directly to a GetUnitUserData
// call. AutoIndex automatically assigns an ID to each unit as it enters the
// map, and instantly frees that ID as the unit leaves the map. Detection of
// leaving units is accomplished in constant time without a periodic scan.
//
// AutoIndex uses UnitUserData by default. If something else in your map
// would conflict with that, you can set the UseUnitUserData configuration
// constant to false, and a hashtable will be used instead. Note that hash-
// tables are about 60% slower.
//
// If you turn on debug mode, AutoIndex will be able to display several
// helpful error messages. The following issues will be detected:
// -Passing a removed or decayed unit to GetUnitId
// -Code outside of AutoIndex has overwritten a unit's UserData value.
// -GetUnitId was used on a filtered unit (a unit you don't want indexed).
//
// AutoIndex provides events upon indexing or deindexing units. This
// effectively allows you to notice when units enter or leave the game. Also
// included are the AutoData, AutoCreate, and AutoDestroy modules, which allow
// you to fully utilize AutoIndex's enter/leave detection capabilities in
// conjunction with your structs.
//
//===========================================================================
// How to install AutoIndex:
//===========================
//
// 1.) Copy and paste this script into your map.
// 2.) Save it to allow the ObjectMerger macro to generate the "Leave Detect"
// ability for you. Close and re-open the map. After that, disable the macro
// to prevent the delay while saving.
//
//===========================================================================
// How to use AutoIndex:
//=======================
//
// So you can get a unique integer for each unit, but how do you use that to
// attach data to a unit? GetUnitId will always return a number in the range of
// 1-8190. This means it can be used as an array index, as demonstrated below:
/*
globals
integer array IntegerData
real array RealData
SomeStruct array SomeStructData
englobals
function Example takes nothing returns nothing
local unit u = CreateUnit(Player(0), 'hpea', 0., 0., 0.)
local integer id = GetUnitId(u)
//You now have a unique index for the unit, so you can
//attach or retrieve data about the unit using arrays.
set IntegerData[id] = 5
set RealData[id] = 25.0
set SomeStructData[id] = SomeStruct.create()
//If you have access to the same unit in another function, you can
//retrieve the data by using GetUnitId() and reading the arrays.
endfunction
*/
// The UnitFilter function in the configuration section is provided so that
// you can make AutoIndex completely ignore certain unit-types. Ignored units
// won't be indexed or fire indexed/deindexed events. You may want to filter out
// dummy casters or system-private units, especially ones that use UnitUserData
// internally. xe dummy units are automatically filtered.
//
//===========================================================================
// How to use OnUnitIndexed / OnUnitDeindexed:
//=============================================
//
// AutoIndex will fire the OnUnitIndexed event when a unit enters the map,
// and the OnUnitDeindexed event when a unit leaves the map. Functions used
// as events must take a unit and return nothing. An example is given below:
/*
function UnitEntersMap takes unit u returns nothing
call BJDebugMsg(GetUnitName(u)+" with ID "+I2S(GetUnitId(u))+" entered the map.")
endfunction //Using GetUnitId() during Indexed events works fine...
function UnitLeavesMap takes unit u returns nothing
call BJDebugMsg(GetUnitName(u)+" with ID "+I2S(GetUnitId(u))+" left the map.")
endfunction //So does using GetUnitId() during Deindexed events.
function Init takes nothing returns nothing
call OnUnitIndexed(UnitEntersMap)
call OnUnitDeindexed(UnitLeavesMap)
endfunction
*/
// If you call OnUnitIndexed during map initialization, every existing
// unit will be considered as entering the map. This saves you from the need
// to manually enumerate preplaced units (or units created by initialization
// code that ran before OnUnitIndexed was called).
//
// OnUnitDeindexed runs while a unit still exists, which means you can
// still do things such as destroy special effects attached to the unit.
// The unit will cease to exist immediately after the event is over.
//
//===========================================================================
// AutoIndex API:
//================
//
// GetUnitId(unit) -> integer
// This function returns a unique ID in the range of 1-8190 for the
// specified unit. Returns 0 if a null unit was passed. This function
// inlines directly to GetUnitUserData or LoadInteger if debug mode
// is disabled. If debug mode is enabled, this function will print
// an error message when passed a decayed or filtered unit.
//
// IsUnitIndexed(unit) -> boolean
// This function returns a boolean indicating whether the specified
// unit has been indexed. The only time this will return false is
// for units you have filtered using the UnitFilter function, or
// for xe dummy units. You can use this function to easily detect
// dummy units and avoid performing certain actions on them.
//
// OnUnitIndexed(IndexFunc)
// This function accepts an IndexFunc, which must take a unit and
// return nothing. The IndexFunc will be fired instantly whenever
// a unit enters the map. You may use GetUnitId on the unit. When
// you call this function during map initialization, every existing
// unit will be considered as entering the map.
//
// OnUnitDeindexed(IndexFunc)
// Same as above, but runs whenever a unit is leaving the map. When
// this event runs, the unit still exists, but it will cease to exist
// as soon as the event ends. You may use GetUnitId on the unit.
//
//===========================================================================
// How to use AutoData:
//======================
//
// The AutoData module allows you to associate one or more instances
// of the implementing struct with units, as well as iterate through all
// of the instances associated with each unit.
//
// This association is accomplished through the "me" instance member,
// which the module will place in the implementing struct. Whichever unit
// you assign to "me" becomes the owner of that instance. You may change
// ownership by reassigning "me" to another unit at any time, or you may
// make the instance unowned by assigning "me" to null.
//
// AutoData implements the static method operator [] in your struct
// to allow you to access instances from their owning units. For example,
// you may type: local StructName s = StructName[u]. If u has been set
// to own an instance of StructName, s will be set to that instance.
//
// So, what happens if you assign the same owning unit to multiple
// instances? You may use 2D array syntax to access instances assigned to
// the same unit: local StructName s = StructName[u][n], where u is the
// owning unit, and n is the index beginning with 0 for each unit. You
// can access the size of a unit's instance list (i.e. the number of
// instances belonging to the unit) by using the .size instance member.
/*
struct Example
implement AutoData
static method create takes unit u returns Example
local Example this = allocate()
set me = u //Assigning the "me" member from AutoData.
return this
endmethod
endstruct
function Test takes nothing returns nothing
local unit u = CreateUnit(Player(0), 'hpea', 0., 0., 0.)
local Example e1 = Example.create(u)
local Example e2 = Example.create(u)
local Example e3 = Example.create(u)
local Example e
call BJDebugMsg(I2S(Example[u].size)) //Prints 3 because u owns e1, e2, and e3.
set e = Example[u][GetRandomInt(0, Example[u].size - 1)] //Random instance belonging to u.
set e = Example[u] //This is the fastest way to iterate the instances belonging
loop //to a specific unit, starting with the first instance.
exitwhen e == 0 //e will be assigned to 0 when no instances remain.
call BJDebugMsg(I2S(e)) //Prints the values of e1, e2, e3.
set e = e[e.index + 1] //"e.index" refers to the e's position in u's instance list.
endloop //Thus, index + 1 is next, and index - 1 is previous.
endfunction //This trick allows you to avoid a local counter.
*/
// AutoData restrictions:
// -You may not implement AutoData in any struct which has already
// declared static or non-static method operator [].
// -AutoData will conflict with anything named "me", "size", or
// "index" in the implementing struct.
// -AutoData may not be implemented in structs that extend array.
// -You may not declare your own destroy method. (This restriction
// can be dropped as soon as JassHelper supports module onDestroy).
//
// AutoData information:
// -You do not need to null the "me" member when destroying an
// instance. That is done for you automatically during destroy().
// (But if you use deallocate(), you must null "me" manually.)
// -StructName[u] and StructName[u][0] refer to the same instance,
// which is the first instance that was associated with unit u.
// -StructName[u][StructName[u].size - 1] refers to the instance that
// was most recently associated with unit u.
// -Instances keep their relative order in the list when one is removed.
//
//===========================================================================
// How to use AutoCreate:
//=======================
//
// The AutoCreate module allows you to automatically create instances
// of the implementing struct for units as they enter the game. AutoCreate
// automatically implements AutoData into your struct. Any time an instance
// is automatically created for a unit, that instance's "me" member will be
// assigned to the entering unit.
//
// AutoCreate restrictions:
// -All of the same restrictions as AutoData.
// -If your struct's allocate() method takes parameters (i.e. the parent
// type's create method takes parameters), you must declare a create
// method and pass those extra parameters to allocate yourself.
//
// AutoCreate information:
// -You may optionally declare the createFilter method, which specifies
// which units should recieve an instance as they enter the game. If
// you do not declare it, all entering units will recieve an instance.
// -You may optionally declare the onCreate method, which will run when
// AutoCreate automatically creates an instance. (This is just a stand-
// in until JassHelper supports the onCreate method.)
// -You may declare your own create method, but it must take a single
// unit parameter (the entering unit) if you do so.
/*
struct Example
private static method createFilter takes unit u returns boolean
return GetUnitTypeId(u) == 'hfoo' //Created only for Footmen.
endmethod
private method onCreate takes nothing returns nothing
call BJDebugMsg(GetUnitName(me)+" entered the game!")
endmethod
implement AutoCreate
endstruct
*/
//===========================================================================
// How to use AutoDestroy:
//=========================
//
// The AutoDestroy module allows you to automatically destroy instances
// of the implementing struct when their "me" unit leaves the game. AutoDestroy
// automatically implements AutoData into your struct. You must assign a unit
// to the "me" member of an instance for this module to have any effect.
//
// AutoDestroy restrictions:
// -All of the same restrictions as AutoData.
//
// AutoDestroy information:
// -If you also implement AutoCreate in the same struct, remember that it
// assigns the "me" unit automatically. That means you can have fully
// automatic creation and destruction.
/*
struct Example
static method create takes unit u returns Example
local Example this = allocate()
set me = u //You should assign a unit to "me",
return this //otherwise AutoDestroy does nothing.
endmethod //Not necessary if using AutoCreate.
private method onDestroy takes nothing returns nothing
call BJDebugMsg(GetUnitName(me)+" left the game!")
endmethod
implement AutoDestroy
endstruct
*/
//===========================================================================
// Configuration:
//================
//! external ObjectMerger w3a Adef lvdt anam "Leave Detect" aart "" arac 0
//Save your map with this Object Merger call enabled, then close and reopen your
//map. Disable it by removing the exclamation to remove the delay while saving.
globals
private constant integer LeaveDetectAbilityID = 'lvdt'
//This rawcode must match the parameter after "Adef" in the
//ObjectMerger macro above. You may change both if you want.
private constant boolean UseUnitUserData = true
//If this is set to true, UnitUserData will be used. You should only set
//this to false if something else in your map already uses UnitUserData.
//A hashtable will be used instead, but it is about 60% slower.
private constant boolean SafeMode = true
//This is set to true by default so that GetUnitId() will ALWAYS work.
//If if this is set to false, GetUnitId() may fail to work in a very
//rare circumstance: creating a unit that has a default-on autocast
//ability, and using GetUnitId() on that unit as it enters the game,
//within a trigger that detects any order. Set this to false for a
//performance boost only if you think you can avoid this issue.
private constant boolean AutoDataFastMode = true
//If this is set to true, AutoData will utilize one hashtable per time
//it is implemented. If this is set to false, all AutoDatas will share
//a single hashtable, but iterating through the instances belonging to
//a unit will become about 12.5% slower. Your map will break if you
//use more than 255 hashtables simultaneously. Only set this to false
//if you suspect you will run out of hashtable instances.
endglobals
private function UnitFilter takes unit u returns boolean
return true
endfunction
//Make this function return false for any unit-types you want to ignore.
//Ignored units won't be indexed or fire OnUnitIndexed/OnUnitDeindexed
//events. The unit parameter "u" to refers to the unit being filtered.
//Do not filter out xe dummy units; they are automatically filtered.
//===========================================================================
// AutoData / AutoCreate / AutoDestroy modules:
//==============================================
function interface AutoCreator takes unit u returns nothing
function interface AutoDestroyer takes unit u returns nothing
globals
hashtable AutoData = null //If AutoDataFastMode is disabled, this hashtable will be
endglobals //initialized and shared between all AutoData implementations.
module AutoData
private static hashtable ht
private static thistype array data
private static integer array listsize
private static key typeid //Good thing keys exist to identify each implementing struct.
private unit meunit
private integer id
readonly integer index //The user can avoid using a local counter because this is accessable.
static method operator [] takes unit u returns thistype
return data[GetUnitId(u)]
endmethod //This is as fast as retrieving an instance from a unit gets.
method operator [] takes integer index returns thistype
static if AutoDataFastMode then //If fast mode is enabled...
return LoadInteger(ht, id, index)
else //Each instance has its own hashtable to associate unit and index.
return LoadInteger(AutoData, id, index*8190+typeid)
endif //Otherwise, simulate a 3D array associating unit, struct-type ID, and index.
endmethod //Somehow, this version is 12.5% slower just because of the math.
private method setIndex takes integer index, thistype data returns nothing
static if AutoDataFastMode then //Too bad you can't have a module-private operator []=.
call SaveInteger(ht, id, index, data)
else
call SaveInteger(AutoData, id, index*8190+typeid, data)
endif
endmethod
private method remove takes nothing returns nothing
if meunit == null then //If the struct doesn't have an owner...
return //Nothing needs to be done.
endif
loop
exitwhen index == listsize[id] //The last value gets overwritten by 0.
call setIndex(index, this[index + 1]) //Shift each element down by one.
set this[index].index = index //Update the shifted instance's index.
set index = index + 1
endloop
set listsize[id] = listsize[id] - 1
set data[id] = this[0] //Ensure thistype[u] returns the same value as thistype[u][0].
set meunit = null
endmethod
private method add takes unit u returns nothing
if meunit != null then //If the struct has an owner...
call remove() //remove it first.
endif
set meunit = u
set id = GetUnitId(u) //Cache GetUnitId for slight performance boost.
if data[id] == 0 then //If this is the first instance for this unit...
set data[id] = this //Update the value that thistype[u] returns.
endif
set index = listsize[id] //Remember the index for removal.
call setIndex(index, this) //Add to the array.
set listsize[id] = index + 1
endmethod
method operator me takes nothing returns unit
return meunit
endmethod
method operator me= takes unit u returns nothing
if u != null then //If assigning "me" a non-null value...
call add(u) //Add this instance to that unit's array.
else //If assigning "me" a null value...
call remove() //Remove this instance from that unit's array.
endif
endmethod
method operator size takes nothing returns integer
return listsize[id]
endmethod
method destroy takes nothing returns nothing
call deallocate()
call remove() //This makes removal automatic when an instance is destroyed.
endmethod
private static method onInit takes nothing returns nothing
static if AutoDataFastMode then //If fast mode is enabled...
set ht = InitHashtable() //Initialize one hashtable per instance.
else //If fast mode is disabled...
if AutoData == null then //If the hashtable hasn't been initialized yet...
set AutoData = InitHashtable() //Initialize the shared hashtable.
endif
endif
endmethod
endmodule
module AutoCreate
implement AutoData //AutoData is necessary for AutoCreate.
private static method creator takes unit u returns nothing
local thistype this
local boolean b = true //Assume that the instance will be created.
static if thistype.createFilter.exists then //If createFilter exists...
set b = createFilter(u) //evaluate it and update b.
endif
if b then //If the instance should be created...
static if thistype.create.exists then //If the create method exists...
set this = create(u) //Create the instance, passing the entering unit.
else //If the create method doesn't exist...
set this = allocate() //Just allocate the instance.
endif
set me = u //Assign the instance's owner as the entering unit.
static if thistype.onCreate.exists then //If onCreate exists...
call onCreate() //Call it, because JassHelper should do this anyway.
endif
endif
endmethod
private static method onInit takes nothing returns nothing
call AutoIndex.addAutoCreate(thistype.creator)
endmethod //During module initialization, pass the creator function to AutoIndex.
endmodule
module AutoDestroy
implement AutoData //AutoData is necessary for AutoDestroy.
static method destroyer takes unit u returns nothing
loop
exitwhen thistype[u] == 0
call thistype[u].destroy()
endloop
endmethod //Destroy each instance owned by the unit until none are left.
private static method onInit takes nothing returns nothing
call AutoIndex.addAutoDestroy(thistype.destroyer)
endmethod //During module initialization, pass the destroyer function to AutoIndex.
endmodule
//===========================================================================
// AutoIndex struct:
//===================
function interface IndexFunc takes unit u returns nothing
hook RemoveUnit AutoIndex.hook_RemoveUnit
hook ReplaceUnitBJ AutoIndex.hook_ReplaceUnitBJ
debug hook SetUnitUserData AutoIndex.hook_SetUnitUserData
private keyword getIndex
private keyword getIndexDebug
private keyword isUnitIndexed
private keyword onUnitIndexed
private keyword onUnitDeindexed
struct AutoIndex
private static trigger enter = CreateTrigger()
private static trigger order = CreateTrigger()
private static trigger creepdeath = CreateTrigger()
private static group preplaced = CreateGroup()
private static timer allowdecay = CreateTimer()
private static hashtable ht
private static boolean array dead
private static boolean array summoned
private static boolean array animated
private static boolean array nodecay
private static boolean array removing
private static IndexFunc array indexfuncs
private static integer indexfuncs_n = -1
private static IndexFunc array deindexfuncs
private static integer deindexfuncs_n = -1
private static IndexFunc indexfunc
private static AutoCreator array creators
private static integer creators_n = -1
private static AutoDestroyer array destroyers
private static integer destroyers_n = -1
private static unit array allowdecayunit
private static integer allowdecay_n = -1
private static boolean duringinit = true
private static boolean array altered
private static unit array idunit
//===========================================================================
static method getIndex takes unit u returns integer
static if UseUnitUserData then
return GetUnitUserData(u)
else
return LoadInteger(ht, 0, GetHandleId(u))
endif
endmethod //Resolves to an inlinable one-liner after the static if.
static method getIndexDebug takes unit u returns integer
if u == null then
return 0
elseif GetUnitTypeId(u) == 0 then
call BJDebugMsg("AutoIndex error: Removed or decayed unit passed to GetUnitId.")
elseif idunit[getIndex(u)] != u and GetIssuedOrderId() != 852056 then
call BJDebugMsg("AutoIndex error: "+GetUnitName(u)+" is a filtered unit.")
endif
return getIndex(u)
endmethod //If debug mode is enabled, use the getIndex method that shows errors.
private static method setIndex takes unit u, integer index returns nothing
static if UseUnitUserData then
call SetUnitUserData(u, index)
else
call SaveInteger(ht, 0, GetHandleId(u), index)
endif
endmethod //Resolves to an inlinable one-liner after the static if.
static method isUnitIndexed takes unit u returns boolean
return u != null and idunit[getIndex(u)] == u
endmethod
static method isUnitAnimateDead takes unit u returns boolean
return animated[getIndex(u)]
endmethod //Don't use this; use IsUnitAnimateDead from AutoEvents instead.
//===========================================================================
private static method onUnitIndexed_sub takes nothing returns nothing
call indexfunc.evaluate(GetEnumUnit())
endmethod
static method onUnitIndexed takes IndexFunc func returns nothing
set indexfuncs_n = indexfuncs_n + 1
set indexfuncs[indexfuncs_n] = func
if duringinit then //During initialization, evaluate the indexfunc for every preplaced unit.
set indexfunc = func
call ForGroup(preplaced, function AutoIndex.onUnitIndexed_sub)
endif
endmethod
static method onUnitDeindexed takes IndexFunc func returns nothing
set deindexfuncs_n = deindexfuncs_n + 1
set deindexfuncs[deindexfuncs_n] = func
endmethod
static method addAutoCreate takes AutoCreator func returns nothing
set creators_n = creators_n + 1
set creators[creators_n] = func
endmethod
static method addAutoDestroy takes AutoDestroyer func returns nothing
set destroyers_n = destroyers_n + 1
set destroyers[destroyers_n] = func
endmethod
//===========================================================================
private static method hook_RemoveUnit takes unit whichUnit returns nothing
set removing[getIndex(whichUnit)] = true
endmethod //Intercepts whenever RemoveUnit is called and sets a flag.
private static method hook_ReplaceUnitBJ takes unit whichUnit, integer newUnitId, integer unitStateMethod returns nothing
set removing[getIndex(whichUnit)] = true
endmethod //Intercepts whenever ReplaceUnitBJ is called and sets a flag.
private static method hook_SetUnitUserData takes unit whichUnit, integer data returns nothing
static if UseUnitUserData then
if idunit[getIndex(whichUnit)] == whichUnit then
if getIndex(whichUnit) == data then
call BJDebugMsg("AutoIndex error: Code outside AutoIndex attempted to alter "+GetUnitName(whichUnit)+"'s index.")
else
call BJDebugMsg("AutoIndex error: Code outside AutoIndex altered "+GetUnitName(whichUnit)+"'s index.")
if idunit[data] != null then
call BJDebugMsg("AutoIndex error: "+GetUnitName(whichUnit)+" and "+GetUnitName(idunit[data])+" now have the same index.")
endif
set altered[data] = true
endif
endif
endif //In debug mode, intercepts whenever SetUnitUserData is used on an indexed unit.
endmethod //Displays an error message if outside code tries to alter a unit's index.
//===========================================================================
private static method allowDecay takes nothing returns nothing
local integer n = allowdecay_n
loop
exitwhen n < 0
set nodecay[getIndex(allowdecayunit[n])] = false
set allowdecayunit[n] = null
set n = n - 1
endloop
set allowdecay_n = -1
endmethod //Iterate through all the units in the stack and allow them to decay again.
private static method detectStatus takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer index = getIndex(u)
local integer n
if idunit[index] == u then //Ignore non-indexed units.
if not IsUnitType(u, UNIT_TYPE_DEAD) then
if dead[index] then //The unit was dead, but now it's alive.
set dead[index] = false //The unit has been resurrected.
//! runtextmacro optional RunAutoEvent("Resurrect")
//If AutoEvents is in the map, run the resurrection events.
if IsUnitType(u, UNIT_TYPE_SUMMONED) and not summoned[index] then
set summoned[index] = true //If the unit gained the summoned flag,
set animated[index] = true //it's been raised with Animate Dead.
//! runtextmacro optional RunAutoEvent("AnimateDead")
//If AutoEvents is in the map, run the Animate Dead events.
endif
endif
else
if not removing[index] and not dead[index] and not animated[index] then
set dead[index] = true //The unit was alive, but now it's dead.
set nodecay[index] = true //A dead unit can't decay for at least 0. seconds.
set allowdecay_n = allowdecay_n + 1 //Add the unit to a stack. After the timer
set allowdecayunit[allowdecay_n] = u //expires, allow the unit to decay again.
call TimerStart(allowdecay, 0., false, function AutoIndex.allowDecay)
//! runtextmacro optional RunAutoEvent("Death")
//If AutoEvents is in the map, run the Death events.
elseif removing[index] or (dead[index] and not nodecay[index]) or (not dead[index] and animated[index]) then
//If .nodecay was false and the unit is dead and was previously dead, the unit decayed.
//If .animated was true and the unit is dead, the unit died and exploded.
//If .removing was true, the unit is being removed or replaced.
set n = deindexfuncs_n
loop //Run the OnUnitDeindexed events.
exitwhen n < 0
call deindexfuncs[n].evaluate(u)
set n = n - 1
endloop
set n = destroyers_n
loop //Destroy AutoDestroy structs for the leaving unit.
exitwhen n < 0
call destroyers[n].evaluate(u)
set n = n - 1
endloop
call AutoIndex(index).destroy() //Free the index by destroying the AutoIndex struct.
set idunit[index] = null //Null this unit reference to prevent a leak.
endif
endif
endif
set u = null
return false
endmethod
//===========================================================================
private static method unitEntersMap takes unit u returns nothing
local integer index
local integer n = 0
if getIndex(u) != 0 then
return //Don't index a unit that already has an ID.
endif
static if LIBRARY_xebasic then
if GetUnitTypeId(u) == XE_DUMMY_UNITID then
return //Don't index xe dummy units.
endif
endif
if not UnitFilter(u) then
return //Don't index units that fail the unit filter.
endif
set index = create()
call setIndex(u, index) //Assign an index to the entering unit.
call UnitAddAbility(u, LeaveDetectAbilityID) //Add the leave detect ability to the entering unit.
call UnitMakeAbilityPermanent(u, true, LeaveDetectAbilityID) //Prevent it from disappearing on morph.
set dead[index] = IsUnitType(u, UNIT_TYPE_DEAD) //Reset all of the flags for the entering unit.
set summoned[index] = IsUnitType(u, UNIT_TYPE_SUMMONED) //Each of these flags are necessary to detect
set animated[index] = false //when a unit leaves the map.
set nodecay[index] = false
set removing[index] = false
debug set altered[index] = false //In debug mode, this flag tracks wheter a unit's index was altered.
set idunit[index] = u //Attach the unit that is supposed to have this index to the index.
if duringinit then //If a unit enters the map during initialization...
call GroupAddUnit(preplaced, u) //Add the unit to the preplaced units group. This ensures that
endif //all units are noticed by OnUnitIndexed during initialization.
loop //Create AutoCreate structs for the entering unit.
exitwhen n > creators_n
call creators[n].evaluate(u)
set n = n + 1
endloop
set n = 0
loop //Run the OnUnitIndexed events.
exitwhen n > indexfuncs_n
call indexfuncs[n].evaluate(u)
set n = n + 1
endloop
endmethod
private static method onIssuedOrder takes nothing returns boolean
static if SafeMode then //If SafeMode is enabled, perform this extra check.
if getIndex(GetTriggerUnit()) == 0 then //If the unit doesn't already have
call unitEntersMap(GetTriggerUnit()) //an index, then assign it one.
endif
endif
return GetIssuedOrderId() == 852056 //If the order is Undefend, allow detectStatus to run.
endmethod
private static method initEnteringUnit takes nothing returns boolean
call unitEntersMap(GetFilterUnit())
return false
endmethod
//===========================================================================
private static method afterInit takes nothing returns nothing
set duringinit = false //Initialization is over; set a flag.
call DestroyTimer(GetExpiredTimer()) //Destroy the timer.
call GroupClear(preplaced) //The preplaced units group is
call DestroyGroup(preplaced) //no longer needed, so clean it.
set preplaced = null
endmethod
private static method onInit takes nothing returns nothing
local region maparea = CreateRegion()
local rect bounds = GetWorldBounds()
local group g = CreateGroup()
local integer i = 15
static if not UseUnitUserData then
set ht = InitHashtable() //Only create a hashtable if it will be used.
endif
loop
exitwhen i < 0
call SetPlayerAbilityAvailable(Player(i), LeaveDetectAbilityID, false)
//Make the LeaveDetect ability unavailable so that it doesn't show up on the command card of every unit.
call TriggerRegisterPlayerUnitEvent(order, Player(i), EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
//Register the "EVENT_PLAYER_UNIT_ISSUED_ORDER" event for each player.
call GroupEnumUnitsOfPlayer(g, Player(i), function AutoIndex.initEnteringUnit)
//Enum every non-filtered unit on the map during initialization and assign it a unique
//index. By using GroupEnumUnitsOfPlayer, even units with Locust can be detected.
set i = i - 1
endloop
call TriggerAddCondition(order, And(function AutoIndex.onIssuedOrder, function AutoIndex.detectStatus))
//The detectStatus method will fire every time a non-filtered unit recieves an undefend order.
//And() is used here to avoid using a trigger action, which starts a new thread and is slower.
call TriggerRegisterPlayerUnitEvent(creepdeath, Player(12), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerAddCondition(creepdeath, function AutoIndex.detectStatus)
//The detectStatus method must also fire when a neutral hostile creep dies, in case it was
//sleeping. Sleeping creeps don't fire undefend orders on non-damaging deaths.
call RegionAddRect(maparea, bounds) //GetWorldBounds() includes the shaded boundry areas.
call TriggerRegisterEnterRegion(enter, maparea, function AutoIndex.initEnteringUnit)
//The filter function of an EnterRegion trigger runs instantly when a unit is created.
call TimerStart(CreateTimer(), 0., false, function AutoIndex.afterInit)
//After any time elapses, perform after-initialization actions.
call GroupClear(g)
call DestroyGroup(g)
call RemoveRect(bounds)
set g = null
set bounds = null
endmethod
endstruct
//===========================================================================
// User functions:
//=================
function GetUnitId takes unit u returns integer
static if DEBUG_MODE then //If debug mode is enabled...
return AutoIndex.getIndexDebug(u) //call the debug version of GetUnitId.
else //If debug mode is disabled...
return AutoIndex.getIndex(u) //call the normal, inlinable version.
endif
endfunction
function IsUnitIndexed takes unit u returns boolean
return AutoIndex.isUnitIndexed(u)
endfunction
function OnUnitIndexed takes IndexFunc func returns nothing
call AutoIndex.onUnitIndexed(func)
endfunction
function OnUnitDeindexed takes IndexFunc func returns nothing
call AutoIndex.onUnitDeindexed(func)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library AbilityPreload initializer Init
// Information:
//==============
//
// Preloading removes the noticeable delay the first time an ability is
// loaded in a game. It is suggested that you preload every ability that
// is not already on a unit that is placed on the map or created at init.
//
// How to install PreloadAbility:
//================================
//
// Just copy the script into your map, no further tweaking needed.
//
// How to use PreloadAbility:
//============================
//
// Just call PreloadAbility(abilityid) during an init function. There is no
// point calling it after init, since it will do nothing, and it would not
// be "pre"-loading anyway.
//
//===========================================================================
globals
private boolean InitDone = false
private unit PreloadUnit
endglobals
function AbilityPreload takes integer abilityid returns nothing
if not InitDone then
call BJDebugMsg("AbilityPreload error: Library has not been initialized yet")
return
elseif GetUnitTypeId(PreloadUnit) == 0 then
call BJDebugMsg("AbilityPreload error: Can't preload an ability after initialization")
return
endif
call UnitAddAbility(PreloadUnit, abilityid)
endfunction
//===========================================================================
private function Init takes nothing returns nothing
set PreloadUnit = CreateUnit(Player(15), 'zsmc', 0., 0., 0.)
call UnitApplyTimedLife(PreloadUnit, 0, .001)
call ShowUnit(PreloadUnit, false)
call UnitAddAbility(PreloadUnit, 'Aloc')
set InitDone = true
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library UnitMaxState initializer Initialize requires optional AbilityPreload, optional xepreload
//==============================================================================
// UnitMaxState v2.1
//==============================================================================
// Credits:
//------------------------------------------------------------------------------
// Written By:
// Earth-Fury
//
// Original System By:
// Blade.dk
//
// Intermittent Version By:
// Deaod
//
// With Thanks To:
// - weaaddar for BonusMod and thus inspiration
// - PitzerMike for the ObjectMerger
// - Vexorian for vJass and Jass Helper
// - PipeDream for Grimoire
// - SFilip for TESH
// - MindWorX for maintaining NewGen
//------------------------------------------------------------------------------
// If you use this library in your map, please at least give credit to Blade.dk.
// Without him, this library would not exist.
//==============================================================================
// Introduction:
//------------------------------------------------------------------------------
// UnitMaxState is a library which allows you to modify a unit's maximum life,
// or maximum mana. To achieve this, the library abuses a bug with the AIlf and
// AImz abilities, which is too complex to explain here.
//
// I do believe it was indeed Blade.dk who initially found this bug. If not,
// it's still his system I stole and rewrote. Further, let me thank Deaod for
// writing up his version of this system, which inspired both the reality of
// this rewrite, and the method abilities are handled within it.
//
//==============================================================================
// Requirements:
//------------------------------------------------------------------------------
// UnitMaxState is written in vJass and requires the NewGen editor, or
// Jass Helper with PitzerMike's Object Merger configured for it.
//
// UnitMaxState requires the latest version of Jass Helper.
//
// Preloading of abilities requires either AbilityPreload or xepreload. Neither
// are required for the library to function; however, having one or the other
// will remove the slight delay the first time a unit's max state is changed.
//
//==============================================================================
// Using UnitMaxState:
//------------------------------------------------------------------------------
// UnitMaxState comes with two useful functions:
//
// nothing SetUnitMaxState(unit <target>, unitstate <state>, real <value>)
// Changes <target>'s unitstate <state> to be equal to <value>.
//
// nothing AddUnitMaxState(unit <target>, unitstate <state>, real <value>)
// Adds <value> to <target>'s <state> unitstate. Note that you can use
// negative values with this function.
//
// Both of these functions accept unitstate's other than UNIT_STATE_MAX_LIFE and
// UNIT_STATE_MAX_MANA. There is a small performance penalty in using these over
// direct usage of SetUnitState.
//
// You must not use life/mana boosting upgrades in combination with this system.
//
// Attempting to set a unit's maximum life below 1, or mana below 0 will do
// nothing. A debug message will be output if the script is compiled in
// debug mode.
//==============================================================================
//==============================================================================
// Configuration:
//------------------------------------------------------------------------------
// The below textmacro call is an all-in-one configuration line.
//------------------------------------------------------------------------------
// The first parameter is a boolean.
//
// If true, the abilities used by this system will be created on save. This adds
// a slight delay to saving your map. You only ever have to create the abilities
// the first time this library is added to your map, or if you modify any of
// the other configuration options.
//
// Note that to make the ability creation permanent, you must save with ability
// creation enabled, close your map, and reopen it in the editor. You can then
// disable ability creation, as the abilities will be permanently in your map.
//------------------------------------------------------------------------------
// The second parameter is an integer.
//
// This is the number of abilities this system will use for adding/removing
// life/mana. Note that this system uses four sets of abilities, so the actual
// number of abilities generated and used will be the value you pass here,
// multiplied by 4.
//
// The higher this number, the faster large bonuses will be added. This number
// should never have to go above 13. Between 3 and 5 will work fine for most
// maps.
//------------------------------------------------------------------------------
// The fourth and fifth parameters are 3 character prefixes for rawcodes.
//
// The first one is for the life-modifying abilities, while the second is for
// the mana-modifying abilities.
//
// Please, make sure your map has no abilities whose rawcodes begin with either
// of these prefixes before saving! Otherwise, those abilities will be
// overwritten. You can change these to any 3 character combination, if your
// map does already contain abilities whose rawcodes begin with these prefixes.
//------------------------------------------------------------------------------
//! runtextmacro UnitMaxState_Configuration("true", "3", "ZxL", "ZxM")
//------------------------------------------------------------------------------
// End of configuration
//------------------------------------------------------------------------------
//! textmacro UnitMaxState_Configuration takes LOAD_ABILITIES, ABILITY_COUNT, LIFE_PREFIX, MANA_PREFIX
//*
//! externalblock extension=lua ObjectMerger $FILENAME$
//! i function CreateAbilities(baseAbility, rawcodePrefix, field, name, icon)
//! i k = 0
//! i for sign = -1, 1, 2 do
//! i signStr = "+"
//! i if sign < 0 then
//! i signStr = "-"
//! i end
//! i j = 0
//! i for i = 0, (abilityCount - 1) * 3, 3 do
//! i j = j + 1
//! i createobject(baseAbility, rawcodePrefix .. string.sub(Chars, k + 1, k + 1))
//! i makechange(current, "anam", "UnitMaxState - " .. name)
//! i makechange(current, "ansf", "(" .. signStr .. tostring(j) .. ")")
//! i makechange(current, "aart", "ReplaceableTextures\\CommandButtons\\" .. icon)
//! i makechange(current, "aite", 0)
//! i makechange(current, "alev", 4)
//! i makechange(current, field, 1, 0)
//! i makechange(current, field, 2, 2^(i + 0) * sign)
//! i makechange(current, field, 3, 2^(i + 1) * sign)
//! i makechange(current, field, 4, 2^(i + 2) * sign)
//! i k = k + 1
//! i end
//! i end
//! i end
//! i if $LOAD_ABILITIES$ then
//! i setobjecttype("abilities")
//! i abilityCount = $ABILITY_COUNT$
//! i Chars = "abcdefghijklmnopqrstuvwxyz"
//! i CreateAbilities("AIlf", "$LIFE_PREFIX$", "Ilif", "Life", "BTNHealthStone.blp")
//! i CreateAbilities("AImz", "$MANA_PREFIX$", "Iman", "Mana", "BTNManaStone.blp")
//! i end
//! endexternalblock
// */
globals
private constant integer RAWCODE_LIFE = '$LIFE_PREFIX$a'
private constant integer RAWCODE_MANA = '$MANA_PREFIX$a'
public constant integer ABILITY_COUNT = $ABILITY_COUNT$
endglobals
//! endtextmacro
globals
private constant boolean PRELOAD_ABILITIES = true
private integer array POWERS_OF_2
endglobals
private function ErrorMsg takes string s returns nothing
debug call BJDebugMsg("SetUnitMaxState: " + s)
endfunction
function SetUnitMaxState takes unit target, unitstate state, real targetValue returns nothing
local integer difference
local integer rawcode
local integer abilityId
local integer abilityLevel
local integer currentAbility
if state == UNIT_STATE_MAX_LIFE then
set rawcode = RAWCODE_LIFE
if targetValue < 1 then
call ErrorMsg("You can not set a unit's max life to below 1")
return
endif
elseif state == UNIT_STATE_MAX_MANA then
set rawcode = RAWCODE_MANA
if targetValue < 0 then
call ErrorMsg("You can not set a unit's max mana to below 0")
return
endif
else
call SetUnitState(target, state, targetValue)
return
endif
set difference = R2I(targetValue) - R2I(GetUnitState(target, state))
if difference < 0 then
set difference = -difference
set rawcode = rawcode + ABILITY_COUNT
endif
set abilityId = ABILITY_COUNT - 1
set abilityLevel = 4
set currentAbility = rawcode + abilityId
loop
exitwhen difference == 0
if difference >= POWERS_OF_2[abilityId * 3 + (abilityLevel - 2)] then
call UnitAddAbility(target, currentAbility)
call SetUnitAbilityLevel(target, currentAbility, abilityLevel)
call UnitRemoveAbility(target, currentAbility)
set difference = difference - POWERS_OF_2[abilityId * 3 + (abilityLevel - 2)]
else
set abilityLevel = abilityLevel - 1
if abilityLevel <= 1 then
set abilityId = abilityId - 1
set abilityLevel = 4
set currentAbility = rawcode + abilityId
endif
endif
endloop
endfunction
function AddUnitMaxState takes unit target, unitstate state, real additionalValue returns nothing
call SetUnitMaxState(target, state, GetUnitState(target, state) + additionalValue)
endfunction
//! textmacro UnitMaxState_Preload takes RAWCODE
set i = 0
loop
exitwhen i == ABILITY_COUNT * 2 - 1
static if LIBRARY_AbilityPreload then
call AbilityPreload($RAWCODE$ + i)
elseif LIBRARY_xepreload then
call XE_PreloadAbility($RAWCODE$ + i)
endif
set i = i + 1
endloop
//! endtextmacro
private function Initialize takes nothing returns nothing
local integer i
local integer k
set i = 1
set POWERS_OF_2[0] = 1
loop
exitwhen i == ABILITY_COUNT * 2 * 2 * 3 + 1
set POWERS_OF_2[i] = POWERS_OF_2[i - 1] * 2
set i = i + 1
endloop
static if DEBUG_MODE and PRELOAD_ABILITIES and not LIBRARY_AbilityPreload and not LIBRARY_xepreload then
call ErrorMsg("Ability preloading was enabled, but neither of the supported preload libraries are present")
elseif PRELOAD_ABILITIES then
//! runtextmacro UnitMaxState_Preload("RAWCODE_LIFE")
//! runtextmacro UnitMaxState_Preload("RAWCODE_MANA")
endif
endfunction
endlibrary
//TESH.scrollpos=42
//TESH.alwaysfold=0
library IndieSummons initializer Init requires AutoIndex, TimerUtils, Table
//**************************************************************************************************
//*
//* Independant Summons (Code + config)
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* You just need to copy this trigger, notice that these functions do nothing without the other
//* part which has the header functions and you'll also need to call them.
//*
//**************************************************************************************************
// 2010-01-18 (Original system by Vexorian, modified by MoCo):
// - vjassification of system
// - now works with latest patches
//==================================================================================================
// Independant Summons Configuration:
//
globals
private Table SummonIdTab
private unit array Summons[1]
private unit array Masters[1]
private integer N = 0
private constant integer MAX_N = 64
endglobals
private constant function IndieSummon_maxdelay takes nothing returns real
return 2.5 //* The max delay betwen orders issued to the summon
endfunction
private constant function IndieSummon_mindelay takes nothing returns real
return 1.00 //* The min delay betwen orders issued to the summon
endfunction
private constant function IndieSummon_maxdistance takes nothing returns real
return 800.0 //* If the distance betwen the summon and the master is greater than this value,
// The summon will move to the position of the master instead of attack move
endfunction
private constant function IndieSummon_cometomaxdist takes nothing returns real
return 500.0 //* Max distance for issued orders to approach the master
endfunction
private constant function IndieSummon_cometomindist takes nothing returns real
return 100.0 //* Min distance for issued orders to approach the master
endfunction
//==================================================================================================
private function SetSummonId takes unit summon returns integer
set N = N + 1
set SummonIdTab[GetUnitId(summon)] = N
if N > MAX_N then
set N = 0
endif
return SummonIdTab[GetUnitId(summon)]
endfunction
private function GetSummonId takes unit summon returns integer
return SummonIdTab[GetUnitId(summon)]
endfunction
private function IndieSummon_GetMaster takes unit summon returns unit
local integer id = GetSummonId(summon)
return Masters[id]
return null
endfunction
private function IndieSummon_StopAI takes unit summon returns nothing
local integer id = GetSummonId(summon)
set Masters[id] = null
endfunction
private function IndieSummon_Order takes unit summon, unit master returns nothing
local integer o=GetUnitCurrentOrder(summon)
local real tx=GetUnitX(master)
local real ty=GetUnitY(master)
local real angle
local real dist
set dist=Pow(tx-GetUnitX(summon),2) + Pow(ty-GetUnitY(summon),2)
if (dist > (IndieSummon_maxdistance()*IndieSummon_maxdistance()) ) and (o == 0 or o == OrderId("attack") or o == OrderId("move") or o == OrderId("stop") or o==851971) then
call IssuePointOrder(summon, "move", tx,ty)
elseif dist >= (IndieSummon_cometomindist()*IndieSummon_cometomindist()) and (o == 0 or o == 851971) then
set angle = GetRandomReal( GetUnitFacing(master)-80, GetUnitFacing(master)+80)
if (ModuloInteger(GetUnitPointValue(summon),2)==0) then
set angle=angle * bj_DEGTORAD
else
set angle=- angle * bj_DEGTORAD
endif
set dist = GetRandomReal(IndieSummon_cometomindist(), IndieSummon_cometomaxdist() )
set tx=tx+dist*Cos(angle)
set ty=ty+dist*Sin(angle)
if not IssuePointOrder(summon, "attack", tx, ty ) then
call IssuePointOrder(summon, "move", tx, ty )
endif
endif
set summon=null
set master=null
endfunction
private function IndieSummon_AntiSmart_Timer takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
local unit s = Summons[id]
local unit m = Masters[id]
if (GetUnitCurrentOrder(s)!=851971) then
call DestroyTimer(t)
else
call IndieSummon_Order( s, m )
call TimerStart(t,0.1,false,function IndieSummon_AntiSmart_Timer)
endif
set t = null
set s = null
set m = null
endfunction
private function IndieSummon_AntiSmart takes nothing returns nothing
local timer t
local integer id = GetSummonId(GetTriggerUnit())
if (GetIssuedOrderId() == 851971) then
set t=CreateTimer()
call SetTimerData(t, id)
call TimerStart(t,0,false,function IndieSummon_AntiSmart_Timer)
set t=null
endif
endfunction
private function IndieSummon_loop takes integer id returns nothing
local unit summon = Summons[id]
local unit master // = Masters[id]
local trigger smart=CreateTrigger()
local integer n = 0
local triggeraction ac = TriggerAddAction( smart, function IndieSummon_AntiSmart)
call TriggerRegisterUnitEvent( smart, summon, EVENT_UNIT_ISSUED_TARGET_ORDER )
call TriggerRegisterUnitEvent( smart, summon, EVENT_UNIT_ISSUED_POINT_ORDER )
loop
exitwhen (GetWidgetLife(summon)<=0)
set master = Masters[id]
if (master==null) then
exitwhen true
else
call IndieSummon_Order( summon, master)
call PolledWait( GetRandomReal( IndieSummon_mindelay(), IndieSummon_maxdelay() ))
endif
endloop
set Masters[id] = null
call TriggerRemoveAction(smart,ac)
if smart != null then
call DestroyTrigger(smart)
endif
set ac=null
set summon=null
set master=null
set smart=null
endfunction
function IndieSummon_SetMaster takes unit summon, unit master returns nothing
local integer id
set id = SetSummonId(summon)
set Masters[id] = master
set Summons[id] = summon
call IndieSummon_loop.execute(id)
endfunction
//===========================================================================
private function Init takes nothing returns nothing
set SummonIdTab = Table.create()
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
//******************************************************************************
//* *
//* K N O C K B A C K *
//* Actual Code *
//* v1.07 *
//* *
//* By: Rising_Dusk *
//* *
//******************************************************************************
library KnockbackRisingDusk initializer Init needs TerrainPathability, GroupUtils, AutoIndex, LastOrder
globals
//*********************************************************
//* These are the configuration constants for the system
//*
//* EFFECT_ATTACH_POINT: Where on the unit the effect attaches
//* EFFECT_PATH_WATER: What special effect to attach over water
//* EFFECT_PATH_GROUND: What special effect to attach over ground
//* DEST_RADIUS: Radius around which destructs die
//* DEST_RADIUS_SQUARED: Radius squared around which destructs die
//* ADJACENT_RADIUS: Radius for knocking back adjacent units
//* ADJACENT_FACTOR: Factor for collision speed transfers
//* TIMER_INTERVAL: The interval for the timer that gets run
//* ISSUE_LAST_ORDER: A boolean to issue last orders or not
//*
private constant string EFFECT_ATTACH_POINT = "origin"
private constant string EFFECT_PATH_WATER = "MDX\\KnockbackWater.mdx"
private constant string EFFECT_PATH_GROUND = "MDX\\KnockbackDust.mdx"
private constant real DEST_RADIUS = 180.
private constant real DEST_RADIUS_SQUARED = DEST_RADIUS*DEST_RADIUS
private constant real ADJACENT_RADIUS = 180.
private constant real ADJACENT_FACTOR = 0.75
private constant real TIMER_INTERVAL = 0.05
private constant boolean ISSUE_LAST_ORDER = true
//*********************************************************
//* These are static constants used by the system and shouldn't be changed
//*
//* Timer: The timer that runs all of the effects for the spell
//* Counter: The counter for how many KB instances exist
//* HitIndex: Indexes for a given unit's knockback
//* Knockers: The array of all struct instances that exist
//* Entries: Counters for specific unit instances in system
//* ToClear: How many instances to remove on next run
//* DesBoolexpr: The check used for finding destructables
//* AdjBoolexpr: The check for picking adjacent units to knockback
//* DestRect: The rect used to check for destructables
//*
private timer Timer = CreateTimer()
private integer Counter = 0
private integer array HitIndex
private integer array Knockers
private integer array Entries
private integer array ToClear
private boolexpr DesBoolexpr = null
private boolexpr AdjBoolexpr = null
private rect DestRect = Rect(0,0,1,1)
//* Temporary variables used by the system
private real TempX = 0.
private real TempY = 0.
private unit TempUnit1 = null
private unit TempUnit2 = null
endglobals
//* Boolean for whether or not to display effects on a unit
private function ShowEffects takes unit u returns boolean
return not IsUnitType(u, UNIT_TYPE_FLYING)
endfunction
//* Functions for the destructable destruction
private function KillDests_Check takes nothing returns boolean
local real x = GetDestructableX(GetFilterDestructable())
local real y = GetDestructableY(GetFilterDestructable())
return (TempX-x)*(TempX-x) + (TempY-y)*(TempY-y) <= DEST_RADIUS_SQUARED
endfunction
private function KillDests takes nothing returns nothing
call KillDestructable(GetEnumDestructable())
endfunction
//* Functions for knocking back adjacent units
private function KnockAdj_Check takes nothing returns boolean
return TempUnit2 != GetFilterUnit() and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(TempUnit1)) and IsUnitType(GetFilterUnit(), UNIT_TYPE_GROUND) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) and GetWidgetLife(GetFilterUnit()) > 0.405 and GetUnitAbilityLevel(GetFilterUnit(), 'Avul') <= 0
endfunction
//******************************************************************************
//* Some additional functions that can be used
function KnockbackStop takes unit targ returns boolean
local integer id = GetUnitId(targ)
set ToClear[id] = Entries[id]
return ToClear[id] > 0
endfunction
function IsKnockedBack takes unit targ returns boolean
return Entries[GetUnitId(targ)] > 0
endfunction
//* Struct for the system, I recommend leaving it alone
private struct knocker
unit Source = null
unit Target = null
group HitGroup = null
effect KBEffect = null
integer FXMode = 0
boolean KillDest = false
boolean KnockAdj = false
boolean ChainAdj = false
boolean ShowEff = false
real Decrement = 0.
real Displace = 0.
real CosA = 0.
real SinA = 0.
public method checkterrain takes knocker n returns integer
local integer i = 0
local real x = GetUnitX(n.Target)
local real y = GetUnitY(n.Target)
if IsTerrainWalkable(x, y) then
set i = 1
elseif IsTerrainShallowWater(x, y) then
set i = 2
endif
return i
endmethod
static method create takes unit source, unit targ, real angle, real disp, real dec, boolean killDestructables, boolean knockAdjacent, boolean chainAdjacent returns knocker
local knocker n = knocker.allocate()
set n.Target = targ
set n.Source = source
set n.FXMode = n.checkterrain(n)
set n.HitGroup = NewGroup()
set n.KillDest = killDestructables
set n.KnockAdj = knockAdjacent
set n.ChainAdj = chainAdjacent
set n.ShowEff = ShowEffects(targ)
set n.Decrement = dec
set n.Displace = disp
set n.CosA = Cos(angle)
set n.SinA = Sin(angle)
if n.ShowEff then
if n.FXMode == 1 then
set n.KBEffect = AddSpecialEffectTarget(EFFECT_PATH_GROUND, n.Target, EFFECT_ATTACH_POINT)
elseif n.FXMode == 2 then
set n.KBEffect = AddSpecialEffectTarget(EFFECT_PATH_WATER, n.Target, EFFECT_ATTACH_POINT)
debug else
debug call BJDebugMsg(SCOPE_PREFIX+" Error (On Create): Unknown Terrain Type")
endif
endif
return n
endmethod
private method onDestroy takes nothing returns nothing
local integer id = GetUnitId(this.Target)
set Entries[id] = Entries[id] - 1
if GetWidgetLife(this.Target) > 0.405 and Entries[id] <= 0 and ISSUE_LAST_ORDER then
//* Issue last order if activated
call IssueLastOrder(this.Target)
endif
if this.ShowEff then
//* Destroy effect if it exists
call DestroyEffect(this.KBEffect)
endif
call ReleaseGroup(this.HitGroup)
endmethod
endstruct
private function Update takes nothing returns nothing
local unit u = null
local unit s = null
local rect r = null
local knocker n = 0
local knocker m = 0
local integer i = Counter - 1
local integer j = 0
local integer mode = 0
local integer id = 0
local real xi = 0.
local real yi = 0.
local real xf = 0.
local real yf = 0.
loop
exitwhen i < 0
set n = Knockers[i]
set u = n.Target
set mode = n.FXMode
set id = GetUnitId(u)
set xi = GetUnitX(u)
set yi = GetUnitY(u)
if n.Displace <= 0 or ToClear[id] > 0 then
//* Clean up the knockback when it is over
if ToClear[id] > 0 then
set ToClear[id] = ToClear[id] - 1
endif
call n.destroy()
set Counter = Counter - 1
if Counter < 0 then
call PauseTimer(Timer)
set Counter = 0
else
set Knockers[i] = Knockers[Counter]
endif
else
//* Propagate the knockback in space and time
set xf = xi + n.Displace*n.CosA
set yf = yi + n.Displace*n.SinA
call SetUnitPosition(u, xf, yf)
set n.FXMode = n.checkterrain(n)
//* Modify the special effect if necessary
if n.ShowEff then
if n.FXMode == 1 and mode == 2 then
call DestroyEffect(n.KBEffect)
set n.KBEffect = AddSpecialEffectTarget(EFFECT_PATH_GROUND, n.Target, EFFECT_ATTACH_POINT)
elseif n.FXMode == 2 and mode == 1 then
call DestroyEffect(n.KBEffect)
set n.KBEffect = AddSpecialEffectTarget(EFFECT_PATH_WATER, n.Target, EFFECT_ATTACH_POINT)
debug elseif n.FXMode == 0 then
debug call BJDebugMsg(SCOPE_PREFIX+" Error (In Update): Unknown Terrain Type")
endif
endif
//* Decrement displacement left to go
set n.Displace = n.Displace - n.Decrement
//* Destroy destructables if desired
if n.KillDest then
set TempX = GetUnitX(u)
set TempY = GetUnitY(u)
call MoveRectTo(DestRect, TempX, TempY)
call EnumDestructablesInRect(DestRect, DesBoolexpr, function KillDests)
endif
//* Knockback nearby units if desired
if n.KnockAdj then
set xi = GetUnitX(u)
set yi = GetUnitY(u)
set TempUnit1 = n.Source
set TempUnit2 = u
call GroupEnumUnitsInRange(ENUM_GROUP, xi, yi, ADJACENT_RADIUS, AdjBoolexpr)
loop
set s = FirstOfGroup(ENUM_GROUP)
exitwhen s == null
if not IsUnitInGroup(s, n.HitGroup) then
set xf = GetUnitX(s)
set yf = GetUnitY(s)
call GroupAddUnit(n.HitGroup, s)
set m = knocker.create(n.Source, s, Atan2(yf-yi, xf-xi), n.Displace*ADJACENT_FACTOR, n.Decrement, n.KillDest, n.ChainAdj, n.ChainAdj)
call GroupAddUnit(m.HitGroup, u)
set Knockers[Counter] = m
set Counter = Counter + 1
endif
call GroupRemoveUnit(ENUM_GROUP, s)
endloop
endif
endif
set i = i - 1
endloop
set u = null
set s = null
endfunction
//******************************************************************************
//* How to knockback a unit
function KnockbackTarget takes unit source, unit targ, real angle, real startspeed, real decrement, boolean killDestructables, boolean knockAdjacent, boolean chainAdjacent returns boolean
local knocker n = 0
local integer id = GetUnitId(targ)
local boolean b = true
//* Protect users from themselves
if decrement <= 0. or startspeed <= 0. or targ == null then
debug call BJDebugMsg(SCOPE_PREFIX+" Error (On Call): Invalid Starting Conditions")
set b = false
else
//* Can't chain if you don't knockback adjacent units
if not knockAdjacent and chainAdjacent then
set chainAdjacent = false
endif
set n = knocker.create(source, targ, angle*bj_DEGTORAD, startspeed*TIMER_INTERVAL, decrement*TIMER_INTERVAL*TIMER_INTERVAL, killDestructables, knockAdjacent, chainAdjacent)
if Counter == 0 then
call TimerStart(Timer, TIMER_INTERVAL, true, function Update)
endif
set Entries[id] = Entries[id] + 1
set HitIndex[id] = Counter + 1
set Knockers[Counter] = n
set Counter = Counter + 1
endif
return b
endfunction
private function Init takes nothing returns nothing
call SetRect(DestRect, -DEST_RADIUS, -DEST_RADIUS, DEST_RADIUS, DEST_RADIUS)
set DesBoolexpr = Condition(function KillDests_Check)
set AdjBoolexpr = Condition(function KnockAdj_Check)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library TerrainPathability initializer Init
//******************************************************************************
//* BY: Rising_Dusk
//*
//* This script can be used to detect the type of pathing at a specific point.
//* It is valuable to do it this way because the IsTerrainPathable is very
//* counterintuitive and returns in odd ways and aren't always as you would
//* expect. This library, however, facilitates detecting those things reliably
//* and easily.
//*
//******************************************************************************
//*
//* > function IsTerrainDeepWater takes real x, real y returns boolean
//* > function IsTerrainShallowWater takes real x, real y returns boolean
//* > function IsTerrainLand takes real x, real y returns boolean
//* > function IsTerrainPlatform takes real x, real y returns boolean
//* > function IsTerrainWalkable takes real x, real y returns boolean
//*
//* These functions return true if the given point is of the type specified
//* in the function's name and false if it is not. For the IsTerrainWalkable
//* function, the MAX_RANGE constant below is the maximum deviation range from
//* the supplied coordinates that will still return true.
//*
//* The IsTerrainPlatform works for any preplaced walkable destructable. It will
//* return true over bridges, destructable ramps, elevators, and invisible
//* platforms. Walkable destructables created at runtime do not create the same
//* pathing hole as preplaced ones do, so this will return false for them. All
//* other functions except IsTerrainWalkable return false for platforms, because
//* the platform itself erases their pathing when the map is saved.
//*
//* After calling IsTerrainWalkable(x, y), the following two global variables
//* gain meaning. They return the X and Y coordinates of the nearest walkable
//* point to the specified coordinates. These will only deviate from the
//* IsTerrainWalkable function arguments if the function returned false.
//*
//* Variables that can be used from the library:
//* [real] TerrainPathability_X
//* [real] TerrainPathability_Y
//*
globals
private constant real MAX_RANGE = 10.
private constant integer DUMMY_ITEM_ID = 'wolg'
endglobals
globals
private item Item = null
private rect Find = null
private item array Hid
private integer HidMax = 0
public real X = 0.
public real Y = 0.
endglobals
function IsTerrainDeepWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
function IsTerrainShallowWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
function IsTerrainLand takes real x, real y returns boolean
return IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY)
endfunction
function IsTerrainPlatform takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
private function HideItem takes nothing returns nothing
if IsItemVisible(GetEnumItem()) then
set Hid[HidMax] = GetEnumItem()
call SetItemVisible(Hid[HidMax], false)
set HidMax = HidMax + 1
endif
endfunction
function IsTerrainWalkable takes real x, real y returns boolean
//Hide any items in the area to avoid conflicts with our item
call MoveRectTo(Find, x, y)
call EnumItemsInRect(Find ,null, function HideItem)
//Try to move the test item and get its coords
call SetItemPosition(Item, x, y) //Unhides the item
set X = GetItemX(Item)
set Y = GetItemY(Item)
static if LIBRARY_IsTerrainWalkable then
//This is for compatibility with the IsTerrainWalkable library
set IsTerrainWalkable_X = X
set IsTerrainWalkable_Y = Y
endif
call SetItemVisible(Item, false)//Hide it again
//Unhide any items hidden at the start
loop
exitwhen HidMax <= 0
set HidMax = HidMax - 1
call SetItemVisible(Hid[HidMax], true)
set Hid[HidMax] = null
endloop
//Return walkability
return (X-x)*(X-x)+(Y-y)*(Y-y) <= MAX_RANGE*MAX_RANGE and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
private function Init takes nothing returns nothing
set Find = Rect(0., 0., 128., 128.)
set Item = CreateItem(DUMMY_ITEM_ID, 0, 0)
call SetItemVisible(Item, false)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library LastOrder initializer Init
//******************************************************************************
//* BY: Rising_Dusk
//*
//* LastOrder is a library that was designed to allow interfacing with the last
//* N orders any unit on your map has received. This library was also designed
//* to be used as a means to reissue lost orders to a unit either after
//* preventing a spell cast or in many other situations.
//*
//* There are two configuration constants for you to play with in using this
//* script. ORDERS_TO_HOLD is basically the size of the game's memory for each
//* individual unit. The larger the number is, the further back you can retrace
//* a unit's order list. Setting this value to 3 suffices for all actual
//* mechanics purposes. Raise it only if you have a specific application where
//* you need more. Lowering it to 2 covers most cases, but may miss a few, and
//* lowering it to 1 prevents you from adequately canceling spells and properly
//* reissuing previous orders. I recommend leaving it alone at 3. The MAX_ORDERS
//* constant is the number of orders that the system holds over all units at a
//* given time. If you are worried about running out, go ahead and increase it,
//* but be aware that it will use big arrays (which are slower) if you use a
//* number over 8191. Don't lower it under 8191, there's no reason to. Don't
//* change the non-private constants, there's no reason to.
//*
//* function GetPastOrder takes unit u, integer whichOrder returns order
//* function GetPastOrderId takes unit u, integer whichOrder returns integer
//* function GetPastOrderString takes unit u, integer whichOrder returns string
//* function GetPastOrderType takes unit u, integer whichOrder returns integer
//* function GetPastOrderX takes unit u, integer whichOrder returns real
//* function GetPastOrderY takes unit u, integer whichOrder returns real
//* function GetPastOrderTarget takes unit u, integer whichOrder returns widget
//*
//* The above API is the main list of functions the user can use to interface
//* with past orders. If you want the immediate last order for a player, use 1
//* for the whichOrder integer. The 'order' returned by GetPastOrder is a struct
//* that contains all information of an issued order. If you want to interface
//* directly with the struct and skip all of the interfacing wrappers, you have
//* access to them via the following commands:
//*
//* [unit] .u The unit being ordered.
//* [integer] .id The order id of the past order.
//* [integer] .typ The type of the past order. (See constants)
//* [boolean] .fin A flag indicating whether the order was finished.
//* [widget] .tar The target widget of the past order.
//* [real] .x The x coordinate of the target point of the order.
//* [real] .y The y coordinate of the target point of the order.
//*
//* There is also a sizable API for backwards compatibility with older versions
//* of the library. This API assumes that you're talking about a specific past
//* order, either the lastmost order or the second lastmost. In most cases,
//* these are still useful because they remove an argument from the call.
//*
//* function GetLastOrder takes unit u returns order
//* function GetLastOrderId takes unit u returns integer
//* function GetLastOrderString takes unit u returns string
//* function GetLastOrderType takes unit u returns integer
//* function GetLastOrderX takes unit u returns real
//* function GetLastOrderY takes unit u returns real
//* function GetLastOrderTarget takes unit u returns widget
//* function IsLastOrderFinished takes unit u returns boolean
//*
//* Besides being able to get information about all of the past orders a unit
//* has been issued, the most useful part of this system is actually reissuing
//* those orders as a means to fix lost orders or intercept and prevent spell
//* casting. The following API is then available to the user:
//*
//* function IssuePastOrder takes unit u, integer whichOrder returns boolean
//* function IssueLastOrder takes unit u returns boolean
//* function IssueSecondLastOrder takes unit u returns boolean
//* function AbortOrder takes unit u returns boolean
//*
//* If you want to reissue a past order for a given unit, IssuePastOrder is the
//* function that you'll want to use on a unit. To issue the last or second last
//* orders, there are functions for those as well. (They mostly exist for
//* backwards compatibility) AbortOrder is a means for anyone using this script
//* to stop a unit from running any given order that they happen to have at any
//* moment. AbortOrder is used in conjunction with a supplementary library,
//* AbortSpell, to seamlessly replicate WC3's spell error messages.
//*
//* function IssueArbitraryOrder takes unit u, order o returns boolean
//*
//* IssueArbitraryOrder is special in that it ignores many of the normal checks
//* and automatically forces a unit to take on a specific order. This can be
//* convenient if you want to make one unit take on another unit's order, for
//* instance. Be forewarned that this overwrites whatever the unit was doing and
//* issues the order no matter what, so use only as needed.
//*
//* If you have any further questions regarding LastOrder or how to use it, feel
//* free to visit [url]www.wc3c.net[/url] and ask questions there. This library should only
//* ever be released at WC3C and at no other site. Please give credits if this
//* library finds its way into your maps, and otherwise thanks for reading!
//*
//* Enjoy!
//*
globals
//Order type variables
constant integer ORDER_TYPE_TARGET = 1
constant integer ORDER_TYPE_POINT = 2
constant integer ORDER_TYPE_IMMEDIATE = 3
//System constants
private constant integer ORDERS_TO_HOLD = 3 //How many past orders the
//system holds for each unit.
//Should be at least 2.
private constant integer MAX_ORDERS = 8191 //The max number of orders
//the system can maintain.
//Going over 8191 uses big
//arrays, which are slower
//than normal arrays.
endglobals
globals
private hashtable ht = InitHashtable()
endglobals
struct order[MAX_ORDERS]
unit u
integer id
integer typ
boolean fin
widget tar
real x
real y
static method create takes unit ordered, integer ordid, integer ordtyp, widget target, real ordx, real ordy returns order
local order o = order.allocate()
local integer i = ORDERS_TO_HOLD
local integer hid = GetHandleId(ordered)
set o.u = ordered
set o.id = ordid
set o.typ = ordtyp
set o.fin = false
set o.tar = target
set o.x = ordx
set o.y = ordy
//Handle stored orders in the hashtable
loop
//We hold up to the constant ORDERS_TO_HOLD in the table
exitwhen i == 1
//Moves the N-1th order to the Nth slot, etc. except storing new last order
if HaveSavedInteger(ht, hid, i-1) then
if i == ORDERS_TO_HOLD and HaveSavedInteger(ht, hid, i) then
//Destroy lastmost order struct
call order.destroy(order(LoadInteger(ht, hid, i)))
endif
//Can only do this if the N-1th order exists
call SaveInteger(ht, hid, i, LoadInteger(ht, hid, i-1))
endif
set i = i - 1
endloop
//Store the new order to the hashtable as 1th last order
call SaveInteger(ht, hid, 1, integer(o))
return o
endmethod
endstruct
//******************************************************************************
//! textmacro LastOrderDebug takes ORDER, RETURN
debug if $ORDER$ > ORDERS_TO_HOLD then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Order out of range")
debug return $RETURN$
debug endif
debug if not HaveSavedInteger(ht, GetHandleId(u), $ORDER$) then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: The "+I2S($ORDER$)+"th order doesn't exist")
debug return $RETURN$
debug endif
//! endtextmacro
function GetPastOrder takes unit u, integer whichOrder returns order
//! runtextmacro LastOrderDebug("whichOrder", "0")
return order(LoadInteger(ht, GetHandleId(u), whichOrder))
endfunction
function GetPastOrderId takes unit u, integer whichOrder returns integer
//! runtextmacro LastOrderDebug("whichOrder", "0")
return order(LoadInteger(ht, GetHandleId(u), whichOrder)).id
endfunction
function GetPastOrderString takes unit u, integer whichOrder returns string
//! runtextmacro LastOrderDebug("whichOrder", "\"\"")
return OrderId2String(order(LoadInteger(ht, GetHandleId(u), whichOrder)).id)
endfunction
function GetPastOrderType takes unit u, integer whichOrder returns integer
//! runtextmacro LastOrderDebug("whichOrder", "0")
return order(LoadInteger(ht, GetHandleId(u), whichOrder)).typ
endfunction
function GetPastOrderX takes unit u, integer whichOrder returns real
//! runtextmacro LastOrderDebug("whichOrder", "0.")
return order(LoadInteger(ht, GetHandleId(u), whichOrder)).x
endfunction
function GetPastOrderY takes unit u, integer whichOrder returns real
//! runtextmacro LastOrderDebug("whichOrder", "0.")
return order(LoadInteger(ht, GetHandleId(u), whichOrder)).y
endfunction
function GetPastOrderTarget takes unit u, integer whichOrder returns widget
//! runtextmacro LastOrderDebug("whichOrder", "null")
return order(LoadInteger(ht, GetHandleId(u), whichOrder)).tar
endfunction
//******************************************************************************
function GetLastOrder takes unit u returns order
return GetPastOrder(u, 1)
endfunction
function GetLastOrderId takes unit u returns integer
return GetPastOrderId(u, 1)
endfunction
function GetLastOrderString takes unit u returns string
return GetPastOrderString(u, 1)
endfunction
function GetLastOrderType takes unit u returns integer
return GetPastOrderType(u, 1)
endfunction
function GetLastOrderX takes unit u returns real
return GetPastOrderX(u, 1)
endfunction
function GetLastOrderY takes unit u returns real
return GetPastOrderY(u, 1)
endfunction
function GetLastOrderTarget takes unit u returns widget
return GetPastOrderTarget(u, 1)
endfunction
function IsLastOrderFinished takes unit u returns boolean
//! runtextmacro LastOrderDebug("1", "false")
return GetUnitCurrentOrder(u) == 0 or order(LoadInteger(ht, GetHandleId(u), 1)).fin
endfunction
//******************************************************************************
private function OrderFilter takes unit u, integer id returns boolean
//* Excludes specific orders or unit types from registering with the system
//*
//* 851972: stop
//* Stop is excluded from the system because it is the order that
//* tells a unit to do nothing. It should be ignored by the system.
//*
//* 851971: smart
//* 851986: move
//* 851983: attack
//* 851984: attackground
//* 851990: patrol
//* 851993: holdposition
//* These are the UI orders that are passed to the system.
//*
//* 851973: stunned
//* This order is issued when a unit is stunned onto the stunner
//* It's ignored by the system, since you'd never want to reissue it
//*
//* >= 852055, <= 852762
//* These are all spell IDs from defend to incineratearrowoff with
//* a bit of leeway at the ends for orders with no strings.
//*
return id == 851971 or id == 851986 or id == 851983 or id == 851984 or id == 851990 or id == 851993 or (id >= 852055 and id <= 852762)
endfunction
private function IssuePastOrderFilter takes unit u, integer whichOrder returns boolean
//* Some criteria for whether or not a unit's last order should be given
//*
//* INSTANT type orders are excluded because generally, reissuing an instant
//* order doesn't make sense. You can remove that check below if you'd like,
//* though.
//*
//* The Type check is really just to ensure that no spell recursion can
//* occur with IssueLastOrder. The problem with intercepting the spell cast
//* event is that it happens after the order is 'caught' and registered to
//* this system. Therefore, to just IssueLastOrder tells it to recast the
//* spell! That's a problem, so we need a method to eliminate it.
//*
return GetUnitTypeId(u) != 0 and not IsUnitType(u, UNIT_TYPE_DEAD) and GetPastOrderType(u, whichOrder) != 0 and GetPastOrderType(u, whichOrder) != ORDER_TYPE_IMMEDIATE
endfunction
//******************************************************************************
function IssuePastOrder takes unit u, integer whichOrder returns boolean
local order o = GetPastOrder(u, whichOrder)
if IssuePastOrderFilter(u, whichOrder) and not o.fin then
if o.typ == ORDER_TYPE_TARGET then
return IssueTargetOrderById(u, o.id, o.tar)
elseif o.typ == ORDER_TYPE_POINT then
if o.id == 851971 then
//This adjusts for a bug in the point order's boolean return
//when issuing a smart order
call IssuePointOrderById(u, o.id, o.x, o.y)
return true
else
return IssuePointOrderById(u, o.id, o.x, o.y)
endif
elseif o.typ == ORDER_TYPE_IMMEDIATE then
return IssueImmediateOrderById(u, o.id)
endif
endif
return false
endfunction
function IssueLastOrder takes unit u returns boolean
return IssuePastOrder(u, 1)
endfunction
function IssueSecondLastOrder takes unit u returns boolean
return IssuePastOrder(u, 2)
endfunction
function IssueArbitraryOrder takes unit u, order o returns boolean
if o.typ == ORDER_TYPE_TARGET then
return IssueTargetOrderById(u, o.id, o.tar)
elseif o.typ == ORDER_TYPE_POINT then
if o.id == 851971 then
//This adjusts for a bug in the point order's boolean return
//when issuing a smart order
call IssuePointOrderById(u, o.id, o.x, o.y)
return true
else
return IssuePointOrderById(u, o.id, o.x, o.y)
endif
elseif o.typ == ORDER_TYPE_IMMEDIATE then
return IssueImmediateOrderById(u, o.id)
endif
return false
endfunction
function AbortOrder takes unit u returns boolean
if IsUnitPaused(u) then
return false
else
call PauseUnit(u, true)
call IssueImmediateOrder(u, "stop")
call PauseUnit(u, false)
endif
return true
endfunction
//**********************************************************
private function Conditions takes nothing returns boolean
return OrderFilter(GetTriggerUnit(), GetIssuedOrderId())
endfunction
private function Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local widget t = GetOrderTarget()
local integer oid = GetIssuedOrderId()
local integer oty = 0
if GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER then
call order.create(u, oid, ORDER_TYPE_TARGET, t, GetWidgetX(t), GetWidgetY(t))
elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER then
call order.create(u, oid, ORDER_TYPE_POINT, null, GetOrderPointX(), GetOrderPointY())
elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_ORDER then
call order.create(u, oid, ORDER_TYPE_IMMEDIATE, null, GetUnitX(u), GetUnitY(u))
debug else
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Invalid order type")
endif
set u = null
set t = null
endfunction
//**********************************************************
private function SpellActions takes nothing returns nothing
local order o = GetPastOrder(GetTriggerUnit(), 1)
set o.fin = true
endfunction
//**********************************************************
private function OnAdd takes nothing returns boolean
local integer hid = GetHandleId(GetFilterUnit())
local integer i = ORDERS_TO_HOLD
//Handle stored orders in the hashtable
loop
//We hold up to the constant ORDERS_TO_HOLD in the table
exitwhen i == 0
//If any of the N orders exist for this handle id, kill them all
if HaveSavedInteger(ht, hid, i) then
call order.destroy(order(LoadInteger(ht, hid, i)))
call RemoveSavedInteger(ht, hid, i)
endif
set i = i - 1
endloop
return false
endfunction
//**********************************************************
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
local region re = CreateRegion()
local rect m = GetWorldBounds()
//Main order catching trigger
call TriggerAddAction(trg, function Actions)
call TriggerAddCondition(trg, Condition(function Conditions))
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_ISSUED_ORDER)
//Spell trigger to set a flag that indicates a spell order's completion
set trg = CreateTrigger()
call TriggerAddAction(trg, function SpellActions)
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
//Entering world trigger that clears old data from handle ids
set trg = CreateTrigger()
call RegionAddRect(re, m)
call TriggerRegisterEnterRegion(trg, re, Condition(function OnAdd))
call RemoveRect(m)
set trg = null
set re = null
set m = null
endfunction
endlibrary