Ticket #3987: civselection_randomcivoptionWIP_v2.patch

File civselection_randomcivoptionWIP_v2.patch, 56.0 KB (added by Sandarac, 8 years ago)

More Fixes.

  • binaries/data/config/default.cfg

     
    8585noautomipmap = true
    8686novbo = false
    8787noframebufferobject = false
     88randomcultures = true
    8889
    8990; Disable hardware cursors
    9091nohwcursor = false
  • binaries/data/mods/public/gui/civselect/civselect.js

     
     1// Globals
     2var g_CivData = {};
     3var g_GroupingData = {};
     4var g_GroupingChoice = "none";
     5var g_SelectedGroupingChoice = "none";
     6var g_Player = 0;
     7var g_Selected = {
     8    "isGroup": false,
     9    "code": "athen"
     10};
     11var g_EmblemMargin = 8;
     12var g_HeaderEmblemSize = 80;
     13var g_DoubleClick = false;
     14
     15/**
     16 * Run when UI Page loaded.
     17 */
     18function init(settings)
     19{
     20    // Cache civ data
     21    g_CivData = loadCivData(true);
     22    g_Player = settings.player;
     23
     24    // If no civ passed, choose one at random
     25    if (!settings.civ)
     26    {
     27        let num = Math.floor(Math.random() * Object.keys(g_CivData).length);
     28        settings.civ = {
     29            "codes": [ Object.keys(g_CivData)[num] ],
     30            "grouped": false
     31        };
     32    }
     33    g_DoubleClick = false;
     34    // Cache grouping data and create list
     35    let grpList = [ "Ungrouped" ];
     36    let grpList_data = [ "nogroup" ];
     37    for (let grp of Engine.BuildDirEntList("simulation/data/civs/grouping/", "*.json", false))
     38    {
     39        let data = Engine.ReadJSONFile(grp);
     40        if (!data)
     41            continue;
     42        translateObjectKeys(data, ["ListEntry"]);
     43        g_GroupingData[data.Code] = loadGroupingSchema(data.Folder, data.CivAttribute);
     44        grpList.push(data.ListEntry);
     45        grpList_data.push(data.Code);
     46    }
     47
     48    let grpSel = Engine.GetGUIObjectByName("groupSelection");
     49
     50    grpSel.list = grpList;
     51    grpSel.list_data = grpList_data;
     52
     53    // Read civ choice from passed data
     54    if (!settings.civ.grouped)
     55    {
     56        g_Selected.code = settings.civ.codes[0];
     57        grpSel.selected = 0;
     58        selectCiv(g_Selected.code);
     59    }
     60    else
     61    {
     62        g_GroupingChoice = settings.civ.group.type;
     63        g_SelectedGroupingChoice = settings.civ.group.type;
     64        g_Selected.isGroup = true;
     65        if (settings.civ.group.code !== "all")
     66        {
     67            g_Selected.code = settings.civ.group.code;
     68            grpSel.selected = grpSel.list_data.indexOf(g_GroupingChoice);
     69            selectGroup(g_Selected.code);
     70        }
     71        else
     72        {
     73            grpSel.selected = 0;
     74            selectAllCivs();
     75        }
     76    }
     77    Engine.GetGUIObjectByName("randomCultures").checked = Engine.ConfigDB_GetValue("user", "randomcultures") === "true";
     78}
     79
     80function chooseGrouping(choice)
     81{
     82    if (choice === "nogroup")
     83        draw_ungrouped();
     84    else
     85        draw_grouped(choice);
     86}
     87
     88function draw_grouped(group)
     89{
     90    Engine.GetGUIObjectByName("optionRandomCultures").hidden = !Engine.GetGUIObjectByName("allUngrouped_check").checked;
     91
     92    let grp = 0;
     93    let emb = 0;
     94    let vOffset = 0;
     95    g_GroupingChoice = group;
     96
     97    let grouping = g_GroupingData[group];
     98    let selectedCivs = []
     99
     100    for (let civ in g_CivData)
     101        g_CivData[civ].embs = [];
     102    for (let code in grouping)
     103    {
     104        // Pre-emptive check to make sure we have at least one emblem left
     105        if (!Engine.GetGUIObjectByName("emblem["+emb+"]"))
     106            break;
     107
     108        let grpObj = Engine.GetGUIObjectByName("civGroup["+grp+"]");
     109        if (grpObj === undefined)
     110        {
     111            error("There are more grouping choices available than can be supported by the current GUI layout");
     112            break;
     113        }
     114
     115        let grpSize = grpObj.size;
     116        grpSize.top = vOffset;
     117        grpSize.left = (code === "groupless") ? g_EmblemMargin : g_HeaderEmblemSize-g_EmblemMargin;
     118        grpObj.size = grpSize;
     119        grpObj.hidden = false;
     120
     121        g_GroupingData[g_GroupingChoice][code].embs = [];
     122
     123        let grpHeading = Engine.GetGUIObjectByName("civGroup["+grp+"]_heading");
     124        grpHeading.caption = grouping[code].Name;
     125
     126        if (code !== "groupless")
     127        {
     128            let grpBtn = Engine.GetGUIObjectByName("emblem["+emb+"]_btn");
     129            grpBtn.tooltip = grouping[code].Name;
     130            setBtnFunc(grpBtn, selectGroup, [ code ]);
     131
     132            setEmbPos("emblem["+emb+"]", 0, vOffset+g_EmblemMargin);
     133            setEmbSize("emblem["+emb+"]", g_HeaderEmblemSize);
     134
     135            let sprite = (code!==g_Selected.code) ? "grayscale:" : "";
     136            if (grouping[code].Emblem)
     137                sprite += grouping[code].Emblem;
     138            else
     139                sprite += g_CivData[grouping[code].civlist[0]].Emblem;
     140            Engine.GetGUIObjectByName("emblem["+emb+"]_img").sprite = "stretched:"+sprite;
     141            Engine.GetGUIObjectByName("emblem["+emb+"]").hidden = false;
     142            g_GroupingData[g_GroupingChoice][code].embs.push(emb);
     143            ++emb;
     144        }
     145
     146        let range = [ emb ];
     147
     148        for (let civ of grouping[code].civlist)
     149        {
     150            if (g_Selected.code !== "all" && g_Selected.isGroup && g_GroupingData[g_GroupingChoice] &&
     151                g_GroupingData[g_SelectedGroupingChoice][g_Selected.code].civlist.indexOf(civ) > -1)
     152                selectedCivs.push(emb);
     153            if (!g_Selected.isGroup && civ == g_Selected.code)
     154                selectedCivs.push(emb);
     155            let embImg = Engine.GetGUIObjectByName("emblem["+emb+"]_img");
     156            if (embImg === undefined)
     157            {
     158                error("There are not enough images in the current GUI layout to support that many civs");
     159                break;
     160            }
     161            g_CivData[civ].embs.push(emb);
     162            g_GroupingData[g_GroupingChoice][code].embs.push(emb);
     163
     164            embImg.sprite = "stretched:";
     165            if (civ !== g_Selected.code && code !== g_Selected.code)
     166                embImg.sprite += "grayscale:";
     167            embImg.sprite += g_CivData[civ].Emblem;
     168
     169            let embBtn = Engine.GetGUIObjectByName("emblem["+emb+"]_btn");
     170            embBtn.tooltip = g_CivData[civ].Name;
     171            setBtnFunc(embBtn, selectCiv, [ civ ]);
     172            Engine.GetGUIObjectByName("emblem["+emb+"]").hidden = false;
     173
     174            emb++;
     175        }
     176        range[1] = emb - 1;
     177
     178        setEmbSize("emblem["+range[0]+"]", 58);
     179        vOffset += grpHeading.size.bottom + 2;
     180        vOffset += gridArrayRepeatedObjects("emblem[emb]", "emb", 4, range, vOffset, ((code==="groupless")?g_EmblemMargin:g_HeaderEmblemSize));
     181        vOffset += g_EmblemMargin * 2;
     182        grp++;
     183    }
     184    hideRemaining("emblem[", emb, "]");
     185    hideRemaining("civGroup[", grp, "]");
     186    highlightEmblems(selectedCivs);
     187
     188    if (g_Selected.code === "all")
     189        selectAllCivs();
     190}
     191
     192function draw_ungrouped()
     193{
     194    setEmbSize("emblem[0]");
     195    gridArrayRepeatedObjects("emblem[emb]", "emb", 8);
     196
     197    let emb = 0;
     198    let selectedCivs = []
     199    for (let civ in g_CivData)
     200    {
     201        if (g_Selected.code !== "all" && g_Selected.isGroup && g_GroupingData[g_GroupingChoice] &&
     202            g_GroupingData[g_SelectedGroupingChoice][g_Selected.code].civlist.indexOf(civ) > -1)
     203            selectedCivs.push(emb);
     204        if (!g_Selected.isGroup && civ == g_Selected.code)
     205            selectedCivs.push(emb);
     206
     207        g_CivData[civ].embs = [emb];
     208
     209        let embImg = Engine.GetGUIObjectByName("emblem["+emb+"]_img");
     210
     211        if (embImg === undefined)
     212        {
     213            error("There are not enough images in the current GUI layout to support that many civs");
     214            break;
     215        }
     216
     217        embImg.sprite = "stretched:";
     218        if (civ !== g_Selected.code)
     219            embImg.sprite += "grayscale:";
     220        embImg.sprite += g_CivData[civ].Emblem;
     221
     222        let embBtn = Engine.GetGUIObjectByName("emblem["+emb+"]_btn");
     223        embBtn.tooltip = g_CivData[civ].Name
     224        setBtnFunc(embBtn, selectCiv, [ civ ]);
     225        Engine.GetGUIObjectByName("emblem["+emb+"]").hidden = false;
     226        emb++;
     227    }
     228    hideRemaining("emblem[", emb, "]");
     229    hideRemaining("civGroup[", 0, "]");
     230    highlightEmblems(selectedCivs);
     231
     232    if (g_Selected.code === "all")
     233        selectAllCivs();
     234}
     235
     236function selectCiv(code)
     237{
     238    Engine.GetGUIObjectByName("optionRandomCultures").hidden = true;
     239    Engine.GetGUIObjectByName("allUngrouped_check").checked = false;
     240    highlightEmblems(g_CivData[code].embs);
     241
     242    g_Selected.isGroup = false;
     243    g_Selected.code = code;
     244    let choice = Engine.GetGUIObjectByName("selected_text");
     245    choice.caption = sprintf(translate("You have selected the %(civname)s"), {"civname": g_CivData[code].Name});
     246
     247    g_SelectedGroupingChoice = "none";
     248
     249    displayCivInfo(code);
     250}
     251
     252function displayCivInfo(code)
     253{
     254    if (g_DoubleClick)
     255        return;
     256
     257    let heading = Engine.GetGUIObjectByName("selected_heading");
     258    heading.caption = g_CivData[code].Name;
     259
     260    let civList = Engine.GetGUIObjectByName("selected_civs");
     261    civList.hidden = true;
     262
     263    let history = Engine.GetGUIObjectByName("selected_history");
     264    history.caption = g_CivData[code].History;
     265
     266    let size = history.parent.size;
     267    size.top = 48;
     268    history.parent.size = size;
     269    history.parent.hidden = false;
     270}
     271
     272function selectGroup(code)
     273{
     274    highlightEmblems(g_GroupingData[g_GroupingChoice][code].embs);
     275    Engine.GetGUIObjectByName("allUngrouped_check").checked = false;
     276    Engine.GetGUIObjectByName("optionRandomCultures").hidden = true;
     277
     278    g_Selected.isGroup = true;
     279    g_Selected.code = code;
     280    g_SelectedGroupingChoice = g_GroupingChoice;
     281   
     282    displayGroupingInfo(code);
     283
     284    let choice = Engine.GetGUIObjectByName("selected_text");
     285    if (g_GroupingData[g_GroupingChoice][code].Singular)
     286        choice.caption = sprintf(translate("A random %(civGroup)s civilization will be chosen."), {
     287            "civGroup": g_GroupingData[g_GroupingChoice][code].Singular
     288        });
     289    else
     290        choice.caption = translate("A civilization  will be chosen at random from this group");
     291}
     292
     293function displayGroupingInfo(code)
     294{
     295    let heading = Engine.GetGUIObjectByName("selected_heading");
     296    heading.caption = g_GroupingData[g_GroupingChoice][code].Name;
     297
     298    let civList = Engine.GetGUIObjectByName("selected_civs");
     299    civList.hidden = false;
     300    civList.caption = "";
     301    let civCount = 0;
     302    for (let civ of g_GroupingData[g_GroupingChoice][code].civlist)
     303    {
     304        civList.caption += g_CivData[civ].Name + "\n";
     305        civCount++;
     306    }
     307
     308    let history = Engine.GetGUIObjectByName("selected_history");
     309    history.caption = g_GroupingData[g_GroupingChoice][code].History;
     310    let size = history.parent.size;
     311    size.top = 18 * civCount + 64;
     312    history.parent.size = size;
     313    history.parent.hidden = false;
     314}
     315
     316function selectAllCivs()
     317{
     318    Engine.GetGUIObjectByName("allUngrouped_check").checked = true;
     319    Engine.GetGUIObjectByName("optionRandomCultures").hidden = false;
     320
     321    let embs = [];
     322    for (let i=0; ; ++i)
     323    {
     324        if (!Engine.GetGUIObjectByName("emblem["+i+"]"))
     325            break;
     326        embs.push(i);
     327    }
     328    highlightEmblems(embs);
     329
     330    g_Selected.isGroup = true;
     331    g_Selected.code = "all";
     332
     333    let heading = Engine.GetGUIObjectByName("selected_heading");
     334    heading.caption = sprintf(translate("Random %(civGroup)s"), {
     335            "civGroup": translateWithContext("All Civs", "All")
     336        });
     337
     338    let civList = Engine.GetGUIObjectByName("selected_civs");
     339    civList.hidden = false;
     340    civList.caption = "";
     341    let civCount = 0;
     342    for (let civ in g_CivData)
     343    {
     344        civList.caption += g_CivData[civ].Name+"\n";
     345        civCount++;
     346    }
     347
     348    let history = Engine.GetGUIObjectByName("selected_history");
     349    history.parent.hidden = true;
     350
     351    let choice = Engine.GetGUIObjectByName("selected_text");
     352    choice.caption = translate("A civilization will be chosen at random");
     353}
     354
     355function highlightEmblems(embs = [])
     356{
     357    for (let e=0; ; ++e)
     358    {
     359        if (!Engine.GetGUIObjectByName("emblem["+e+"]"))
     360            return;
     361
     362        let embImg = Engine.GetGUIObjectByName("emblem["+e+"]_img");
     363        let sprite = embImg.sprite.split(":");
     364        embImg.sprite = "stretched:" + ((embs.indexOf(e)<0)?"grayscale:":"") + sprite.pop();
     365    }
     366}
     367
     368function setBtnFunc(btn, func, vars = null)
     369{
     370    btn.onMouseLeftRelease = function () { func.apply(null, vars); };
     371    btn.onMouseLeftDoubleClick = function () { returnCiv.apply(null, vars); g_DoubleClick = true; };   
     372}
     373
     374function randomCultures()
     375{
     376    Engine.ConfigDB_CreateValue("user", "randomcultures", String(Engine.GetGUIObjectByName("randomCultures").checked));
     377    Engine.ConfigDB_SetChanges("user", true);
     378    Engine.ConfigDB_WriteFile("user", "config/user.cfg");
     379}
     380
     381function returnCiv()
     382{
     383    let code = g_Selected.code;
     384    let civ = {
     385            "codes": [ g_Selected.code ],
     386            "grouped": false,
     387        }
     388    if (g_Selected.isGroup)
     389    {
     390        civ.codes = g_Selected.code == "all" ? Object.keys(g_CivData) : g_GroupingData[g_SelectedGroupingChoice][code].civlist;
     391        civ.grouped = true;
     392        civ.group = {
     393                "caption": g_Selected.code === "all" ? "All" : g_GroupingData[g_SelectedGroupingChoice][code].Singular,
     394                "code": g_Selected.code,
     395                "type": g_SelectedGroupingChoice,
     396            };
     397    }
     398    Engine.PopGuiPageCB({
     399            "player": g_Player,
     400            "civ": civ,
     401            "randomCultures" : Engine.GetGUIObjectByName("randomCultures").checked
     402        });
     403}
  • binaries/data/mods/public/gui/civselect/civselect.xml

     
     1<?xml version="1.0" encoding="utf-8"?>
     2
     3<objects>
     4    <script file="gui/common/functions_civinfo.js"/>
     5    <script file="gui/common/functions_global_object.js"/>
     6    <script file="gui/common/functions_repeat_positioning.js"/>
     7    <script file="gui/common/functions_utility.js"/>
     8    <script file="gui/civselect/helpers.js"/>
     9    <script file="gui/civselect/civselect.js"/>
     10
     11    <!-- Add a translucent black background to fade out the match page -->
     12    <object type="image" z="0" sprite="bkTranslucent"/>
     13
     14    <object type="image" style="ModernDialog" size="50%-488 50%-360 50%+488 50%+360">
     15
     16        <object style="TitleText" type="text" size="50%-128 -18 50%+128 14">
     17            <translatableAttribute id="caption">Civilization Selection</translatableAttribute>
     18        </object>
     19
     20        <object size="16 32 70%-8 100%-32">
     21
     22            <!-- grouping selection -->
     23            <object size="50% 0 100% 40">
     24                <object
     25                    name="groupSelectionHeading"
     26                    type="text"
     27                    font="sans-bold-16"
     28                    textcolor="white"
     29                    text_align="right"
     30                    size="0 2 100%-196 32"
     31                >
     32                    <translatableAttribute id="caption">Group by:</translatableAttribute>
     33                </object>
     34
     35                <object name="groupSelection" type="dropdown" style="ModernDropDown" size="100%-192 0 100% 26">
     36                    <translatableAttribute id="tooltip">Choose how to group civilizations</translatableAttribute>
     37                    <action on="SelectionChange">chooseGrouping(this.list_data[this.selected]);</action>
     38                </object>
     39            </object>
     40
     41            <!-- draw space -->
     42            <object type="image" size="0 40 100% 100%">
     43
     44                <repeat count="32" var="em">
     45                    <object name="emblem[em]" size="4 8 4+64 8+64">
     46                        <object type="image" style="EmblemImage" name="emblem[em]_img"/>
     47                        <object type="button" style="EmblemButton" name="emblem[em]_btn" tooltip_style="sessionToolTipBold">
     48                        </object>
     49                    </object>
     50                </repeat>
     51
     52                <repeat count="12" var="g">
     53                    <object size="8 8 100%-8 24+72+16" name="civGroup[g]">
     54                        <object
     55                            name="civGroup[g]_heading"
     56                            type="text"
     57                            font="sans-16"
     58                            textcolor="white"
     59                            text_align="left"
     60                            size="2 0 50% 24"
     61                        >
     62                            <translatableAttribute id="caption">A group:</translatableAttribute>
     63                        </object>
     64                        <object sprite="ModernGoldLine" type="image" size="0 24 100% 25"/>
     65                    </object>
     66                </repeat>
     67            </object>
     68
     69        </object>
     70
     71        <object sprite="ModernDarkBoxGold" type="image" size="70%+8 32 100%-16 90%-70">
     72
     73            <!-- Selection Details -->
     74            <object
     75                name="selected_heading"
     76                type="text"
     77                font="sans-bold-24"
     78                textcolor="white"
     79                text_align="center"
     80                size="0 12 100% 40"
     81            />
     82
     83            <object
     84                name="selected_civs"
     85                type="text"
     86                font="sans-16"
     87                textcolor="white"
     88                text_align="center"
     89                size="4 44 100%-4 100%-4"
     90            />
     91
     92            <object size="8 48 100%-8 100%-8" type="image" sprite="ModernDarkBoxGold">
     93                <object
     94                    name="selected_history"
     95                    type="text"
     96                    font="sans-14"
     97                    textcolor="white"
     98                    text_align="center"
     99                    size="4 4 100%-4 100%-4"
     100                />
     101            </object>
     102
     103        </object>
     104        <object
     105            name="selected_text"
     106            type="text"
     107            font="sans-12"
     108            textcolor="green"
     109            text_align="center"
     110            text_valign="bottom"
     111            size="70%+8 100%-64 100%-16 100%-48"
     112        />
     113
     114        <object name="allUngrouped" size="650 589 120% 25%">
     115            <object size="0 0 40% 28" type="text" style="ModernRightLabelText">
     116                <translatableAttribute id="caption">Select All:</translatableAttribute>
     117            </object>
     118            <object name="allUngrouped_check" size="225 5 46% -5%" type="checkbox" style="ModernTickBox">
     119                <action on="Press">selectAllCivs();</action>
     120                <translatableAttribute id="tooltip">A civilization will be picked from all possible civilizations (Random All).</translatableAttribute>
     121            </object>
     122        </object>
     123
     124        <object name="optionRandomCultures" size="650 619 120% 25%">
     125            <object size="0 0 40% 28" type="text" style="ModernRightLabelText">
     126                <translatableAttribute id="caption">Random Cultures:</translatableAttribute>
     127            </object>
     128            <object name="randomCultures" size="225 5 46% -5%" type="checkbox" style="ModernTickBox">
     129                <action on="Press">randomCultures();</action>
     130                <translatableAttribute id="tooltip">Civilizations set to "Random All" will be chosen by culture.</translatableAttribute>
     131            </object>
     132        </object>
     133
     134        <!-- Close the dialog -->
     135        <object
     136            type="button"
     137            style="StoneButton"
     138            size="70%+8 100%-44 85%-8 100%-16"
     139        >
     140            <translatableAttribute id="caption">Cancel</translatableAttribute>
     141            <action on="Press">
     142                <![CDATA[
     143                    Engine.PopGuiPage();
     144                ]]>
     145            </action>
     146        </object>
     147
     148        <object
     149            type="button"
     150            style="StoneButton"
     151            size="85% 100%-44 100%-16 100%-16"
     152        >
     153            <translatableAttribute id="caption">Select</translatableAttribute>
     154            <action on="Press">
     155                <![CDATA[
     156                    returnCiv();
     157                ]]>
     158            </action>
     159        </object>
     160
     161    </object>
     162
     163</objects>
  • binaries/data/mods/public/gui/civselect/helpers.js

     
     1
     2/**
     3 * Arranges same-size `<repeat>`d objects in a grid. Automatically scales to object size.
     4 * @param basename The base name of the object, such as "object[n]" or "object[a]_sub[b]"
     5 * @param splitvar The var identifying the repeat count, without the square brackets
     6 * @param vMargin The gap, in px, between the rows
     7 * @param limit Array of limits, of the form `[ {from}, {to} ]`. If an empty array, then it will do all objects matching the basname
     8 * @param vOffset Vertical offset from top of parent object to start drawing from
     9 * @return The height difference between the top of the first element and the bottom of the last.
     10 */
     11function gridArrayRepeatedObjects (basename, splitvar="n", vMargin=0, limit=[], vOffset=0, hOffset=0)
     12{
     13    basename = basename.split("["+splitvar+"]", 2);
     14
     15    if (limit.length == 0)
     16    {
     17        limit = [0, 0, 1];
     18        while (Engine.GetGUIObjectByName(basename.join("["+ (limit[1]+1) +"]")))
     19        {
     20            ++limit[1];
     21            ++limit[2];
     22        }
     23    }
     24    else if (limit.length < 2)
     25    {
     26        error("Invalid limit arguments");
     27        return 0;
     28    }
     29    else
     30        limit[2] = limit[1] - limit[0] + 1;
     31
     32    let firstObj = Engine.GetGUIObjectByName(basename.join("["+limit[0]+"]"));
     33    let child = firstObj.getComputedSize();
     34    child.width = child.right - child.left;
     35    child.height = child.bottom - child.top;
     36
     37    let parent = firstObj.parent.getComputedSize();
     38    parent.width = parent.right - parent.left - hOffset;
     39
     40    let rowLength = Math.floor(parent.width / child.width);
     41    let hMargin = parent.width - child.width * rowLength;
     42    hMargin = Math.round(hMargin / (rowLength + 1));
     43
     44    child.width += hMargin;
     45    child.height += vMargin;
     46
     47    let i = limit[0];
     48    for (let r = 0; r < Math.ceil(limit[2]/rowLength); ++r)
     49    {
     50        for (let c = 0; c < rowLength; ++c)
     51        {
     52            let newSize = new GUISize();
     53            newSize.left = c * child.width + hMargin + hOffset;
     54            newSize.right = (c+1) * child.width + hOffset;
     55            newSize.top = r * child.height + vMargin + vOffset;
     56            newSize.bottom = (r+1) * child.height + vOffset;
     57            Engine.GetGUIObjectByName(basename.join("["+ i++ +"]")).size = newSize;
     58
     59            if (i > limit[1])
     60                break;
     61        }
     62    }
     63
     64    var lastObj = Engine.GetGUIObjectByName(basename.join("["+(i-1)+"]"));
     65    return (lastObj.size.bottom - firstObj.size.top);
     66}
     67
     68/**
     69 * Load Data about a grouping schema
     70 *
     71 * @param attr The JSON attribute in the Civ JSON files that lists which of the groups in this schema that civ belongs to
     72 * @param folder The folder containing the groups of this schema
     73 */
     74function loadGroupingSchema (folder, attr)
     75{
     76    let groupData = {};
     77    let groupless = [];
     78
     79    for (let code of Object.keys(g_CivData))
     80    {
     81        let civ = g_CivData[code];
     82        let nogroup = true;
     83        let groups = civ[attr] || [];
     84        if (typeof groups === "string")
     85            groups = [ groups ];
     86
     87        for (let grp of groups)
     88        {
     89            if (groupData[grp] === undefined)
     90            {
     91                let data = Engine.ReadJSONFile("simulation/data/civs/"+folder+"/"+grp+".json");
     92                if (!data)
     93                    continue;
     94                translateObjectKeys(data, ["Name", "Singular", "History"]);
     95
     96                groupData[grp] = data;
     97                groupData[grp].civlist = [];
     98            }
     99            groupData[grp].civlist.push(code);
     100            nogroup = false;
     101        }
     102        if (nogroup)
     103            groupless.push(code);
     104    }
     105    if (groupless.length > 0)
     106        groupData.groupless = {
     107            "Name" : translateWithContext("Set of civs with no defined group", "Ungrouped"),
     108            "Code" : "groupless",
     109            "History" : "-",
     110            "civlist": groupless
     111        };
     112    return groupData;
     113}
     114
     115function setEmbSize (objectName, length=128)
     116{
     117    let objSize = Engine.GetGUIObjectByName(objectName).size;
     118    objSize.right = objSize.left + length;
     119    objSize.bottom = objSize.top + length;
     120    Engine.GetGUIObjectByName(objectName).size = objSize;
     121}
     122
     123function setEmbPos (objectName, x=0, y=0)
     124{
     125    let objSize = Engine.GetGUIObjectByName(objectName).size;
     126    let wid = objSize.right - objSize.left;
     127    objSize.left = x;
     128    objSize.top = y;
     129    Engine.GetGUIObjectByName(objectName).size = objSize;
     130    setEmbSize(objectName, wid);
     131}
  • binaries/data/mods/public/gui/civselect/setup.xml

     
     1<?xml version="1.0" encoding="utf-8"?>
     2
     3<setup>
     4    <tooltip name="treeTooltip"
     5        anchor="top"
     6        buffer_zone="4"
     7        delay="50"
     8        font="sans-14"
     9        maxwidth="480"
     10        offset="16 24"
     11        sprite="bkTooltip"
     12        textcolor="white"
     13    />
     14</setup>
  • binaries/data/mods/public/gui/civselect/sprites.xml

     
     1<?xml version="1.0" encoding="utf-8"?>
     2
     3<sprites>
     4
     5    <sprite name="CivIconPress">
     6        <image
     7            texture="session/portraits/emblems/states/click.png"
     8        />
     9    </sprite>
     10
     11</sprites>
  • binaries/data/mods/public/gui/civselect/styles.xml

     
     1<?xml version="1.0" encoding="utf-8"?>
     2
     3<styles>
     4
     5    <style name="EmblemButton"
     6        sprite=""
     7        sprite_over="CivIconOver"
     8        sprite_pressed="CivIconPress"
     9        size="0 0 100% 100%"
     10        sound_pressed="audio/interface/ui/ui_button_click.ogg"
     11    />
     12
     13    <style name="EmblemImage"
     14        sprite="stretched:pregame/shell/logo/wfg_logo_white.png"
     15        size="0 0 100% 100%"
     16    />
     17
     18    <style name="HeroImage"
     19        sprite="stretched:pregame/shell/logo/wfg_logo_white.png"
     20        size="0 0 32 32"
     21    />
     22
     23</styles>
  • binaries/data/mods/public/gui/common/functions_repeat_positioning.js

     
     1/*
     2    DESCRIPTION : Functions related to positioning UI elements
     3    NOTES       :
     4*/
     5
     6/**
     7 * Horizontally spaces same-width objects repeated with the `<repeat>` tag
     8 * @param basename The base name of the object, such as "object[n]" or "object[a]_sub[b]"
     9 * @param splitvar The var identifying the repeat count, without the square brackets
     10 * @param margin The gap, in px, between the repeated objects
     11 * @return The number of elements affected
     12 */
     13function horizSpaceRepeatedObjects (basename, splitvar="n", margin=0)
     14{
     15    basename = basename.split("["+splitvar+"]", 2);
     16    for (let c = 0;;)
     17    {
     18        let objObj = Engine.GetGUIObjectByName(basename.join("["+ c +"]"));
     19        if (!objObj)
     20            return c;
     21
     22        let objSize = objObj.size;
     23        let objWidth = objSize.right - objSize.left;
     24        objSize.left = c * (objWidth + margin) + margin;
     25        objSize.right = ++c * (objWidth + margin);
     26        objObj.size = objSize;
     27    }
     28}
     29
     30/**
     31 * Horizontally fit objects repeated with the `<repeat>` tag within a parent object
     32 * @param basename The base name of the object, such as "object[n]" or "object[a]_sub[b]"
     33 * @param splitvar The var identifying the repeat count, without the square brackets
     34 * @param margin The gap, in px, between the repeated objects
     35 * @param limit The number of elements to fit
     36 * @return The number of elements affected
     37 */
     38function horizFitRepeatedObjects (basename, splitvar="n", margin=0, limit=0)
     39{
     40    basename = basename.split("["+splitvar+"]", 2);
     41
     42    var objObj;
     43    if (limit == 0)
     44        do
     45            objObj = Engine.GetGUIObjectByName(basename.join("["+ ++limit +"]"));
     46        while (objObj !== undefined)
     47
     48    for (let c = 0; c < limit; ++c)
     49    {
     50        objObj = Engine.GetGUIObjectByName(basename.join("["+ c +"]"));
     51        let objSize = objObj.size;
     52        objSize.rleft = c * (100/limit);
     53        objSize.rright = (c+1) * (100/limit);
     54        objSize.right = -margin;
     55        objObj.size = objSize;
     56    }
     57
     58    return limit;
     59}
     60
     61/**
     62 * Vertically spaces same-height objects repeated with the `<repeat>` tag
     63 * @param basename The base name of the object, such as "object[n]" or "object[a]_sub[b]"
     64 * @param splitvar The var identifying the repeat count, without the square brackets
     65 * @param margin The gap, in px, between the repeated objects
     66 * @return The number of elements affected
     67 */
     68function vertiSpaceRepeatedObjects (basename, splitvar="n", margin=0)
     69{
     70    basename = basename.split("["+splitvar+"]", 2);
     71    for (let c=0;;)
     72    {
     73        let objObj = Engine.GetGUIObjectByName(basename.join("["+ c +"]"));
     74        if (!objObj)
     75            return c;
     76
     77        let objSize = objObj.size;
     78        let objHeight = objSize.bottom - objSize.top;
     79        objSize.top = c * (objHeight + margin) + margin;
     80        objSize.bottom = ++c * (objHeight + margin);
     81        objObj.size = objSize;
     82    }
     83}
     84
     85/**
     86 * Hide all repeated elements after a certain index
     87 * @param prefix The part of the element name preceeding the index
     88 * @param idx The index from which to start
     89 * @param prefix The part of the element name after the index
     90 */
     91function hideRemaining(prefix, idx, suffix)
     92{
     93    for (;; ++idx)
     94    {
     95        let obj = Engine.GetGUIObjectByName(prefix+idx+suffix);
     96        if (!obj)
     97            break;
     98        obj.hidden = true;
     99    }
     100}
  • binaries/data/mods/public/gui/gamesetup/gamesetup.js

     
    142142const g_RandomMap = '[color="' + g_ColorRandom + '"]' + translateWithContext("map selection", "Random") + "[/color]";
    143143
    144144/**
    145  * Placeholder item for the civ-dropdownlists.
     145 * Style for the random civ strings.
    146146 */
    147 const g_RandomCiv = '[color="' + g_ColorRandom + '"]' + translateWithContext("civilization", "Random") + '[/color]';
     147const g_RandomCivStyle = ['[color="' + g_ColorRandom + '"]', '[/color]'];
    148148
    149149/**
     150 *
     151 */
     152var g_RandomCivObj = {};
     153
     154var g_RandomCultures = Engine.ConfigDB_GetValue("user", "randomcultures") === "true";
     155
     156/**
    150157 * Whether this is a single- or multiplayer match.
    151158 */
    152159var g_IsNetworked;
     
    257264    g_DefaultPlayerData = g_Settings.PlayerDefaults;
    258265    g_DefaultPlayerData.shift();
    259266    for (let i in g_DefaultPlayerData)
    260         g_DefaultPlayerData[i].Civ = "random";
     267        g_DefaultPlayerData[i].CivObj = {
     268                "codes": [ g_DefaultPlayerData[i].Civ ],
     269                "grouped": false
     270        };
     271       
     272    g_RandomCivObj = {
     273                    "codes": Object.keys(g_CivData).filter(civ => g_CivData[civ].SelectableInGameSetup),
     274                    "grouped": true,
     275                    "group": { "type": "none", "code": "all", "caption": translateWithContext("All Civs", "All") }
     276            };
    261277
    262278    setTimeout(displayGamestateNotifications, 1000);
    263279}
     
    269285{
    270286    Engine.GetGUIObjectByName("cancelGame").tooltip = Engine.HasXmppClient() ? translate("Return to the lobby.") : translate("Return to the main menu.");
    271287
    272     initCivNameList();
    273288    initMapTypes();
    274289    initMapFilters();
    275290
     
    534549    for (let i = 0; i < g_MaxPlayers; ++i)
    535550    {
    536551        Engine.GetGUIObjectByName("playerAssignment["+i+"]").hidden = true;
    537         Engine.GetGUIObjectByName("playerCiv["+i+"]").hidden = true;
    538552        Engine.GetGUIObjectByName("playerTeam["+i+"]").hidden = true;
    539553    }
    540554
     
    620634        colorPicker.list_data = g_PlayerColors.map((color, index) => index);
    621635        colorPicker.selected = -1;
    622636        colorPicker.onSelectionChange = function() { selectPlayerColor(playerSlot, this.selected); };
    623 
    624         Engine.GetGUIObjectByName("playerCiv["+i+"]").onSelectionChange = function() {
    625             if ((this.selected != -1)&&(g_GameAttributes.mapType !== "scenario"))
    626                 g_GameAttributes.settings.PlayerData[playerSlot].Civ = this.list_data[this.selected];
    627 
    628             updateGameAttributes();
    629         };
    630637    }
    631638}
    632639
     
    807814    return undefined;
    808815}
    809816
    810 /**
    811  * Initialize the dropdowns containing all selectable civs (including random).
    812  */
    813 function initCivNameList()
     817function setCiv(args)
    814818{
    815     let civList = Object.keys(g_CivData).filter(civ => g_CivData[civ].SelectableInGameSetup).map(civ => ({ "name": g_CivData[civ].Name, "code": civ })).sort(sortNameIgnoreCase);
    816     let civListNames = [g_RandomCiv].concat(civList.map(civ => civ.name));
    817     let civListCodes = ["random"].concat(civList.map(civ => civ.code));
    818 
    819     for (let i = 0; i < g_MaxPlayers; ++i)
    820     {
    821         let civ = Engine.GetGUIObjectByName("playerCiv["+i+"]");
    822         civ.list = civListNames;
    823         civ.list_data = civListCodes;
    824         civ.selected = 0;
    825     }
     819    g_GameAttributes.settings.PlayerData[args.player].CivObj = args.civ;
     820    g_RandomCultures = args.randomCultures;
     821    updateGameAttributes();
    826822}
    827823
    828824/**
     
    917913    if (!g_IsNetworked)
    918914        mapSettings.CheatsEnabled = true;
    919915
    920     // Replace unselectable civs with random civ
     916    // Filter out unselectable civs
    921917    let playerData = mapSettings.PlayerData;
    922918    if (playerData && g_GameAttributes.mapType != "scenario")
    923919        for (let i in playerData)
    924             if (!g_CivData[playerData[i].Civ] || !g_CivData[playerData[i].Civ].SelectableInGameSetup)
    925                 playerData[i].Civ = "random";
     920        {
     921                if (!playerData[i].CivObj)
     922                        continue;
     923                playerData[i].CivObj.codes = playerData[i].CivObj.codes.filter((code) => {return g_CivData[code] && g_CivData[code].SelectableInGameSetup});
     924                if (playerData[i].CivObj.codes.length === 0)
     925                    playerData[i].CivObj = g_RandomCivObj;
     926        }
    926927
    927928    // Apply map settings
    928929    let newMapData = loadMapData(mapName);
     
    961962
    962963    playerData.forEach((pData, index) => {
    963964        pData.Color = pData.Color || g_PlayerColors[index];
    964         pData.Civ = pData.Civ || "random";
     965        pData.CivObj = pData.CivObj ? pData.CivObj : (pData.Civ && pData.Civ !== "random" ? { "codes": [ pData.Civ ], "grouped": false } : g_RandomCivObj)
    965966        pData.AI = pData.AI || "";
    966967    });
    967968
     
    12441245    let cultures = Object.keys(g_CivData).filter(civ => g_CivData[civ].SelectableInGameSetup).map(civ => g_CivData[civ].Culture);
    12451246    cultures = cultures.filter((culture, index) => cultures.indexOf(culture) === index);
    12461247
    1247     // Determine random civs and botnames
    12481248    for (let i in g_GameAttributes.settings.PlayerData)
    12491249    {
    1250         // Pick a random civ of a random culture
    1251         let chosenCiv = g_GameAttributes.settings.PlayerData[i].Civ || "random";
    1252         if (chosenCiv == "random")
     1250        // Determine civ
     1251        let civs = g_GameAttributes.settings.PlayerData[i].CivObj.codes;
     1252        let chosenCiv = civs[0];
     1253
     1254        if (civs.length > 1)
    12531255        {
    1254             let culture = cultures[Math.floor(Math.random() * cultures.length)];
    1255             let civs = Object.keys(g_CivData).filter(civ => g_CivData[civ].Culture == culture);
     1256            if (g_RandomCultures && g_GameAttributes.settings.PlayerData[i].CivObj.group.code == "all")
     1257            {
     1258                let culture = cultures[Math.floor(Math.random() * cultures.length)];
     1259                let civs = Object.keys(g_CivData).filter(civ => g_CivData[civ].Culture == culture);
     1260            }
    12561261            chosenCiv = civs[Math.floor(Math.random() * civs.length)];
    12571262        }
     1263
    12581264        g_GameAttributes.settings.PlayerData[i].Civ = chosenCiv;
    12591265
    12601266        // Pick one of the available botnames for the chosen civ
     
    14161422        let pName = Engine.GetGUIObjectByName("playerName["+i+"]");
    14171423        let pAssignment = Engine.GetGUIObjectByName("playerAssignment["+i+"]");
    14181424        let pAssignmentText = Engine.GetGUIObjectByName("playerAssignmentText["+i+"]");
    1419         let pCiv = Engine.GetGUIObjectByName("playerCiv["+i+"]");
    14201425        let pCivText = Engine.GetGUIObjectByName("playerCivText["+i+"]");
    14211426        let pTeam = Engine.GetGUIObjectByName("playerTeam["+i+"]");
    14221427        let pTeamText = Engine.GetGUIObjectByName("playerTeamText["+i+"]");
     
    14311436
    14321437        let team = getSetting(pData, pDefs, "Team");
    14331438        let civ = getSetting(pData, pDefs, "Civ");
     1439        let civObj = getSetting(pData, pDefs, "CivObj");
    14341440
    14351441        pAssignmentText.caption = pAssignment.list[0] ? pAssignment.list[Math.max(0, pAssignment.selected)] : translate("Loading...");
    1436         pCivText.caption = civ == "random" ? g_RandomCiv : (g_CivData[civ] ? g_CivData[civ].Name : "Unknown");
     1442
     1443        if (civObj)
     1444        {
     1445                if (civObj.grouped)
     1446                        pCivText.caption = g_RandomCivStyle[0] + sprintf(translate("Random %(civGroup)s"), {"civGroup": civObj.group.caption }) + g_RandomCivStyle[1];
     1447                else if (civObj.codes.length > 1)   
     1448                        pCivText.caption = g_RandomCivStyle[0] + translateWithContext("Selection from a group of civilizations", "Arbitrary Selection") + g_RandomCivStyle[1];
     1449                else
     1450                        pCivText.caption = (g_CivData[civObj.codes[0]] ? g_CivData[civObj.codes[0]].Name : translateWithContext("Unnamed civilization", "Unknown"));
     1451        }
     1452
    14371453        pTeamText.caption = (team !== undefined && team >= 0) ? team+1 : "-";
    1438 
    1439         pCiv.selected = civ ? pCiv.list_data.indexOf(civ) : 0;
    14401454        pTeam.selected = team !== undefined && team >= 0 ? team+1 : 0;
    14411455
    14421456        hideControl("playerAssignment["+i+"]", "playerAssignmentText["+i+"]", g_IsController);
    1443         hideControl("playerCiv["+i+"]", "playerCivText["+i+"]", notScenario);
    14441457        hideControl("playerTeam["+i+"]", "playerTeamText["+i+"]", notScenario);
     1458        Engine.GetGUIObjectByName("playerCivButton["+i+"]").hidden = !notScenario;
    14451459
    14461460        // Allow host to chose player colors on non-scenario maps
    14471461        let pColorPicker = Engine.GetGUIObjectByName("playerColorPicker["+i+"]");
     
    17411755        // Swap civilizations if they aren't fixed
    17421756        if (g_GameAttributes.mapType != "scenario")
    17431757        {
    1744             [g_GameAttributes.settings.PlayerData[playerID - 1].Civ, g_GameAttributes.settings.PlayerData[newSlot].Civ] =
    1745                 [g_GameAttributes.settings.PlayerData[newSlot].Civ, g_GameAttributes.settings.PlayerData[playerID - 1].Civ];
     1758            [g_GameAttributes.settings.PlayerData[playerID - 1].CivObj, g_GameAttributes.settings.PlayerData[newSlot].CivObj] =
     1759                [g_GameAttributes.settings.PlayerData[newSlot].CivObj, g_GameAttributes.settings.PlayerData[playerID - 1].CivObj];
    17461760        }
    17471761    }
    17481762
     
    17521766        g_PlayerAssignments[guid].player = newPlayerID;
    17531767
    17541768    g_GameAttributes.settings.PlayerData[newSlot].AI = "";
     1769    updateGameAttributes();
    17551770}
    17561771
    17571772function submitChatInput()
     
    18221837function resetCivilizations()
    18231838{
    18241839    for (let i in g_GameAttributes.settings.PlayerData)
    1825         g_GameAttributes.settings.PlayerData[i].Civ = "random";
     1840        g_GameAttributes.settings.PlayerData[i].CivObj = g_RandomCivObj;
    18261841
    18271842    updateGameAttributes();
    18281843}
  • binaries/data/mods/public/gui/gamesetup/gamesetup.xml

     
    7272                        size="67.5%+93 0 67.5%+109 16"
    7373                        tooltip_style="onscreenToolTip"
    7474                    >
    75                         <translatableAttribute id="tooltip">Reset any civilizations that have been selected to the default (random)</translatableAttribute>
     75                        <translatableAttribute id="tooltip">Reset any civilizations that have been selected to the default (Random All)</translatableAttribute>
    7676                        <action on="Press">resetCivilizations();</action>
    7777                    </object>
    7878                    <object name="playerTeamHeading" type="text" style="ModernLabelText" size="85%+15 0 100%-15 100%">
     
    100100                            >
    101101                                <translatableAttribute id="tooltip">Configure AI settings.</translatableAttribute>
    102102                            </object>
    103                             <object name="playerCiv[n]" type="dropdown" style="ModernDropDown" size="50%+69 2 85% 30" tooltip_style="onscreenToolTip">
    104                                 <translatableAttribute id="tooltip">Select player's civilization.</translatableAttribute>
     103                            <object name="playerCivText[n]" type="text" style="ModernLabelText" size="50%+65 0 85%-16 30"/>
     104
     105                            <object name="playerCivButton[n]"
     106                                type="button"
     107                                sprite="ModernGear"
     108                                sprite_over="ModernGearHover"
     109                                sprite_pressed="ModernGearPressed"
     110                                size="85%-24 4 85% 28"
     111                                tooltip_style="onscreenToolTip"
     112                            >
     113                                <translatableAttribute id="tooltip">Select a civilisation</translatableAttribute>
     114                                <action on="Press"><![CDATA[
     115                                    let player = this.name.slice(16, -1);
     116                                    Engine.PushGuiPage("page_civselect.xml", {
     117                                        "player": player,
     118                                        "civ": g_GameAttributes.settings.PlayerData[player].CivObj,
     119                                        "callback": "setCiv"
     120                                    });
     121                                ]]></action>
    105122                            </object>
    106                             <object name="playerCivText[n]" type="text" style="ModernLabelText" size="50%+65 0 85% 30"/>
    107123                            <object name="playerTeam[n]" type="dropdown" style="ModernDropDown" size="85%+5 2 100%-5 30" tooltip_style="onscreenToolTip">
    108124                                <translatableAttribute id="tooltip">Select player's team.</translatableAttribute>
    109125                            </object>
     126
    110127                            <object name="playerTeamText[n]" type="text" style="ModernLabelText" size="85%+5 0 100%-5 100%"/>
    111128                        </object>
    112129                    </repeat>
    113130                </object>
    114131            </object>
     132
    115133            <object size="24 64 100%-460 358" type="image" sprite="CoverFillDark" name="playerAssignmentsPanelCover" hidden="true"/>
     134
    116135            <!-- Map selection -->
    117 
    118136            <object size="100%-425 355 100%-285 470" name="mapTypeTooltip">
    119137                <object type="text" style="ModernRightLabelText" size="0 0 100% 30">
    120138                    <translatableAttribute id="caption">Map Type:</translatableAttribute>
  • binaries/data/mods/public/gui/page_civselect.xml

     
     1<?xml version="1.0" encoding="utf-8"?>
     2<page>
     3    <include>common/modern/setup.xml</include>
     4    <include>common/modern/styles.xml</include>
     5    <include>common/modern/sprites.xml</include>
     6
     7    <include>common/setup.xml</include>
     8    <include>common/sprite1.xml</include>
     9    <include>common/styles.xml</include>
     10    <include>common/common_sprites.xml</include>
     11    <include>common/common_styles.xml</include>
     12
     13    <include>civselect/styles.xml</include>
     14    <include>civselect/sprites.xml</include>
     15    <include>civselect/civselect.xml</include>
     16    <!-- for some reason, the setup file has to be after in
     17    order to get transparency to work properly for the tooltip... -->
     18<!--    <include>civselect/setup.xml</include>-->
     19</page>
  • binaries/data/mods/public/simulation/data/civs/athen.json

     
    11{
    22    "Code":"athen",
    3     "Culture":"hele",
     3    "Culture":[ "helle" ],
     4    "Region":[ "medit", "europe" ],
    45    "Name":"Athenians",
    56    "Emblem":"session/portraits/emblems/emblem_athenians.png",
    67    "History":"As the cradle of Western civilization and the birthplace of democracy, Athens was famed as a center for the arts, learning and philosophy. The Athenians were also powerful warriors, particularly at sea. At its peak, Athens dominated a large part of the Hellenic world for several decades.",
  • binaries/data/mods/public/simulation/data/civs/brit.json

     
    11{
    22    "Code": "brit",
    3     "Culture": "celt",
     3    "Culture":[ "celt" ],
     4    "Region":[ "europe" ],
    45    "Name": "Britons",
    56    "Emblem": "session/portraits/emblems/emblem_britons.png",
    67    "History": "The Britons were the Celtic tribes of the British Isles. Using chariots, longswordsmen and powerful melee soldiers, they staged fearesome revolts against Rome to protect their customs and interests. Also, they built thousands of unique structures such as hill forts, crannogs and brochs.",
  • binaries/data/mods/public/simulation/data/civs/cart.json

     
    11{
    22    "Code": "cart",
    3     "Culture": "cart",
     3    "Culture":[ ],
     4    "Region":[ "africa", "medit" ],
    45    "Name": "Carthaginians",
    56    "Emblem": "session/portraits/emblems/emblem_carthaginians.png",
    67    "History": "Carthage, a city-state in modern-day Tunisia, was a formidable force in the western Mediterranean, eventually taking over much of North Africa and modern-day Spain in the third century B.C. The sailors of Carthage were among the fiercest contenders on the high seas, and masters of naval trade. They deployed towered War Elephants on the battlefield to fearsome effect, and had defensive walls so strong, they were never breached.",
  • binaries/data/mods/public/simulation/data/civs/cultures/celt.json

     
     1{
     2    "Name" : "Celtic Tribes",
     3    "Code" : "celt",
     4    "History" : "At its peak (around 200 B.C.), the massive Celtic Empire spanned from Spain to Romania and Northern Italy to Scotland; although it wasn't a true empire because the Celtic people were not united by any form of government, but only in language and various social aspects. Their lack of any cohesion was probably the largest contributing factor to their ultimate submission to Rome by 100 A.D. The other contributing factors were their lack of armor and their inability to counter the mighty legions and siege weapons of Rome.",
     5    "Singular" : "Celtic"
     6}
  • binaries/data/mods/public/simulation/data/civs/cultures/egypt.json

     
     1{
     2    "Name" : "The Egyptians",
     3    "Code" : "egypt",
     4    "History" : "-",
     5    "Singular" : "Egyptian"
     6}
  • binaries/data/mods/public/simulation/data/civs/cultures/helle.json

     
     1{
     2    "Name" : "The Hellenes",
     3    "Code" : "helle",
     4    "History" : "The Hellenes were a people famous today for their architecture, fighting ability, and culture. The Hellenic peoples of the Dorian, Ionian, and Aeolian tribes swept into modern day Greece from 3000 B.C. to around 1100 B.C. in successive waves that eventually supplanted the previously established cultures of Mycenae and Minoan Crete. They were most active during the period of colonization that took place in the 7th and 6th centuries B.C., the Greco-Persian Wars (499-449 B.C.), the Peloponnesian War (431-404 B.C.), and the conquests of Alexander the Great (4th Century B.C.). Their civilization would endure until their final absorption by Rome in 146 B.C.",
     5    "Singular" : "Hellenic"
     6}
  • binaries/data/mods/public/simulation/data/civs/cultures/indian.json

     
     1{
     2    "Name" : "The Indians",
     3    "Code" : "indian",
     4    "History" : "-",
     5    "Singular" : "Indian"
     6}
  • binaries/data/mods/public/simulation/data/civs/cultures/rome.json

     
     1{
     2    "Name" : "The Romans",
     3    "Code" : "rome",
     4    "History" : "-",
     5    "Singular" : "Roman"
     6}
  • binaries/data/mods/public/simulation/data/civs/cultures/succe.json

     
     1{
     2    "Name" : "The Successors",
     3    "Code" : "succe",
     4    "History" : "The Successor kingdoms were carved out from the short-lived Macedonian Empire built by Philip of Macedon and his son, Alexander the Great. The chief three kingdoms were Ptolomaic Egypt, the Seleucid Empire, and the Kingdom of Macedon. Together, they helped propel the Eastern Mediterranean and Middle East into the Hellenistic Age - a time of internecine warfare and technological and cultural advancement.",
     5    "Singular" : "Successor"
     6}
  • binaries/data/mods/public/simulation/data/civs/gaul.json

     
    11{
    22    "Code": "gaul",
    3     "Culture": "celt",
     3    "Culture":[ "celt" ],
     4    "Region":[ "europe" ],
    45    "Name": "Gauls",
    56    "Emblem": "session/portraits/emblems/emblem_celts.png",
    67    "History": "The Gauls were the Celtic tribes of continental Europe. Dominated by a priestly class of Druids, they featured a sophisticated culture of advanced metalworking, agriculture, trade and even road engineering. With heavy infantry and cavalry, Gallic warriors valiantly resisted Caesar's campaign of conquest and Rome's authoritarian rule.",
  • binaries/data/mods/public/simulation/data/civs/grouping/culture.json

     
     1{
     2    "Code": "culture",
     3    "CivAttribute": "Culture",
     4    "ListEntry": "By Culture",
     5    "Folder": "cultures"
     6}
  • binaries/data/mods/public/simulation/data/civs/grouping/region.json

     
     1{
     2    "Code": "region",
     3    "CivAttribute": "Region",
     4    "ListEntry": "By Geographic Region",
     5    "Folder": "regions"
     6}
  • binaries/data/mods/public/simulation/data/civs/iber.json

     
    11{
    22    "Code": "iber",
    3     "Culture": "iber",
     3    "Culture":[ ],
     4    "Region":[ "europe" ],
    45    "Name": "Iberians",
    56    "Emblem": "session/portraits/emblems/emblem_iberians.png",
    67    "History": "The Iberians were a people of mysterious origins and language, with a strong tradition of horsemanship and metalworking. A relatively peaceful culture, they usually fought in other's battles only as mercenaries. However, they proved tenacious when Rome sought to take their land and freedom from them, and employed pioneering guerrilla tactics and flaming javelins as they fought back.",
  • binaries/data/mods/public/simulation/data/civs/mace.json

     
    11{
    22    "Code":"mace",
    3     "Culture":"hele",
     3    "Culture":[ "helle", "succe" ],
     4    "Region":[ "medit", "europe" ],
    45    "Name":"Macedonians",
    56    "Emblem":"session/portraits/emblems/emblem_macedonians.png",
    67    "History":"Macedonia was an ancient Greek kingdom, centered in the northeastern part of the Greek peninsula. Under the leadership of Alexander the Great, Macedonian forces and allies took over most of the world they knew, including Egypt, Persia and parts of the Indian subcontinent, allowing a diffusion of Hellenic and eastern cultures for years to come.",
  • binaries/data/mods/public/simulation/data/civs/maur.json

     
    11{
    22    "Code": "maur",
    3     "Culture": "maur",
     3    "Culture":[ ],
     4    "Region":[ "asia" ],
    45    "Name": "Mauryans",
    56    "Emblem": "session/portraits/emblems/emblem_mauryans.png",
    67    "History": "Founded in 322 B.C. by Chandragupta Maurya, the Mauryan Empire was the first to rule most of the Indian subcontinent, and was one of the largest and most populous empires of antiquity. Its military featured bowmen who used the long-range bamboo longbow, fierce female warriors, chariots, and thousands of armored war elephants. Its philosophers, especially the famous Acharya Chanakya, contributed to such varied fields such as economics, religion, diplomacy, warfare, and good governance. Under the rule of Ashoka the Great, the empire saw 40 years of peace, harmony, and prosperity.",
  • binaries/data/mods/public/simulation/data/civs/pers.json

     
    11{
    22    "Code": "pers",
    3     "Culture": "pers",
     3    "Culture":[ ],
     4    "Region":[ "medit" ],
    45    "Name": "Persians",
    56    "Emblem": "session/portraits/emblems/emblem_persians.png",
    67    "History": "The Persian Empire, when ruled by the Achaemenid dynasty, was one of the greatest empires of antiquity, stretching at its zenith from the Indus Valley in the east to Greece in the west. The Persians were the pioneers of empire-building of the ancient world, successfully imposing a centralized rule over various peoples with different customs, laws, religions and languages, and building a cosmopolitan army made up of contingents from each of these nations.",
  • binaries/data/mods/public/simulation/data/civs/ptol.json

     
    11{
    22    "Code":"ptol",
    3     "Culture":"ptol",
     3    "Culture":[ ],
     4    "Region":[ "africa" ],
    45    "Name":"Ptolemies",
    56    "Emblem":"session/portraits/emblems/emblem_ptolemies.png",
    67    "History":"The Ptolemaic dynasty was a Macedonian Greek royal family which ruled the Ptolemaic Empire in Egypt during the Hellenistic period. Their rule lasted for 275 years, from 305 BC to 30 BC. They were the last dynasty of ancient Egypt.",
  • binaries/data/mods/public/simulation/data/civs/regions/africa.json

     
     1{
     2    "Name" : "Africa",
     3    "Code" : "africa",
     4    "History" : "-",
     5    "Singular" : "African",
     6    "Emblem" : "session/portraits/emblems/grouping/region_africa.png"
     7}
  • binaries/data/mods/public/simulation/data/civs/regions/asia.json

     
     1{
     2    "Name" : "Asia",
     3    "Code" : "asia",
     4    "History" : "-",
     5    "Singular" : "Asian",
     6    "Emblem" : "session/portraits/emblems/grouping/region_asia.png"
     7}
  • binaries/data/mods/public/simulation/data/civs/regions/europe.json

     
     1{
     2    "Name" : "Europe",
     3    "Code" : "europe",
     4    "History" : "-",
     5    "Singular" : "European",
     6    "Emblem" : "session/portraits/emblems/grouping/region_europe.png"
     7}
  • binaries/data/mods/public/simulation/data/civs/regions/medit.json

     
     1{
     2    "Name" : "The Mediterranean",
     3    "Code" : "medit",
     4    "History" : "-",
     5    "Singular" : "Mediterranean",
     6    "Emblem" : "session/portraits/emblems/grouping/region_medi.png"
     7}
  • binaries/data/mods/public/simulation/data/civs/rome.json

     
    11{
    22    "Code": "rome",
    3     "Culture": "rome",
     3    "Culture":[ ],
     4    "Region":[ "medit", "europe" ],
    45    "Name": "Romans",
    56    "Emblem": "session/portraits/emblems/emblem_romans.png",
    67    "History": "The Romans controlled one of the largest empires of the ancient world, stretching at its peak from southern Scotland to the Sahara Desert, and containing between 60 million and 80 million inhabitants, one quarter of the Earth's population at that time. Rome also remained one of the strongest nations on earth for almost 800 years. The Romans were the supreme builders of the ancient world, excelled at siege warfare and had an exquisite infantry and navy.",
  • binaries/data/mods/public/simulation/data/civs/sele.json

     
    11{
    22    "Code":"sele",
    3     "Culture":"sele",
     3    "Culture":[ "succe" ],
     4    "Region":[ "medit" ],
    45    "Name":"Seleucids",
    56    "Emblem":"session/portraits/emblems/emblem_seleucids.png",
    67    "History":"The Macedonian-Greek dynasty that ruled most of Alexander's former empire.",
  • binaries/data/mods/public/simulation/data/civs/spart.json

     
    11{
    22    "Code":"spart",
    3     "Culture":"hele",
     3    "Culture":[ "helle" ],
     4    "Region":[ "medit", "europe" ],
    45    "Name":"Spartans",
    56    "Emblem":"session/portraits/emblems/emblem_spartans.png",
    67    "History":"Sparta was a prominent city-state in ancient Greece, and its dominant military power on land from circa 650 B.C. Spartan culture was obsessed with military training and excellence, with rigorous training for boys beginning at age seven. Thanks to its military might, Sparta led a coalition of Greek forces during the Greco-Persian Wars, and won over Athens in the Peloponnesian Wars, though at great cost.",