Ticket #1234: #1234-2012-03-22.patch

File #1234-2012-03-22.patch, 18.4 KB (added by leper, 12 years ago)
  • binaries/data/mods/public/civs/cart.json

     
    9292        {
    9393            "Template": "units/cart_cavalry_javelinist_b"
    9494        }
     95    ],
     96    "Formations":
     97    [
     98        "Scatter",
     99        "Box",
     100        "Column Closed",
     101        "Line Closed",
     102        "Column Open",
     103        "Line Open",
     104        "Flank",
     105        "Skirmish",
     106        "Wedge",
     107        "Battle Line"
    95108    ]
    96109}
  • binaries/data/mods/public/civs/celt.json

     
    140140        {
    141141            "Template": "units/celt_cavalry_swordsman_b"
    142142        }
     143    ],
     144    "Formations":
     145    [
     146        "Scatter",
     147        "Box",
     148        "Column Closed",
     149        "Line Closed",
     150        "Column Open",
     151        "Line Open",
     152        "Flank",
     153        "Skirmish",
     154        "Wedge",
     155        "Battle Line"
    143156    ]
    144157}
  • binaries/data/mods/public/civs/hele.json

     
    159159        {
    160160            "Template": "units/hele_cavalry_swordsman_b"
    161161        }
     162    ],
     163    "Formations":
     164    [
     165        "Scatter",
     166        "Box",
     167        "Column Closed",
     168        "Line Closed",
     169        "Column Open",
     170        "Line Open",
     171        "Flank",
     172        "Skirmish",
     173        "Wedge",
     174        "Battle Line",
     175        "Phalanx",
     176        "Syntagma"
    162177    ]
    163178}
  • binaries/data/mods/public/civs/iber.json

     
    9999        {
    100100            "Template": "units/iber_cavalry_spearman_b"
    101101        }
     102    ],
     103    "Formations":
     104    [
     105        "Scatter",
     106        "Box",
     107        "Column Closed",
     108        "Line Closed",
     109        "Column Open",
     110        "Line Open",
     111        "Flank",
     112        "Skirmish",
     113        "Wedge",
     114        "Battle Line"
    102115    ]
    103116}
  • binaries/data/mods/public/civs/pers.json

     
    100100        {
    101101            "Template": "units/pers_cavalry_javelinist_b"
    102102        }
     103    ],
     104    "Formations":
     105    [
     106        "Scatter",
     107        "Box",
     108        "Column Closed",
     109        "Line Closed",
     110        "Column Open",
     111        "Line Open",
     112        "Flank",
     113        "Skirmish",
     114        "Wedge",
     115        "Battle Line"
    103116    ]
    104117}
  • binaries/data/mods/public/civs/rome.json

     
    105105        {
    106106            "Template": "units/rome_cavalry_spearman_b"
    107107        }
     108    ],
     109    "Formations":
     110    [
     111        "Scatter",
     112        "Box",
     113        "Column Closed",
     114        "Line Closed",
     115        "Column Open",
     116        "Line Open",
     117        "Flank",
     118        "Skirmish",
     119        "Wedge",
     120        "Battle Line",
     121        "Testudo"
    108122    ]
    109123}
  • binaries/data/mods/public/gui/session/unit_commands.js

     
    531531                function (item) { unload(entState.id, groups.getEntsByName(item)); } );
    532532        }
    533533
    534         var formations = getEntityFormationsList(entState);
     534        var formations = Engine.GuiInterfaceCall("GetAvailableFormations");
    535535        if (hasClass(entState, "Unit") && !hasClass(entState, "Animal") && !entState.garrisonHolder && formations.length)
    536536        {
    537537            setupUnitPanel("Formation", usedPanels, entState, formations,
  • binaries/data/mods/public/gui/session/utility_functions.js

     
    121121    return dmgArray.join("[font=\"serif-12\"], [/font]");
    122122}
    123123
    124 function getEntityFormationsList(entState)
    125 {
    126     var civ = g_Players[entState.player].civ;
    127     var formations = getCivFormations(civ);
    128     return formations;
    129 }
    130 
    131 function getCivFormations(civ)
    132 {
    133     // TODO: this should come from the civ JSON files instead
    134 
    135     var civFormations = ["Scatter", "Box", "Column Closed", "Line Closed", "Column Open", "Line Open", "Flank", "Skirmish", "Wedge", "Battle Line"];
    136     if (civ == "hele")
    137     {
    138         civFormations.push("Phalanx");
    139         civFormations.push("Syntagma");
    140     }
    141     else if (civ == "rome")
    142     {
    143         civFormations.push("Testudo");
    144     }
    145     return civFormations;
    146 }
    147 
    148124function getEntityCommandsList(entState)
    149125{
    150126    var commands = [];
  • binaries/data/mods/public/simulation/components/Formation.js

     
    214214
    215215    // Choose a sensible size/shape for the various formations, depending on number of units
    216216    var cols;
    217     if (columnar || this.formationName == "Column Closed")
     217   
     218    if (columnar)
     219        this.formationName = "Column Closed";
     220    switch(this.formationName)
    218221    {
     222    case "Column Closed":
    219223        // Have at most 3 files
    220224        if (count <= 3)
    221225            cols = count;
    222226        else
    223227            cols = 3;
    224228        shape = "square";
    225     }
    226     else if (this.formationName == "Phalanx")
    227     {
     229        break;
     230    case "Phalanx":
    228231        // Try to have at least 5 files (so batch training gives a single line),
    229232        // and at most 8
    230233        if (count <= 5)
     
    238241        else
    239242            cols = Math.ceil(count/6);
    240243        shape = "square";
    241     }
    242     else if (this.formationName == "Line Closed")
    243     {
     244        break;
     245    case "Line Closed":
    244246        if (count <= 3)
    245247            cols = count;
    246248        else if (count < 30)
     
    248250        else
    249251            cols = Math.ceil(count/3);
    250252        shape = "square";
    251     }
    252     else if (this.formationName == "Testudo")
    253     {
     253        break;
     254    case "Testudo":
    254255        cols = Math.ceil(Math.sqrt(count));
    255256        shape = "square";
    256     }
    257     else if (this.formationName == "Column Open")
    258     {
    259         cols = 2
     257        break;
     258    case "Column Open":
     259        cols = 2;
    260260        shape = "opensquare";
    261     }
    262     else if (this.formationName == "Line Open")
    263     {
     261        break;
     262    case "Line Open":
    264263        if (count <= 5)
    265264            cols = 3;
    266265        else if (count <= 11)
     
    270269        else
    271270            cols = 6;
    272271        shape = "opensquare";
    273     }
    274     else if (this.formationName == "Scatter")
    275     {
     272        break;
     273    case "Scatter":
    276274        var width = Math.sqrt(count) * separation * 5;
    277275
    278276        for (var i = 0; i < count; ++i)
    279277        {
    280278            offsets.push({"x": Math.random()*width, "z": Math.random()*width});
    281279        }
    282     }
    283     else if (this.formationName == "Circle")
    284     {
     280        break;
     281    case "Circle":
    285282        var depth;
    286283        var pop;
    287284        if (count <= 36)
     
    291288        }
    292289        else
    293290        {
    294             depth = 3
     291            depth = 3;
    295292            pop = Math.ceil(count / depth);
    296293        }
    297294
     
    311308                left--;
    312309            }
    313310        }
    314     }
    315     else if (this.formationName == "Box")
    316     {
     311        break;
     312    case "Box":
    317313        var root = Math.ceil(Math.sqrt(count));
    318314
    319315        var left = count;
     
    334330                    meleeleft -= stodo;
    335331                }
    336332                else    // compact
     333                {
    337334                    stodo = Math.max(0, left - (width-2)*(width-2));
     335                }
    338336            }
    339337
    340338            for (var r = -sq; r <= sq && stodo; ++r)
     
    352350                }
    353351            }
    354352        }
    355     }
    356     else if (this.formationName == "Skirmish")
    357     {
     353        break;
     354    case "Skirmish":
    358355        cols = Math.ceil(count/2);
    359356        shape = "opensquare";
    360     }
    361     else if (this.formationName == "Wedge")
    362     {
     357        break;
     358    case "Wedge":
    363359        var depth = Math.ceil(Math.sqrt(count));
    364360
    365361        var left = count;
     
    387383                }
    388384            }
    389385        }
    390     }
    391     else if (this.formationName == "Flank")
    392     {
     386        break;
     387    case "Flank":
    393388        cols = 3;
    394389        var leftside = [];
    395390        leftside[0] = Math.ceil(count/2);
     
    412407                left -= n;
    413408            }
    414409        }
    415     }
    416     else if (this.formationName == "Syntagma")
    417     {
    418         var cols = Math.ceil(Math.sqrt(count));
     410        break;
     411    case "Syntagma":
     412        cols = Math.ceil(Math.sqrt(count));
    419413        shape = "square";
    420     }
    421     else if (this.formationName == "Battle Line")
    422     {
     414        break;
     415    case "Battle Line":
    423416        if (count <= 5)
    424417            cols = count;
    425418        else if (count <= 10)
     
    433426        shape = "opensquare";
    434427        separation /= 1.5;
    435428        ordering = "cavalryOnTheSides";
     429        break;
     430    default:    // We encountered an unknown formation (probably due to a modding attempt) -> Warn the user
     431        warn("Formation.js: ComputeFormationOffsets: unknown formation: " + this.formationName);
     432        break;
    436433    }
    437434
    438435    if (shape == "square")
  • binaries/data/mods/public/simulation/components/GuiInterface.js

     
    362362        return "";
    363363};
    364364
     365GuiInterface.prototype.GetAvailableFormations = function(player, data)
     366{
     367    var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     368    var cmpPlayer = Engine.QueryInterface(cmpPlayerMan.GetPlayerByID(player), IID_Player);
     369    return cmpPlayer.GetFormations();
     370};
     371
    365372GuiInterface.prototype.GetFormationRequirements = function(player, data)
    366373{
    367374    return GetFormationRequirements(data.formationName);
     
    804811    "GetTemplateData": 1,
    805812    "GetNextNotification": 1,
    806813
     814    "GetAvailableFormations": 1,
    807815    "GetFormationRequirements": 1,
    808816    "CanMoveEntsIntoFormation": 1,
    809817    "IsFormationSelected": 1,
  • binaries/data/mods/public/simulation/components/Identity.js

     
    123123    return this.GetFormationsList().indexOf(name) != -1;
    124124};
    125125
     126Identity.prototype.CanUseFormations = function()
     127{
     128    return this.GetFormationsList().length == 0 ? false : true;
     129};
     130
    126131Identity.prototype.GetSelectionGroupName = function()
    127132{
    128133    return (this.template.SelectionGroupName || "");
  • binaries/data/mods/public/simulation/components/Player.js

     
    2525    this.diplomacy = [];    // array of diplomatic stances for this player with respect to other players (including gaia and self)
    2626    this.conquestCriticalEntitiesCount = 0; // number of owned units with ConquestCritical class
    2727    this.phase = "village";
     28    this.formations = [];
    2829    this.startCam = undefined;
    2930    this.controlAllUnits = false;
    3031    this.isAI = false;
     
    233234    this.phase = p;
    234235};
    235236
     237Player.prototype.GetFormations = function()
     238{
     239    return this.formations;
     240};
     241
     242Player.prototype.SetFormations = function(formations)
     243{
     244    this.formations = formations;
     245};
     246
    236247Player.prototype.GetStartingCameraPos = function()
    237248{
    238249    return this.startCam.position;
  • binaries/data/mods/public/simulation/helpers/Commands.js

     
    380380
    381381    case "formation":
    382382        var entities = FilterEntityList(cmd.entities, player, controlAllUnits);
    383         GetFormationUnitAIs(entities).forEach(function(cmpUnitAI) {
     383        GetFormationUnitAIs(entities, cmd.name).forEach(function(cmpUnitAI) {
    384384            var cmpFormation = Engine.QueryInterface(cmpUnitAI.entity, IID_Formation);
    385385            if (!cmpFormation)
    386386                return;
     
    481481 * Returns a list of UnitAI components, each belonging either to a
    482482 * selected unit or to a formation entity for groups of the selected units.
    483483 */
    484 function GetFormationUnitAIs(ents)
     484function GetFormationUnitAIs(ents, formName)
    485485{
    486486    // If an individual was selected, remove it from any formation
    487487    // and command it individually
     
    508508            continue;
    509509
    510510        var cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
    511         // TODO: Currently we use LineClosed as effectively a boolean flag
    512         // to determine whether formations are allowed at all. Instead we
    513         // should check specific formation names and do something sensible
    514         // (like what?) when some units don't support them.
    515         // TODO: We'll also need to fix other formation code to use
    516         // "LineClosed" instead of "Line Closed" etc consistently.
    517         if (cmpIdentity && cmpIdentity.CanUseFormation("LineClosed"))
     511        // TODO: If formName is undefined we just check whether we can
     512        // use LineClosed instead of checking the current formation.
     513        // NOTE: We should keep "LineClosed" (instead of "Line Closed")
     514        // to Commands.js, Identity.js and the xml files. If you need to
     515        // access the formation data from the xml files use .replace(/\s+/,'').
     516        if (cmpIdentity && cmpIdentity.CanUseFormations()
     517            && cmpIdentity.CanUseFormation(formName === undefined ? "LineClosed" : formName.replace(/\s+/,'')))
    518518            formedEnts.push(ent);
    519519        else
    520520            nonformedUnitAIs.push(cmpUnitAI);
     
    651651    var count = ents.length;
    652652
    653653    // TODO: should check the player's civ is allowed to use this formation
     654    // See simulation/components/Player.js GetFormations() for a list of all allowed formations
    654655
    655656    var requirements = GetFormationRequirements(formationName);
    656657    if (!requirements)
  • binaries/data/mods/public/simulation/helpers/Player.js

     
    118118                }
    119119            }
    120120           
     121            // If formations are explicitly defined, use that; otherwise use civ defaults
     122            if (getSetting(pData, pDefs, "Formations") !== undefined)
     123            {
     124                cmpPlayer.SetFormations(getSetting(pData, pDefs, "Formations"));
     125            }
     126            else
     127            {
     128                // We read the formation data from civ/{civ}.json
     129                var rawFormations = Engine.ReadCivJSONFile(cmpPlayer.GetCiv()+".json");
     130                if (!(rawFormations && rawFormations.Formations))
     131                {
     132                    throw("Player.js: Error reading "+cmpPlayer.GetCiv()+".json");
     133                }
     134                cmpPlayer.SetFormations(rawFormations.Formations);
     135            }
     136           
    121137            var startCam = getSetting(pData, pDefs, "StartingCamera");
    122138            if (startCam !== undefined)
    123139            {
  • binaries/data/mods/public/simulation/templates/template_unit_support_female_citizen.xml

     
    2626  <Builder>
    2727    <Rate>1.0</Rate>
    2828    <Entities datatype="tokens">
    29       structures/{civ}_house
     29      structures/{civ}_house
    3030      structures/{civ}_mill
    3131      structures/{civ}_farmstead
    3232      structures/{civ}_field
     
    5151    <History>Women in the ancient world took on a variety of roles - from leadership (Celts) to servant (Greeks). Women are hard workers, the economic backbone of any civilisation. In history, it was typical when all the males (capable of fighting) were killed for the females, children, and elderly to be sold as slaves.</History>
    5252    <Tooltip>Gather resources, build civic structures, and inspire nearby males to work faster. Bonused at foraging and farming.</Tooltip>
    5353    <Classes datatype="tokens">Worker Female</Classes>
     54    <Formations disable=""/>
    5455  </Identity>
    5556  <ResourceGatherer>
    5657    <MaxDistance>2.0</MaxDistance>
     
    6970  </ResourceGatherer>
    7071  <Sound>
    7172    <SoundGroups>
    72       <select>voice/hellenes/civ/civ_female_select.xml</select>
    73       <order_walk>voice/hellenes/civ/civ_female_select.xml</order_walk>
     73      <select>voice/hellenes/civ/civ_female_select.xml</select>
     74      <order_walk>voice/hellenes/civ/civ_female_select.xml</order_walk>
    7475      <order_attack>voice/hellenes/civ/civ_female_select.xml</order_attack>
    7576      <order_gather>voice/hellenes/civ/civ_female_select.xml</order_gather>
    7677      <order_repair>voice/hellenes/civ/civ_female_select.xml</order_repair>
  • source/simulation2/system/ComponentManager.cpp

     
    8181        m_ScriptInterface.RegisterFunction<int, std::string, CComponentManager::Script_AddLocalEntity> ("AddLocalEntity");
    8282        m_ScriptInterface.RegisterFunction<void, int, CComponentManager::Script_DestroyEntity> ("DestroyEntity");
    8383        m_ScriptInterface.RegisterFunction<CScriptVal, std::wstring, CComponentManager::Script_ReadJSONFile> ("ReadJSONFile");
     84        m_ScriptInterface.RegisterFunction<CScriptVal, std::wstring, CComponentManager::Script_ReadCivJSONFile> ("ReadCivJSONFile");
    8485    }
    8586
    8687    // Define MT_*, IID_* as script globals, and store their names
     
    938939
    939940CScriptVal CComponentManager::Script_ReadJSONFile(void* cbdata, std::wstring fileName)
    940941{
     942    return ReadJSONFile(cbdata, L"simulation/data", fileName);
     943}
     944
     945CScriptVal CComponentManager::Script_ReadCivJSONFile(void* cbdata, std::wstring fileName)
     946{
     947    return ReadJSONFile(cbdata, L"civs", fileName);
     948}
     949
     950CScriptVal CComponentManager::ReadJSONFile(void* cbdata, std::wstring relativePath, std::wstring fileName)
     951{
    941952    CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
    942953
    943     VfsPath path = VfsPath("simulation/data") / fileName;
     954    VfsPath path = VfsPath(relativePath) / fileName;
    944955
    945956    return componentManager->GetScriptInterface().ReadJSONFile(path).get();
    946957}
  • source/simulation2/system/ComponentManager.h

     
    233233    static int Script_AddLocalEntity(void* cbdata, std::string templateName);
    234234    static void Script_DestroyEntity(void* cbdata, int ent);
    235235    static CScriptVal Script_ReadJSONFile(void* cbdata, std::wstring fileName);
     236    static CScriptVal Script_ReadCivJSONFile(void* cbdata, std::wstring fileName);
     237
     238    static CScriptVal ReadJSONFile(void* cbdata, std::wstring relativePath, std::wstring fileName);
    236239
    237240    CMessage* ConstructMessage(int mtid, CScriptVal data);
    238241    void SendGlobalMessage(entity_id_t ent, const CMessage& msg) const;