Name | Type | is_array | initial_value |
function Skill_Paladin takes unit u, integer level returns nothing
// HOLY LIGHT
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AHhb' )
// DEVOTION AURA
elseif (level == 2 or level == 4 or level == 8) then
call SelectHeroSkill( u, 'AHad' )
// DIVINE SHIELD
elseif (level == 7 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AHds' )
// RESURRECTION
elseif (level == 6) then
call SelectHeroSkill( u, 'AHre' )
endif
endfunction
function Skill_Archmage takes unit u, integer level returns nothing
// WATER ELEMENTAL
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AHwe' )
// BRILLIANCE AURA
elseif (level == 2 or level == 4 or level == 8) then
call SelectHeroSkill( u, 'AHbz' )
// BLIZZARD
elseif (level == 7 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AHab' )
// MASS TELEPORT
elseif (level == 6) then
call SelectHeroSkill( u, 'AHmt' )
endif
endfunction
function Skill_MountainKing takes unit u, integer level returns nothing
// STORM BOLT
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AHtb' )
// BASH
elseif (level == 2 or level == 4 or level == 8) then
call SelectHeroSkill( u, 'AHbh' )
// THUNDER CLAP
elseif (level == 7 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AHtc' )
// AVATAR
elseif (level == 6) then
call SelectHeroSkill( u, 'AHav' )
endif
endfunction
function Skill_Bloodmage takes unit u, integer level returns nothing
// FLAME STRIKE
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AHfs' )
// SIPHON MANA
elseif (level == 2 or level == 4 or level == 8) then
call SelectHeroSkill( u, 'AHdr' )
// BANISH
elseif (level == 7 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AHbn' )
// PHOENIX
elseif (level == 6) then
call SelectHeroSkill( u, 'AHpx' )
endif
endfunction
function Skill_Blademaster takes unit u, integer level returns nothing
// WINDWALK
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AOwk' )
// CRITICAL STRIKE
elseif (level == 2 or level == 4 or level == 8) then
call SelectHeroSkill( u, 'AOcr' )
// MIRROR IMAGE
elseif (level == 7 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AOmi' )
// BLADESTORM
elseif (level == 6) then
call SelectHeroSkill( u, 'AOww' )
endif
endfunction
function Skill_Farseer takes unit u, integer level returns nothing
// FERAL SPIRIT
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AOsf' )
// CHAIN LIGHTNING
elseif (level == 2 or level == 4 or level == 7) then
call SelectHeroSkill( u, 'AOcl' )
// FAR SIGHT
elseif (level == 8 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AOfs' )
// EARTHQUAKE
elseif (level == 6) then
call SelectHeroSkill( u, 'AOeq' )
endif
endfunction
function Skill_Chieftain takes unit u, integer level returns nothing
// WARSTOMP
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AOws' )
// ENDURENCE AURA
elseif (level == 2 or level == 4 or level == 8) then
call SelectHeroSkill( u, 'AOae' )
// SHOCKWAVE
elseif (level == 7 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AOsh' )
// REINCARNATION
elseif (level == 6) then
call SelectHeroSkill( u, 'AOre' )
endif
endfunction
function Skill_ShadowHunter takes unit u, integer level returns nothing
// HEALING WAVE
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AOhw' )
// HEX
elseif (level == 2 or level == 4 or level == 8) then
call SelectHeroSkill( u, 'AOhx' )
// SERPENT WARD
elseif (level == 7 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AOsw' )
// BIG BAD VODOO
elseif (level == 6) then
call SelectHeroSkill( u, 'AOvd' )
endif
endfunction
function Skill_DeathKnight takes unit u, integer level returns nothing
// DEATH COIL
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AUdc' )
// UNHOLY AURA
elseif (level == 2 or level == 4 or level == 7) then
call SelectHeroSkill( u, 'AUau' )
// DEATH PACT
elseif (level == 8 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AUdp' )
// ANIMATE DEAD
elseif (level == 6) then
call SelectHeroSkill( u, 'AUan' )
endif
endfunction
function Skill_Lich takes unit u, integer level returns nothing
// FROST NOVA
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AUfn' )
// DARK RITUAL
elseif (level == 2 or level == 4 or level == 8) then
call SelectHeroSkill( u, 'AUdr' )
// FROST ARMOR
elseif (level == 7 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AUfu' )
// DEATH AND DECAY
elseif (level == 6) then
call SelectHeroSkill( u, 'AUdd' )
endif
endfunction
function Skill_Dreadlord takes unit u, integer level returns nothing
// CARRION SWARM
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AUcs' )
// VAMPIRIC AURA
elseif (level == 2 or level == 4 or level == 8) then
call SelectHeroSkill( u, 'AUav' )
// SLEEP
elseif (level == 7 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AUsl' )
// INFERNO
elseif (level == 6) then
call SelectHeroSkill( u, 'AUin' )
endif
endfunction
function Skill_CryptLord takes unit u, integer level returns nothing
// CARRION BEETLES
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AUcb' )
// SPIKED CARAPACE
elseif (level == 2 or level == 4 or level == 8) then
call SelectHeroSkill( u, 'AUts' )
// IMPALE
elseif (level == 7 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AUim' )
// LOCUST SWARM
elseif (level == 6) then
call SelectHeroSkill( u, 'AUls' )
endif
endfunction
function Skill_Priestress takes unit u, integer level returns nothing
// SEARING ARROW
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AEfa' )
// TRUESHOT AURA
elseif (level == 2 or level == 4 or level == 7) then
call SelectHeroSkill( u, 'AEar' )
// SCOUT
elseif (level == 8 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AEst' )
// STARFALL
elseif (level == 6) then
call SelectHeroSkill( u, 'AEsf' )
endif
endfunction
function Skill_Keeper takes unit u, integer level returns nothing
// FORCE OF NATURE
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AEfn' )
// ENTANGLING ROOTS
elseif (level == 2 or level == 4 or level == 7) then
call SelectHeroSkill( u, 'AEer' )
// THORNS AURA
elseif (level == 8 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AEah' )
// TRANQUILITY
elseif (level == 6) then
call SelectHeroSkill( u, 'AEtq' )
endif
endfunction
function Skill_DemonHunter takes unit u, integer level returns nothing
// MANA BURN
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AEmb' )
// EVASION
elseif (level == 2 or level == 4 or level == 7) then
call SelectHeroSkill( u, 'AEev' )
// IMMOLATION
elseif (level == 8 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AEim' )
// METAMORPHOSIS
elseif (level == 6) then
call SelectHeroSkill( u, 'AEme' )
endif
endfunction
function Skill_Warden takes unit u, integer level returns nothing
// SHADOW STRIKE
if (level == 1 or level == 3 or level == 5) then
call SelectHeroSkill( u, 'AEsh' )
// BLINK
elseif (level == 2 or level == 4 or level == 8) then
call SelectHeroSkill( u, 'AEbl' )
// FAN OF KNIVES
elseif (level == 7 or level == 9 or level == 10) then
call SelectHeroSkill( u, 'AEfk' )
// VENGEANCE
elseif (level == 6) then
call SelectHeroSkill( u, 'AEsv' )
endif
endfunction
////////////////////////////////////////////////////////////////////////////////////////
//
// Find hero and level
//
////////////////////////////////////////////////////////////////////////////////////////
function Trig_Choose_Hero_Spell_Actions takes unit u returns nothing
local integer level
set level = GetHeroLevel(u)
//////////////////////////////
// HUMAN
if (GetUnitRace(u) == RACE_HUMAN) then
//////////////////////////////
// PALADIN
if (GetUnitTypeId(u) == 'Hpal' ) then
call Skill_Paladin(u, level)
// ARCHMAGE
elseif (GetUnitTypeId(u) == 'Hamg' ) then
call Skill_Archmage(u, level)
// MOUNTAIN KING
elseif (GetUnitTypeId(u) == 'Hmkg' ) then
call Skill_MountainKing(u, level)
// BLOODMAGE
elseif (GetUnitTypeId(u) == 'Hblm' ) then
call Skill_Bloodmage(u, level)
endif
//////////////////////////////
// ORC
elseif (GetUnitRace(u) == RACE_ORC) then
//////////////////////////////
// BLADEMASTER
if (GetUnitTypeId(u) == 'Obla' ) then
call Skill_Blademaster(u, level)
// FARSEER
elseif (GetUnitTypeId(u) == 'Ofar' ) then
call Skill_Farseer(u, level)
// TAUREN CHIEFTAIN
elseif (GetUnitTypeId(u) == 'Otch' ) then
call Skill_Chieftain(u, level)
// SHADOW HUNTER
elseif (GetUnitTypeId(u) == 'Oshd' ) then
call Skill_ShadowHunter(u, level)
endif
//////////////////////////////
// UNDEAD
elseif (GetUnitRace(u) == RACE_UNDEAD) then
//////////////////////////////
// DEATH KNIGHT
if (GetUnitTypeId(u) == 'Udea' ) then
call Skill_DeathKnight(u, level)
// LICH
elseif (GetUnitTypeId(u) == 'Ulic' ) then
call Skill_Lich(u, level)
// DREADLORD
elseif (GetUnitTypeId(u) == 'Udre' ) then
call Skill_Dreadlord(u, level)
// CRYPT LORD
elseif (GetUnitTypeId(u) == 'Ucrl' ) then
call Skill_CryptLord(u, level)
endif
//////////////////////////////
// NIGHT ELF
elseif (GetUnitRace(u) == RACE_NIGHTELF) then
//////////////////////////////
// KEEPER OF THE GROVE
if (GetUnitTypeId(u) == 'Ekee' ) then
call Skill_Keeper(u, level)
// PRIESTRESS OF THE M
elseif (GetUnitTypeId(u) == 'Emoo' ) then
call Skill_Priestress(u, level)
// DEMON HUNTER
elseif (GetUnitTypeId(u) == 'Edem' ) then
call Skill_DemonHunter(u, level)
// WARDEN
elseif (GetUnitTypeId(u) == 'Ewar' ) then
call Skill_Warden(u, level)
endif
//////////////////////////////
endif
endfunction
//===========================================================================
//function InitTrig_Choose_Hero_Spell takes nothing returns nothing
// set gg_trg_Choose_Hero_Spell = CreateTrigger( )
// call TriggerAddAction( gg_trg_Choose_Hero_Spell, function Trig_Choose_Hero_Spell_Actions )
//endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
//==============================================================================
// Custom Race System by Archmage Owenalacaster
//==============================================================================
//
// Purpose:
// - Creates the starting units for custom races and replaces the standard
// Melee Initialization trigger. Custom races are selected by race and
// handicap.
//
// Usage:
// - Register a new custom race with CustomRace.create(name, RACE, handicap)
// Handicaps: Valid handicap values are 1.0, 0.9, 0.8, 0.7, 0.6 and 0.5.
// - Register a new custom race for all handicaps of a single race with
// CustomRace.createAll(name, RACE)
// - Extend the registration of a race with c.register(RACE, handicap)
// - Set the townhall type with c.setTownHall(unitid)
// - Add a new worker type with c.addWorkerType(unitid, priority, qty)
// Priorities: c.NEAR_MINE spawns workers near the mine, where workers
// typically spawn.
// c.NEAR_HALL spawns workers near the town hall, where
// Ghouls spawn.
// - Add a random hero type with c.addHeroType(unitid)
// - Set the ai script used by computer players with c.setAIScript(stringpath)
// - Set a callback function with c.setCallback(CustomRaceCall.function)
// Callbacks: The callback is executed after all the starting units for a
// player are created, and its purpose is to provide enhanced
// initial behaviour for a race. A good example of this with the
// standard races would be the Undead Goldmine Haunting and
// Night Elves Goldmine Entangling.
// The callback function passes as arguments all the units
// generated in addition to the nearest goldmine detected.
// Please note that if a random hero is not created, the last
// argument will have a null value, so always do a check.
// - Get a player's custom race name string with GetPlayerCustomRaceName(player)
//
// Notes:
// - Supports a maximum of 24 custom races.
// - Maximum for worker and hero types are configurable.
//
// Requirements:
// - JassHelper version 0.9.E.0 or newer (older versions may still work).
//
// Installation:
// - Create a new trigger called CustomRaceSystem.
// - Convert it to custom text and replace all the code with this code.
//
// Special Thanks:
// - Alevice: He practically co-wrote the code.
// - cosmicat: His formula for circular unit formation.
// Co-developing the single-array registry.
//
//==============================================================================
library CustomRaceSystem initializer Init
//===========================================================================
// CONFIGURATION SECTION
//===========================================================================
globals
// Unit Type Constants
private constant integer MAX_WORKERTYPES = 4
private constant integer MAX_HEROTYPES = 4
endglobals
//===========================================================================
// END CONFIGURATION SECTION
//===========================================================================
function interface CustomRaceCall takes player play, group workers, unit goldmine, unit townhall, unit randhero returns nothing
private function r2S takes race r returns string
if r == RACE_HUMAN then
return "Human"
elseif r == RACE_ORC then
return "Orc"
elseif r == RACE_UNDEAD then
return "Undead"
elseif r == RACE_NIGHTELF then
return "Night Elf"
endif
return "Unknown"
endfunction
private function r2I takes race r returns integer
if r == RACE_HUMAN then
return 1
elseif r == RACE_ORC then
return 2
elseif r == RACE_UNDEAD then
return 3
elseif r == RACE_NIGHTELF then
return 4
endif
return 5
endfunction
globals
// Victory Defeat Variables
private string array KEY_STRUCTURE
private integer KEY_STRUCTURE_COUNT = 0
endglobals
//===========================================================================
// STRUCT DATA
//===========================================================================
private keyword createStartingUnits
struct CustomRace
string name
// Town Hall Variable
integer townhallType = 0
//string townhallName
// Town Hall name is not currently supported.
// Worker Variables
integer totalWorkerTypes = 0
integer array workerType[MAX_WORKERTYPES]
integer array workerPriority[MAX_WORKERTYPES]
integer array workerQty[MAX_WORKERTYPES]
// Random Hero Variables
integer totalHeroTypes = 0
integer array heroType[MAX_HEROTYPES]
// AI Script Directory String Variable
string aiscript = ""
// Callback Variable
private CustomRaceCall c
// Registry Variable
static integer array REGISTRY
// Spawn Priority Variables
static integer NEAR_MINE = 0
static integer NEAR_HALL = 1
static method get takes race r, real h returns CustomRace
return CustomRace(.REGISTRY[((r2I(r)-1)*6)+(10-R2I(h*10.))])
endmethod
method register takes race r, real h returns boolean
local CustomRace c = CustomRace.get(r,h)
if c != 0 then
debug call BJDebugMsg("|cffff0000Registration of "+.name+" failed due to conflict with "+c.name+" registered for "+r2S(r)+" race Handicap "+R2S(h))
return false
endif
set .REGISTRY[((r2I(r)-1)*6)+(10-R2I(h*10.))] = integer(this)
return true
endmethod
static method create takes string name, race r, real h returns CustomRace
local CustomRace c = CustomRace.allocate()
set c.name = name
if not c.register(r,h) then
call c.destroy()
return 0
endif
return c
endmethod
static method createAll takes string name, race r returns CustomRace
local CustomRace c = CustomRace.allocate()
set c.name = name
if not c.register(r,1.0) and not c.register(r,0.9) and not c.register(r,0.8) and not c.register(r,0.7) and not c.register(r,0.6) and not c.register(r,0.5) then
call c.destroy()
return 0
endif
return c
endmethod
method setTownHall takes integer hallid returns nothing
set .townhallType = hallid
set KEY_STRUCTURE[KEY_STRUCTURE_COUNT] = UnitId2String(hallid)
set KEY_STRUCTURE_COUNT = KEY_STRUCTURE_COUNT+1
endmethod
method addWorkerType takes integer workerid, integer priority, integer quantity returns nothing
set .workerType[.totalWorkerTypes] = workerid
set .workerPriority[.totalWorkerTypes] = priority
set .workerQty[.totalWorkerTypes] = quantity
set .totalWorkerTypes = .totalWorkerTypes+1
endmethod
method addHeroType takes integer heroid returns nothing
local integer i = 0
set .heroType[.totalHeroTypes] = heroid
set .totalHeroTypes = .totalHeroTypes+1
loop
call SetPlayerTechMaxAllowed(Player(i),heroid,1)
set i = i+1
exitwhen i == bj_MAX_PLAYERS
endloop
endmethod
private method getRandomHeroType takes nothing returns integer
local integer randomindex = GetRandomInt(0,.totalHeroTypes-1)
return .heroType[randomindex]
endmethod
method setAIScript takes string s returns nothing
set .aiscript = s
endmethod
method setCallback takes CustomRaceCall callb returns nothing
set .c = callb
endmethod
private method createRandomHero takes player p, location loc returns unit
local unit h = CreateUnitAtLoc(p, .getRandomHeroType(), loc, bj_UNIT_FACING)
if bj_meleeGrantHeroItems then
call MeleeGrantItemsToHero(h)
endif
return h
endmethod
method createStartingUnits takes player p returns nothing
local location startLoc = GetPlayerStartLocationLoc(p)
local location nearMineLoc = startLoc
local location nearTownLoc = startLoc
local location spawnLoc = startLoc
local location heroLoc = startLoc
local unit nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
local unit myTownhall = null
local unit myRandHero = null
local group workerGroup = CreateGroup()
local integer workertypeindex = 0
local integer workerqty = 0
local integer spawnPriority = 0
if nearestMine != null then
set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine),startLoc,320,0)
set nearTownLoc = MeleeGetProjectedLoc(startLoc,GetUnitLoc(nearestMine),288,0)
set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine),startLoc,384,45)
endif
set myTownhall = CreateUnitAtLoc(p,.townhallType,startLoc,bj_UNIT_FACING)
loop
exitwhen workertypeindex == .totalWorkerTypes
set spawnPriority = .workerPriority[workertypeindex]
if (spawnPriority==.NEAR_HALL) then
set spawnLoc = nearTownLoc
elseif(spawnPriority==.NEAR_MINE) then
set spawnLoc = nearMineLoc
endif
loop
call GroupAddUnit(workerGroup, CreateUnitAtLoc(p,.workerType[workertypeindex],PolarProjectionBJ(spawnLoc,65,(I2R(workerqty)*(360.00 / I2R(.workerQty[workertypeindex]))) + 90),bj_UNIT_FACING))
set workerqty = workerqty + 1
exitwhen workerqty >= .workerQty[workertypeindex]
endloop
call RemoveLocation(spawnLoc)
set workerqty = 0
set workertypeindex = workertypeindex+1
endloop
if (IsMapFlagSet(MAP_RANDOM_HERO) and .totalHeroTypes>0 ) then
set myRandHero = .createRandomHero(p,heroLoc)
else
call SetPlayerState(p,PLAYER_STATE_RESOURCE_HERO_TOKENS,bj_MELEE_STARTING_HERO_TOKENS)
endif
if(.c!=0) then
call .c.evaluate(p,workerGroup,nearestMine,myTownhall,myRandHero)
else
call DestroyGroup(workerGroup)
endif
if nearMineLoc != startLoc then
call RemoveLocation(nearMineLoc)
call RemoveLocation(nearTownLoc)
call RemoveLocation(heroLoc)
endif
call RemoveLocation(startLoc)
set startLoc = null
set nearMineLoc = null
set nearTownLoc = null
set spawnLoc = null
set heroLoc = null
set nearestMine = null
set myTownhall = null
set myRandHero = null
set workerGroup = null
endmethod
endstruct
globals
private string array PLAYER_RACE
endglobals
function GetPlayerCustomRaceName takes player p returns string
return PLAYER_RACE[GetPlayerId(p)]
endfunction
//===========================================================================
// UNIT CREATION SECTION
//===========================================================================
private function CreateStartingUnitsForAllPlayers takes nothing returns nothing
local integer index = 0
local player indexPlayer
local race playerRace
local CustomRace c
loop
set indexPlayer = Player(index)
if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
set playerRace = GetPlayerRace(indexPlayer)
set c = CustomRace.get(playerRace,GetPlayerHandicap(indexPlayer)+0.01)
if (GetPlayerController(indexPlayer) == MAP_CONTROL_USER or (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER and c.aiscript != "" )) and c != 0 then
set PLAYER_RACE[index] = c.name
call c.createStartingUnits(indexPlayer)
elseif playerRace == RACE_HUMAN then
call MeleeStartingUnitsHuman(indexPlayer,GetStartLocationLoc(GetPlayerStartLocation(indexPlayer)),true,true,true)
elseif playerRace == RACE_ORC then
call MeleeStartingUnitsOrc(indexPlayer,GetStartLocationLoc(GetPlayerStartLocation(indexPlayer)),true,true,true)
elseif playerRace == RACE_NIGHTELF then
call MeleeStartingUnitsNightElf(indexPlayer,GetStartLocationLoc(GetPlayerStartLocation(indexPlayer)),true,true,true)
elseif playerRace == RACE_UNDEAD then
call MeleeStartingUnitsUndead(indexPlayer,GetStartLocationLoc(GetPlayerStartLocation(indexPlayer)),true,true,true)
else
call MeleeStartingUnitsUnknownRace(indexPlayer,GetStartLocationLoc(GetPlayerStartLocation(indexPlayer)),true,true,true)
endif
endif
set index = index + 1
exitwhen index == bj_MAX_PLAYERS
endloop
endfunction
//===========================================================================
// CUSTOM MELEE AI SECTION
//===========================================================================
private function CustomMeleeStartingAI takes nothing returns nothing
local integer index = 0
local player indexPlayer
local race indexRace
local CustomRace c
loop
set indexPlayer = Player(index)
if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
set indexRace = GetPlayerRace(indexPlayer)
set c = CustomRace.get(indexRace,GetPlayerHandicap(indexPlayer)+0.01)
call SetPlayerHandicap(indexPlayer,1.0)
if (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER) then
// Run a race-specific melee AI script.
if c != 0 and c.aiscript != "" then
call StartMeleeAI(indexPlayer, c.aiscript)
elseif (indexRace == RACE_HUMAN) then
call PickMeleeAI(indexPlayer, "human.ai", null, null)
elseif (indexRace == RACE_ORC) then
call PickMeleeAI(indexPlayer, "orc.ai", null, null)
elseif (indexRace == RACE_UNDEAD) then
call PickMeleeAI(indexPlayer, "undead.ai", null, null)
call RecycleGuardPosition(bj_ghoul[index])
elseif (indexRace == RACE_NIGHTELF) then
call PickMeleeAI(indexPlayer, "elf.ai", null, null)
else
// Unrecognized race.
endif
call ShareEverythingWithTeamAI(indexPlayer)
endif
endif
set index = index + 1
exitwhen index == bj_MAX_PLAYERS
endloop
endfunction
//===========================================================================
// VICTORY DEFEAT SECTION
//===========================================================================
private function CustomGetAllyKeyStructureCount takes player whichPlayer returns integer
local integer i = 0
local integer keyStructs = 0
local integer playerIndex = 0
local player indexPlayer
loop
set indexPlayer = Player(playerIndex)
if (PlayersAreCoAllied(whichPlayer, indexPlayer)) then
set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "townhall", true, true)
set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "greathall", true, true)
set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "necropolis", true, true)
set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "treeoflife", true, true)
loop
set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, KEY_STRUCTURE[i], true, true)
set i = i+1
exitwhen i == KEY_STRUCTURE_COUNT
endloop
endif
set playerIndex = playerIndex + 1
exitwhen playerIndex == bj_MAX_PLAYERS
endloop
return keyStructs
endfunction
private function CustomPlayerIsCrippled takes player whichPlayer returns boolean
local integer allyStructures = MeleeGetAllyStructureCount(whichPlayer)
local integer allyKeyStructures = CustomGetAllyKeyStructureCount(whichPlayer)
return (allyStructures > 0) and (allyKeyStructures <= 0)
endfunction
private function CustomCheckForCrippledPlayers takes nothing returns nothing
local integer playerIndex
local player indexPlayer
local boolean isNowCrippled
call MeleeCheckForLosersAndVictors()
if bj_finishSoonAllExposed then
return
endif
set playerIndex = 0
loop
set indexPlayer = Player(playerIndex)
set isNowCrippled = CustomPlayerIsCrippled(indexPlayer)
if (not bj_playerIsCrippled[playerIndex] and isNowCrippled) then
set bj_playerIsCrippled[playerIndex] = true
call TimerStart(bj_crippledTimer[playerIndex], bj_MELEE_CRIPPLE_TIMEOUT, false, function MeleeCrippledPlayerTimeout)
if (GetLocalPlayer() == indexPlayer) then
call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], true)
call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, GetLocalizedString("CRIPPLE_WARNING_HUMAN"))
endif
elseif (bj_playerIsCrippled[playerIndex] and not isNowCrippled) then
set bj_playerIsCrippled[playerIndex] = false
call PauseTimer(bj_crippledTimer[playerIndex])
if (GetLocalPlayer() == indexPlayer) then
call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], false)
if (MeleeGetAllyStructureCount(indexPlayer) > 0) then
if (bj_playerIsExposed[playerIndex]) then
call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, GetLocalizedString("CRIPPLE_UNREVEALED"))
else
call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, GetLocalizedString("CRIPPLE_UNCRIPPLED"))
endif
endif
endif
call MeleeExposePlayer(indexPlayer, false)
endif
set playerIndex = playerIndex + 1
exitwhen playerIndex == bj_MAX_PLAYERS
endloop
endfunction
private function CustomInitVictoryDefeat takes nothing returns nothing
local trigger checker = CreateTrigger()
local trigger trig
local integer index
local player indexPlayer
set bj_finishSoonTimerDialog = CreateTimerDialog(null)
call TriggerAddAction(checker, function CustomCheckForCrippledPlayers)
set trig = CreateTrigger()
call TriggerRegisterGameEvent(trig, EVENT_GAME_TOURNAMENT_FINISH_SOON)
call TriggerAddAction(trig, function MeleeTriggerTournamentFinishSoon)
set trig = CreateTrigger()
call TriggerRegisterGameEvent(trig, EVENT_GAME_TOURNAMENT_FINISH_NOW)
call TriggerAddAction(trig, function MeleeTriggerTournamentFinishNow)
set index = 0
loop
set indexPlayer = Player(index)
if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
set bj_meleeDefeated[index] = false
set bj_meleeVictoried[index] = false
set bj_playerIsCrippled[index] = false
set bj_playerIsExposed[index] = false
set bj_crippledTimer[index] = CreateTimer()
set bj_crippledTimerWindows[index] = CreateTimerDialog(bj_crippledTimer[index])
call TimerDialogSetTitle(bj_crippledTimerWindows[index], MeleeGetCrippledTimerMessage(indexPlayer))
call TriggerRegisterPlayerUnitEvent(checker, indexPlayer, EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL, null)
call TriggerRegisterPlayerUnitEvent(checker, indexPlayer, EVENT_PLAYER_UNIT_DEATH, null)
call TriggerRegisterPlayerUnitEvent(checker, indexPlayer, EVENT_PLAYER_UNIT_CONSTRUCT_START, null)
call TriggerRegisterPlayerAllianceChange(checker, indexPlayer, ALLIANCE_PASSIVE)
call TriggerRegisterPlayerStateEvent(checker, indexPlayer, PLAYER_STATE_ALLIED_VICTORY, EQUAL, 1)
set trig = CreateTrigger()
call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_DEFEAT)
call TriggerAddAction(trig, function MeleeTriggerActionPlayerDefeated)
set trig = CreateTrigger()
call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_LEAVE)
call TriggerAddAction(trig, function MeleeTriggerActionPlayerLeft)
else
set bj_meleeDefeated[index] = true
set bj_meleeVictoried[index] = false
if (IsPlayerObserver(indexPlayer)) then
set trig = CreateTrigger()
call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_LEAVE)
call TriggerAddAction(trig, function MeleeTriggerActionPlayerLeft)
endif
endif
set index = index + 1
exitwhen index == bj_MAX_PLAYERS
endloop
call TimerStart(CreateTimer(), 2.0, false, function CustomCheckForCrippledPlayers)
endfunction
private function TimerAction takes nothing returns nothing
call SetFloatGameState(GAME_STATE_TIME_OF_DAY, bj_MELEE_STARTING_TOD)
call MeleeStartingHeroLimit()
call MeleeGrantHeroItems()
call MeleeStartingResources()
call MeleeClearExcessUnits()
call CreateStartingUnitsForAllPlayers()
call CustomMeleeStartingAI()
call CustomInitVictoryDefeat()
call DestroyTimer(GetExpiredTimer())
endfunction
private function Init takes nothing returns nothing
call TimerStart(CreateTimer(),0,false,function TimerAction)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library NagaSetup initializer Init requires CustomRaceSystem
private function Init takes nothing returns nothing
local CustomRace c = CustomRace.create("Naga",RACE_NIGHTELF,0.9)
call c.setTownHall('ntid') // Temple of Tides
call c.addWorkerType('nsla',c.NEAR_MINE,5) // Mur'gul Slave
call c.addHeroType('E000') // Illidan
call c.addHeroType('U000') // Lady Vashj
call c.addHeroType('N004') // Naga Royal Guard
call c.addHeroType('O000') // Sea Giant
//call c.setAIScript("human.ai")
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library NightElfSetup initializer Init requires CustomRaceSystem
private function EntangleGoldMine takes player play, group workers, unit goldmine, unit townhall, unit randhero returns nothing
call SetUnitPosition(townhall,GetUnitX(goldmine),GetUnitY(goldmine))
call IssueTargetOrder(townhall, "entangleinstant", goldmine)
call DestroyGroup(workers)
endfunction
private function Init takes nothing returns nothing
local CustomRace c = CustomRace.create("Night Elf",RACE_NIGHTELF,1.0)
call c.setTownHall('etol') // Tree of Life
call c.addWorkerType('ewsp',c.NEAR_MINE,5) // Wisp
call c.addHeroType('Ekee') // Keeper of the Grove
call c.addHeroType('Emoo') // Priestess of the Moon
call c.addHeroType('Edem') // Demon Hunter
call c.addHeroType('Ewar') // Warden
call c.setCallback(CustomRaceCall.EntangleGoldMine)
call c.setAIScript("elf.ai")
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library UndeadSetup initializer Init requires CustomRaceSystem
private function WorkerHideToggle takes nothing returns nothing
call ShowUnit(GetEnumUnit(),IsUnitHidden(GetEnumUnit()))
endfunction
private function HauntGoldMine takes player play, group workers, unit goldmine, unit townhall, unit randhero returns nothing
call ForGroup(workers,function WorkerHideToggle)
call BlightGoldMineForPlayerBJ(goldmine,play)
call ForGroup(workers,function WorkerHideToggle)
call DestroyGroup(workers)
endfunction
private function Init takes nothing returns nothing
local CustomRace c = CustomRace.create("Undead",RACE_UNDEAD,1.0)
call c.setTownHall('unpl') // Necropolis
call c.addWorkerType('uaco',c.NEAR_MINE,3) // Acolyte
call c.addWorkerType('ugho',c.NEAR_HALL,1) // Ghoul
call c.addHeroType('Udea') // Death Knight
call c.addHeroType('Ulic') // Lich
call c.addHeroType('Udre') // Dreadlord
call c.addHeroType('Ucrl') // Cryptlord
call c.setCallback(CustomRaceCall.HauntGoldMine)
call c.setAIScript("undead.ai")
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library OrcSetup initializer Init requires CustomRaceSystem
private function Init takes nothing returns nothing
local CustomRace c = CustomRace.create("Orc",RACE_ORC,1.0)
call c.setTownHall('ogre') // Great Hall
call c.addWorkerType('opeo',c.NEAR_MINE,5) // Peon
call c.addHeroType('Obla') // Blademaster
call c.addHeroType('Ofar') // Far Seer
call c.addHeroType('Otch') // Tauren Chieftain
call c.addHeroType('Oshd') // Shadow Hunter
call c.setAIScript("orc.ai")
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library HumanSetup initializer Init requires CustomRaceSystem
private function Init takes nothing returns nothing
local CustomRace c = CustomRace.create("Human",RACE_HUMAN,1.0)
call c.setTownHall('htow') // Town Hall
call c.addWorkerType('hpea',c.NEAR_MINE,5) // Peasant
call c.addHeroType('Hpal') // Paladin
call c.addHeroType('Hamg') // Archmage
call c.addHeroType('Hmkg') // Mountain King
call c.addHeroType('Hblm') // Blood Mage
call c.setAIScript("human.ai")
endfunction
endlibrary