Name | Type | is_array | initial_value |
AfterDamageEvent | real | No | |
ClearDamageEvent | trigger | No | |
DAMAGE_FACTOR_BRACERS | real | No | |
DAMAGE_FACTOR_ELUNES | real | No | |
DAMAGE_FACTOR_ETHEREAL | real | No | |
DamageBlockingAbility | abilcode | No | |
DamageEvent | real | No | |
DamageEventAmount | real | No | |
DamageEventOverride | boolean | No | |
DamageEventPrevAmt | real | No | |
DamageEventSource | unit | No | |
DamageEventsWasted | integer | No | |
DamageEventTarget | unit | No | |
DamageEventTrigger | trigger | No | |
DamageEventType | integer | No | |
DamageModifierEvent | real | No | |
DamageTypeBlocked | integer | No | |
DamageTypeCriticalStrike | integer | No | |
DamageTypeExplosive | integer | No | |
DamageTypeHeal | integer | No | |
DamageTypeReduced | integer | No | |
DmgEvBracers | itemcode | No | |
DmgEvRecursionN | integer | No | |
DmgEvRunning | boolean | No | |
DmgEvStarted | boolean | No | |
DmgEvTimer | timer | No | |
DmgEvTrig | trigger | No | |
HideDamageFrom | boolean | Yes | |
IsDamageSpell | boolean | No | |
LastDamageHP | real | No | |
LastDmgPrevAmount | real | Yes | |
LastDmgPrevType | integer | Yes | |
LastDmgSource | unit | Yes | |
LastDmgTarget | unit | Yes | |
LastDmgValue | real | Yes | |
LastDmgWasSpell | boolean | Yes | |
NextDamageOverride | boolean | No | |
NextDamageType | integer | No | |
SpellDamageAbility | abilcode | No | |
UDex | integer | No | |
UDexGen | integer | No | |
UDexNext | integer | Yes | |
UDexPrev | integer | Yes | |
UDexRecycle | integer | No | |
UDexUnits | unit | Yes | |
UDexWasted | integer | No | |
UnitDamageRegistered | boolean | Yes | |
UnitIndexerEnabled | boolean | No | |
UnitIndexEvent | real | No | |
UnitIndexLock | integer | Yes |
//TESH.scrollpos=91
//TESH.alwaysfold=0
struct Camera
private static constant real INTERVAL = 0.03
private static string array HELP_TEXT
private static integer HELP_TEXT_SIZE = 0
readonly static real angleOfAttack = 5.306 * bj_RADTODEG
readonly static real farZ = 5000.000
readonly static real fieldOfView = 1.222 * bj_RADTODEG
readonly static real roll = 0.000
readonly static real rotation = 1.571 * bj_RADTODEG
readonly static real targetDistance = 1650.000
readonly static real zOffset = 0.000
public static method setDefault takes nothing returns nothing
set angleOfAttack = 5.306 * bj_RADTODEG
set farZ = 5000.000
set fieldOfView = 1.222 * bj_RADTODEG
set roll = 0.000
set rotation = 1.571 * bj_RADTODEG
set targetDistance = 1650.000
set zOffset = 0.000
endmethod
private static method onInterval takes nothing returns nothing
call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, .angleOfAttack, .INTERVAL)
call SetCameraField(CAMERA_FIELD_FARZ, .farZ, .INTERVAL)
call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, .fieldOfView, .INTERVAL)
call SetCameraField(CAMERA_FIELD_ROLL, .roll, .INTERVAL)
call SetCameraField(CAMERA_FIELD_ROTATION, .rotation, .INTERVAL)
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, .targetDistance, .INTERVAL)
call SetCameraField(CAMERA_FIELD_ZOFFSET, .zOffset, .INTERVAL)
endmethod
public static method setField takes player p, string field, real value returns boolean
local integer i
if field == "angleOfAttack" then
if GetLocalPlayer() == p then
set .angleOfAttack = value
endif
return true
elseif field == "farZ" then
if GetLocalPlayer() == p then
set .farZ = value
endif
return true
elseif field == "fieldOfView" then
if GetLocalPlayer() == p then
set .fieldOfView = value
endif
return true
elseif field == "roll" then
if GetLocalPlayer() == p then
set .roll = value
endif
return true
elseif field == "rotation" then
if GetLocalPlayer() == p then
set .rotation = value
endif
return true
elseif field == "targetDistance" or field == "zoom" then
if GetLocalPlayer() == p then
set .targetDistance = value
endif
return true
elseif field == "zOffset" then
if GetLocalPlayer() == p then
set .zOffset = value
endif
return true
elseif field == "camReset" then
if GetLocalPlayer() == p then
call .setDefault()
endif
return true
elseif field == "camHelp" then
if GetLocalPlayer() == p then
set i = 0
loop
exitwhen i >= .HELP_TEXT_SIZE
call DisplayTextToPlayer(p, 0, 0, .HELP_TEXT[i])
set i = i +1
endloop
endif
return true
endif
return false
endmethod
private static method onInit takes nothing returns nothing
local string command = ChatCommands.COMMAND_CHARACTER
set .HELP_TEXT[0] = "Camera Commands:"
set .HELP_TEXT[1] = " - "+command+"camHelp : shows camera commands"
set .HELP_TEXT[2] = " - "+command+"camReset : resets the camera settings to default"
set .HELP_TEXT[3] = " - "+command+"angleOfAttack #value : changes angle of attack"
set .HELP_TEXT[4] = " - "+command+"farZ #value : changes far z"
set .HELP_TEXT[5] = " - "+command+"fieldOfView #value : changes field of view"
set .HELP_TEXT[6] = " - "+command+"roll #value : changes roll"
set .HELP_TEXT[7] = " - "+command+"rotation #value : changes rotation"
set .HELP_TEXT[8] = " - "+command+"targetDistance #value : changes target distance"
set .HELP_TEXT[9] = " - "+command+"zoom #value : changes target distance"
set .HELP_TEXT[10] = " - "+command+"zOffset #value : changes height offset"
set .HELP_TEXT_SIZE = 11
call TimerStart(CreateTimer(), .INTERVAL, true, function thistype.onInterval)
endmethod
endstruct
//TESH.scrollpos=0
//TESH.alwaysfold=0
debug struct Debug
debug public static method messageEx takes string text, real duration returns nothing
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, duration, text)
debug endmethod
debug public static method message takes string text returns nothing
debug call .messageEx(text, 60)
debug endmethod
debug endstruct
//TESH.scrollpos=166
//TESH.alwaysfold=0
struct ChatCommands
readonly static constant string COMMAND_CHARACTER = "-"
private static string array HELP_TEXT
private static integer HELP_TEXT_SIZE = 0
readonly static player host
public static method setHost takes player p returns nothing
set .host = p
endmethod
private static method onChat takes nothing returns boolean
local string message = GetEventPlayerChatString()
local string command
local player p
local integer i
if SubString(message, 0, 1) != .COMMAND_CHARACTER then
return false
endif
set p = GetTriggerPlayer()
set message = SubString(message, 1, 999)
call String.split(message, " ")
if Camera.setField(p, String.splitResults[0], S2R(String.splitResults[1])) then
return false
elseif String.splitResults[0] == "help" then
if GetLocalPlayer() == p then
set i = 0
loop
exitwhen i >= .HELP_TEXT_SIZE
call DisplayTextToPlayer(p, 0, 0, .HELP_TEXT[i])
set i = i +1
endloop
endif
return false
elseif String.splitResults[0] == "clear" then
if GetLocalPlayer() == p then
call ClearTextMessages()
endif
return false
elseif String.splitResults[0] == "showPlayers" then
if GetLocalPlayer() == p then
call Players.dbgPlayers()
endif
return false
endif
if p != .host then
if GetLocalPlayer() == p then
call DisplayTextToPlayer(p, 0, 0, "You are not the host.")
endif
return false
endif
if String.splitResults[0] == "showTeams" then
if GetLocalPlayer() == p then
call Team.printTeams()
endif
return false
elseif String.splitResults[0] == "setHost" then
set i = S2I(String.splitResults[1]) -1
if i >= 0 then
if Players.isPlaying(i) then
call .setHost(Player(i))
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, GetPlayerName(.host) + " now became the host.")
elseif GetLocalPlayer() == p then
call DisplayTextToPlayer(p, 0, 0, I2S(i) + " is not in the game.")
endif
endif
return false
elseif not BattleSettings.hasStarted then
if String.splitResults[0] == "setGold" then
set BattleSettings.gold = S2I(String.splitResults[1])
call DisplayTextToPlayer(p, 0, 0, "Gold has been set to " + I2S(BattleSettings.gold))
return false
/*
elseif String.splitResults[0] == "setLumber" then
set BattleSettings.lumber = S2I(String.splitResults[1])
return false
*//*
elseif String.splitResults[0] == "setFood" then
set BattleSettings.food = S2I(String.splitResults[1])
return false
*/
elseif String.splitResults[0] == "start" then
if String.splitResults[1] == "random" then
if String.splitResults[2] == "1v1" then
call BattleSettings.createBattle(BattleSettings.BATTLE_TYPE_RANDOM_1V1)
return false
elseif String.splitResults[2] == "2v2" then
call BattleSettings.createBattle(BattleSettings.BATTLE_TYPE_RANDOM_2V2)
return false
elseif String.splitResults[2] == "3v3" then
call BattleSettings.createBattle(BattleSettings.BATTLE_TYPE_RANDOM_3V3)
return false
elseif String.splitResults[2] == "4v4" then
call BattleSettings.createBattle(BattleSettings.BATTLE_TYPE_RANDOM_4V4)
return false
elseif String.splitResults[2] == "5v5" then
call BattleSettings.createBattle(BattleSettings.BATTLE_TYPE_RANDOM_5V5)
return false
elseif String.splitResults[2] == "6v6" then
call BattleSettings.createBattle(BattleSettings.BATTLE_TYPE_RANDOM_6V6)
return false
endif
elseif String.splitResults[1] == "battle" then
call BattleSettings.createFixedBattle()
return false
endif
elseif String.splitResults[0] == "resetRace" then
call Race.createWisps()
return false
endif
else
if String.splitResults[0] == "forceStart" then
call BattleSettings.forceStart()
return false
elseif String.splitResults[0] == "stop" then
call BattleSettings.stopBattle()
return false
elseif String.splitResults[0] == "setPlayerGold" then
set i = S2I(String.splitResults[1]) -1
if i >= 0 and i < 16 then
if Players.isPlaying(i) then
call SetPlayerStateBJ(Player(i), PLAYER_STATE_RESOURCE_GOLD, S2I(String.splitResults[2]))
elseif GetLocalPlayer() == p then
call DisplayTextToPlayer(p, 0, 0, I2S(i) + " is not in the game.")
endif
endif
return false
endif
endif
if GetLocalPlayer() == p then
call DisplayTextToPlayer(p, 0, 0, "\"" + message + "\" is no valid command")
endif
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
exitwhen i >= 12
call TriggerRegisterPlayerChatEvent(t, Player(i), .COMMAND_CHARACTER, false)
set i = i +1
endloop
call TriggerAddCondition(t, Filter(function thistype.onChat))
set .HELP_TEXT[0] = "General Commands:\n"
set .HELP_TEXT[1] = " - "+.COMMAND_CHARACTER+"help : shows the help text"
set .HELP_TEXT[2] = " - "+.COMMAND_CHARACTER+"camHelp : shows the camera commands"
set .HELP_TEXT[3] = " - "+.COMMAND_CHARACTER+"clear : clears the screen from messages"
set .HELP_TEXT[7] = " - "+.COMMAND_CHARACTER+"showPlayers : shows all the current players in the game (including race and gold)"
set .HELP_TEXT[4] = "Host Commands:"
set .HELP_TEXT[5] = " - "+.COMMAND_CHARACTER+"setGold #amount : sets the available gold to the given number"
set .HELP_TEXT[6] = " - "+.COMMAND_CHARACTER+"setPlayerGold #player #amount : sets the current gold of a certain player to the given number"
set .HELP_TEXT[8] = " - "+.COMMAND_CHARACTER+"start random 1v1 : starts a 1 versus 1 match with random players"
set .HELP_TEXT[9] = " - "+.COMMAND_CHARACTER+"start random 2v2 : starts a 2 versus 2 match with random players"
set .HELP_TEXT[10] = " - "+.COMMAND_CHARACTER+"start random 3v3, 4v4, 5v5, 6v6 are also available"
set .HELP_TEXT[11] = " - "+.COMMAND_CHARACTER+"start battle # # # vs # # # : starts an x versus x match with the given players"
set .HELP_TEXT[12] = " - "+.COMMAND_CHARACTER+"forceStart : starts the current battle without having to wait for all players to send their units to war"
set .HELP_TEXT[13] = " - "+.COMMAND_CHARACTER+"stop : stops the current battle"
set .HELP_TEXT[14] = " - "+.COMMAND_CHARACTER+"resetRace : resets the races to be able to pick other races"
set .HELP_TEXT[15] = " - "+.COMMAND_CHARACTER+"setHost #player : sets the host to the given player"
set .HELP_TEXT_SIZE = 16
//hidden commands:
// /showTeams
//
endmethod
endstruct
//TESH.scrollpos=127
//TESH.alwaysfold=0
struct BattleSettings
readonly static constant integer BATTLE_TYPE_RANDOM_1V1 = 0
readonly static constant integer BATTLE_TYPE_RANDOM_2V2 = 1
readonly static constant integer BATTLE_TYPE_RANDOM_3V3 = 2
readonly static constant integer BATTLE_TYPE_RANDOM_4V4 = 3
readonly static constant integer BATTLE_TYPE_RANDOM_5V5 = 4
readonly static constant integer BATTLE_TYPE_RANDOM_6V6 = 5
readonly static constant integer BATTLE_TYPE_TOURNAMENT_1V1 = 10
readonly static constant integer BATTLE_TYPE_TOURNAMENT_2V2 = 11
readonly static constant integer BATTLE_TYPE_TOURNAMENT_3V3 = 12
readonly static constant integer BATTLE_TYPE_TOURNAMENT_4V4 = 13
readonly static Team array team
private static integer array numOfUnits
private static constant timer SELECTION_TIMER = CreateTimer()
public static boolean hasStarted = false
private static boolean isInPreparationMode = false
public static integer gold = 0
public static integer lumber = 0
public static integer food = 0
private static destructable array barrels
private static integer barrelsSize
private static integer array playersDone
public static method createStartingAreaBounds takes nothing returns nothing
local real x
local real y
local real minX
local real minY
local real maxX
local real maxY
local real grid = 64.
local rect array areas
local integer i = 0
set areas[0] = gg_rct_Player_1_Start
set areas[1] = gg_rct_Player_2_Start
set .barrelsSize = 0
set .hasStarted = true
set .isInPreparationMode = true
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, .team[0].getNames() + " vs " + .team[1].getNames())
loop
exitwhen i >= 2
set minX = GetRectMinX(areas[i])
set minY = GetRectMinY(areas[i])
set maxX = GetRectMaxX(areas[i])
set maxY = GetRectMaxY(areas[i])
call .team[i].createWorkers(GetRectCenterX(areas[i]), GetRectCenterY(areas[i]), 180*i)
call .team[i].setVision(areas[i])
set x = minX - grid/2
set y = minY - grid/2
loop
exitwhen x >= maxX + grid
set .barrels[.barrelsSize] = CreateDestructable('B000', x, y, 0, 1, 0)
set .barrelsSize = .barrelsSize +1
set x = x + grid
endloop
set x = minX - grid/2
set y = maxY + grid/2
loop
exitwhen x >= maxX + grid
set .barrels[.barrelsSize] = CreateDestructable('B000', x, y, 0, 1, 0)
set .barrelsSize = .barrelsSize +1
set x = x + grid
endloop
set x = minX - grid/2
set y = minY + grid/2
loop
exitwhen y >= maxY + grid
set .barrels[.barrelsSize] = CreateDestructable('B000', x, y, 0, 1, 0)
set .barrelsSize = .barrelsSize +1
set y = y + grid
endloop
set x = maxX + grid/2
set y = minY + grid/2
loop
exitwhen y >= maxY + grid
set .barrels[.barrelsSize] = CreateDestructable('B000', x, y, 0, 1, 0)
set .barrelsSize = .barrelsSize +1
set y = y + grid
endloop
set i = i +1
endloop
endmethod
private static method setupRandomPlayers takes integer numOfPlayersInTeam returns boolean
local Players array p
local integer i = 0
if Players.NUM_OF_PLAYERS < 2*numOfPlayersInTeam then
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Not enough players to run this game mode.")
return false
endif
call Players.prepareDummyPlayers()
call Players.prepareContestants()
loop
exitwhen i >= numOfPlayersInTeam
set p[i] = Players.getContestants()
set p[i + numOfPlayersInTeam] = Players.getContestants()
set i = i +1
endloop
set i = 0
loop
exitwhen i >= numOfPlayersInTeam
call p[i].addDummyPlayers()
call p[i + numOfPlayersInTeam].addDummyPlayers()
call .team[0].addPlayer(p[i])
call .team[1].addPlayer(p[i + numOfPlayersInTeam])
set i = i +1
endloop
return true
endmethod
public static method createBattle takes integer battleType returns nothing
if Race.numOfPlayersLeft > 0 then
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Can't start the game until all players have chosen a race.")
return
endif
set .playersDone[0] = 0
set .playersDone[1] = 0
if .team[0] == 0 then
set .team[0] = Team.create()
set .team[1] = Team.create()
else
call .team[0].setAllied(false)
call .team[1].setAllied(false)
call .team[0].resetDummyPlayers()
call .team[0].resetPlayers()
call .team[1].resetDummyPlayers()
call .team[1].resetPlayers()
endif
set .numOfUnits[0] = 0
set .numOfUnits[1] = 0
if battleType == .BATTLE_TYPE_RANDOM_1V1 then
if not .setupRandomPlayers(1) then
return
endif
elseif battleType == .BATTLE_TYPE_RANDOM_2V2 then
if not .setupRandomPlayers(2) then
return
endif
elseif battleType == .BATTLE_TYPE_RANDOM_3V3 then
if not .setupRandomPlayers(3) then
return
endif
elseif battleType == .BATTLE_TYPE_RANDOM_4V4 then
if not .setupRandomPlayers(4) then
return
endif
elseif battleType == .BATTLE_TYPE_RANDOM_5V5 then
if not .setupRandomPlayers(5) then
return
endif
elseif battleType == .BATTLE_TYPE_RANDOM_6V6 then
if not .setupRandomPlayers(6) then
return
endif
endif
call .team[0].setAllied(true)
call .team[1].setAllied(true)
call .team[0].setResources(PLAYER_STATE_RESOURCE_GOLD, .gold)
call .team[0].setResources(PLAYER_STATE_RESOURCE_LUMBER, .lumber)
call .team[1].setResources(PLAYER_STATE_RESOURCE_GOLD, .gold)
call .team[1].setResources(PLAYER_STATE_RESOURCE_LUMBER, .lumber)
call BattleSettings.createStartingAreaBounds()
endmethod
public static method createFixedBattle takes nothing returns nothing
local Players array p
local integer i = 0
local integer j = 0
local integer t = 0
if Race.numOfPlayersLeft > 0 then
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Can't start the game until all players have chosen a race.")
return
endif
set .playersDone[0] = 0
set .playersDone[1] = 0
if .team[0] == 0 then
set .team[0] = Team.create()
set .team[1] = Team.create()
else
call .team[0].setAllied(false)
call .team[1].setAllied(false)
call .team[0].resetDummyPlayers()
call .team[0].resetPlayers()
call .team[1].resetDummyPlayers()
call .team[1].resetPlayers()
endif
set .numOfUnits[0] = 0
set .numOfUnits[1] = 0
call Players.prepareDummyPlayers()
call Players.prepareContestants()
set i = 2
loop
exitwhen i >= String.splitResultsLength
if String.splitResults[i] == "vs" then
set t = t +1
else
set p[j] = Players.getContestant(S2I(String.splitResults[i]) -1)
if p[j] != 0 then
call .team[t].addPlayer(p[j])
else
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Player " + String.splitResults[i] + " is not in the game.")
endif
set j = j +1
endif
set i = i +1
endloop
loop
set j = j -1
exitwhen j < 0
call p[j].addDummyPlayers()
endloop
call .team[0].setAllied(true)
call .team[1].setAllied(true)
call .team[0].setResources(PLAYER_STATE_RESOURCE_GOLD, .gold)
call .team[1].setResources(PLAYER_STATE_RESOURCE_GOLD, .gold)
call BattleSettings.createStartingAreaBounds()
endmethod
private static method removeStartingAreaBounds takes nothing returns nothing
set .isInPreparationMode = false
loop
exitwhen .barrelsSize == 0
set .barrelsSize = .barrelsSize -1
call RemoveDestructable(.barrels[.barrelsSize])
endloop
call .team[0].resetVision()
call .team[1].resetVision()
call .team[0].setResources(PLAYER_STATE_RESOURCE_GOLD, 0)
call .team[0].setResources(PLAYER_STATE_RESOURCE_LUMBER, 0)
call .team[1].setResources(PLAYER_STATE_RESOURCE_GOLD, 0)
call .team[1].setResources(PLAYER_STATE_RESOURCE_LUMBER, 0)
endmethod
private static method transformUnits takes nothing returns boolean
local integer teamId
local boolean b = true
set teamId = 0
loop
exitwhen teamId >= 2
set .numOfUnits[teamId] = .team[teamId].transformUnits(teamId)
if .numOfUnits[teamId] == 0 then
set b = false
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "The team of " + .team[teamId].getNames() + " was so stupid to not make any units that we decided to end this battle.")
endif
set teamId = teamId +1
endloop
return b
endmethod
private static method clearSelection takes nothing returns nothing
call ClearSelection()
endmethod
public static method stopBattle takes nothing returns nothing
local group g
local unit FoG
if not .hasStarted then
return
endif
if .isInPreparationMode then
call .removeStartingAreaBounds()
call .transformUnits()
endif
call .team[0].setAllied(false)
call .team[1].setAllied(false)
call .team[0].resetDummyPlayers()
call .team[1].resetDummyPlayers()
set .hasStarted = false
call PauseTimer(.SELECTION_TIMER)
set g = CreateGroup()
call GroupEnumUnitsInRange(g, 0, 0, 99999, null)
loop
set FoG = FirstOfGroup(g)
exitwhen FoG == null
call GroupRemoveUnit(g, FoG)
call RemoveUnit(FoG)
endloop
call DestroyGroup(g)
set g = null
endmethod
public static method forceStart takes nothing returns nothing
call .removeStartingAreaBounds()
if .transformUnits() then
call TimerStart(.SELECTION_TIMER, 0.03, true, function thistype.clearSelection)
else
call .stopBattle()
endif
endmethod
public static method playerHasFinished takes integer playerId returns nothing
local integer i = 0
local boolean b = false
loop
exitwhen i >= 2
if .team[i].contains(Players.get[playerId]) then
set .playersDone[i] = .playersDone[i] +1
if .playersDone[i] == .team[i].size then
call .team[i].resetVision()
if .playersDone[1-i] == .team[1-i].size then
call .forceStart()
endif
endif
endif
set i = i +1
endloop
endmethod
private static method endBattle takes integer victor returns nothing
call .stopBattle()
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "The team of " + .team[victor].getNames() + " has won!")
endmethod
private static method onDeath takes nothing returns boolean
local integer teamId = UnitType.getTeamId(GetTriggerUnit())
set .numOfUnits[teamId] = .numOfUnits[teamId] -1
if .numOfUnits[teamId] == 0 then
call .endBattle(1 - teamId)
endif
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(t, Condition(function thistype.onDeath))
endmethod
endstruct
//TESH.scrollpos=27
//TESH.alwaysfold=0
struct AbilityCommands
private static constant integer TO_WAR_RAWCODE = 'A000'
private static constant integer RACE_SELECTOR_HUMAN = 'A001'
private static constant integer RACE_SELECTOR_DWARVES = 'A007'
private static constant integer RACE_SELECTOR_ORC = 'A002'
private static method onCast takes nothing returns boolean
local integer abilityId = GetSpellAbilityId()
local Players p
local unit u
local integer pId
if abilityId == .TO_WAR_RAWCODE then
set u = GetTriggerUnit()
set pId = GetPlayerId(GetOwningPlayer(u))
call RemoveUnit(u)
set u = null
set p = Players.get[pId]
call BattleSettings.playerHasFinished(pId)
elseif abilityId == .RACE_SELECTOR_HUMAN then
set u = GetTriggerUnit()
set p = Players.get[GetPlayerId(GetOwningPlayer(u))]
call RemoveUnit(u)
set u = null
call p.setRace(Race.HUMAN)
set Race.numOfPlayersLeft = Race.numOfPlayersLeft -1
elseif abilityId == .RACE_SELECTOR_DWARVES then
set u = GetTriggerUnit()
set p = Players.get[GetPlayerId(GetOwningPlayer(u))]
call RemoveUnit(u)
set u = null
call p.setRace(Race.DWARVES)
set Race.numOfPlayersLeft = Race.numOfPlayersLeft -1
elseif abilityId == .RACE_SELECTOR_ORC then
set u = GetTriggerUnit()
set p = Players.get[GetPlayerId(GetOwningPlayer(u))]
call RemoveUnit(u)
set u = null
call p.setRace(Race.ORCS)
set Race.numOfPlayersLeft = Race.numOfPlayersLeft -1
endif
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST)
call TriggerAddCondition(t, Filter(function thistype.onCast))
endmethod
endstruct
//TESH.scrollpos=135
//TESH.alwaysfold=0
/*
function B2S takes boolean bool returns string
function Boolean2String takes boolean bool returns string
function S2B takes string str returns boolean
function String2Boolean takes string str returns boolean
function FirstIndexOf takes string source, string charSequence returns integer
function NumberIndexOf takes string source, string charSequence, integer number returns integer
function LastIndexOf takes string source, string charSequence returns integer
function FirstIndexOfNot takes string source, string charSequence returns integer
function NumberIndexOfNot takes string source, string charSequence, integer number returns integer
function LastIndexOfNot takes string source, string charSequence returns integer
function ReplaceCountFromIndex takes string source, string charSequence, string replacement, integer index, integer amount returns string
function ReplaceFirst takes string source, string charSequence, string replacement returns string
function ReplaceLast takes string source, string charSequence, string replacement returns string
function ReplaceCount takes string source, string charSequence, string replacement, integer count returns string
function ReplaceAllFromIndex takes string source, string charSequence, string replacement, integer index returns string
function ReplaceAll takes string source, string charSequence, string replacement returns string
function Matches takes string source, string regex returns boolean
function IsHexCode takes string source returns boolean
*/
struct String
readonly static string array splitResults
readonly static integer splitResultsLength
//IndexOf functions
public static method numberIndexOf takes string source, string charSequence, integer number returns integer
local integer index = 0
local integer sequenceLength = StringLength(charSequence)
local integer length = StringLength(source) - sequenceLength
loop
exitwhen index > length
if SubString(source, index, index + sequenceLength) == charSequence then
set number = number -1
if number == 0 then
return index
endif
endif
set index = index + 1
endloop
return -1
endmethod
public static method firstIndexOf takes string source, string charSequence returns integer
return .numberIndexOf(source, charSequence, 1)
endmethod
public static method lastIndexOf takes string source, string charSequence returns integer
local integer index = 0
local integer result = -1
local integer sequenceLength = StringLength(charSequence)
local integer length = StringLength(source) - sequenceLength
loop
exitwhen index > length
if SubString(source, index, index + sequenceLength) == charSequence then
set result = index
endif
set index = index + 1
endloop
return result
endmethod
public static method numberIndexOfNot takes string source, string charSequence, integer number returns integer
local integer index = 0
local integer sequenceLength = StringLength(charSequence)
local integer length = StringLength(source) - sequenceLength
loop
exitwhen index > length
if SubString(source, index, index + sequenceLength) != charSequence then
set number = number -1
if number == 0 then
return index
endif
endif
set index = index + 1
endloop
return -1
endmethod
public static method firstIndexOfNot takes string source, string charSequence returns integer
return .numberIndexOfNot(source, charSequence, 1)
endmethod
public static method lastIndexOfNot takes string source, string charSequence returns integer
local integer index = 0
local integer result = -1
local integer sequenceLength = StringLength(charSequence)
local integer length = StringLength(source) - sequenceLength
loop
exitwhen index > length
if SubString(source, index, index + sequenceLength) != charSequence then
set result = index
endif
set index = index + 1
endloop
return result
endmethod
public static method firstIndexOfBJ takes string source, string charSequence returns integer
return .firstIndexOf(source, charSequence) + 1
endmethod
public static method numberIndexOfBJ takes string source, string charSequence, integer number returns integer
return .numberIndexOf(source, charSequence, number) + 1
endmethod
public static method lastIndexOfBJ takes string source, string charSequence returns integer
return .lastIndexOf(source, charSequence) + 1
endmethod
public static method firstIndexOfNotBJ takes string source, string charSequence returns integer
return .firstIndexOfNot(source, charSequence) + 1
endmethod
public static method numberIndexOfNotBJ takes string source, string charSequence, integer number returns integer
return .numberIndexOfNot(source, charSequence, number) + 1
endmethod
public static method lastIndexOfNotBJ takes string source, string charSequence returns integer
return .lastIndexOfNot(source, charSequence) + 1
endmethod
//Replace functions
public static method replaceCountFromIndex takes string source, string charSequence, string replacement, integer index, integer amount returns string
local integer sourceLength = StringLength(source)
local integer sequenceLength = StringLength(charSequence)
local integer replacementLength = StringLength(replacement)
local integer length = sourceLength - sequenceLength
loop
exitwhen index > length or amount == 0
if SubString(source, index, index + sequenceLength) == charSequence then
set source = SubString(source, 0, index) + replacement + SubString(source, index + replacementLength, sourceLength)
set sourceLength = StringLength(source)
set length = sourceLength - sequenceLength
set amount = amount + 1
set index = index + replacementLength
else
set index = index + 1
endif
endloop
return source
endmethod
public static method replaceFirst takes string source, string charSequence, string replacement returns string
return .replaceCountFromIndex(source, charSequence, replacement, 0, 1)
endmethod
public static method replaceLast takes string source, string charSequence, string replacement returns string
return .replaceCountFromIndex(source, charSequence, replacement, .lastIndexOf(source, charSequence), 1)
endmethod
public static method replaceCount takes string source, string charSequence, string replacement, integer count returns string
return .replaceCountFromIndex(source, charSequence, replacement, 0, count)
endmethod
public static method replaceAllFromIndex takes string source, string charSequence, string replacement, integer index returns string
return .replaceCountFromIndex(source, charSequence, replacement, index, -1)
endmethod
public static method replaceAll takes string source, string charSequence, string replacement returns string
return .replaceCountFromIndex(source, charSequence, replacement, 0, -1)
endmethod
//Splitting a line into words
public static method split takes string line, string regex returns nothing
set .splitResultsLength = 0
loop
set line = SubString(line, .firstIndexOfNot(line, " "), 999)
exitwhen StringLength(line) == 0
set .splitResults[.splitResultsLength] = SubString(line, .firstIndexOfNot(line, " "), .firstIndexOf(line, " "))
set line = SubString(line, StringLength(.splitResults[.splitResultsLength]), 999)
set .splitResultsLength = .splitResultsLength +1
endloop
endmethod
endstruct
//TESH.scrollpos=31
//TESH.alwaysfold=0
struct Race
readonly static thistype HUMAN
readonly static thistype DWARVES
readonly static thistype HIGH_ELVES
readonly static thistype NIGHT_ELVES
readonly static thistype ORCS
readonly static thistype UNDEAD
readonly static thistype GOBLIN
readonly static constant integer SELECTOR = 'e000'
readonly static thistype array race
public static integer numOfPlayersLeft = 0
readonly integer worker
readonly string name
private static method onInit takes nothing returns nothing
set .HUMAN = .allocate()
set .HUMAN.worker = 'h001'
set .HUMAN.name = "Human"
set .DWARVES = .allocate()
set .DWARVES.worker = 'h00T'
set .DWARVES.name = "Dwarves"
set .HIGH_ELVES = .allocate()
set .HIGH_ELVES.worker = 'hfoo'
set .HIGH_ELVES.name = "High Elves"
set .NIGHT_ELVES = .allocate()
set .NIGHT_ELVES.worker = 'hfoo'
set .NIGHT_ELVES.name = "Night Elves"
set .ORCS = .allocate()
set .ORCS.worker = 'o000'
set .ORCS.name = "Orcs"
set .UNDEAD = .allocate()
set .UNDEAD.worker = 'hfoo'
set .UNDEAD.name = "Undead"
set .GOBLIN = .allocate()
set .GOBLIN.worker = 'hfoo'
set .GOBLIN.name = "Goblin"
endmethod
public method toString takes nothing returns string
return name
endmethod
public static method createWisps takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= Players.NUM_OF_PLAYERS
call CreateUnit(Players.PLAYERS[i].ref, .SELECTOR, 0, 0, 0)
call SetCameraPosition(0, 0)
set i = i +1
endloop
set Race.numOfPlayersLeft = Players.NUM_OF_PLAYERS
endmethod
endstruct
//TESH.scrollpos=0
//TESH.alwaysfold=0
function StartRaceSelection takes nothing returns nothing
local integer i = 0
local player p
local boolean b = true
local fogmodifier f
local rect r = GetWorldBounds()
loop
exitwhen i >= bj_MAX_PLAYER_SLOTS
set p = Player(i)
if (GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p) == MAP_CONTROL_USER) then
call Players.create(i)
if b then
set b = false
call ChatCommands.setHost(p)
endif
else
set f = CreateFogModifierRect(p, FOG_OF_WAR_VISIBLE, r, false, false)
call FogModifierStart(f)
endif
set i = i +1
endloop
call Race.createWisps()
call DestroyTimer(GetExpiredTimer())
endfunction
//===========================================================================
function InitTrig_RaceSelection takes nothing returns nothing
call TimerStart(CreateTimer(), 0, false, function StartRaceSelection)
endfunction
//TESH.scrollpos=73
//TESH.alwaysfold=0
struct Team
readonly integer size
readonly Players array players[16]
public static method create takes nothing returns thistype
local thistype this = .allocate()
set .size = 0
return this
endmethod
public method destroy takes nothing returns nothing
set .size = 0
call .deallocate()
endmethod
public method addPlayer takes Players p returns nothing
set .players[.size] = p
set .size = .size +1
endmethod
public method resetDummyPlayers takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= .size
call .players[i].resetDummyPlayers()
set i = i +1
endloop
endmethod
public method resetPlayers takes nothing returns nothing
set .size = .size -1
loop
call .players[.size].resetDummyPlayers()
exitwhen .size <= 0
set .size = .size -1
endloop
endmethod
public method createWorkers takes real x, real y, real face returns nothing
local integer i = 0
loop
exitwhen i >= .size
call .players[i].createWorker(x, y, face)
set i = i +1
endloop
endmethod
public method setVision takes rect r returns nothing
local integer i = 0
loop
exitwhen i >= .size
call .players[i].setVision(r)
set i = i +1
endloop
endmethod
public method resetVision takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= .size
call .players[i].resetVision()
set i = i +1
endloop
endmethod
public method transformUnits takes integer teamId returns integer
local integer pId = 0
local integer x = 0
loop
exitwhen pId >= .size
set x = x + .players[pId].transformUnits(teamId)
set pId = pId +1
endloop
return x
endmethod
public method setResources takes playerstate resource, integer amount returns nothing
local integer i = 0
loop
exitwhen i >= .size
call .players[i].setResource(resource, amount)
set i = i +1
endloop
endmethod
public method contains takes Players p returns boolean
local integer i = 0
loop
exitwhen i >= .size
if .players[i] == p then
return true
endif
set i = i +1
endloop
return false
endmethod
public method setAllied takes boolean allied returns nothing
local integer i = 0
local integer i2
loop
exitwhen i >= .size
set i2 = 0
loop
exitwhen i2 >= .size
//call BJDebugMsg(I2S(.players[i].getId()) + " allied to " + I2S(.players[i2].getId()))
call .players[i].setAllied(.players[i2], allied)
set i2 = i2 +1
endloop
set i = i +1
endloop
endmethod
public method printPlayers takes nothing returns nothing
local integer i = 0
local string s = "[ "
if .size > 0 then
loop
set s = s + I2S(.players[i].getId())
set i = i +1
exitwhen i >= .size
set s = s + ", "
endloop
endif
if GetLocalPlayer() == ChatCommands.host then
call BJDebugMsg(s + " ]")
endif
endmethod
public method printDummyPlayers takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= .size
call .players[i].printDummyPlayers()
set i = i +1
endloop
endmethod
public static method printTeams takes nothing returns nothing
call BattleSettings.team[0].printPlayers()
call BattleSettings.team[0].printDummyPlayers()
call BattleSettings.team[1].printPlayers()
call BattleSettings.team[1].printDummyPlayers()
endmethod
public method getNames takes nothing returns string
local string s
local integer i
if .size == 0 then
return "noone"
endif
set s = ""
set i = 0
loop
set s = s + .players[i].getName()
set i = i +1
exitwhen i >= .size
set s = s + " & "
endloop
return s
endmethod
endstruct
//TESH.scrollpos=324
//TESH.alwaysfold=0
struct Players
readonly static integer NUM_OF_PLAYERS = 0
readonly static thistype array PLAYERS
readonly static integer tempNumOfPlayers
readonly static thistype array tempPlayers
readonly static integer contestants
readonly static thistype array get
readonly player ref
readonly Race race
readonly playercolor defaultColor
readonly player array dummyPlayers[12]
readonly integer dummyPlayersSize
private fogmodifier fog
private fogmodifier globalFog
public static method create takes integer pId returns thistype
local thistype this = .allocate()
local rect r
set .get[pId] = this
set .ref = Player(pId)
set .PLAYERS[.NUM_OF_PLAYERS] = this
set .NUM_OF_PLAYERS = .NUM_OF_PLAYERS +1
set .defaultColor = GetPlayerColor(.ref)
set .dummyPlayersSize = 1
set .dummyPlayers[0] = .ref
set r = GetWorldBounds()
set .globalFog = CreateFogModifierRect(.ref, FOG_OF_WAR_VISIBLE, r, false, false)
call FogModifierStart(.globalFog)
call RemoveRect(r)
set r = null
return this
endmethod
public method getName takes nothing returns string
return GetPlayerName(.ref)
endmethod
public method getId takes nothing returns integer
return GetPlayerId(.ref)
endmethod
public method getGold takes nothing returns integer
return GetPlayerState(.ref, PLAYER_STATE_RESOURCE_GOLD)
endmethod
public method setGold takes integer gold returns nothing
call SetPlayerStateBJ(.ref, PLAYER_STATE_RESOURCE_GOLD, gold)
endmethod
public method setRace takes Race r returns nothing
set .race = r
endmethod
public method createWorker takes real x, real y, real face returns nothing
call CreateUnit(.ref, .race.worker, x, y, face)
if GetLocalPlayer() == .ref then
call SetCameraPosition(x, y)
endif
endmethod
public method setVision takes rect r returns nothing
// old version (desync):
if GetLocalPlayer() == .ref then
call FogEnable(true)
endif
// new version:
call FogModifierStop(.globalFog)
// both versions:
set .fog = CreateFogModifierRect(.ref, FOG_OF_WAR_VISIBLE, r, false, false)
call FogModifierStart(.fog)
endmethod
public method resetVision takes nothing returns nothing
call FogModifierStop(.fog)
call DestroyFogModifier(.fog)
set .fog = null
call FogModifierStart(.globalFog)
endmethod
public method transformUnits takes integer teamId returns integer
local group g = CreateGroup()
local unit FoG
local integer i = 0
local integer x = 0
local real face = teamId * 180
loop
exitwhen i >= .dummyPlayersSize
call SetPlayerColor(.dummyPlayers[i], .defaultColor)
set i = i +1
endloop
set i = 0
call GroupEnumUnitsOfPlayer(g, .ref, null)
loop
set FoG = FirstOfGroup(g)
exitwhen FoG == null
call GroupRemoveUnit(g, FoG)
if UnitType.transform(teamId, .dummyPlayers[i], .defaultColor, FoG, face) then
set x = x +1
set i = i +1
if i >= .dummyPlayersSize then
set i = 0
endif
endif
endloop
call DestroyGroup(g)
set g = null
return x
endmethod
public method setResource takes playerstate resource, integer amount returns nothing
call SetPlayerStateBJ(.ref, resource, amount)
endmethod
private static integer array tempPlayerArray
private static integer tempPlayersMax
public static method prepareDummyPlayers takes nothing returns nothing
set .tempPlayersMax = 0
loop
exitwhen .tempPlayersMax >= 12
set .tempPlayerArray[.tempPlayersMax] = .tempPlayersMax
set .tempPlayersMax = .tempPlayersMax +1
endloop
endmethod
public method setAllied takes Players other, boolean allied returns nothing
local integer i = 0
local integer i2
loop
exitwhen i >= .dummyPlayersSize
set i2 = 0
loop
exitwhen i2 >= .dummyPlayersSize
call SetPlayerAlliance(.dummyPlayers[i], other.dummyPlayers[i2], ALLIANCE_PASSIVE, allied)
call SetPlayerAlliance(other.dummyPlayers[i2], .dummyPlayers[i], ALLIANCE_PASSIVE, allied)
call SetPlayerAlliance(.dummyPlayers[i], other.dummyPlayers[i2], ALLIANCE_SHARED_SPELLS, allied)
call SetPlayerAlliance(other.dummyPlayers[i2], .dummyPlayers[i], ALLIANCE_SHARED_SPELLS, allied)
set i2 = i2 +1
endloop
set i = i +1
endloop
endmethod
public method resetDummyPlayers takes nothing returns nothing
call .setAllied(this, false)
loop
exitwhen .dummyPlayersSize <= 1
set .dummyPlayersSize = .dummyPlayersSize -1
endloop
endmethod
private method addDummyPlayer takes integer pId returns nothing
local player p = Player(pId)
local integer i = 0
loop
exitwhen i >= .dummyPlayersSize
call SetPlayerAlliance(.dummyPlayers[i], p, ALLIANCE_PASSIVE, true)
call SetPlayerAlliance(p, .dummyPlayers[i], ALLIANCE_PASSIVE, true)
call SetPlayerAlliance(.dummyPlayers[i], p, ALLIANCE_SHARED_SPELLS, true)
call SetPlayerAlliance(p, .dummyPlayers[i], ALLIANCE_SHARED_SPELLS, true)
set i = i +1
endloop
set .dummyPlayers[.dummyPlayersSize] = p
set .dummyPlayersSize = .dummyPlayersSize +1
endmethod
public method addDummyPlayers takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= (12 / .contestants) -1
set .tempPlayersMax = .tempPlayersMax -1
call .addDummyPlayer(.tempPlayerArray[.tempPlayersMax])
set i = i +1
endloop
endmethod
public static method prepareContestants takes nothing returns nothing
set .tempNumOfPlayers = 0
loop
exitwhen .tempNumOfPlayers == .NUM_OF_PLAYERS
set .tempPlayers[.tempNumOfPlayers] = .PLAYERS[.tempNumOfPlayers]
set .tempNumOfPlayers = .tempNumOfPlayers +1
endloop
set .contestants = 0
endmethod
public static method getContestants takes nothing returns thistype
local integer i
local thistype r
set .tempNumOfPlayers = .tempNumOfPlayers -1
set i = GetRandomInt(0, .tempNumOfPlayers)
set r = .tempPlayers[i]
set .tempPlayers[i] = .tempPlayers[.tempNumOfPlayers]
set .tempPlayersMax = .tempPlayersMax -1
set .tempPlayerArray[r.getId()] = .tempPlayerArray[.tempPlayersMax]
set .contestants = .contestants +1
return r
endmethod
public static method getContestant takes integer id returns thistype
local integer i = 0
local integer i2
loop
exitwhen i >= .tempNumOfPlayers
if .get[id] == .tempPlayers[i] then
set .tempNumOfPlayers = .tempNumOfPlayers -1
set .tempPlayers[i] = .tempPlayers[.tempNumOfPlayers]
set i2 = 0
loop
exitwhen i2 >= .tempPlayersMax
if .tempPlayerArray[i2] == id then
set .tempPlayersMax = .tempPlayersMax -1
set .tempPlayerArray[i2] = .tempPlayerArray[.tempPlayersMax]
exitwhen true
endif
set i2 = i2 +1
endloop
set .contestants = .contestants +1
return .get[id]
endif
set i = i +1
endloop
return 0
endmethod
private static method onLeave takes nothing returns boolean
local integer pId = GetPlayerId(GetTriggerPlayer())
local integer i = 0
loop
exitwhen i >= .NUM_OF_PLAYERS
if .PLAYERS[i].getId() == pId then
set .NUM_OF_PLAYERS = .NUM_OF_PLAYERS -1
set .PLAYERS[i] = .PLAYERS[.NUM_OF_PLAYERS]
endif
set i = i +1
endloop
return false
endmethod
public static method isPlaying takes integer pId returns boolean
local integer i = 0
loop
exitwhen i >= .NUM_OF_PLAYERS
if .PLAYERS[i].getId() == pId then
return true
endif
set i = i +1
endloop
return false
endmethod
public static method printContestants takes nothing returns nothing
local integer i = 0
local string s = "[ "
if .tempNumOfPlayers > 0 then
loop
set s = s + I2S(.tempPlayers[i].getId())
set i = i +1
exitwhen i >= .tempNumOfPlayers
set s = s + ", "
endloop
endif
if GetLocalPlayer() == ChatCommands.host then
call BJDebugMsg(s + " ]")
endif
endmethod
public static method printPlayers takes nothing returns nothing
local integer i = 0
local string s = "[ "
if .tempPlayersMax > 0 then
loop
set s = s + I2S(.tempPlayerArray[i])
set i = i +1
exitwhen i >= .tempPlayersMax
set s = s + ", "
endloop
endif
if GetLocalPlayer() == ChatCommands.host then
call BJDebugMsg(s + " ]")
endif
endmethod
public method resetColor takes nothing returns nothing
call SetPlayerColor(.ref, .defaultColor)
endmethod
public static method resetColors takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= .NUM_OF_PLAYERS
call .PLAYERS[i].resetColor()
set i = i +1
endloop
endmethod
public method printDummyPlayers takes nothing returns nothing
local integer i = 0
local string s = "[ "
if .dummyPlayersSize > 0 then
loop
set s = s + I2S(GetPlayerId(.dummyPlayers[i]))
set i = i +1
exitwhen i >= .dummyPlayersSize
set s = s + ", "
endloop
endif
if GetLocalPlayer() == ChatCommands.host then
call BJDebugMsg(s + " ]")
endif
endmethod
public static method dbgPlayers takes nothing returns nothing
local integer i = 0
loop
exitwhen i == .NUM_OF_PLAYERS
call BJDebugMsg(I2S(.PLAYERS[i].getId() +1) + " : " + .PLAYERS[i].getName() + " : " + .PLAYERS[i].race.toString() + " ("+I2S(.PLAYERS[i].getGold())+"g)")
set i = i +1
endloop
endmethod
private static method setEnemy takes nothing returns nothing
local integer i = 0
local integer i2
local integer max = 12
loop
exitwhen i >= max
set i2 = 0
loop
exitwhen i2 >= max
call SetPlayerAlliance(Player(i), Player(i2), ALLIANCE_PASSIVE, false)
set i2 = i2 +1
endloop
set i = i +1
endloop
call DestroyTimer(GetExpiredTimer())
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
exitwhen i >= 12
call TriggerRegisterPlayerEvent(t, Player(i), EVENT_PLAYER_LEAVE)
set i = i +1
endloop
call TriggerAddCondition(t, Condition(function thistype.onLeave))
call TimerStart(CreateTimer(), 0, false, function thistype.setEnemy)
endmethod
endstruct
//TESH.scrollpos=86
//TESH.alwaysfold=0
struct UnitType
private static constant hashtable TABLE = InitHashtable()
private static integer array team
readonly integer building
readonly integer rawcode
readonly UnitStats stats
public static method cast takes unit u returns thistype
return LoadInteger(.TABLE, GetUnitTypeId(u), 0)
endmethod
public static method getTeamId takes unit u returns integer
return .team[GetUnitUserData(u)]
endmethod
private static method create takes integer building, integer rawcode returns thistype
local thistype this = .allocate()
set .building = building
set .rawcode = rawcode
call SaveInteger(.TABLE, building, 0, this)
call SaveInteger(.TABLE, rawcode, 0, this)
set .stats = UnitStats.create()
return this
endmethod
public static method transform takes integer teamId, player p, playercolor c, unit u, real face returns boolean
local thistype this = LoadInteger(.TABLE, GetUnitTypeId(u), 0)
local real x = GetUnitX(u)
local real y = GetUnitY(u)
call RemoveUnit(u)
if this == 0 then
return false
endif
set u = CreateUnit(p, .rawcode, x, y, face)
call SetUnitColor(u, c)
set .team[GetUnitUserData(u)] = teamId
return true
endmethod
private static method onInit takes nothing returns nothing
local thistype this
// Human:
//Outlaw
set this = .create('h00H', 'h00J')
set .stats.damageType = UnitStats.DAMAGE_TYPE_BLUNT
call .stats.setDamageTypeFactors(1.20, 0.80, 0.80, 0.80, 1.00, 0.80)
//Spearman
set this = .create('h00K', 'h00L')
set .stats.damageType = UnitStats.DAMAGE_TYPE_PIKE
call .stats.setDamageTypeFactors(1.20, 0.80, 0.80, 0.80, 1.00, 0.80)
//Footman
set this = .create('h000', 'h002')
set .stats.damageType = UnitStats.DAMAGE_TYPE_SHARP
call .stats.setDamageTypeFactors(0.80, 1.20, 0.70, 1.20, 1.00, 1.80)
//Longbowman
set this = .create('h003', 'h004')
set .stats.damageType = UnitStats.DAMAGE_TYPE_PIERCE
call .stats.setDamageTypeFactors(1.20, 0.80, 0.80, 0.80, 1.00, 0.80)
//Archmage
set this = .create('h009', 'h00A')
set .stats.damageType = UnitStats.DAMAGE_TYPE_MAGIC
call .stats.setDamageTypeFactors(1.00, 1.00, 1.00, 1.20, 0.60, 1.00)
//Ligt Cavalry
set this = .create('h005', 'h006')
set .stats.damageType = UnitStats.DAMAGE_TYPE_PIKE
call .stats.setDamageTypeFactors(1.20, 0.80, 3.00, 0.80, 1.00, 1.50)
//Captain
set this = .create('h01D', 'h01B')
set .stats.damageType = UnitStats.DAMAGE_TYPE_SHARP
call .stats.setDamageTypeFactors(0.80, 1.20, 0.70, 1.20, 1.00, 1.80)
//Catapult
set this = .create('h007', 'h008')
set .stats.damageType = UnitStats.DAMAGE_TYPE_SIEGE
call .stats.setDamageTypeFactors(2.00, 2.00, 0.50, 0.01, 0.00, 3.00)
//Dwarves:
//Shield Breaker
set this = .create('h014', 'h00U')
set .stats.damageType = UnitStats.DAMAGE_TYPE_BLUNT
call .stats.setDamageTypeFactors(0.80, 1.20, 0.70, 1.20, 1.00, 1.80)
//Phalanx
set this = .create('h019', 'h00V')
set .stats.damageType = UnitStats.DAMAGE_TYPE_PIKE
call .stats.setDamageTypeFactors(1.20, 0.80, 0.80, 0.80, 1.00, 0.80)
//Ogre
set this = .create('h015', 'h00X')
set .stats.damageType = UnitStats.DAMAGE_TYPE_BLUNT
call .stats.setDamageTypeFactors(0.90, 0.90, 1.80, 1.20, 1.00, 1.40)
//Archer
set this = .create('h017', 'h00Z')
set .stats.damageType = UnitStats.DAMAGE_TYPE_PIERCE
call .stats.setDamageTypeFactors(1.00, 1.00, 0.80, 1.20, 1.00, 1.00)
//Axe Thrower
set this = .create('h016', 'h00Y')
set .stats.damageType = UnitStats.DAMAGE_TYPE_BLUNT
call .stats.setDamageTypeFactors(1.20, 0.80, 0.80, 0.80, 1.00, 0.80)
//Rider
set this = .create('h013', 'h00W')
set .stats.damageType = UnitStats.DAMAGE_TYPE_BLUNT
call .stats.setDamageTypeFactors(0.80, 1.20, 3.00, 1.00, 1.00, 2.40)
//Warlord
set this = .create('h012', 'h011')
set .stats.damageType = UnitStats.DAMAGE_TYPE_BLUNT
call .stats.setDamageTypeFactors(0.80, 1.20, 3.00, 1.20, 1.00, 2.00)
//Tank
set this = .create('h018', 'h010')
set .stats.damageType = UnitStats.DAMAGE_TYPE_SIEGE
call .stats.setDamageTypeFactors(0.50, 0.50, 0.70, 0.00, 0.00, 2.00)
//Orc:
//Blademaster
set this = .create('h00B', 'h00N')
set .stats.damageType = UnitStats.DAMAGE_TYPE_SHARP
call .stats.setDamageTypeFactors(1.20, 1.00, 0.80, 1.00, 1.00, 1.00)
//Axemaster
set this = .create('h00C', 'h00M')
set .stats.damageType = UnitStats.DAMAGE_TYPE_BLUNT
call .stats.setDamageTypeFactors(1.20, 1.00, 0.80, 1.00, 1.00, 1.00)
//Guard
set this = .create('h00I', 'h00O')
set .stats.damageType = UnitStats.DAMAGE_TYPE_PIKE
call .stats.setDamageTypeFactors(1.20, 1.00, 0.80, 1.00, 1.00, 1.00)
//Hunter
set this = .create('h00D', 'h00S')
set .stats.damageType = UnitStats.DAMAGE_TYPE_PIERCE
call .stats.setDamageTypeFactors(1.00, 1.20, 1.00, 1.00, 0.60, 1.00)
//Warlock
set this = .create('h00G', 'h00R')
set .stats.damageType = UnitStats.DAMAGE_TYPE_MAGIC
call .stats.setDamageTypeFactors(1.00, 1.20, 1.00, 1.00, 0.60, 1.00)
//Raider
set this = .create('h00F', 'h00P')
set .stats.damageType = UnitStats.DAMAGE_TYPE_BLUNT
call .stats.setDamageTypeFactors(1.20, 1.00, 3.00, 0.80, 1.00, 1.50)
//Warchief
set this = .create('h01C', 'h01A')
set .stats.damageType = UnitStats.DAMAGE_TYPE_BLUNT
call .stats.setDamageTypeFactors(0.80, 1.20, 0.70, 1.20, 1.00, 1.80)
//Catapult
set this = .create('h00E', 'h00Q')
set .stats.damageType = UnitStats.DAMAGE_TYPE_SIEGE
call .stats.setDamageTypeFactors(2.00, 2.00, 0.50, 0.01, 0.00, 3.00)
endmethod
endstruct
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct UnitStats
readonly static constant integer DAMAGE_TYPE_SHARP = 0
readonly static constant integer DAMAGE_TYPE_BLUNT = 1
readonly static constant integer DAMAGE_TYPE_PIKE = 2
readonly static constant integer DAMAGE_TYPE_PIERCE = 3
readonly static constant integer DAMAGE_TYPE_MAGIC = 4
readonly static constant integer DAMAGE_TYPE_SIEGE = 5
public integer damageType
public real array damageTypeFactors[6]
public static method create takes nothing returns thistype
return .allocate()
endmethod
public method setDamageTypeFactors takes real r1, real r2, real r3, real r4, real r5, real r6 returns nothing
set .damageTypeFactors[0] = r1
set .damageTypeFactors[1] = r2
set .damageTypeFactors[2] = r3
set .damageTypeFactors[3] = r4
set .damageTypeFactors[4] = r5
set .damageTypeFactors[5] = r6
endmethod
endstruct
//TESH.scrollpos=139
//TESH.alwaysfold=0
//===========================================================================
// Damage Engine lets you detect, amplify, block or nullify damage. It even
// lets you detect if the damage was physical or from a spell. Just reference
// DamageEventAmount/Source/Target or the boolean IsDamageSpell, to get the
// necessary damage event data.
//
// - Detect damage: use the event "DamageEvent Equal to 1.00"
// - To change damage before it's dealt: use the event "DamageModifierEvent Equal to 1.00"
// - Detect damage after it was applied, use the event "AfterDamageEvent Equal to 1.00"
// - Detect spell damage: use the condition "IsDamageSpell Equal to True"
// - Detect zero-damage: use the event "DamageEvent Equal to 2.00" (an AfterDamageEvent will not fire for this)
//
// You can specify the DamageEventType before dealing triggered damage. To prevent an already-improbable error, I recommend running the trigger "ClearDamageEvent (Checking Conditions)" after dealing triggered damage from within a damage event:
// - Set NextDamageType = DamageTypeWhatever
// - Unit - Cause...
// - Trigger - Run ClearDamageEvent (Checking Conditions)
//
// You can modify the DamageEventAmount and the DamageEventType from a "DamageModifierEvent Equal to 1.00" trigger.
// - If the amount is modified to negative, it will count as a heal.
// - If the amount is set to 0, no damage will be dealt.
//
// If you need to reference the original in-game damage, use the variable "DamageEventPrevAmt".
//
//===========================================================================
// Programming note about "integer i" and "udg_DmgEvRecursionN": integer i
// ranges from -1 upwards. "udg_DmgEvRecursionN" ranges from 0 upwards.
// "integer i" is always 1 less than "udg_DmgEvRecursionN"
//
function DmgEvResetVars takes nothing returns nothing
local integer i = udg_DmgEvRecursionN - 2
set udg_DmgEvRecursionN = i + 1
if i >= 0 then
set udg_DamageEventPrevAmt = udg_LastDmgPrevAmount[i]
set udg_DamageEventAmount = udg_LastDmgValue[i]
set udg_DamageEventSource = udg_LastDmgSource[i]
set udg_DamageEventTarget = udg_LastDmgTarget[i]
set udg_IsDamageSpell = udg_LastDmgWasSpell[i]
set udg_DamageEventType = udg_LastDmgPrevType[i]
endif
endfunction
function CheckDamagedLifeEvent takes boolean clear returns nothing
if clear then
set udg_NextDamageOverride = false
set udg_NextDamageType = 0
endif
if udg_DmgEvTrig != null then
call DestroyTrigger(udg_DmgEvTrig)
set udg_DmgEvTrig = null
if udg_IsDamageSpell then
call SetWidgetLife(udg_DamageEventTarget, RMaxBJ(udg_LastDamageHP, 0.41))
if udg_LastDamageHP <= 0.405 then
if udg_DamageEventType < 0 then
call SetUnitExploded(udg_DamageEventTarget, true)
endif
//Kill the unit
call DisableTrigger(udg_DamageEventTrigger)
call UnitDamageTarget(udg_DamageEventSource, udg_DamageEventTarget, -999, false, false, null, DAMAGE_TYPE_UNIVERSAL, null)
call EnableTrigger(udg_DamageEventTrigger)
endif
elseif GetUnitAbilityLevel(udg_DamageEventTarget, udg_DamageBlockingAbility) > 0 then
call UnitRemoveAbility(udg_DamageEventTarget, udg_DamageBlockingAbility)
call SetWidgetLife(udg_DamageEventTarget, udg_LastDamageHP)
endif
if udg_DamageEventAmount != 0.00 and not udg_HideDamageFrom[GetUnitUserData(udg_DamageEventSource)] then
set udg_AfterDamageEvent = 0.00
set udg_AfterDamageEvent = 1.00
set udg_AfterDamageEvent = 0.00
endif
call DmgEvResetVars()
endif
endfunction
function DmgEvOnExpire takes nothing returns nothing
set udg_DmgEvStarted = false
call CheckDamagedLifeEvent(true)
endfunction
function PreCheckDamagedLifeEvent takes nothing returns boolean
call CheckDamagedLifeEvent(true)
return false
endfunction
function OnUnitDamage takes nothing returns boolean
local boolean override = udg_DamageEventOverride
local integer i = udg_DmgEvRecursionN - 1
local string s
local real prevAmount
local real life
local real prevLife
local unit u
call CheckDamagedLifeEvent(false) //in case the unit state event failed and the 0.00 second timer hasn't yet expired
if i >= 0 then
if i < 16 then
set udg_LastDmgPrevAmount[i]= udg_DamageEventPrevAmt
set udg_LastDmgValue[i] = udg_DamageEventAmount
set udg_LastDmgSource[i] = udg_DamageEventSource
set udg_LastDmgTarget[i] = udg_DamageEventTarget
set udg_LastDmgWasSpell[i] = udg_IsDamageSpell
set udg_LastDmgPrevType[i] = udg_DamageEventType
else
set s = "WARNING: Recursion error when dealing damage! Make sure when you deal damage from within a DamageEvent trigger, do it like this:\n\n"
set s = s + "Trigger - Turn off (This Trigger)\n"
set s = s + "Unit - Cause...\n"
set s = s + "Trigger - Turn on (This Trigger)"
//Delete the next couple of lines to disable the in-game recursion crash warnings
call ClearTextMessages()
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.00, 0.00, 999.00, s)
return false
endif
endif
set udg_DmgEvRecursionN = i + 2
set u = GetTriggerUnit()
set prevAmount = GetEventDamage()
set udg_DamageEventSource = GetEventDamageSource()
set udg_DamageEventAmount = prevAmount
set udg_DamageEventTarget = u
set udg_DamageEventType = udg_NextDamageType
set udg_NextDamageType = 0
set udg_DamageEventOverride = udg_NextDamageOverride
set udg_NextDamageOverride = false
if prevAmount == 0.00 then
if not udg_HideDamageFrom[GetUnitUserData(udg_DamageEventSource)] then
set udg_DamageEventPrevAmt = 0.00
set udg_DamageEvent = 0.00
set udg_DamageEvent = 2.00
set udg_DamageEvent = 0.00
endif
call DmgEvResetVars()
else
if not udg_DmgEvStarted then
set udg_DmgEvStarted = true
call TimerStart(udg_DmgEvTimer, 0.00, false, function DmgEvOnExpire)
endif
set udg_IsDamageSpell = prevAmount < 0.00
if udg_IsDamageSpell then
set prevAmount = -udg_DamageEventAmount
set life = 1.00
if IsUnitType(u, UNIT_TYPE_ETHEREAL) and not IsUnitType(u, UNIT_TYPE_HERO) then
set life = life*udg_DAMAGE_FACTOR_ETHEREAL //1.67
endif
if GetUnitAbilityLevel(u, 'Aegr') > 0 then
set life = life*udg_DAMAGE_FACTOR_ELUNES //0.80
endif
if udg_DmgEvBracers != 0 and IsUnitType(u, UNIT_TYPE_HERO) then
//Inline of UnitHasItemOfTypeBJ without the potential handle ID leak.
set i = 6
loop
set i = i - 1
if GetItemTypeId(UnitItemInSlot(u, i)) == udg_DmgEvBracers then
set life = life*udg_DAMAGE_FACTOR_BRACERS //0.67
exitwhen true
endif
exitwhen i == 0
endloop
endif
set udg_DamageEventAmount = prevAmount*life
endif
set udg_DamageEventPrevAmt = prevAmount
set udg_DamageModifierEvent = 0.00
if not udg_DamageEventOverride then
set udg_DamageModifierEvent = 1.00
if not udg_DamageEventOverride then
set udg_DamageModifierEvent = 2.00
set udg_DamageModifierEvent = 3.00
endif
endif
set udg_DamageEventOverride = override
if udg_DamageEventAmount > 0.00 then
set udg_DamageModifierEvent = 4.00
endif
set udg_DamageModifierEvent = 0.00
if not udg_HideDamageFrom[GetUnitUserData(udg_DamageEventSource)] then
set udg_DamageEvent = 0.00
set udg_DamageEvent = 1.00
set udg_DamageEvent = 0.00
endif
call CheckDamagedLifeEvent(true) //in case the unit state event failed from a recursive damage event
//All events have run and the damage amount is finalized.
set life = GetWidgetLife(u)
set udg_DmgEvTrig = CreateTrigger()
call TriggerAddCondition(udg_DmgEvTrig, Filter(function PreCheckDamagedLifeEvent))
if not udg_IsDamageSpell then
if udg_DamageEventAmount != prevAmount then
set life = life + prevAmount - udg_DamageEventAmount
if GetUnitState(u, UNIT_STATE_MAX_LIFE) < life then
set udg_LastDamageHP = life - prevAmount
call UnitAddAbility(u, udg_DamageBlockingAbility)
endif
call SetWidgetLife(u, RMaxBJ(life, 0.42))
endif
call TriggerRegisterUnitStateEvent(udg_DmgEvTrig, u, UNIT_STATE_LIFE, LESS_THAN, RMaxBJ(0.41, life - prevAmount/2.00))
else
set udg_LastDamageHP = GetUnitState(u, UNIT_STATE_MAX_LIFE)
set prevLife = life
if life + prevAmount*0.75 > udg_LastDamageHP then
set life = RMaxBJ(udg_LastDamageHP - prevAmount/2.00, 1.00)
call SetWidgetLife(u, life)
set life = (life + udg_LastDamageHP)/2.00
else
set life = life + prevAmount*0.50
endif
set udg_LastDamageHP = prevLife - (prevAmount - (prevAmount - udg_DamageEventAmount))
call TriggerRegisterUnitStateEvent(udg_DmgEvTrig, u, UNIT_STATE_LIFE, GREATER_THAN, life)
endif
set u = null
endif
return false
endfunction
function CreateDmgEvTrg takes nothing returns nothing
set udg_DamageEventTrigger = CreateTrigger()
call TriggerAddCondition(udg_DamageEventTrigger, Filter(function OnUnitDamage))
endfunction
function SetupDmgEv takes nothing returns boolean
local integer i = udg_UDex
local unit u
if udg_UnitIndexEvent == 1.00 then
set u = udg_UDexUnits[i]
if GetUnitAbilityLevel(u, 'Aloc') == 0 and TriggerEvaluate(gg_trg_Damage_Engine_Config) then
set udg_UnitDamageRegistered[i] = true
call TriggerRegisterUnitEvent(udg_DamageEventTrigger, u, EVENT_UNIT_DAMAGED)
call UnitAddAbility(u, udg_SpellDamageAbility)
call UnitMakeAbilityPermanent(u, true, udg_SpellDamageAbility)
endif
set u = null
else
set udg_HideDamageFrom[i] = false
if udg_UnitDamageRegistered[i] then
set udg_UnitDamageRegistered[i] = false
set udg_DamageEventsWasted = udg_DamageEventsWasted + 1
if udg_DamageEventsWasted == 32 then //After 32 registered units have been removed...
set udg_DamageEventsWasted = 0
//Rebuild the mass EVENT_UNIT_DAMAGED trigger:
call DestroyTrigger(udg_DamageEventTrigger)
call CreateDmgEvTrg()
set i = udg_UDexNext[0]
loop
exitwhen i == 0
if udg_UnitDamageRegistered[i] then
call TriggerRegisterUnitEvent(udg_DamageEventTrigger, udg_UDexUnits[i], EVENT_UNIT_DAMAGED)
endif
set i = udg_UDexNext[i]
endloop
endif
endif
endif
return false
endfunction
//===========================================================================
function InitTrig_Damage_Engine takes nothing returns nothing
local unit u = CreateUnit(Player(15), 'uloc', 0, 0, 0)
local integer i = 16
//Create this trigger with UnitIndexEvents in order add and remove units
//as they are created or removed.
local trigger t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 1.00)
call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 2.00)
call TriggerAddCondition(t, Filter(function SetupDmgEv))
set t = null
//Run the configuration trigger to set all configurables:
if gg_trg_Damage_Engine_Config == null then
//It's possible this InitTrig_ function ran first, in which case use ExecuteFunc.
call ExecuteFunc("Trig_Damage_Engine_Config_Actions")
else
call TriggerExecute(gg_trg_Damage_Engine_Config)
endif
//Create trigger for storing all EVENT_UNIT_DAMAGED events.
call CreateDmgEvTrg()
//Create GUI-friendly trigger for cleaning up after UnitDamageTarget.
set udg_ClearDamageEvent = CreateTrigger()
call TriggerAddCondition(udg_ClearDamageEvent, Filter(function PreCheckDamagedLifeEvent))
//Disable SpellDamageAbility for every player.
loop
set i = i - 1
call SetPlayerAbilityAvailable(Player(i), udg_SpellDamageAbility, false)
exitwhen i == 0
endloop
//Preload abilities.
call UnitAddAbility(u, udg_DamageBlockingAbility)
call UnitAddAbility(u, udg_SpellDamageAbility)
call RemoveUnit(u)
set u = null
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function ApplyAttackTypeBonus takes nothing returns nothing
if not udg_IsDamageSpell then
set udg_DamageEventAmount = udg_DamageEventAmount * UnitType.cast(udg_DamageEventTarget).stats.damageTypeFactors[UnitType.cast(udg_DamageEventSource).stats.damageType]
//debug call Debug.message("Damage multiplied by " + R2S(UnitType.cast(udg_DamageEventTarget).stats.damageTypeFactors[UnitType.cast(udg_DamageEventSource).stats.damageType]))
endif
endfunction
//===========================================================================
function InitTrig_Apply_Attack_Type_Bonus takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_DamageModifierEvent", EQUAL, 0)
call TriggerAddAction(t, function ApplyAttackTypeBonus)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Test_Actions takes nothing returns nothing
call SetPlayerAlliance(Player(1), Player(0), ALLIANCE_SHARED_CONTROL, true)
call SetPlayerAlliance(Player(1), Player(0), ALLIANCE_SHARED_ADVANCED_CONTROL, true)
call SetPlayerAlliance(Player(2), Player(0), ALLIANCE_SHARED_CONTROL, true)
call SetPlayerAlliance(Player(2), Player(0), ALLIANCE_SHARED_ADVANCED_CONTROL, true)
call SetPlayerAlliance(Player(3), Player(0), ALLIANCE_SHARED_CONTROL, true)
call SetPlayerAlliance(Player(3), Player(0), ALLIANCE_SHARED_ADVANCED_CONTROL, true)
endfunction
//===========================================================================
function InitTrig_Test takes nothing returns nothing
set gg_trg_Test = CreateTrigger( )
call TriggerAddAction( gg_trg_Test, function Trig_Test_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct Order extends array
readonly static constant integer OFFSET = 851970
readonly static constant integer ABSORB = 852529
readonly static constant integer ACIDBOMB = 852662
readonly static constant integer ACOLYTEHARVEST = 852185
readonly static constant integer AIMOVE = 851988
readonly static constant integer AMBUSH = 852131
readonly static constant integer ANCESTRALSPIRIT = 852490
readonly static constant integer ANCESTRALSPIRITTARGET = 852491
readonly static constant integer ANIMATEDEAD = 852217
readonly static constant integer ANTIMAGICSHELL = 852186
readonly static constant integer ATTACK = 851983
readonly static constant integer ATTACKGROUND = 851984
readonly static constant integer ATTACKONCE = 851985
readonly static constant integer ATTRIBUTEMODSKILL = 852576
readonly static constant integer AURAUNHOLY = 852215
readonly static constant integer AURAVAMPIRIC = 852216
readonly static constant integer AUTODISPEL = 852132
readonly static constant integer AUTODISPELOFF = 852134
readonly static constant integer AUTODISPELON = 852133
readonly static constant integer AUTOENTANGLE = 852505
readonly static constant integer AUTOENTANGLEINSTANT = 852506
readonly static constant integer AUTOHARVESTGOLD = 852021
readonly static constant integer AUTOHARVESTLUMBER = 852022
readonly static constant integer AVATAR = 852086
readonly static constant integer AVENGERFORM = 852531
readonly static constant integer AWAKEN = 852466
readonly static constant integer BANISH = 852486
readonly static constant integer BARKSKIN = 852135
readonly static constant integer BARKSKINOFF = 852137
readonly static constant integer BARKSKINON = 852136
readonly static constant integer BATTLEROAR = 852099
readonly static constant integer BATTLESTATIONS = 852099
readonly static constant integer BEARFORM = 852138
readonly static constant integer BERSERK = 852100
readonly static constant integer BLACKARROW = 852577
readonly static constant integer BLACKARROWOFF = 852579
readonly static constant integer BLACKARROWON = 852578
readonly static constant integer BLIGHT = 852187
readonly static constant integer BLINK = 852525
readonly static constant integer BLIZZARD = 852089
readonly static constant integer BLOODLUST = 852101
readonly static constant integer BLOODLUSTOFF = 852103
readonly static constant integer BLOODLUSTON = 852102
readonly static constant integer BOARD = 852043
readonly static constant integer BREATHOFFIRE = 852580
readonly static constant integer BREATHOFFROST = 852560
readonly static constant integer BUILD = 851994
readonly static constant integer BURROW = 852533
readonly static constant integer CANNIBALIZE = 852188
readonly static constant integer CARRIONSCARABS = 852551
readonly static constant integer CARRIONSCARABSINSTANT = 852554
readonly static constant integer CARRIONSCARABSOFF = 852553
readonly static constant integer CARRIONSCARABSON = 852552
readonly static constant integer CARRIONSWARM = 852218
readonly static constant integer CHAINLIGHTNING = 852119
readonly static constant integer CHANNEL = 852600
readonly static constant integer CHARM = 852581
readonly static constant integer CHEMICALRAGE = 852663
readonly static constant integer CLOUDOFFOG = 852473
readonly static constant integer CLUSTERROCKETS = 852652
readonly static constant integer COLDARROWS = 852244
readonly static constant integer COLDARROWSTARG = 852243
readonly static constant integer CONTROLMAGIC = 852474
readonly static constant integer CORPOREALFORM = 852493
readonly static constant integer CORROSIVEBREATH = 852140
readonly static constant integer COUPLEINSTANT = 852508
readonly static constant integer COUPLETARGET = 852507
readonly static constant integer CREEPANIMATEDEAD = 852246
readonly static constant integer CREEPDEVOUR = 852247
readonly static constant integer CREEPHEAL = 852248
readonly static constant integer CREEPHEALOFF = 852250
readonly static constant integer CREEPHEALON = 852249
readonly static constant integer CREEPTHUNDERBOLT = 852252
readonly static constant integer CREEPTHUNDERCLAP = 852253
readonly static constant integer CRIPPLE = 852189
readonly static constant integer CURSE = 852190
readonly static constant integer CURSEOFF = 852192
readonly static constant integer CURSEON = 852191
readonly static constant integer CYCLONE = 852144
readonly static constant integer DARKCONVERSION = 852228
readonly static constant integer DARKPORTAL = 852229
readonly static constant integer DARKRITUAL = 852219
readonly static constant integer DARKSUMMONING = 852220
readonly static constant integer DEATHANDDECAY = 852221
readonly static constant integer DEATHCOIL = 852222
readonly static constant integer DEATHPACT = 852223
readonly static constant integer DECOUPLE = 852509
readonly static constant integer DEFEND = 852055
readonly static constant integer DETECTAOE = 852015
readonly static constant integer DETONATE = 852145
readonly static constant integer DEVOUR = 852104
readonly static constant integer DEVOURMAGIC = 852536
readonly static constant integer DISASSOCIATE = 852240
readonly static constant integer DISENCHANT = 852495
readonly static constant integer DISMOUNT = 852470
readonly static constant integer DISPEL = 852057
readonly static constant integer DIVINESHIELD = 852090
readonly static constant integer DOOM = 852583
readonly static constant integer DRAIN = 852487
readonly static constant integer DREADLORDINFERNO = 852224
readonly static constant integer DROPITEM = 852001
readonly static constant integer DRUNKENHAZE = 852585
readonly static constant integer EARTHQUAKE = 852121
readonly static constant integer EATTREE = 852146
readonly static constant integer ELEMENTALFURY = 852586
readonly static constant integer ENSNARE = 852106
readonly static constant integer ENSNAREOFF = 852108
readonly static constant integer ENSNAREON = 852107
readonly static constant integer ENTANGLE = 852147
readonly static constant integer ENTANGLEINSTANT = 852148
readonly static constant integer ENTANGLINGROOTS = 852171
readonly static constant integer ETHEREALFORM = 852496
readonly static constant integer EVILEYE = 852105
readonly static constant integer FAERIEFIRE = 852149
readonly static constant integer FAERIEFIREOFF = 852151
readonly static constant integer FAERIEFIREON = 852150
readonly static constant integer FANOFKNIVES = 852526
readonly static constant integer FARSIGHT = 852122
readonly static constant integer FINGEROFDEATH = 852230
readonly static constant integer FIREBOLT = 852231
readonly static constant integer FLAMESTRIKE = 852488
readonly static constant integer FLAMINGARROWS = 852174
readonly static constant integer FLAMINGARROWSTARG = 852173
readonly static constant integer FLAMINGATTACK = 852540
readonly static constant integer FLAMINGATTACKTARG = 852539
readonly static constant integer FLARE = 852060
readonly static constant integer FORCEBOARD = 852044
readonly static constant integer FORCEOFNATURE = 852176
readonly static constant integer FORKEDLIGHTNING = 852586
readonly static constant integer FREEZINGBREATH = 852195
readonly static constant integer FRENZY = 852561
readonly static constant integer FRENZYOFF = 852563
readonly static constant integer FRENZYON = 852562
readonly static constant integer FROSTARMOR = 852225
readonly static constant integer FROSTARMOROFF = 852459
readonly static constant integer FROSTARMORON = 852458
readonly static constant integer FROSTNOVA = 852226
readonly static constant integer GETITEM = 851981
readonly static constant integer GOLD2LUMBER = 852233
readonly static constant integer GRABTREE = 852511
readonly static constant integer HARVEST = 852018
readonly static constant integer HEAL = 852063
readonly static constant integer HEALINGSPRAY = 852664
readonly static constant integer HEALINGWARD = 852109
readonly static constant integer HEALINGWAVE = 852501
readonly static constant integer HEALOFF = 852065
readonly static constant integer HEALON = 852064
readonly static constant integer HEX = 852502
readonly static constant integer HOLDPOSITION = 851993
readonly static constant integer HOLYBOLT = 852092
readonly static constant integer HOWLOFTERROR = 852588
readonly static constant integer HUMANBUILD = 851995
readonly static constant integer IMMOLATION = 852177
readonly static constant integer IMPALE = 852555
readonly static constant integer INCINERATEARROW = 852670
readonly static constant integer INCINERATEARROWOFF = 852672
readonly static constant integer INCINERATEARROWON = 852671
readonly static constant integer INFERNO = 852232
readonly static constant integer INNERFIRE = 852066
readonly static constant integer INNERFIREOFF = 852068
readonly static constant integer INNERFIREON = 852067
readonly static constant integer INSTANT = 852200
readonly static constant integer INVISIBILITY = 852069
readonly static constant integer LAVAMONSTER = 852667
readonly static constant integer LIGHTNINGSHIELD = 852110
readonly static constant integer LOAD = 852046
readonly static constant integer LOADARCHER = 852142
readonly static constant integer LOADCORPSE = 852050
readonly static constant integer LOADCORPSEINSTANT = 852053
readonly static constant integer LOCUSTSWARM = 852556
readonly static constant integer LUMBER2GOLD = 852234
readonly static constant integer MAGICDEFENSE = 852478
readonly static constant integer MAGICLEASH = 852480
readonly static constant integer MAGICUNDEFENSE = 852479
readonly static constant integer MANABURN = 852179
readonly static constant integer MANAFLAREOFF = 852513
readonly static constant integer MANAFLAREON = 852512
readonly static constant integer MANASHIELDOFF = 852590
readonly static constant integer MANASHIELDON = 852589
readonly static constant integer MASSTELEPORT = 852093
readonly static constant integer MECHANICALCRITTER = 852564
readonly static constant integer METAMORPHOSIS = 852180
readonly static constant integer MILITIA = 852072
readonly static constant integer MILITIACONVERT = 852071
readonly static constant integer MILITIAOFF = 852073
readonly static constant integer MILITIAUNCONVERT = 852651
readonly static constant integer MINDROT = 852565
readonly static constant integer MIRRORIMAGE = 852123
readonly static constant integer MONSOON = 852591
readonly static constant integer MOUNT = 852469
readonly static constant integer MOUNTHIPPOGRYPH = 852143
readonly static constant integer MOVE = 851986
readonly static constant integer NAGABUILD = 852467
readonly static constant integer NEUTRALDETECTAOE = 852023
readonly static constant integer NEUTRALINTERACT = 852566
readonly static constant integer NEUTRALSPELL = 852630
readonly static constant integer NIGHTELFBUILD = 851997
readonly static constant integer ORCBUILD = 851996
readonly static constant integer PARASITE = 852601
readonly static constant integer PARASITEOFF = 852603
readonly static constant integer PARASITEON = 852602
readonly static constant integer PATROL = 851990
readonly static constant integer PHASESHIFT = 852514
readonly static constant integer PHASESHIFTINSTANT = 852517
readonly static constant integer PHASESHIFTOFF = 852516
readonly static constant integer PHASESHIFTON = 852515
readonly static constant integer PHOENIXFIRE = 852481
readonly static constant integer PHOENIXMORPH = 852482
readonly static constant integer POISONARROWS = 852255
readonly static constant integer POISONARROWSTARG = 852254
readonly static constant integer POLYMORPH = 852074
readonly static constant integer POSSESSION = 852196
readonly static constant integer PRESERVATION = 852568
readonly static constant integer PURGE = 852111
readonly static constant integer RAINOFCHAOS = 852237
readonly static constant integer RAINOFFIRE = 852238
readonly static constant integer RAISEDEAD = 852197
readonly static constant integer RAISEDEADOFF = 852199
readonly static constant integer RAISEDEADON = 852198
readonly static constant integer RAVENFORM = 852155
readonly static constant integer RECHARGE = 852157
readonly static constant integer RECHARGEOFF = 852159
readonly static constant integer RECHARGEON = 852158
readonly static constant integer REJUVINATION = 852160
readonly static constant integer RENEW = 852161
readonly static constant integer RENEWOFF = 852163
readonly static constant integer RENEWON = 852162
readonly static constant integer REPAIR = 852024
readonly static constant integer REPAIROFF = 852026
readonly static constant integer REPAIRON = 852025
readonly static constant integer REPLENISH = 852542
readonly static constant integer REPLENISHLIFE = 852545
readonly static constant integer REPLENISHLIFEOFF = 852547
readonly static constant integer REPLENISHLIFEON = 852546
readonly static constant integer REPLENISHMANA = 852548
readonly static constant integer REPLENISHMANAOFF = 852550
readonly static constant integer REPLENISHMANAON = 852549
readonly static constant integer REPLENISHOFF = 852544
readonly static constant integer REPLENISHON = 852543
readonly static constant integer REQUEST_HERO = 852239
readonly static constant integer REQUESTSACRIFICE = 852201
readonly static constant integer RESTORATION = 852202
readonly static constant integer RESTORATIONOFF = 852204
readonly static constant integer RESTORATIONON = 852203
readonly static constant integer RESUMEBUILD = 851999
readonly static constant integer RESUMEHARVESTING = 852017
readonly static constant integer RESURRECTION = 852094
readonly static constant integer RETURNRESOURCES = 852020
readonly static constant integer REVENGE = 852241
readonly static constant integer REVIVE = 852039
readonly static constant integer ROAR = 852164
readonly static constant integer ROBOGOBLIN = 852656
readonly static constant integer ROOT = 852165
readonly static constant integer SACRIFICE = 852205
readonly static constant integer SANCTUARY = 852569
readonly static constant integer SCOUT = 852181
readonly static constant integer SELFDESTRUCT = 852040
readonly static constant integer SELFDESTRUCTOFF = 852042
readonly static constant integer SELFDESTRUCTON = 852041
readonly static constant integer SENTINEL = 852182
readonly static constant integer SETRALLY = 851980
readonly static constant integer SHADOWSIGHT = 852570
readonly static constant integer SHADOWSTRIKE = 852527
readonly static constant integer SHOCKWAVE = 852125
readonly static constant integer SILENCE = 852592
readonly static constant integer SLEEP = 852227
readonly static constant integer SLOW = 852075
readonly static constant integer SLOWOFF = 852077
readonly static constant integer SLOWON = 852076
readonly static constant integer SMART = 851971
readonly static constant integer SOULBURN = 852668
readonly static constant integer SOULPRESERVATION = 852242
readonly static constant integer SPELLSHIELD = 852571
readonly static constant integer SPELLSHIELDAOE = 852572
readonly static constant integer SPELLSTEAL = 852483
readonly static constant integer SPELLSTEALOFF = 852485
readonly static constant integer SPELLSTEALON = 852484
readonly static constant integer SPIES = 852235
readonly static constant integer SPIRITLINK = 852499
readonly static constant integer SPIRITOFVENGEANCE = 852528
readonly static constant integer SPIRITTROLL = 852573
readonly static constant integer SPIRITWOLF = 852126
readonly static constant integer STAMPEDE = 852593
readonly static constant integer STANDDOWN = 852113
readonly static constant integer STARFALL = 852183
readonly static constant integer STASISTRAP = 852114
readonly static constant integer STEAL = 852574
readonly static constant integer STOMP = 852127
readonly static constant integer STONEFORM = 852206
readonly static constant integer STOP = 851972
readonly static constant integer SUBMERGE = 852604
readonly static constant integer SUMMONFACTORY = 852658
readonly static constant integer SUMMONGRIZZLY = 852594
readonly static constant integer SUMMONPHOENIX = 852489
readonly static constant integer SUMMONQUILLBEAST = 852595
readonly static constant integer SUMMONWAREAGLE = 852596
readonly static constant integer TANKDROPPILOT = 852079
readonly static constant integer TANKLOADPILOT = 852080
readonly static constant integer TANKPILOT = 852081
readonly static constant integer TAUNT = 852520
readonly static constant integer THUNDERBOLT = 852095
readonly static constant integer THUNDERCLAP = 852096
readonly static constant integer TORNADO = 852597
readonly static constant integer TOWNBELLOFF = 852083
readonly static constant integer TOWNBELLON = 852082
readonly static constant integer TRANQUILITY = 852184
readonly static constant integer TRANSMUTE = 852665
readonly static constant integer UNAVATAR = 852087
readonly static constant integer UNAVENGERFORM = 852532
readonly static constant integer UNBEARFORM = 852139
readonly static constant integer UNBURROW = 852534
readonly static constant integer UNCOLDARROWS = 852245
readonly static constant integer UNCORPOREALFORM = 852494
readonly static constant integer UNDEADBUILD = 851998
readonly static constant integer UNDEFEND = 852056
readonly static constant integer UNDIVINESHIELD = 852091
readonly static constant integer UNETHEREALFORM = 852497
readonly static constant integer UNFLAMINGARROWS = 852175
readonly static constant integer UNFLAMINGATTACK = 852541
readonly static constant integer UNHOLYFRENZY = 852209
readonly static constant integer UNIMMOLATION = 852178
readonly static constant integer UNLOAD = 852047
readonly static constant integer UNLOADALL = 852048
readonly static constant integer UNLOADALLCORPSES = 852054
readonly static constant integer UNLOADALLINSTANT = 852049
readonly static constant integer UNPOISONARROWS = 852256
readonly static constant integer UNRAVENFORM = 852156
readonly static constant integer UNROBOGOBLIN = 852657
readonly static constant integer UNROOT = 852166
readonly static constant integer UNSTABLECONCOCTION = 852500
readonly static constant integer UNSTONEFORM = 852207
readonly static constant integer UNSUBMERGE = 852605
readonly static constant integer UNSUMMON = 852210
readonly static constant integer UNWINDWALK = 852130
readonly static constant integer VENGEANCE = 852521
readonly static constant integer VENGEANCEINSTANT = 852524
readonly static constant integer VENGEANCEOFF = 852523
readonly static constant integer VENGEANCEON = 852522
readonly static constant integer VOLCANO = 852669
readonly static constant integer VOODOO = 852503
readonly static constant integer WARD = 852504
readonly static constant integer WATERELEMENTAL = 852097
readonly static constant integer WATERYMINION = 852598
readonly static constant integer WEB = 852211
readonly static constant integer WEBOFF = 852213
readonly static constant integer WEBON = 852212
readonly static constant integer WHIRLWIND = 852128
readonly static constant integer WINDWALK = 852129
readonly static constant integer WISPHARVEST = 852214
readonly static constant integer SCROLLOFSPEED = 852285
readonly static constant integer CANCEL = 851976
readonly static constant integer MOVESLOT1 = 852002
readonly static constant integer MOVESLOT2 = 852003
readonly static constant integer MOVESLOT3 = 852004
readonly static constant integer MOVESLOT4 = 852005
readonly static constant integer MOVESLOT5 = 852006
readonly static constant integer MOVESLOT6 = 852007
readonly static constant integer USESLOT1 = 852008
readonly static constant integer USESLOT2 = 852009
readonly static constant integer USESLOT3 = 852010
readonly static constant integer USESLOT4 = 852011
readonly static constant integer USESLOT5 = 852012
readonly static constant integer USESLOT6 = 852013
readonly static constant integer SKILLMENU = 852000
readonly static constant integer STUNNED = 851973
readonly static constant integer INSTANT1 = 851991
readonly static constant integer INSTANT2 = 851987
readonly static constant integer INSTANT3 = 851975
readonly static constant integer INSTANT4 = 852019
private static method create takes nothing returns thistype
return 0
endmethod
public static constant method getIssuedOrderId takes nothing returns integer
return GetIssuedOrderId()
endmethod
public static constant method getOrderedUnit takes nothing returns unit
return GetOrderedUnit()
endmethod
public static constant method getOrderPointX takes nothing returns real
return GetOrderPointX()
endmethod
public static constant method getOrderPointY takes nothing returns real
return GetOrderPointY()
endmethod
public static constant method getOrderTarget takes nothing returns widget
return GetOrderTarget()
endmethod
public static constant method getOrderTargetDestructable takes nothing returns destructable
return GetOrderTargetDestructable()
endmethod
public static constant method getOrderTargetItem takes nothing returns item
return GetOrderTargetItem()
endmethod
public static constant method getOrderTargetUnit takes nothing returns unit
return GetOrderTargetUnit()
endmethod
endstruct
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct StringArray
private static integer array freeStackOffset
private static integer array freeStackLength
private static string array data
private integer offset
readonly integer length
public static method create takes integer length returns thistype
local thistype this = .allocate()
set .length = length
return this
endmethod
public method get takes integer index returns string
return .data[.offset + index]
endmethod
public method destroy takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= .length
set .data[i] = ""
set i = i +1
endloop
call .deallocate()
endmethod
endstruct
//TESH.scrollpos=51
//TESH.alwaysfold=0
globals
constant integer OUTLAW = 'h00J'
constant integer SPEARMAN = 'h00L'
constant integer FOOTMAN = 'h002'
constant integer LONGBOWMAN = 'h004'
constant integer ARCHMAGE = 'h00A'
constant integer LIGHTCAVALRY = 'h006'
constant integer CAPTAIN = 'h01B'
constant integer CATAPULT = 'h008'
constant integer BLADEMASTER = 'h00N'
constant integer AXEMASTER = 'h00M'
constant integer GUARD = 'h00O'
constant integer HUNTER = 'h00S'
constant integer WARLOCK = 'h00R'
constant integer RAIDER = 'h00P'
constant integer WARCHIEF = 'h01A'
constant integer CATAPULT2 = 'h008'
constant integer SHIELDBREAKER = 'h00U'
constant integer PHALANX = 'h00V'
constant integer OGRE = 'h00X'
constant integer ARCHER = 'h00Z'
constant integer AXETHROWER = 'h00Y'
constant integer RIDER = 'h00W'
constant integer WARLORD = 'h011'
constant integer TANK = 'h010'
endglobals
function Trig_Test_Unit_Strength_Actions takes nothing returns nothing
local group g = CreateGroup()
local unit FoG
local real x
local real y
local integer array unitId
local integer array unitCount
local integer max
local integer i1
local integer i2
local integer s = 6
//Remove all units on the map:
call GroupEnumUnitsInRange(g, 0, 0, 99999, null)
loop
set FoG = FirstOfGroup(g)
exitwhen FoG == null
call GroupRemoveUnit(g, FoG)
call RemoveUnit(FoG)
endloop
call DestroyGroup(g)
set g = null
//Create units
set x = GetRectCenterX(gg_rct_Player_1_Start)
set y = GetRectCenterY(gg_rct_Player_1_Start)
set max = 2
set unitId[0] = OUTLAW
set unitCount[0] = 1*s
set unitId[1] = CAPTAIN
set unitCount[1] = 1
set i2 = 0
loop
exitwhen i2 >= max
set i1 = 0
loop
exitwhen i1 >= unitCount[i2]
call CreateUnit(Player(0), unitId[i2], x, y, 0)
set i1 = i1 +1
endloop
set i2 = i2 +1
endloop
set x = GetRectCenterX(gg_rct_Player_2_Start)
set y = GetRectCenterY(gg_rct_Player_2_Start)
set max = 2
set unitId[0] = OUTLAW
set unitCount[0] = 1*s
set unitId[1] = WARCHIEF
set unitCount[1] = 1
set i2 = 0
loop
exitwhen i2 >= max
set i1 = 0
loop
exitwhen i1 >= unitCount[i2]
call CreateUnit(Player(1), unitId[i2], x, y, 0)
set i1 = i1 +1
endloop
set i2 = i2 +1
endloop
endfunction
//===========================================================================
function InitTrig_Test_Unit_Strength takes nothing returns nothing
set gg_trg_Test_Unit_Strength = CreateTrigger( )
call TriggerRegisterPlayerEventEndCinematic( gg_trg_Test_Unit_Strength, Player(0) )
call TriggerAddAction( gg_trg_Test_Unit_Strength, function Trig_Test_Unit_Strength_Actions )
endfunction