This Trac instance is not used for development anymore!

We migrated our development workflow to git and Gitea.
To test the future redirection, replace trac by ariadne in the page URL.

Ticket #2160: Regicide_v0.4.patch

File Regicide_v0.4.patch, 9.1 KB (added by elexis, 8 years ago)

Rewrote the loops to address the remarks

  • binaries/data/mods/public/globalscripts/utility.js

    function clone(o)  
    1414        return o;
    1515    for (let key in o)
    1616        r[key] = clone(o[key]);
    1717    return r;
    1818}
     19
     20/**
     21 * "Inside-out" implementation of Fisher-Yates shuffle
     22 */
     23function shuffleArray(source)
     24{
     25    if (!source.length)
     26        return [];
     27
     28    let result = [source[0]];
     29    for (let i = 1; i < source.length; ++i)
     30    {
     31        let j = Math.floor(Math.random() * i);
     32        result[i] = result[j];
     33        result[j] = source[i];
     34    }
     35    return result;
     36}
  • binaries/data/mods/public/maps/random/rmgen/library.js

    const MAX_MAP_SIZE = 512;  
    99const MAP_BORDER_WIDTH = 3;
    1010const FALLBACK_CIV = "athen";
    1111/**
    1212 * Constants needed for heightmap_manipulation.js
    1313 */
    14 const MAX_HEIGHT_RANGE = 0xFFFF / HEIGHT_UNITS_PER_METRE // Engine limit, Roughly 700 meters
     14const MAX_HEIGHT_RANGE = 0xFFFF / HEIGHT_UNITS_PER_METRE; // Engine limit, Roughly 700 meters
    1515const MIN_HEIGHT = - SEA_LEVEL;
    1616const MAX_HEIGHT = MAX_HEIGHT_RANGE - SEA_LEVEL;
    1717// Default angle for buildings
    1818const BUILDING_ORIENTATION = - PI / 4;
    1919
    function min(a, b)  
    9090{
    9191    return a < b ? a : b;
    9292}
    9393
    9494/**
    95  * "Inside-out" implementation of Fisher-Yates shuffle
    96  */
    97 function shuffleArray(source)
    98 {
    99     if (!source.length)
    100         return [];
    101 
    102     let result = [source[0]];
    103     for (let i = 1; i < source.length; ++i)
    104     {
    105         let j = randInt(0, i);
    106         result[i] = result[j];
    107         result[j] = source[i];
    108     }
    109     return result;
    110 }
    111 
    112 /**
    11395 * Retries the given function with those arguments as often as specified.
    11496 */
    11597function retryPlacing(placeFunc, placeArgs, retryFactor, amount, getResult)
    11698{
    11799    let maxFail = amount * retryFactor;
  • binaries/data/mods/public/maps/scripts/Regicide.js

     
     1Trigger.prototype.CheckRegicideDefeat = function(data)
     2{
     3    if (data.entity == this.heroes[data.from])
     4        TriggerHelper.DefeatPlayer(data.from);
     5};
     6
     7Trigger.prototype.InitRegicideGame = function(msg)
     8{
     9    let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
     10
     11    // Get unique list of chosen civs
     12    let civs = [];
     13    let playersCivs = [];
     14    for (let playerID = 1; playerID < TriggerHelper.GetNumberOfPlayers(); ++playerID)
     15    {
     16        let civ = QueryPlayerIDInterface(playerID).GetCiv();
     17        playersCivs[playerID] = civ;
     18
     19        if (civs.indexOf(civ) == -1)
     20            civs.push(civ);
     21    }
     22
     23    // Get all hero templates of these civs
     24    let heroTemplates = {};
     25    for (let templateName of cmpTemplateManager.FindAllTemplates(false))
     26    {
     27        if (templateName.substring(0,6) != "units/")
     28            continue;
     29
     30        let identity = cmpTemplateManager.GetTemplate(templateName).Identity;
     31        let classes = GetIdentityClasses(identity);
     32
     33        if (classes.indexOf("Hero") == -1)
     34            continue;
     35
     36        if (!heroTemplates[identity.Civ])
     37            heroTemplates[identity.Civ] = [];
     38
     39        if (heroTemplates[identity.Civ].indexOf(templateName) == -1)
     40            heroTemplates[identity.Civ].push({
     41                "templateName": templateName,
     42                "classes": classes
     43            });
     44    }
     45
     46    // Sort spawn points by preference
     47    let getPreference = entity => {
     48        let cmpIdentity = Engine.QueryInterface(entity, IID_Identity);
     49        let classes = cmpIdentity.GetClassesList();
     50
     51        if (classes.indexOf("CivilCentre") != -1)
     52            return 3;
     53
     54        if (classes.indexOf("Structure") != -1)
     55            return 2;
     56
     57        if (classes.indexOf("Ship") != -1)
     58            return 1;
     59
     60        return 0;
     61    };
     62
     63    let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
     64    for (let playerID = 1; playerID < TriggerHelper.GetNumberOfPlayers(); ++playerID)
     65    {
     66        let spawnPoints = cmpRangeManager.GetEntitiesByPlayer(playerID).sort((entity1, entity2) =>
     67            getPreference(entity2) - getPreference(entity1));
     68
     69        this.heroes[playerID] = this.SpawnHero(playerID, heroTemplates[playersCivs[playerID]], spawnPoints);
     70    }
     71};
     72
     73/**
     74 * Spawn a random hero at one of the given locations (which are checked in order).
     75 * Garrison it if the location is a ship.
     76 *
     77 * @param spawnPoints - entity IDs at which to spawn
     78 */
     79Trigger.prototype.SpawnHero = function(playerID, heroTemplates, spawnPoints)
     80{
     81    for (let heroTemplate of shuffleArray(heroTemplates))
     82        for (let spawnPoint of spawnPoints)
     83        {
     84            let cmpPosition = Engine.QueryInterface(spawnPoint, IID_Position);
     85            if (!cmpPosition || !cmpPosition.IsInWorld())
     86                continue;
     87
     88            let isShip = TriggerHelper.EntityHasClass(spawnPoint, "Ship");
     89            if (isShip)
     90            {
     91                let cmpGarrisonHolder = Engine.QueryInterface(spawnPoint, IID_GarrisonHolder);
     92                if (cmpGarrisonHolder.IsFull() ||
     93                    !MatchesClassList(heroTemplate.classes, cmpGarrisonHolder.GetAllowedClasses()))
     94                    continue;
     95            }
     96
     97            let hero = TriggerHelper.SpawnUnits(spawnPoint, heroTemplate.templateName, 1, playerID);
     98            if (!hero.length)
     99                continue;
     100
     101            hero = hero[0];
     102
     103            if (isShip)
     104            {
     105                let cmpUnitAI = Engine.QueryInterface(hero, IID_UnitAI);
     106                cmpUnitAI.Garrison(spawnPoint);
     107            }
     108
     109            return hero;
     110        }
     111
     112    error("Couldn't spawn hero for player " + playerID);
     113    return undefined;
     114};
     115
     116let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
     117cmpTrigger.heroes = []; // TODO: what if gaia gets a hero?
     118cmpTrigger.DoAfterDelay(0, "InitRegicideGame", {});
     119
     120cmpTrigger.RegisterTrigger("OnOwnershipChanged", "CheckRegicideDefeat", { "enabled": true });
  • binaries/data/mods/public/maps/scripts/TriggerHelper.js

    TriggerHelper.GetOwner = function(ent)  
    2020
    2121    return -1;
    2222};
    2323
    2424/**
    25  * Can be used to "force" a building to spawn a group of entities.
    26  * Only works for buildings that can already train units.
     25 * Can be used to "force" a building/unit to spawn a group of entities.
     26 * A default position is returned if no valid position is found.
    2727 * @param source Entity id of the point where they will be spawned from
    2828 * @param template Name of the template
    2929 * @param count Number of units to spawn
    3030 * @param owner Player id of the owner of the new units. By default, the owner
    3131 * of the source entity.
  • binaries/data/mods/public/simulation/data/settings/victory_conditions/regicide.json

     
     1{
     2    "TranslatedKeys": ["Title", "Description"],
     3    "Data":
     4    {
     5        "Title": "Regicide",
     6        "Description": "Keep your Hero alive to win",
     7        "Scripts":
     8        [
     9            "scripts/TriggerHelper.js",
     10            "scripts/ConquestCommon.js",
     11            "scripts/Conquest.js",
     12            "scripts/Regicide.js"
     13        ]
     14    }
     15}
  • binaries/data/mods/public/simulation/templates/units/maur_ship_trireme.xml

     
    66  <Footprint>
    77    <Square width="17.0" depth="45.0"/>
    88    <Height>8.0</Height>
    99  </Footprint>
    1010  <GarrisonHolder>
    11     <Max>40</Max>
     11    <Max>15</Max>
    1212  </GarrisonHolder>
    1313  <Health>
    1414    <Max op="add">200</Max>
    1515  </Health>
    1616  <Identity>
  • source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp

     
    1 /* Copyright (C) 2015 Wildfire Games.
     1/* Copyright (C) 2016 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
    55 * it under the terms of the GNU General Public License as published by
    66 * the Free Software Foundation, either version 2 of the License, or
    void MapSettingsControl::CreateWidgets()  
    146146    gameTypes.Add(_T("conquest"));
    147147    gameTypes.Add(_T("conquest_structures"));
    148148    gameTypes.Add(_T("conquest_units"));
    149149    gameTypes.Add(_T("wonder"));
    150150    gameTypes.Add(_T("endless"));
     151    gameTypes.Add(_T("regicide"));
    151152
    152153    wxFlexGridSizer* gridSizer = new wxFlexGridSizer(2, 5, 5);
    153154    gridSizer->AddGrowableCol(1);
    154155    // TODO: have preview selector tool?
    155156    gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Preview")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));