Ticket #3987: civselection_randomcivoptionWIP_v3.patch

File civselection_randomcivoptionWIP_v3.patch, 60.8 KB (added by Sandarac, 8 years ago)

Still needs fixes and code quality improvements.

  • binaries/data/config/default.cfg

     
    8585noautomipmap = true
    8686novbo = false
    8787noframebufferobject = false
     88randomcultures = true
    8889
    8990; Disable hardware cursors
    9091nohwcursor = false
     
    233234toggle = "Ctrl+F11"          ; Enable/disable HTTP/GPU modes for new profiler
    234235
    235236[hotkey.selection]
    236 add = Shift                  ; Add units to selection
     237add = Shift                  ; Add units/civilizations to selection
    237238milonly = Alt                ; Add only military units to selection
    238239idleonly = "I"               ; Select only idle units
    239240remove = Ctrl                ; Remove units from selection
  • binaries/data/mods/public/gui/civselect/civselect.js

     
     1let g_CivData = {};
     2let g_GroupingData = {};
     3let g_GroupingChoice = "none";
     4let g_SelectedGroupingChoice = "none";
     5let g_Player = 0;
     6let g_Selected = {
     7    "isGroup": false,
     8    "code": "athen"
     9};
     10let g_EmblemMargin = 8;
     11let g_HeaderEmblemSize = 80;
     12let g_DoubleClick = false;
     13let g_CustomGrouping = false;
     14let g_PreviousSelection = {};
     15
     16/**
     17 * Run when UI Page loaded.
     18 */
     19function init(settings)
     20{
     21    // Cache civ data
     22    g_CivData = loadCivData(true);
     23    g_Player = settings.player;
     24
     25    // If no civ passed, choose one at random
     26    if (!settings.civ)
     27    {
     28        let num = Math.floor(Math.random() * Object.keys(g_CivData).length);
     29        settings.civ = {
     30            "codes": [ Object.keys(g_CivData)[num] ],
     31            "grouped": false
     32        };
     33    }
     34    g_DoubleClick = false;
     35    // Cache grouping data and create list
     36    let grpList = ["Ungrouped"];
     37    let grpList_data = ["nogroup"];
     38    for (let grp of Engine.BuildDirEntList("simulation/data/civs/grouping/", "*.json", false))
     39    {
     40        let data = Engine.ReadJSONFile(grp);
     41        if (!data)
     42            continue;
     43        translateObjectKeys(data, ["ListEntry"]);
     44        g_GroupingData[data.Code] = loadGroupingSchema(data.Folder, data.CivAttribute);
     45
     46        grpList.push(data.ListEntry);
     47        grpList_data.push(data.Code);
     48    }
     49
     50    g_GroupingData["custom"] = {"custom": {"Name": "Custom", "History": "", "code": "cust", "Singular": "Custom", "civlist": settings.civ.codes, "embs": []}};
     51
     52    let grpSel = Engine.GetGUIObjectByName("groupSelection");
     53    grpSel.list = grpList;
     54    grpSel.list_data = grpList_data;
     55
     56    // Read civ choice from passed data
     57    if (!settings.civ.grouped)
     58    {
     59        g_Selected.code = settings.civ.codes[0];
     60        grpSel.selected = 0;
     61        selectCiv(g_Selected.code, true, false);
     62    }
     63    else
     64    {
     65        g_GroupingChoice = settings.civ.group.type;
     66        g_SelectedGroupingChoice = settings.civ.group.type;
     67
     68        g_Selected.isGroup = true;
     69        if (settings.civ.group.code !== "all")
     70        {
     71            g_Selected.code = settings.civ.group.code;
     72            if (settings.civ.group.type != "custom")
     73                grpSel.selected = grpSel.list_data.indexOf(g_GroupingChoice);
     74            else
     75                grpSel.selected = 0;
     76            if (settings.civ.group.type == "custom")
     77            {
     78                g_CustomGrouping = true;
     79                g_GroupingData["custom"]["custom"].civlist = settings.civ.codes;
     80            }
     81            selectCiv(g_Selected.code, true, true);
     82
     83        }
     84        else
     85        {
     86            grpSel.selected = 0;
     87            selectAllCivs();
     88        }
     89    }
     90    Engine.GetGUIObjectByName("randomCultures").checked = Engine.ConfigDB_GetValue("user", "randomcultures") === "true";
     91    Engine.GetGUIObjectByName("selectAll").checked = g_Selected.code == "all";
     92}
     93
     94function chooseGrouping(choice)
     95{
     96    if (choice === "nogroup")
     97        draw_ungrouped();
     98    else
     99        draw_grouped(choice);
     100}
     101
     102function draw_grouped(group)
     103{
     104    Engine.GetGUIObjectByName("optionRandomCultures").hidden = !Engine.GetGUIObjectByName("selectAll").checked;
     105
     106    let grp = 0;
     107    let emb = 0;
     108    let vOffset = 0;
     109    let hOffset = 0;
     110    g_GroupingChoice = group;
     111
     112    let grouping = g_GroupingData[group];
     113    let selectedCivs = [];
     114
     115    for (let civ in g_CivData)
     116        g_CivData[civ].embs = [];
     117    for (let code in grouping)
     118    {
     119        // Pre-emptive check to make sure we have at least one emblem left
     120        if (!Engine.GetGUIObjectByName("emblem["+emb+"]"))
     121            break;
     122
     123        let grpObj = Engine.GetGUIObjectByName("civGroup["+grp+"]");
     124
     125        let grpSize = grpObj.size;
     126        grpSize.top = vOffset;
     127        grpSize.right = hOffset;
     128
     129        grpSize.left = (grp % 2 == 0 || grouping[code].civlist.length > 3) ? g_HeaderEmblemSize-g_EmblemMargin : 400;
     130        grpObj.size = grpSize;
     131        grpObj.hidden = false;
     132
     133        g_GroupingData[g_GroupingChoice][code].embs = [];
     134
     135        let grpHeading = Engine.GetGUIObjectByName("civGroup["+grp+"]_heading");
     136        grpHeading.caption = grouping[code].Name;
     137
     138        let embHeading = Engine.GetGUIObjectByName("emblem["+emb+"]_heading");
     139        embHeading.caption = '';
     140
     141        if (code !== "groupless")
     142        {
     143            let grpBtn = Engine.GetGUIObjectByName("emblem["+emb+"]_btn");
     144            grpBtn.tooltip = grouping[code].Name;
     145            setBtnFunc(grpBtn, selectCiv, [ code, false, true ]);
     146
     147            setEmbPos("emblem["+emb+"]", hOffset, vOffset+g_EmblemMargin);
     148            setEmbSize("emblem["+emb+"]", g_HeaderEmblemSize);
     149
     150            let sprite = (code!==g_Selected.code) ? "grayscale:" : "";
     151            if (grouping[code].Emblem)
     152                sprite += grouping[code].Emblem;
     153            else
     154                sprite += g_CivData[grouping[code].civlist[0]].Emblem;
     155            Engine.GetGUIObjectByName("emblem["+emb+"]_img").sprite = "stretched:"+sprite;
     156            Engine.GetGUIObjectByName("emblem["+emb+"]").hidden = grouping[code].civlist.length == 1;
     157            g_GroupingData[g_GroupingChoice][code].embs.push(emb);
     158            ++emb;
     159        }
     160
     161        let range = [ emb ];
     162
     163        for (let civ of grouping[code].civlist)
     164        {
     165            if (g_GroupingData["custom"]["custom"].civlist.indexOf(civ) > -1)
     166                selectedCivs.push(emb);
     167
     168            if (!g_Selected.isGroup && civ == g_Selected.code)
     169                selectedCivs.push(emb);
     170            let embImg = Engine.GetGUIObjectByName("emblem["+emb+"]_img");
     171            if (!embImg)
     172            {
     173                error("There are not enough images in the current GUI layout to support that many civs");
     174                break;
     175            }
     176
     177            let embHeading = Engine.GetGUIObjectByName("emblem["+emb+"]_heading");
     178            embHeading.caption = '';
     179
     180            g_CivData[civ].embs.push(emb);
     181            g_GroupingData[g_GroupingChoice][code].embs.push(emb);
     182
     183            embImg.sprite = "stretched:";
     184            if (civ !== g_Selected.code && code !== g_Selected.code)
     185                embImg.sprite += "grayscale:";
     186            embImg.sprite += g_CivData[civ].Emblem;
     187
     188            let embBtn = Engine.GetGUIObjectByName("emblem["+emb+"]_btn");
     189            embBtn.tooltip = g_CivData[civ].Name;
     190            setBtnFunc(embBtn, selectCiv, [civ, false, false]);
     191            Engine.GetGUIObjectByName("emblem["+emb+"]").hidden = false;
     192
     193            emb++;
     194        }
     195        range[1] = emb - 1;
     196
     197        if (grp % 2 == 1 && grouping[code].civlist.length < 4)
     198        {
     199            setEmbSize("emblem["+range[0]+"]", 80);
     200            vOffset += grpHeading.size.bottom + 2;
     201            vOffset += gridArrayRepeatedObjects("emblem[emb]", "emb", 4, 0, range, vOffset, (g_HeaderEmblemSize+325));
     202            vOffset += g_EmblemMargin * 2;
     203        }
     204        else
     205        {
     206            setEmbSize("emblem["+range[0]+"]", 80);
     207            if (grouping[code].civlist.length > 4)
     208            {
     209                vOffset += gridArrayRepeatedObjects("emblem[emb]", "emb", 4, 0, range, vOffset+25, g_HeaderEmblemSize);
     210                vOffset += 50;
     211            }
     212            else
     213                gridArrayRepeatedObjects("emblem[emb]", "emb", 4, 0, range, vOffset+25, g_HeaderEmblemSize);
     214        }
     215        hOffset = (hOffset >= 325) || (grouping[code].civlist.length > 3) ? 0 : 325;
     216
     217        grp++;
     218    }
     219    hideRemaining("emblem[", emb, "]");
     220    hideRemaining("civGroup[", grp, "]");
     221    highlightEmblems(selectedCivs);
     222
     223    if (g_Selected.code === "all")
     224        selectAllCivs();
     225}
     226
     227function draw_ungrouped()
     228{
     229    setEmbSize("emblem[0]");
     230    gridArrayRepeatedObjects("emblem[emb]", "emb", 30, 25, [], 0, 0, 4);
     231    gridArrayRepeatedObjects("emblem[emb]_heading", "emb", 0, 0, [], 5, 10);
     232
     233    let emb = 0;
     234    let selectedCivs = [];
     235    for (let civ in g_CivData)
     236    {
     237        if (g_GroupingData["custom"]["custom"].civlist.indexOf(civ) != -1)
     238        {
     239            selectedCivs.push(emb);
     240            g_GroupingData["custom"]["custom"].embs.push(emb);
     241        }
     242
     243        if (!g_Selected.isGroup && civ == g_Selected.code)
     244            selectedCivs.push(emb);
     245
     246        g_CivData[civ].embs = [emb];
     247
     248        let embImg = Engine.GetGUIObjectByName("emblem["+emb+"]_img");
     249
     250        let embHeading = Engine.GetGUIObjectByName("emblem["+emb+"]_heading");
     251        embHeading.caption = g_CivData[civ].Name;
     252
     253        let range = [emb];
     254        if (!embImg)
     255        {
     256            error("There are not enough images in the current GUI layout to support that many civs");
     257            break;
     258        }
     259
     260        range[1] = emb - 1;
     261
     262        embImg.sprite = "stretched:";
     263        if (civ !== g_Selected.code)
     264            embImg.sprite += ":";
     265        embImg.sprite += g_CivData[civ].Emblem;
     266
     267        let embBtn = Engine.GetGUIObjectByName("emblem["+emb+"]_btn");
     268        embBtn.tooltip = '';
     269        setBtnFunc(embBtn, selectCiv, [civ, false, false]);
     270
     271        Engine.GetGUIObjectByName("emblem["+emb+"]").hidden = false;
     272        emb++;
     273    }
     274    hideRemaining("emblem[", emb, "]");
     275    hideRemaining("civGroup[", 0, "]");
     276
     277    highlightEmblems(selectedCivs);
     278
     279    if (g_Selected.code === "all")
     280        selectAllCivs();
     281}
     282
     283function selectCiv(code, onInit, isGroup)
     284{
     285    let customCivs = g_GroupingData["custom"]["custom"].civlist;
     286    let customCivsEmbs = g_GroupingData["custom"]["custom"].embs;
     287
     288    if (g_Selected.code == code && customCivs.length == 1 && !onInit)
     289    {
     290        selectAllCivs();
     291        return;
     292    }
     293
     294    let selection = [];
     295    if (isGroup)
     296        selection = g_GroupingData[g_GroupingChoice][code];
     297    else
     298        selection = g_CivData[code];
     299
     300    g_Selected.isGroup = isGroup;
     301    g_Selected.code = code;
     302    if (g_Selected.code !== "all")
     303        g_PreviousSelection = clone(g_Selected);
     304
     305    if (Engine.HotkeyIsPressed("selection.add"))
     306    {
     307        g_CustomGrouping = true;
     308        // if the civ has already been selected, remove it
     309        if (customCivsEmbs.indexOf(selection.embs[0]) != -1
     310        && customCivsEmbs.length >= 1 || customCivsEmbs.indexOf(selection.embs[0]) != -1)
     311        {
     312            customCivs.splice(customCivs.indexOf(code), 1);
     313
     314            for (let civEmb of selection.embs)
     315            {
     316                let index = customCivsEmbs.indexOf(civEmb);
     317                customCivsEmbs.splice(index, 1);
     318            }
     319        }
     320        else
     321        {
     322            for (let civEmb of selection.embs)
     323                customCivsEmbs.push(civEmb);
     324
     325            customCivs.push(code)
     326        }
     327
     328        if (customCivs.length > 1)
     329            g_SelectedGroupingChoice = "custom";
     330        else
     331        {
     332            g_CustomGrouping = false;
     333            code = customCivs[0];
     334            g_Selected.code = customCivs[0];
     335        }
     336        highlightEmblems(customCivsEmbs);
     337    }
     338    else
     339    {
     340        if (!onInit && code != "custom")
     341            g_CustomGrouping = false;
     342        customCivs = [];
     343        customCivsEmbs = [];
     344        if (selection)
     345            for (let civEmb of selection.embs)
     346                customCivsEmbs.push(civEmb);
     347        customCivs.push(code);
     348        if (selection)
     349            highlightEmblems(selection.embs);
     350        if (isGroup)
     351            g_SelectedGroupingChoice = g_GroupingChoice;
     352    }
     353
     354    g_GroupingData["custom"]["custom"].civlist = customCivs;
     355    g_GroupingData["custom"]["custom"].embs = customCivsEmbs;
     356
     357    Engine.GetGUIObjectByName("optionRandomCultures").hidden = true;
     358    Engine.GetGUIObjectByName("selectAll").checked = false;
     359
     360    let choice = Engine.GetGUIObjectByName("selected_text");
     361    choice.caption = g_CustomGrouping ? sprintf(translate("Random choice")) :
     362                    sprintf(translate("You have selected the %(civname)s"), {"civname": selection.Name});
     363
     364    displayCivInfo(code, selection, isGroup);
     365}
     366
     367function updateSelectedText()
     368{
     369    let choice = Engine.GetGUIObjectByName("selected_text");
     370    if (g_CustomGrouping)
     371        choice.caption = sprintf(translate("Random choice between selected civilizations and groupings"));
     372}
     373
     374function displayCivInfo(code, selection, isGroup)
     375{
     376    if (g_DoubleClick)
     377        return;
     378
     379    let heading = Engine.GetGUIObjectByName("selected_heading");
     380    heading.caption = g_CustomGrouping ? "Random Custom" : isGroup ?
     381                    g_GroupingData[g_GroupingChoice][code].Name : g_CivData[code].Name;
     382
     383    let civList = Engine.GetGUIObjectByName("selected_civs");
     384    civList.hidden = !g_CustomGrouping;
     385    civList.caption = "";
     386    let civCount = 0;
     387    for (let item of g_GroupingData["custom"]["custom"].civlist)
     388    {
     389        civList.caption += Object.keys(g_CivData).indexOf(item) > -1 ? g_CivData[item].Name: g_GroupingData[g_GroupingChoice][item].Name;
     390        civList.caption += "\n";
     391        civCount++;
     392    }
     393
     394    let history = Engine.GetGUIObjectByName("selected_history");
     395    if (!g_CustomGrouping)
     396        history.caption = selection.History;
     397
     398    let size = history.parent.size;
     399    size.top = 48;
     400    history.parent.size = size;
     401    history.parent.hidden = g_CustomGrouping;
     402}
     403
     404function selectAllCivs()
     405{
     406    if (g_Selected.code == "all")
     407    {
     408        Engine.GetGUIObjectByName("selectAll").checked = false;
     409
     410        g_PreviousSelection.code = g_PreviousSelection.code || Object.keys(g_CivData)[Math.floor(Math.random() * Object.keys(g_CivData).length)];
     411        g_PreviousSelection.isGroup = g_PreviousSelection.isGroup || false;
     412        selectCiv(g_PreviousSelection.code, false, g_PreviousSelection.isGroup);
     413        return;
     414    }
     415
     416    Engine.GetGUIObjectByName("optionRandomCultures").hidden = false;
     417
     418    let embs = [];
     419    for (let i=0; ; ++i)
     420    {
     421        if (!Engine.GetGUIObjectByName("emblem["+i+"]"))
     422            break;
     423        embs.push(i);
     424    }
     425    highlightEmblems(embs);
     426
     427    g_Selected.isGroup = true;
     428    g_Selected.code = "all";
     429
     430    let heading = Engine.GetGUIObjectByName("selected_heading");
     431    heading.caption = sprintf(translate("Random %(civGroup)s"), {
     432            "civGroup": translateWithContext("All Civs", "All")
     433        });
     434
     435    let civList = Engine.GetGUIObjectByName("selected_civs");
     436    civList.hidden = false;
     437    civList.caption = "";
     438    let civCount = 0;
     439    for (let civ in g_CivData)
     440    {
     441        civList.caption += g_CivData[civ].Name + "\n";
     442        civCount++;
     443    }
     444
     445    let history = Engine.GetGUIObjectByName("selected_history");
     446    history.parent.hidden = true;
     447
     448    let choice = Engine.GetGUIObjectByName("selected_text");
     449    choice.caption = translate("A civilization will be chosen at random");
     450
     451    Engine.GetGUIObjectByName("selectAll").checked = g_Selected.code == "all";
     452}
     453
     454function highlightEmblems(embs = [])
     455{
     456    for (let e=0; ; ++e)
     457    {
     458        if (!Engine.GetGUIObjectByName("emblem["+e+"]"))
     459            return;
     460
     461        let embImg = Engine.GetGUIObjectByName("emblem["+e+"]_img");
     462        let sprite = embImg.sprite.split(":");
     463        embImg.sprite = "stretched:" + ((embs.indexOf(e)<0)?"grayscale:":"") + sprite.pop();
     464    }
     465}
     466
     467function setBtnFunc(btn, func, vars = null)
     468{
     469    btn.onMouseLeftRelease = function () { func.apply(null, vars); };
     470    btn.onMouseLeftDoubleClick = function () { returnCiv.apply(null, vars); g_DoubleClick = true; };   
     471}
     472
     473function randomCultures()
     474{
     475    Engine.ConfigDB_CreateValue("user", "randomcultures", String(Engine.GetGUIObjectByName("randomCultures").checked));
     476    Engine.ConfigDB_SetChanges("user", true);
     477    Engine.ConfigDB_WriteFile("user", "config/user.cfg");
     478}
     479
     480function returnCiv()
     481{
     482    let code = g_Selected.code;
     483    let civ = {
     484            "codes": [g_Selected.code],
     485            "grouped": false,
     486        }
     487
     488    if (g_CustomGrouping)
     489    {
     490        civ.codes = g_GroupingData["custom"]["custom"].civlist;
     491        civ.grouped = true;
     492        civ.group = {
     493                "caption": "Custom",
     494                "code": "custom",
     495                "type": g_SelectedGroupingChoice,
     496            };
     497       
     498        for (let item of civ.codes)
     499        {
     500            if ((Object.keys(g_CivData).indexOf(item)) == -1)
     501                civ.codes.splice(civ.codes.indexOf(item), 1, g_GroupingData[g_GroupingChoice][item].civlist);
     502        }
     503    }
     504    else if (g_Selected.isGroup && !g_CustomGrouping)
     505    {
     506        civ.codes = g_Selected.code == "all" ? Object.keys(g_CivData) : g_GroupingData[g_SelectedGroupingChoice][code].civlist;
     507        civ.grouped = true;
     508        civ.group = {
     509                "caption": g_Selected.code === "all" ? "All" : g_GroupingData[g_SelectedGroupingChoice][code].Singular,
     510                "code": g_Selected.code,
     511                "type": g_SelectedGroupingChoice,
     512            };
     513    }
     514    Engine.PopGuiPageCB({
     515            "player": g_Player,
     516            "civ": civ,
     517            "randomCultures" : Engine.GetGUIObjectByName("randomCultures").checked
     518        });
     519}
  • 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 type="text" size="4 8 4+159 100+64" font="sans-bold-24" textcolor="white" name="emblem[em]_heading"/>
     46                    <object name="emblem[em]" size="4 8 4+64 8+64">
     47
     48                        <object type="image" style="EmblemImage" name="emblem[em]_img"/>
     49                        <object type="button" style="EmblemButton" name="emblem[em]_btn" tooltip_style="sessionToolTipBold">
     50                        </object>
     51                    </object>
     52                </repeat>
     53
     54                <repeat count="12" var="g">
     55                    <object size="8 8 100%-8 24+72+16" name="civGroup[g]">
     56                        <object
     57                            name="civGroup[g]_heading"
     58                            type="text"
     59                            font="sans-16"
     60                            textcolor="white"
     61                            text_align="left"
     62                            size="2 0 50% 24"
     63                        >
     64                            <translatableAttribute id="caption">A group:</translatableAttribute>
     65                        </object>
     66                        <object sprite="ModernGoldLine" type="image" size="0 24 45% 25"/>
     67                    </object>
     68                </repeat>
     69            </object>
     70
     71        </object>
     72
     73        <object sprite="ModernDarkBoxGold" type="image" size="70%+8 32 100%-16 90%-70">
     74
     75            <!-- Selection Details -->
     76            <object
     77                name="selected_heading"
     78                type="text"
     79                font="sans-bold-24"
     80                textcolor="white"
     81                text_align="center"
     82                size="0 12 100% 40"
     83            />
     84
     85            <object
     86                name="selected_civs"
     87                type="text"
     88                font="sans-16"
     89                textcolor="white"
     90                text_align="center"
     91                size="4 44 100%-4 100%-4"
     92            />
     93
     94            <object size="8 48 100%-8 100%-8" type="image" sprite="ModernDarkBoxGold">
     95                <object
     96                    name="selected_history"
     97                    type="text"
     98                    font="sans-14"
     99                    textcolor="white"
     100                    text_align="center"
     101                    size="4 4 100%-4 100%-4"
     102                />
     103            </object>
     104
     105        </object>
     106        <object
     107            name="selected_text"
     108            type="text"
     109            font="sans-12"
     110            textcolor="green"
     111            text_align="center"
     112            text_valign="bottom"
     113            size="70%+8 100%-64 100%-16 100%-48"
     114        />
     115
     116        <object name="optionSelectAll" size="650 589 120% 25%">
     117            <object size="0 0 40% 28" type="text" style="ModernRightLabelText">
     118                <translatableAttribute id="caption">Select All:</translatableAttribute>
     119            </object>
     120            <object name="selectAll" size="225 5 46% -5%" type="checkbox" style="ModernTickBox">
     121                <action on="Press">selectAllCivs();</action>
     122                <translatableAttribute id="tooltip">A civilization will be picked from all possible civilizations (Random All).</translatableAttribute>
     123            </object>
     124        </object>
     125
     126        <object name="optionRandomCultures" size="650 619 120% 25%">
     127            <object size="0 0 40% 28" type="text" style="ModernRightLabelText">
     128                <translatableAttribute id="caption">Random Cultures:</translatableAttribute>
     129            </object>
     130            <object name="randomCultures" size="225 5 46% -5%" type="checkbox" style="ModernTickBox">
     131                <action on="Press">randomCultures();</action>
     132                <translatableAttribute id="tooltip">Civilizations set to "Random All" will be chosen by culture.</translatableAttribute>
     133            </object>
     134        </object>
     135
     136        <!-- Close the dialog -->
     137        <object
     138            type="button"
     139            style="StoneButton"
     140            size="70%+8 100%-44 85%-8 100%-16"
     141        >
     142            <translatableAttribute id="caption">Cancel</translatableAttribute>
     143            <action on="Press">
     144                <![CDATA[
     145                    Engine.PopGuiPage();
     146                ]]>
     147            </action>
     148        </object>
     149
     150        <object
     151            type="button"
     152            style="StoneButton"
     153            size="85% 100%-44 100%-16 100%-16"
     154        >
     155            <translatableAttribute id="caption">Select</translatableAttribute>
     156            <action on="Press">
     157                <![CDATA[
     158                    returnCiv();
     159                ]]>
     160            </action>
     161        </object>
     162
     163    </object>
     164
     165</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 splitlet The var identifying the repeat count, without the square brackets
     6 * @param vMargin The gap, in px, between the rows
     7 * @param hMargin The gap, in px, between the columns
     8 * @param limit Array of limits, of the form `[ {from}, {to} ]`. If an empty array, then it will do all objects matching the basname
     9 * @param vOffset Vertical offset from top of parent object to start drawing from
     10 * @return The height difference between the top of the first element and the bottom of the last.
     11 */
     12function gridArrayRepeatedObjects(basename, splitlet="n", vMargin=0, hMargin=0, limit=[], vOffset=0, hOffset=0, rowLength)
     13{
     14    basename = basename.split("["+splitlet+"]", 2);
     15
     16    if (limit.length == 0)
     17    {
     18        limit = [0, 0, 1];
     19        while (Engine.GetGUIObjectByName(basename.join("["+ (limit[1]+1) +"]")))
     20        {
     21            ++limit[1];
     22            ++limit[2];
     23        }
     24    }
     25    else if (limit.length < 2)
     26    {
     27        error("Invalid limit arguments");
     28        return 0;
     29    }
     30    else
     31        limit[2] = limit[1] - limit[0] + 1;
     32
     33    let firstObj = Engine.GetGUIObjectByName(basename.join("["+limit[0]+"]"));
     34    let child = firstObj.getComputedSize();
     35    child.width = child.right - child.left;
     36    child.height = child.bottom - child.top;
     37
     38    let parent = firstObj.parent.getComputedSize();
     39    parent.width = parent.right - parent.left - hOffset;
     40
     41    rowLength = rowLength || Math.floor(parent.width / child.width);
     42
     43    child.width += hMargin;
     44    child.height += vMargin;
     45
     46    let i = limit[0];
     47    for (let r = 0; r < Math.ceil(limit[2] / rowLength); ++r)
     48    {
     49        for (let c = 0; c < rowLength; ++c)
     50        {
     51            let newSize = new GUISize();
     52            newSize.left = c * child.width + hMargin + hOffset;
     53            newSize.right = (c+1) * child.width + hOffset;
     54            newSize.top = r * child.height + vMargin + vOffset;
     55            newSize.bottom = (r+1) * child.height + vOffset;
     56            Engine.GetGUIObjectByName(basename.join("["+ i++ +"]")).size = newSize;
     57
     58            if (i > limit[1])
     59                break;
     60        }
     61    }
     62
     63    let lastObj = Engine.GetGUIObjectByName(basename.join("["+(i-1)+"]"));
     64    return (lastObj.size.bottom - firstObj.size.top);
     65}
     66
     67/**
     68 * Load Data about a grouping schema
     69 *
     70 * @param attr The JSON attribute in the Civ JSON files that lists which of the groups in this schema that civ belongs to
     71 * @param folder The folder containing the groups of this schema
     72 */
     73function loadGroupingSchema(folder, attr)
     74{
     75    let groupData = {};
     76    let groupless = [];
     77
     78    for (let code of Object.keys(g_CivData))
     79    {
     80        let civ = g_CivData[code];
     81        let nogroup = true;
     82        let groups = civ[attr] || [];
     83        if (typeof groups === "string")
     84            groups = [ groups ];
     85
     86        for (let grp of groups)
     87        {
     88            if (groupData[grp] === undefined)
     89            {
     90                let data = Engine.ReadJSONFile("simulation/data/civs/"+folder+"/"+grp+".json");
     91
     92                if (!data)
     93                    continue;
     94
     95                groupData[grp] = data;
     96                groupData[grp].civlist = [];
     97
     98            }
     99            groupData[grp].civlist.push(code);
     100            nogroup = false;
     101        }
     102        if (nogroup)
     103            groupless.push(code);
     104
     105    }
     106    if (groupless.length > 0)
     107        groupData.groupless = {
     108            "Name" : "Ungrouped",
     109            "Code" : "groupless",
     110            "History" : "-",
     111            "civlist": groupless
     112        };
     113
     114    return groupData;
     115}
     116
     117function setEmbSize(objectName, length=128)
     118{
     119    let objSize = Engine.GetGUIObjectByName(objectName).size;
     120    objSize.right = objSize.left + length;
     121    objSize.bottom = objSize.top + length;
     122    Engine.GetGUIObjectByName(objectName).size = objSize;
     123}
     124
     125function setEmbPos(objectName, x=0, y=0)
     126{
     127    let objSize = Engine.GetGUIObjectByName(objectName).size;
     128    let wid = objSize.right - objSize.left;
     129    objSize.left = x;
     130    objSize.top = y;
     131    Engine.GetGUIObjectByName(objectName).size = objSize;
     132    setEmbSize(objectName, wid);
     133}
  • 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

     
    144144const g_RandomMap = '[color="' + g_ColorRandom + '"]' + translateWithContext("map selection", "Random") + "[/color]";
    145145
    146146/**
    147  * Placeholder item for the civ-dropdownlists.
     147 * Style for the random civ strings.
    148148 */
    149 const g_RandomCiv = '[color="' + g_ColorRandom + '"]' + translateWithContext("civilization", "Random") + '[/color]';
     149const g_RandomCivStyle = ['[color="' + g_ColorRandom + '"]', '[/color]'];
    150150
    151151/**
     152 *
     153 */
     154var g_RandomCivObj = {};
     155
     156var g_RandomCultures = Engine.ConfigDB_GetValue("user", "randomcultures") === "true";
     157
     158/**
    152159 * Whether this is a single- or multiplayer match.
    153160 */
    154161var g_IsNetworked;
     
    259266    g_DefaultPlayerData = g_Settings.PlayerDefaults;
    260267    g_DefaultPlayerData.shift();
    261268    for (let i in g_DefaultPlayerData)
    262         g_DefaultPlayerData[i].Civ = "random";
     269        g_DefaultPlayerData[i].CivObj = {
     270                "codes": [ g_DefaultPlayerData[i].Civ ],
     271                "grouped": false
     272        };
     273       
     274    g_RandomCivObj = {
     275                    "codes": Object.keys(g_CivData).filter(civ => g_CivData[civ].SelectableInGameSetup),
     276                    "grouped": true,
     277                    "group": { "type": "none", "code": "all", "caption": translateWithContext("All Civs", "All") }
     278            };
    263279
    264280    setTimeout(displayGamestateNotifications, 1000);
    265281}
     
    271287{
    272288    Engine.GetGUIObjectByName("cancelGame").tooltip = Engine.HasXmppClient() ? translate("Return to the lobby.") : translate("Return to the main menu.");
    273289
    274     initCivNameList();
    275290    initMapTypes();
    276291    initMapFilters();
    277292
     
    536551    for (let i = 0; i < g_MaxPlayers; ++i)
    537552    {
    538553        Engine.GetGUIObjectByName("playerAssignment["+i+"]").hidden = true;
    539         Engine.GetGUIObjectByName("playerCiv["+i+"]").hidden = true;
    540554        Engine.GetGUIObjectByName("playerTeam["+i+"]").hidden = true;
    541555    }
    542556
     
    622636        colorPicker.list_data = g_PlayerColors.map((color, index) => index);
    623637        colorPicker.selected = -1;
    624638        colorPicker.onSelectionChange = function() { selectPlayerColor(playerSlot, this.selected); };
    625 
    626         Engine.GetGUIObjectByName("playerCiv["+i+"]").onSelectionChange = function() {
    627             if ((this.selected != -1)&&(g_GameAttributes.mapType !== "scenario"))
    628                 g_GameAttributes.settings.PlayerData[playerSlot].Civ = this.list_data[this.selected];
    629 
    630             updateGameAttributes();
    631         };
    632639    }
    633640}
    634641
     
    808815    return undefined;
    809816}
    810817
    811 /**
    812  * Initialize the dropdowns containing all selectable civs (including random).
    813  */
    814 function initCivNameList()
     818function setCiv(args)
    815819{
    816     let civList = Object.keys(g_CivData).filter(civ => g_CivData[civ].SelectableInGameSetup).map(civ => ({ "name": g_CivData[civ].Name, "code": civ })).sort(sortNameIgnoreCase);
    817     let civListNames = [g_RandomCiv].concat(civList.map(civ => civ.name));
    818     let civListCodes = ["random"].concat(civList.map(civ => civ.code));
    819 
    820     for (let i = 0; i < g_MaxPlayers; ++i)
    821     {
    822         let civ = Engine.GetGUIObjectByName("playerCiv["+i+"]");
    823         civ.list = civListNames;
    824         civ.list_data = civListCodes;
    825         civ.selected = 0;
    826     }
     820    g_GameAttributes.settings.PlayerData[args.player].CivObj = args.civ;
     821    g_RandomCultures = args.randomCultures;
     822    updateGameAttributes();
    827823}
    828824
    829825/**
     
    918914    if (!g_IsNetworked)
    919915        mapSettings.CheatsEnabled = true;
    920916
    921     // Replace unselectable civs with random civ
     917    // Filter out unselectable civs
    922918    let playerData = mapSettings.PlayerData;
    923919    if (playerData && g_GameAttributes.mapType != "scenario")
    924920        for (let i in playerData)
    925             if (!g_CivData[playerData[i].Civ] || !g_CivData[playerData[i].Civ].SelectableInGameSetup)
    926                 playerData[i].Civ = "random";
     921        {
     922                if (!playerData[i].CivObj)
     923                        continue;
     924                playerData[i].CivObj.codes = playerData[i].CivObj.codes.filter((code) => {return g_CivData[code] && g_CivData[code].SelectableInGameSetup});
     925                if (playerData[i].CivObj.codes.length === 0)
     926                    playerData[i].CivObj = g_RandomCivObj;
     927        }
    927928
    928929    // Apply map settings
    929930    let newMapData = loadMapData(mapName);
     
    962963
    963964    playerData.forEach((pData, index) => {
    964965        pData.Color = pData.Color || g_PlayerColors[index];
    965         pData.Civ = pData.Civ || "random";
     966        pData.CivObj = pData.CivObj ? pData.CivObj : (pData.Civ && pData.Civ !== "random" ? { "codes": [ pData.Civ ], "grouped": false } : g_RandomCivObj)
    966967        pData.AI = pData.AI || "";
    967968    });
    968969
     
    12461247    let cultures = Object.keys(g_CivData).filter(civ => g_CivData[civ].SelectableInGameSetup).map(civ => g_CivData[civ].Culture);
    12471248    cultures = cultures.filter((culture, index) => cultures.indexOf(culture) === index);
    12481249
    1249     // Determine random civs and botnames
    12501250    for (let i in g_GameAttributes.settings.PlayerData)
    12511251    {
    1252         // Pick a random civ of a random culture
    1253         let chosenCiv = g_GameAttributes.settings.PlayerData[i].Civ || "random";
    1254         if (chosenCiv == "random")
     1252        // Determine civ
     1253        let civs = g_GameAttributes.settings.PlayerData[i].CivObj.codes;
     1254        let chosenCiv = civs[Math.floor(Math.random() * civs.length)];
     1255
     1256        if (civs.length > 1)
    12551257        {
    1256             let culture = cultures[Math.floor(Math.random() * cultures.length)];
    1257             let civs = Object.keys(g_CivData).filter(civ => g_CivData[civ].Culture == culture);
    1258             chosenCiv = civs[Math.floor(Math.random() * civs.length)];
     1258            if (g_RandomCultures && g_GameAttributes.settings.PlayerData[i].CivObj.group.code == "all")
     1259            {
     1260                let culture = cultures[Math.floor(Math.random() * cultures.length)];
     1261                warn(uneval(culture));
     1262                let civs = Object.keys(g_CivData).filter(civ => g_CivData[civ].Culture == culture);
     1263                chosenCiv = civs[Math.floor(Math.random() * civs.length)];
     1264            }
     1265            else if (g_GameAttributes.settings.PlayerData[i].CivObj.group.code == "custom" && Object.keys(g_CivData).indexOf(chosenCiv) == -1)
     1266                chosenCiv = chosenCiv[Math.floor(Math.random() * chosenCiv.length)];
    12591267        }
     1268
    12601269        g_GameAttributes.settings.PlayerData[i].Civ = chosenCiv;
    12611270
    12621271        // Pick one of the available botnames for the chosen civ
     
    14191428        let pName = Engine.GetGUIObjectByName("playerName["+i+"]");
    14201429        let pAssignment = Engine.GetGUIObjectByName("playerAssignment["+i+"]");
    14211430        let pAssignmentText = Engine.GetGUIObjectByName("playerAssignmentText["+i+"]");
    1422         let pCiv = Engine.GetGUIObjectByName("playerCiv["+i+"]");
    1423         let pCivText = Engine.GetGUIObjectByName("playerCivText["+i+"]");
     1431        //let pCivText = Engine.GetGUIObjectByName("playerCivText["+i+"]");
     1432        let pCivText = Engine.GetGUIObjectByName("playerCivButton["+i+"]");
    14241433        let pTeam = Engine.GetGUIObjectByName("playerTeam["+i+"]");
    14251434        let pTeamText = Engine.GetGUIObjectByName("playerTeamText["+i+"]");
    14261435        let pColor = Engine.GetGUIObjectByName("playerColor["+i+"]");
     
    14341443
    14351444        let team = getSetting(pData, pDefs, "Team");
    14361445        let civ = getSetting(pData, pDefs, "Civ");
     1446        let civObj = getSetting(pData, pDefs, "CivObj");
    14371447
    14381448        pAssignmentText.caption = pAssignment.list[0] ? pAssignment.list[Math.max(0, pAssignment.selected)] : translate("Loading...");
    1439         pCivText.caption = civ == "random" ? g_RandomCiv : (g_CivData[civ] ? g_CivData[civ].Name : "Unknown");
     1449
     1450        if (civObj)
     1451        {
     1452            if (civObj.grouped)
     1453                pCivText.caption = g_RandomCivStyle[0] + sprintf(translate("Random %(civGroup)s"), {"civGroup": civObj.group.caption }) + g_RandomCivStyle[1];
     1454            else if (civObj.codes.length > 1)   
     1455                pCivText.caption = g_RandomCivStyle[0] + translateWithContext("Selection from a group of civilizations", "Arbitrary Selection") + g_RandomCivStyle[1];
     1456            else
     1457                pCivText.caption = (g_CivData[civObj.codes[0]] ? g_CivData[civObj.codes[0]].Name : translateWithContext("Unnamed civilization", "Unknown"));
     1458        }
     1459
    14401460        pTeamText.caption = (team !== undefined && team >= 0) ? team+1 : "-";
    1441 
    1442         pCiv.selected = civ ? pCiv.list_data.indexOf(civ) : 0;
    14431461        pTeam.selected = team !== undefined && team >= 0 ? team+1 : 0;
    14441462
    14451463        hideControl("playerAssignment["+i+"]", "playerAssignmentText["+i+"]", g_IsController);
    1446         hideControl("playerCiv["+i+"]", "playerCivText["+i+"]", notScenario);
    14471464        hideControl("playerTeam["+i+"]", "playerTeamText["+i+"]", notScenario);
     1465        //Engine.GetGUIObjectByName("playerCivButton["+i+"]").hidden = !notScenario;
    14481466
    14491467        // Allow host to chose player colors on non-scenario maps
    14501468        let pColorPicker = Engine.GetGUIObjectByName("playerColorPicker["+i+"]");
     
    17441762        // Swap civilizations if they aren't fixed
    17451763        if (g_GameAttributes.mapType != "scenario")
    17461764        {
    1747             [g_GameAttributes.settings.PlayerData[playerID - 1].Civ, g_GameAttributes.settings.PlayerData[newSlot].Civ] =
    1748                 [g_GameAttributes.settings.PlayerData[newSlot].Civ, g_GameAttributes.settings.PlayerData[playerID - 1].Civ];
     1765            [g_GameAttributes.settings.PlayerData[playerID - 1].CivObj, g_GameAttributes.settings.PlayerData[newSlot].CivObj] =
     1766                [g_GameAttributes.settings.PlayerData[newSlot].CivObj, g_GameAttributes.settings.PlayerData[playerID - 1].CivObj];
    17491767        }
    17501768    }
    17511769
     
    17551773        g_PlayerAssignments[guid].player = newPlayerID;
    17561774
    17571775    g_GameAttributes.settings.PlayerData[newSlot].AI = "";
     1776    updateGameAttributes();
    17581777}
    17591778
    17601779function submitChatInput()
     
    18331852function resetCivilizations()
    18341853{
    18351854    for (let i in g_GameAttributes.settings.PlayerData)
    1836         g_GameAttributes.settings.PlayerData[i].Civ = "random";
     1855        g_GameAttributes.settings.PlayerData[i].CivObj = g_RandomCivObj;
    18371856
    18381857    updateGameAttributes();
    18391858}
  • binaries/data/mods/public/gui/gamesetup/gamesetup.xml

     
    7878                        size="67.5%+93 0 67.5%+109 16"
    7979                        tooltip_style="onscreenToolTip"
    8080                    >
    81                         <translatableAttribute id="tooltip">Reset any civilizations that have been selected to the default (random)</translatableAttribute>
     81                        <translatableAttribute id="tooltip">Reset any civilizations that have been selected to the default (Random All)</translatableAttribute>
    8282                        <action on="Press">resetCivilizations();</action>
    8383                    </object>
    8484
     
    119119                            >
    120120                                <translatableAttribute id="tooltip">Configure AI settings.</translatableAttribute>
    121121                            </object>
    122                             <object name="playerCiv[n]" type="dropdown" style="ModernDropDown" size="50%+69 2 85% 30" tooltip_style="onscreenToolTip">
    123                                 <translatableAttribute id="tooltip">Select player's civilization.</translatableAttribute>
     122                            <object name="playerCivText[n]"
     123                                type="text"
     124                                style="ModernLabelText"
     125                                size="50%+65 0 85%-16 30"
     126                            >
    124127                            </object>
    125                             <object name="playerCivText[n]" type="text" style="ModernLabelText" size="50%+65 0 85% 30"/>
     128
     129                            <object name="playerCivButton[n]"
     130                                type="button"
     131                                style="StoneButton"
     132                                size="50%+65 0 85%-16 30"
     133                                tooltip_style="onscreenToolTip"
     134                            >
     135                                <translatableAttribute id="tooltip">Select a civilisation</translatableAttribute>
     136                                <action on="MouseLeftRelease"><![CDATA[
     137                                    let player = this.name.slice(16, -1);
     138                                    Engine.PushGuiPage("page_civselect.xml", {
     139                                        "player": player,
     140                                        "civ": g_GameAttributes.settings.PlayerData[player].CivObj,
     141                                        "callback": "setCiv"
     142                                    });
     143                                ]]></action>
     144                            </object>
    126145                            <object name="playerTeam[n]" type="dropdown" style="ModernDropDown" size="85%+5 2 100%-5 30" tooltip_style="onscreenToolTip">
    127146                                <translatableAttribute id="tooltip">Select player's team.</translatableAttribute>
    128147                            </object>
     148
    129149                            <object name="playerTeamText[n]" type="text" style="ModernLabelText" size="85%+5 0 100%-5 100%"/>
    130150                        </object>
    131151                    </repeat>
    132152                </object>
    133153            </object>
     154
    134155            <object size="24 64 100%-460 358" type="image" sprite="CoverFillDark" name="playerAssignmentsPanelCover" hidden="true"/>
     156
    135157            <!-- Map selection -->
    136 
    137158            <object size="100%-425 355 100%-285 470" name="mapTypeTooltip">
    138159                <object type="text" style="ModernRightLabelText" size="0 0 100% 30">
    139160                    <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":["cart"],
     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/cart.json

     
     1{
     2    "Name" : "The Carthaginians",
     3    "Code" : "cart",
     4    "History" : "-",
     5    "Singular" : "Carthaginian"
     6}
  • 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/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/maur.json

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

     
     1{
     2    "Name" : "The Persian Empire",
     3    "Code" : "pers",
     4    "History" : "-",
     5    "Singular" : "Persian"
     6}
  • binaries/data/mods/public/simulation/data/civs/cultures/ptol.json

     
     1{
     2    "Name" : "The Ptolemies",
     3    "Code" : "ptol",
     4    "History" : "-",
     5    "Singular" : "Ptolemaic"
     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":["iber"],
     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":["maur"],
     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":["pers"],
     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":["ptol"],
     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":["rome"],
     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.",