• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Custom Race WinTrigger Remake

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
This little 'system' or whatever you want to call it, allows you to add an additional race to the warcraft 3 system, well... at least as far as recognising townhalls and winning goes.

I have rewritten the Melee game Victory/Defeat conditions trigger to allow you to add more races into the map, not the lobby the map.

It now supports an unlimited number of races (well, limited by your imagination and the integer roll over) You just need to increase the array

What this does:
Adds 'townhalls' to the games cripple detection (you know, when you get revealed for not having a main building)
Enforces victory/defeat conditions that include said townhalls and races in the equation
Allows you to customise a 'you will be revealed' message.
Allows you to customise a 'warning' message


I can't exactly take a screen shot of this >_>
And posting the code would be cumbersome but I'll do it anyway

Code:
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

function MeleeGetCrippledRevealedMessageMod takes player whichPlayer returns string
    return GetLocalizedString("CRIPPLE_REVEALING_PREFIX") + GetPlayerName(whichPlayer) + GetLocalizedString("CRIPPLE_REVEALING_POSTFIX")
endfunction

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

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

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

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

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

function MeleeTriggerActionAllianceChangeMod takes nothing returns nothing
    call MeleeCheckForLosersAndVictors()
    call MeleeCheckForCrippledPlayersMod()
endfunction

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

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

function MeleeTriggerActionUnitDeathMod takes nothing returns nothing
    if (IsUnitType(GetDyingUnit(), UNIT_TYPE_STRUCTURE)) then
        call MeleeCheckLostUnitMod(GetDyingUnit())
    endif
endfunction

function MeleeTriggerActionUnitConstructionStartMod takes nothing returns nothing
    call MeleeCheckAddedUnitMod(GetConstructingStructure())
endfunction

function BaseActions takes nothing returns nothing
    
    local trigger    trig
    local integer    index
    local player     indexPlayer

    // 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, null)
            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, null)
            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, null)
            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

    // 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

function AntiLeakFilterWinTrigger takes nothing returns boolean
    return true
endfunction

//===========================================================================
function InitTrig_MeleeGameWinTriggerMod takes nothing returns nothing
    set gg_trg_MeleeGameWinTriggerMod = CreateTrigger()
    call TriggerAddAction(gg_trg_MeleeGameWinTriggerMod, function BaseActions)
endfunction




Dubey out ^_^

#Changelog#
Apparently dear mr. moderator doesn't understand what this does, so I rewrote the explanation text to try and make it more clear...

Keywords:
Custom, Race, Additional
Contents

Luk, i can haz kustum rase? (Map)

Reviews
16:40, 27th Nov 2009 TriggerHappy: I got your PM and you claim this is the easiest way to modify/add races to startup. It is most certainly not user friendly, or easy to use. Unless I have missed something I am Rejecting permanently, if you...

Moderator

M

Moderator

16:40, 27th Nov 2009
TriggerHappy:

I got your PM and you claim this is the easiest way to modify/add races to startup.

It is most certainly not user friendly, or easy to use. Unless I have missed something I am Rejecting permanently, if you have a problem with this post in the spell resource forum.
 
Top