Ticket #565: Victory_conditions_2.diff

File Victory_conditions_2.diff, 21.6 KB (added by fcxSanya, 14 years ago)

updated diff

  • binaries/data/mods/public/gui/common/functions_global_object.js

     
    66// *******************************************
    77// messageBox
    88// *******************************************
    9 // @params:     int mbWidth, int mbHeight, string mbMessage, string mbTitle, int mbMode, arr mbButtonCaptions
     9// @params:     int mbWidth, int mbHeight, string mbMessage, string mbTitle, int mbMode, arr mbButtonCaptions, arr mbButtonsCode
    1010// @return:     void
    1111// @desc:       Displays a new modal message box.
    1212// *******************************************
  • binaries/data/mods/public/gui/page_summary.xml

     
     1<?xml version="1.0" encoding="utf-8"?>
     2<page>
     3    <include>common/setup.xml</include>
     4    <include>common/styles.xml</include>
     5    <include>common/sprite1.xml</include>
     6    <include>common/init.xml</include>
     7    <include>summary/summary.xml</include>
     8    <include>common/global.xml</include>
     9</page>
  • binaries/data/mods/public/gui/session_new/session.js

     
    1717// Cache EntityStates
    1818var g_EntityStates = {}; // {id:entState}
    1919
     20var g_GameEnded = false;
     21
    2022function GetEntityState(entId)
    2123{
    2224    if (!(entId in g_EntityStates))
     
    7375
    7476function leaveGame()
    7577{
     78    var simState = Engine.GuiInterfaceCall("GetSimulationState");
     79    var playerState = simState.players[Engine.GetPlayerID()];
     80    var gameResult = "You have been defeated...";
     81    if (playerState.state == "won")
     82    {
     83        gameResult = "You have won a battle!";
     84    }
     85   
     86    // post defeat player command
     87    Engine.PostNetworkCommand({
     88        "type": "defeat-player",
     89        "playerId": Engine.GetPlayerID()
     90    });
     91   
    7692    stopMusic();
    7793    endGame();
    78     Engine.SwitchGuiPage("page_pregame.xml");
     94   
     95    Engine.SwitchGuiPage("page_summary.xml", { "gameResult" : gameResult });
     96   
    7997}
    8098
    8199// Return some data that we'll use when hotloading this file after changes
     
    86104
    87105function onTick()
    88106{
     107    checkPlayerState();
     108
    89109    while (true)
    90110    {
    91111        var message = Engine.PollNetworkClient();
     
    119139        getGUIObjectByName("resourcePop").textcolor = "0 0 0";
    120140}
    121141
     142function checkPlayerState()
     143{
     144    var simState = Engine.GuiInterfaceCall("GetSimulationState");
     145    var playerState = simState.players[Engine.GetPlayerID()];
     146   
     147    if(!g_GameEnded)
     148    {
     149        if (playerState.state == "defeated")
     150        {
     151            g_GameEnded = true;
     152            messageBox(400, 200, "You have been defeated... Want you leave the game now?", "Defeat", 0, ["Yes", "No!"], [leaveGame, null]);
     153        }
     154        else if (playerState.state == "won")
     155        {
     156            g_GameEnded = true;
     157            messageBox(400, 200, "You have won a battle! Want you leave the game now?", "Victory", 0, ["Yes", "No!"], [leaveGame, null]);
     158        }
     159    }
     160}
     161
    122162function onSimulationUpdate()
    123163{
    124164    g_Selection.dirty = false;
  • binaries/data/mods/public/gui/summary/summary.js

     
     1function init(data)
     2{
     3    getGUIObjectByName ("summaryTitleBar").caption = "Summary";
     4    getGUIObjectByName ("summaryText").caption = data.gameResult;
     5}
  • binaries/data/mods/public/gui/summary/summary.xml

     
     1<?xml version="1.0" encoding="utf-8"?>
     2
     3<!--
     4==========================================
     5- SUMMARY SCREEN -
     6==========================================
     7-->
     8
     9<objects>
     10    <script file="gui/summary/summary.js"/>
     11    <object name="summary"
     12            type="image"
     13            sprite="bkFillBlack"
     14        >
     15        <!--
     16        ==========================================
     17        - SUMMARY SCREEN - WINDOW
     18        ==========================================
     19        -->
     20
     21        <object name="summaryWindow"
     22            style="wheatWindowGranite"
     23            type="image"
     24            size="25 35 100%-25 100%-25"
     25        >
     26            <object name="summaryTitleBar"
     27                style="wheatWindowTitleBar"
     28                type="button"
     29            />
     30           
     31            <object name="summaryText"
     32                type="text"
     33                size="50 50 100%-50 100%-200"
     34                font="serif-16"
     35                text_align="center"
     36                text_valign="center"
     37            />
     38           
     39            <object type="button" style="wheatButton" size="100%-150 100%-40 100% 100%">
     40                Main menu
     41                <action on="Press"><![CDATA[
     42                    Engine.SwitchGuiPage("page_pregame.xml");
     43                ]]></action>
     44            </object>
     45        </object>
     46    </object>
     47</objects>
  • binaries/data/mods/public/maps/scenarios/Pathfinding_demo.xml

     
    3131{
    3232  "NumPlayers":1,
    3333  "Description":"A map for testing unit movement algorithms.",
    34   "DefaultStance":"holdfire"
     34  "DefaultStance":"holdfire",
     35  "GameType":"endless"
    3536}
    3637]]></ScriptSettings>
    3738    <Entities>
  • binaries/data/mods/public/maps/scenarios/Pathfinding_terrain_demo.xml

     
    3030    <ScriptSettings><![CDATA[
    3131{
    3232  "NumPlayers":1,
    33   "Description":"A map for testing movement costs and terrain properties in the A* pathfinder."
     33  "Description":"A map for testing movement costs and terrain properties in the A* pathfinder.",
     34  "GameType":"endless"
    3435}
    3536]]></ScriptSettings>
    3637    <Entities>
  • binaries/data/mods/public/maps/scenarios/Units_demo.xml

     
    8484    <ScriptSettings><![CDATA[
    8585{
    8686  "NumPlayers":1,
    87   "Description":"Every unit in the game."
     87  "Description":"Every unit in the game.",
     88  "GameType":"endless"
    8889}
    8990]]></ScriptSettings>
    9091    <Entities/>
  • binaries/data/mods/public/simulation/components/EndGameManager.js

     
     1// Interval, which defines how often game will check end game conditions
     2var g_ProgressInterval = 1000;
     3
     4/*
     5    EndGameManager is the system component, which regularly (by timer) checks
     6    victory/defeat conditions and if it is satisfied ends the game
     7*/
     8function EndGameManager() {}
     9
     10EndGameManager.prototype.Schema =
     11    "<a:component type='system'/><empty/>";
     12   
     13EndGameManager.prototype.Init = function()
     14{
     15    // Game type
     16    // given from the map settings
     17    // one of: "conquest" and "endless"
     18    // "conquest" by default
     19    this.gameType = "conquest";
     20}
     21   
     22// Should be started from LoadMapSettings function
     23// when gameType is setted
     24EndGameManager.prototype.Start = function()
     25{
     26    if (this.gameType != "endless")
     27    {
     28        var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     29        this.timer = cmpTimer.SetTimeout(this.entity, IID_EndGameManager, "ProgressTimeout", g_ProgressInterval, {});
     30    }
     31}
     32
     33EndGameManager.prototype.OnDestroy = function()
     34{
     35    if (this.timer)
     36    {
     37        var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     38        cmpTimer.CancelTimer(this.timer);
     39    }
     40};
     41
     42EndGameManager.prototype.SetGameType = function(/*string*/ new_game_type)
     43{
     44   
     45    this.gameType = new_game_type;
     46}
     47
     48EndGameManager.prototype.ProgressTimeout = function(data)
     49{
     50    this.UpdatePlayerStates();
     51   
     52    // repeat the timer
     53    var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     54    this.timer = cmpTimer.SetTimeout(this.entity, IID_EndGameManager, "ProgressTimeout", g_ProgressInterval, data);
     55}
     56
     57EndGameManager.prototype.UpdatePlayerStates = function()
     58{
     59    var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     60    switch (this.gameType)
     61    {
     62        case "conquest":
     63            for (var i = 0; i < cmpPlayerManager.GetNumPlayers(); i++)
     64            {
     65                var playerEntityId = cmpPlayerManager.GetPlayerByID(i);
     66                var cmpPlayer = Engine.QueryInterface(playerEntityId, IID_Player);
     67                if (cmpPlayer.GetState() == "active")
     68                {
     69                    if (cmpPlayer.GetConquestCriticalEntitiesCount() == 0)
     70                    {
     71                        Engine.PostMessage(playerEntityId, MT_PlayerDefeated, null);
     72                    }
     73                }
     74            }
     75            // TODO: update this code for allies
     76            var alivePlayersCount = 0;
     77            var lastAlivePlayerId = -1;
     78            // i starts from 1 because we not count gaia player
     79            for (var i = 1; i < cmpPlayerManager.GetNumPlayers(); i++)
     80            {
     81                var playerEntityId = cmpPlayerManager.GetPlayerByID(i);
     82                var cmpPlayer = Engine.QueryInterface(playerEntityId, IID_Player);
     83                if (cmpPlayer.GetState() == "active")
     84                {
     85                    alivePlayersCount++;
     86                    lastAlivePlayerId = i;
     87                }
     88            }
     89            if (alivePlayersCount == 1)
     90            {
     91                var playerEntityId = cmpPlayerManager.GetPlayerByID(lastAlivePlayerId);
     92                var cmpPlayer = Engine.QueryInterface(playerEntityId, IID_Player);
     93                cmpPlayer.SetState("won");
     94            }
     95            break;
     96        default:
     97            // strange game type ...
     98    }
     99}
     100
     101Engine.RegisterComponentType(IID_EndGameManager, "EndGameManager", EndGameManager);
  • binaries/data/mods/public/simulation/components/GuiInterface.js

     
    3636            "popCount": cmpPlayer.GetPopulationCount(),
    3737            "popLimit": cmpPlayer.GetPopulationLimit(),
    3838            "resourceCounts": cmpPlayer.GetResourceCounts(),
    39             "trainingQueueBlocked": cmpPlayer.IsTrainingQueueBlocked()
     39            "trainingQueueBlocked": cmpPlayer.IsTrainingQueueBlocked(),
     40            "state": cmpPlayer.GetState()
    4041        };
    4142        ret.players.push(playerData);
    4243    }
  • binaries/data/mods/public/simulation/components/Identity.js

     
    6262                        "<value>Mechanical</value>" +
    6363                        "<value>Super</value>" +
    6464                        "<value>Hero</value>" +
     65                        "<value>Structure</value>" +
    6566                        "<value>Civic</value>" +
    6667                        "<value>Economic</value>" +
    6768                        "<value>Defensive</value>" +
    6869                        "<value>Village</value>" +
    6970                        "<value>Town</value>" +
    7071                        "<value>City</value>" +
     72                        "<value>ConquestCritical</value>" +
    7173                        "<value a:help='Primary weapon type'>Bow</value>" + // TODO: what are these used for?
    7274                        "<value a:help='Primary weapon type'>Javelin</value>" +
    7375                        "<value a:help='Primary weapon type'>Spear</value>" +
  • binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js

     
     1Engine.RegisterInterface("EndGameManager");
  • binaries/data/mods/public/simulation/components/Player.js

     
    1919        "metal": 500,   
    2020        "stone": 1000   
    2121    };
     22    // player game state
     23    // one of: "active", "defeated", "won"
     24    this.state = "active";
     25    // buildings count
     26    this.structuresCount = 0;
     27    // Count of entites that needed for survive in
     28    // game of conquest type
     29    this.conquestCriticalEntitiesCount = 0;
    2230};
    2331
    2432Player.prototype.SetPlayerID = function(id)
     
    146154    return true;
    147155};
    148156
     157Player.prototype.GetState = function()
     158{
     159    return this.state;
     160};
     161
     162Player.prototype.SetState = function(/*string*/ new_state)
     163{
     164    this.state = new_state;
     165};
     166
     167Player.prototype.GetStructuresCount = function()
     168{
     169    return this.structuresCount;
     170};
     171
     172Player.prototype.GetConquestCriticalEntitiesCount = function()
     173{
     174    return this.conquestCriticalEntitiesCount;
     175};
     176
    149177// Keep track of population effects of all entities that
    150178// become owned or unowned by this player
    151179Player.prototype.OnGlobalOwnershipChanged = function(msg)
    152180{
     181    var cmpIdentity = Engine.QueryInterface(msg.entity, IID_Identity);
     182    // Is this entity a structure?
     183    var isStructure = (cmpIdentity && cmpIdentity.GetClassesList().indexOf("Structure") != -1);
     184
     185    // Is this entity critical in conquest game type
     186    var isConquestCritical = (cmpIdentity && cmpIdentity.GetClassesList().indexOf("ConquestCritical") != -1);
     187   
    153188    if (msg.from == this.playerID)
    154189    {
     190        if (isStructure)
     191        {
     192            this.structuresCount--;
     193        }
     194        if (isConquestCritical)
     195        {
     196            this.conquestCriticalEntitiesCount--;
     197        }
    155198        var cost = Engine.QueryInterface(msg.entity, IID_Cost);
    156199        if (cost)
    157200        {
     
    162205   
    163206    if (msg.to == this.playerID)
    164207    {
     208        if (isStructure)
     209        {
     210            this.structuresCount++;
     211        }
     212        if (isConquestCritical)
     213        {
     214            this.conquestCriticalEntitiesCount++;
     215        }
    165216        var cost = Engine.QueryInterface(msg.entity, IID_Cost);
    166217        if (cost)
    167218        {
     
    171222    }
    172223};
    173224
     225Player.prototype.OnPlayerDefeated = function()
     226{
     227    this.state = "defeated";
     228    // Reassign all players's entities to gaia player
     229    var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
     230    var entities = cmpRangeManager.GetEntitiesByPlayer(this.playerID);
     231    for each (var entity in entities)
     232    {
     233        // Note: maybe we need to reassign units and buildings only?
     234        var cmpOwnership = Engine.QueryInterface(entity, IID_Ownership);
     235        cmpOwnership.SetOwner(0);
     236    }
     237}
     238
    174239Engine.RegisterComponentType(IID_Player, "Player", Player);
  • binaries/data/mods/public/simulation/helpers/Commands.js

     
    143143                cmpRallyPoint.Unset();
    144144        }
    145145        break;
     146       
     147    case "defeat-player":
     148        // get player entity by playerId
     149        var cmpPlayerMananager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     150        var playerEntity = cmpPlayerManager.GetPlayerByID(cmd.playerId);
     151        // send to player entity "OnPlayerDefeated" message
     152        Engine.PostMessage(playerEntity, MT_PlayerDefeated, null);
     153        break;
    146154
    147155    default:
    148156        error("Ignoring unrecognised command type '" + cmd.type + "'");
  • binaries/data/mods/public/simulation/helpers/Setup.js

     
    1212            cmpUnitAI.SetStance(settings.DefaultStance);
    1313        }
    1414    }
     15   
     16    var cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
     17    if (settings.GameType)
     18    {   
     19        cmpEndGameManager.SetGameType(settings.GameType);
     20    }
     21    cmpEndGameManager.Start();
    1522}
    1623
    1724Engine.RegisterGlobal("LoadMapSettings", LoadMapSettings);
  • binaries/data/mods/public/simulation/templates/template_structure.xml

     
    22<Entity parent="template_entity_full">
    33  <Identity>
    44    <GenericName>Structure</GenericName>
     5    <Classes datatype="tokens">
     6        Structure
     7        ConquestCritical
     8    </Classes>
    59    <IconSheet>snPortraitSheetBuildings</IconSheet>
    610  </Identity>
    711  <BuildRestrictions>
  • binaries/data/mods/public/simulation/templates/template_unit.xml

     
    22<Entity parent="template_entity_full">
    33  <Identity>
    44    <GenericName>Unit</GenericName>
     5    <Classes datatype="tokens">ConquestCritical</Classes>
    56  </Identity>
    67  <Minimap>
    78    <Type>unit</Type>
  • source/simulation2/components/CCmpRangeManager.cpp

     
    365365            m_DebugOverlayLines.clear();
    366366    }
    367367
     368    virtual std::vector<entity_id_t> GetEntitiesByPlayer(int playerId)
     369    {
     370        std::vector<entity_id_t> entities;
     371
     372        u32 ownerMask = CalcOwnerMask(playerId);
     373
     374        for (std::map<entity_id_t, EntityData>::const_iterator it = m_EntityData.begin(); it != m_EntityData.end(); ++it)
     375        {
     376            // Check owner and add to list if corresponds
     377            if ((it->second.ownerMask & ownerMask))
     378                entities.push_back(it->first);
     379        }
     380
     381        return entities;
     382    }
     383
    368384private:
    369385
    370386    /**
  • source/simulation2/components/ICmpRangeManager.cpp

     
    2929DEFINE_INTERFACE_METHOD_1("DisableActiveQuery", void, ICmpRangeManager, DisableActiveQuery, ICmpRangeManager::tag_t)
    3030DEFINE_INTERFACE_METHOD_1("ResetActiveQuery", std::vector<entity_id_t>, ICmpRangeManager, ResetActiveQuery, ICmpRangeManager::tag_t)
    3131DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpRangeManager, SetDebugOverlay, bool)
     32DEFINE_INTERFACE_METHOD_1("GetEntitiesByPlayer", std::vector<entity_id_t>, ICmpRangeManager, GetEntitiesByPlayer, int)
    3233END_INTERFACE_WRAPPER(RangeManager)
  • source/simulation2/components/ICmpRangeManager.h

     
    116116     */
    117117    virtual void SetDebugOverlay(bool enabled) = 0;
    118118
     119    /**
     120     * Returns list of all entities for specific player
     121     * Note: this function probably needs to be moved to some new
     122     * CmpEntitiesManager component with all other entities tracking
     123     * code placed in this component
     124     */
     125    virtual std::vector<entity_id_t> GetEntitiesByPlayer(int playerId) = 0;
     126
    119127    DECLARE_INTERFACE_TYPE(RangeManager)
    120128};
    121129
  • source/simulation2/MessageTypes.h

     
    310310    ICmpPathfinder::Path path;
    311311};
    312312
     313
     314/**
     315 * Sent to player when it was defeated
     316 */
     317class CMessagePlayerDefeated : public CMessage
     318{
     319public:
     320    DEFAULT_MESSAGE_IMPL(PlayerDefeated)
     321
     322    CMessagePlayerDefeated()
     323    {
     324    }
     325};
     326
     327
    313328#endif // INCLUDED_MESSAGETYPES
  • source/simulation2/scripting/MessageTypeConversions.cpp

     
    245245
    246246////////////////////////////////////////////////////////////////
    247247
     248jsval CMessagePlayerDefeated::ToJSVal(ScriptInterface& UNUSED(scriptInterface)) const
     249{
     250    return JSVAL_VOID;
     251}
     252
     253CMessage* CMessagePlayerDefeated::FromJSVal(ScriptInterface& UNUSED(scriptInterface), jsval UNUSED(val))
     254{
     255    return new CMessagePlayerDefeated();
     256}
     257
     258////////////////////////////////////////////////////////////////
     259
    248260CMessage* CMessageFromJSVal(int mtid, ScriptInterface& scriptingInterface, jsval val)
    249261{
    250262    switch (mtid)
  • source/simulation2/Simulation2.cpp

     
    112112            LOAD_SCRIPTED_COMPONENT("GuiInterface");
    113113            LOAD_SCRIPTED_COMPONENT("PlayerManager");
    114114            LOAD_SCRIPTED_COMPONENT("Timer");
     115            LOAD_SCRIPTED_COMPONENT("EndGameManager");
    115116
    116117#undef LOAD_SCRIPTED_COMPONENT
    117118        }
  • source/simulation2/TypeList.h

     
    4545MESSAGE(RangeUpdate)
    4646MESSAGE(TerrainChanged)
    4747MESSAGE(PathResult)
     48MESSAGE(PlayerDefeated)
    4849
    4950// TemplateManager must come before all other (non-test) components,
    5051// so that it is the first to be (de)serialized