- Joined
- Dec 30, 2008
- Messages
- 72
Well, I wrote this script based off of the melee trigger Victory/Defeat, as I needed something to moniter victory, alliance changes and so on so forth for more than the initial 4 races. So I pulled apart the function and finally found where in the game's core little script, the townhall's were checked. After locating it I modified it to allow the user to add more townhalls into this area, and customise the warning message given when you are revealed. After working on this for a while, and having implemented it into my main current map, I decided to place it on hive in the spell's system section. However someone, who obviously doesn't make maps, reviewed it and deemed it useless so he rejected it. So, having emailed him and him being unwilling to change his mind, I decided to post the code here and ask what improvements I should make to ensure it is more user friendly, as that was one of his gripes and the only one I can fix without repairing his brain.
This code should be used in place of the melee trigger (which is run on initialisation) Victory/Defeat conditions, and the variables should be set before it is run
I have attatched a map that shows this in action, to see the map without it
Oh and I only use JASS, not vJASS
JASS:
// Written in part by Ross Dubery
// Modified from MeleeGameWinTrigger
// Version 1.10
//
// The global variables used need to be declared before this scipt runs
//
// |udg_MaxRace| integer
// is the exact number of races you will be having in the map
// so the usual 4 + whatever you add
//
// |udg_SetRace[Number of Players]| integer array
// is the variable that will hold all the races numbers from 0 to MaxRace - 1
// Human - 0
// Orc - 1
// Night Elf - 2
// Undead - 3
// Your Race - 4 etc.
//
// The first four are non-negotiable, and shouldn't be modified
//
// |udg_TIMERTEXTNew[Number of new races - 1]| string array
// this is the timer text that your races will use (that says "You'll be revealed in:")
//
// |udg_WARNINGNew[Number of new races - 1]| string array
// this is the warning text that your races will use (that says 'Construct a KEY STRUCTURE before you are revealed')
//
// |udg_KEYNew[Number of new races - 1]| unittype array
// this is the unit type of the key structures of your race (example human is 'htow') this structure and therefore
// this variable is vital to this trigger and is what causes your new races to be revealed in normal melee maps
//
//
//
// Controls the timer text for the crippled player depending on which race they are
function MeleeGetCrippledTimerMessageMod takes player whichPlayer returns string
local integer r = udg_SetRace[GetPlayerId(whichPlayer)]
local integer index = 4
local integer maxRace = udg_MaxRace - 1
if (r == 0) then
return GetLocalizedString("CRIPPLE_TIMER_HUMAN")
elseif (r == 1) then
return GetLocalizedString("CRIPPLE_TIMER_ORC")
elseif (r == 2) then
return GetLocalizedString("CRIPPLE_TIMER_NIGHTELF")
elseif (r == 3) then
return GetLocalizedString("CRIPPLE_TIMER_UNDEAD")
else
loop
exitwhen index > maxRace
if (r == index) then
return GetLocalizedString(udg_TIMERTEXTNew[index-4])
endif
set index = index + 1
endloop
endif
return ""
endfunction
// returns a string prefixed version of the cripple timer
function MeleeGetCrippledRevealedMessageMod takes player whichPlayer returns string
return GetLocalizedString("CRIPPLE_REVEALING_PREFIX") + GetPlayerName(whichPlayer) + GetLocalizedString("CRIPPLE_REVEALING_POSTFIX")
endfunction
// Controls the cripple text for the crippled player depending on which race they are
function MeleeGetCrippledWarningMessageMod takes player whichPlayer returns string
local integer r = udg_SetRace[GetPlayerId(whichPlayer)]
local integer index = 4
local integer maxRace = udg_MaxRace - 1
if (r == 0) then
return GetLocalizedString("CRIPPLE_WARNING_HUMAN")
elseif (r == 1) then
return GetLocalizedString("CRIPPLE_WARNING_ORC")
elseif (r == 2) then
return GetLocalizedString("CRIPPLE_WARNING_NIGHTELF")
elseif (r == 3) then
return GetLocalizedString("CRIPPLE_WARNING_UNDEAD")
else
loop
exitwhen index > maxRace
if (r == index) then
return GetLocalizedString(udg_WARNINGNew[index-4])
endif
set index = index + 1
endloop
endif
return ""
endfunction
// Counts the number of key structures held by the player and their allies
function MeleeGetAllyKeyStructureCountMod takes player whichPlayer returns integer
local integer playerIndex
local player indexPlayer
local integer keyStructs
local integer index
local integer maxRace = udg_MaxRace - 1
// Count the number of buildings controlled by all not-yet-defeated co-allies.
set keyStructs = 0
set playerIndex = 0
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, "treeoflife", true, true)
set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "necropolis", true, true)
//Add other key structures here
set index = 4
loop
exitwhen index > maxRace
set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId(udg_KEYNew[index-4], indexPlayer)
set index = index + 1
endloop
endif
set playerIndex = playerIndex + 1
exitwhen playerIndex == bj_MAX_PLAYERS
endloop
return keyStructs
endfunction
// Checks if a player is crippled
function MeleePlayerIsCrippledMod takes player whichPlayer returns boolean
local integer allyStructures = MeleeGetAllyStructureCount(whichPlayer)
local integer allyKeyStructures = MeleeGetAllyKeyStructureCountMod(whichPlayer)
// Dead teams are not considered to be crippled.
return (allyStructures > 0) and (allyKeyStructures <= 0)
endfunction
// Determines if a player is crippled yet, and controls the timer
function MeleeCrippledPlayerTimeoutMod takes nothing returns nothing
local timer expiredTimer = GetExpiredTimer()
local integer playerIndex
local player exposedPlayer
// Determine which player's timer expired.
set playerIndex = 0
loop
if (bj_crippledTimer[playerIndex] == expiredTimer) then
exitwhen true
endif
set playerIndex = playerIndex + 1
exitwhen playerIndex == bj_MAX_PLAYERS
endloop
if (playerIndex == bj_MAX_PLAYERS) then
return
endif
set exposedPlayer = Player(playerIndex)
if (GetLocalPlayer() == exposedPlayer) then
// Use only local code (no net traffic) within this block to avoid desyncs.
// Hide the timer window for this player.
call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], false)
endif
// Display a text message to all players, explaining the exposure.
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, MeleeGetCrippledRevealedMessageMod(exposedPlayer))
// Expose the player.
call MeleeExposePlayer(exposedPlayer, true)
endfunction
// Checks for crippled players
function MeleeCheckForCrippledPlayersMod takes nothing returns nothing
local integer playerIndex
local player indexPlayer
local force crippledPlayers = CreateForce()
local boolean isNowCrippled
// The "finish soon" exposure of all players overrides any "crippled" exposure
if bj_finishSoonAllExposed then
return
endif
// Check each player to see if he or she has been crippled or uncrippled.
set playerIndex = 0
loop
set indexPlayer = Player(playerIndex)
set isNowCrippled = MeleePlayerIsCrippledMod(indexPlayer)
if (not bj_playerIsCrippled[playerIndex] and isNowCrippled) then
// Player became crippled; start their cripple timer.
set bj_playerIsCrippled[playerIndex] = true
call TimerStart(bj_crippledTimer[playerIndex], bj_MELEE_CRIPPLE_TIMEOUT, false, function MeleeCrippledPlayerTimeoutMod)
if (GetLocalPlayer() == indexPlayer) then
// Use only local code (no net traffic) within this block to avoid desyncs.
// Show the timer window.
call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], true)
// Display a warning message.
call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, MeleeGetCrippledWarningMessageMod(indexPlayer))
endif
elseif (bj_playerIsCrippled[playerIndex] and not isNowCrippled) then
// Player became uncrippled; stop their cripple timer.
set bj_playerIsCrippled[playerIndex] = false
call PauseTimer(bj_crippledTimer[playerIndex])
if (GetLocalPlayer() == indexPlayer) then
// Use only local code (no net traffic) within this block to avoid desyncs.
// Hide the timer window for this player.
call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], false)
// Display a confirmation message if the player's team is still alive.
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
// If the player granted shared vision, deny that vision now.
call MeleeExposePlayer(indexPlayer, false)
endif
set playerIndex = playerIndex + 1
exitwhen playerIndex == bj_MAX_PLAYERS
endloop
endfunction
// Checks if an alliance has changed which has caused a crippled player to be crippled/uncrippled
function MeleeTriggerActionAllianceChangeMod takes nothing returns nothing
call MeleeCheckForLosersAndVictors()
call MeleeCheckForCrippledPlayersMod()
endfunction
// Checks if a unit has been lost which has caused a crippled player to be crippled/uncrippled
function MeleeCheckLostUnitMod takes unit lostUnit returns nothing
local player lostUnitOwner = GetOwningPlayer(lostUnit)
// We only need to check for mortality if this was the last building.
if (GetPlayerStructureCount(lostUnitOwner, true) <= 0) then
call MeleeCheckForLosersAndVictors()
endif
// Check if the lost unit has crippled or uncrippled the player.
// (A team with 0 units is dead, and thus considered uncrippled.)
call MeleeCheckForCrippledPlayersMod()
endfunction
// Checks if a unit has been created which has caused a crippled player to be crippled/uncrippled
function MeleeCheckAddedUnitMod takes unit addedUnit returns nothing
local player addedUnitOwner = GetOwningPlayer(addedUnit)
// If the player was crippled, this unit may have uncrippled him/her.
if (bj_playerIsCrippled[GetPlayerId(addedUnitOwner)]) then
call MeleeCheckForCrippledPlayersMod()
endif
endfunction
// Checks if a unit has died which has caused a crippled player to be crippled/uncrippled
function MeleeTriggerActionUnitDeathMod takes nothing returns nothing
if (IsUnitType(GetDyingUnit(), UNIT_TYPE_STRUCTURE)) then
call MeleeCheckLostUnitMod(GetDyingUnit())
endif
endfunction
// Checks if a structure has been built which has caused a crippled player to be crippled/uncrippled
function MeleeTriggerActionUnitConstructionStartMod takes nothing returns nothing
call MeleeCheckAddedUnitMod(GetConstructingStructure())
endfunction
//Prevents the player triggers from leaking
function AntiLeakFilterWinTrigger takes nothing returns boolean
return true
endfunction
// Adds all the triggers that control this complex system
function BaseActions takes nothing returns nothing
local trigger trig
local integer index
local player indexPlayer
local filterfunc filter
set filter = Filter(function AntiLeakFilterWinTrigger)
// Create a timer window for the "finish soon" timeout period, it has no timer
// because it is driven by real time (outside of the game state to avoid desyncs)
set bj_finishSoonTimerDialog = CreateTimerDialog(null)
// Set a trigger to fire when we receive a "finish soon" game event
set trig = CreateTrigger()
call TriggerRegisterGameEvent(trig, EVENT_GAME_TOURNAMENT_FINISH_SOON)
call TriggerAddAction(trig, function MeleeTriggerTournamentFinishSoon)
// Set a trigger to fire when we receive a "finish now" game event
set trig = CreateTrigger()
call TriggerRegisterGameEvent(trig, EVENT_GAME_TOURNAMENT_FINISH_NOW)
call TriggerAddAction(trig, function MeleeTriggerTournamentFinishNow)
// Set up each player's mortality code.
set index = 0
loop
set indexPlayer = Player(index)
// Make sure this player slot is playing.
if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
set bj_meleeDefeated[index] = false
set bj_meleeVictoried[index] = false
// Create a timer and timer window in case the player is crippled.
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], MeleeGetCrippledTimerMessageMod(indexPlayer))
// Set a trigger to fire whenever a building is cancelled for this player.
set trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trig, indexPlayer, EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL, filter)
call TriggerAddAction(trig, function MeleeTriggerActionConstructCancel)
// Set a trigger to fire whenever a unit dies for this player.
set trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trig, indexPlayer, EVENT_PLAYER_UNIT_DEATH, filter)
call TriggerAddAction(trig, function MeleeTriggerActionUnitDeathMod)
// Set a trigger to fire whenever a unit begins construction for this player
set trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trig, indexPlayer, EVENT_PLAYER_UNIT_CONSTRUCT_START, filter)
call TriggerAddAction(trig, function MeleeTriggerActionUnitConstructionStartMod)
// Set a trigger to fire whenever this player defeats-out
set trig = CreateTrigger()
call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_DEFEAT)
call TriggerAddAction(trig, function MeleeTriggerActionPlayerDefeated)
// Set a trigger to fire whenever this player leaves
set trig = CreateTrigger()
call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_LEAVE)
call TriggerAddAction(trig, function MeleeTriggerActionPlayerLeft)
// Set a trigger to fire whenever this player changes his/her alliances.
set trig = CreateTrigger()
call TriggerRegisterPlayerAllianceChange(trig, indexPlayer, ALLIANCE_PASSIVE)
call TriggerRegisterPlayerStateEvent(trig, indexPlayer, PLAYER_STATE_ALLIED_VICTORY, EQUAL, 1)
call TriggerAddAction(trig, function MeleeTriggerActionAllianceChangeMod)
else
set bj_meleeDefeated[index] = true
set bj_meleeVictoried[index] = false
// Handle leave events for observers
if (IsPlayerObserver(indexPlayer)) then
// Set a trigger to fire whenever this player leaves
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 DestroyFilter(filter)
set filter = null
// Test for victory / defeat at startup, in case the user has already won / lost.
// Allow for a short time to pass first, so that the map can finish loading.
call TimerStart(CreateTimer(), 2.0, false, function MeleeTriggerActionAllianceChangeMod)
endfunction
// Checks if an alliance has changed which has caused a crippled player to be crippled/uncrippled
//===========================================================================
function InitTrig_MeleeGameWinTriggerMod takes nothing returns nothing
set gg_trg_MeleeGameWinTriggerMod = CreateTrigger()
call TriggerAddAction(gg_trg_MeleeGameWinTriggerMod, function BaseActions)
endfunction
This code should be used in place of the melee trigger (which is run on initialisation) Victory/Defeat conditions, and the variables should be set before it is run
I have attatched a map that shows this in action, to see the map without it
Oh and I only use JASS, not vJASS