Ticket #2048: auras_json.diff

File auras_json.diff, 28.5 KB (added by sanderd17, 11 years ago)
  • binaries/data/mods/public/simulation/components/AuraManager.js

     
     1function AuraManager() {}
     2
     3AuraManager.prototype.Schema =
     4    "<a:component type='system'/><empty/>";
     5
     6AuraManager.prototype.Init = function()
     7{
     8    this.modificationCache = {};
     9    this.modifications = {};
     10    this.templateModificationCache = {};
     11    this.templateModifications = {};
     12};
     13
     14AuraManager.prototype.ApplyBonus = function(value, ent, data, key)
     15{
     16    if (!this.modifications[value])
     17    {
     18        this.modificationCache[value] = {};
     19        this.modifications[value] = {};
     20    }   
     21   
     22    if (!this.modifications[value][ent])
     23    {
     24        this.modifications[value][ent] = {};
     25        this.modificationCache[value][ent] = { "add":0, "multiply":1};
     26    }
     27
     28    if (!this.modifications[value][ent][key])
     29        this.modifications[value][ent][key] = [];
     30
     31    this.modifications[value][ent][key].push(data);
     32
     33    if (this.modifications[value][ent][key].length > 1)
     34        return;
     35    // first time added this aura
     36    if (data.multiply)
     37        this.modificationCache[value][ent].multiply *= data.multiply;
     38   
     39    if (data.add)
     40        this.modificationCache[value][ent].add += data.add;
     41
     42    // post message to the entity to notify it about the change
     43    // TODO with player = -1, this works, but it's ugly. Find a solution
     44    var component = value.split("/")[0];
     45    Engine.PostMessage(ent, MT_TechnologyModification, { "component": component, "player": -1});
     46};
     47
     48AuraManager.prototype.ApplyTemplateBonus = function(value, player, classes, data, key)
     49{
     50    if (!this.templateModifications[value])
     51    {
     52        this.templateModificationCache[value] = {};
     53        this.templateModifications[value] = {};
     54    }   
     55   
     56    if (!this.templateModifications[value][player])
     57    {
     58        this.templateModifications[value][player] = {};
     59        this.templateModificationCache[value][player] = {};
     60    }
     61
     62    if (!this.templateModifications[value][player][key])
     63        this.templateModifications[value][player][key] = [];
     64
     65    this.templateModifications[value][player][key].push(data);
     66
     67    if (this.templateModifications[value][player][key].length > 1)
     68        return;
     69   
     70    // first time added this aura
     71    for each (var c in classes)
     72    {
     73        if (!this.templateModificationCache[value][player][c])
     74            this.templateModificationCache[value][player][c] = [];
     75
     76        if (!this.templateModificationCache[value][player][c][key])
     77            this.templateModificationCache[value][player][c][key] = { "add":0, "multiply":1, "numberOfAuras": 1};
     78
     79        if (data.multiply)
     80            this.templateModificationCache[value][player][c][key].multiply *= data.multiply;
     81       
     82        if (data.add)
     83            this.templateModificationCache[value][player][c][key].add += data.add;
     84
     85
     86        // post message to notify about the change
     87        var component = value.split("/")[0];
     88        Engine.BroadcastMessage(MT_TechnologyModification, { "component": component, "player": player});
     89    }
     90};
     91
     92AuraManager.prototype.RemoveBonus = function(value, ent, key)
     93{
     94    if (!this.modifications[value] ||
     95          !this.modifications[value][ent] ||
     96          !this.modifications[value][ent][key] ||
     97          !this.modifications[value][ent][key].length)
     98        return;
     99   
     100    // get the applied data to remove again
     101    var data = this.modifications[value][ent][key].pop();
     102
     103    if (this.modifications[value][ent][key].length > 0)
     104        return;
     105   
     106    // out of last aura of this kind, remove modifications
     107    if (data.add)
     108        this.modificationCache[value][ent].add -= data.add;
     109
     110    if (data.multiply)
     111        this.modificationCache[value][ent].multiply /= data.multiply;
     112
     113    // post message to the entity to notify it about the change
     114    // TODO with player = 0, this works, but it's ugly. Find a solution
     115    var component = value.split("/")[0];
     116    Engine.PostMessage(ent, MT_TechnologyModification, { "component": component, "player": 0});
     117   
     118   
     119};
     120
     121AuraManager.prototype.RemoveTemplateBonus = function(value, player, classes, key)
     122{
     123    if (!this.templateModifications[value] ||
     124          !this.templateModifications[value][player] ||
     125          !this.templateModifications[value][player][key] ||
     126          !this.templateModifications[value][player][key].length)
     127        return;
     128
     129    this.templateModifications[value][player][key].pop();
     130
     131    if (this.templateModifications[value][player][key].length > 0)
     132        return;
     133
     134    for each (var c in classes)
     135    {
     136        this.templateModificationCache[value][player][c][key].multiply = 1;
     137        this.templateModificationCache[value][player][c][key].add = 0;
     138
     139
     140        // post message to notify about the change
     141        var component = value.split("/")[0];
     142        Engine.BroadcastMessage(MT_TechnologyModification, { "component": component, "player": player});
     143    }
     144};
     145
     146AuraManager.prototype.ApplyModifications = function(valueName, value, ent)
     147{
     148    if (!this.modificationCache[valueName] || !this.modificationCache[valueName][ent])
     149        return value;
     150
     151    value *= this.modificationCache[valueName][ent].multiply;
     152    value += this.modificationCache[valueName][ent].add;
     153    return value;
     154};
     155
     156AuraManager.prototype.ApplyTemplateModifications = function(valueName, value, player, template)
     157{
     158    if (!this.templateModificationCache[valueName] || !this.templateModificationCache[valueName][player])
     159        return value;
     160
     161    var classes = template.Identity.Classes._string.split(/\s+/);
     162
     163    var keyList = [];
     164
     165    for (var c in this.templateModificationCache[valueName][player])
     166    {
     167        if (classes.indexOf(c) == -1)
     168            continue;
     169
     170        for (var key in this.templateModificationCache[valueName][player][c])
     171        {
     172            // don't add an aura with the same key twice
     173            if (keyList.indexOf(key) != -1)
     174                continue;
     175
     176            value *= this.templateModificationCache[valueName][player][c][key].multiply;
     177            value += this.templateModificationCache[valueName][player][c][key].add;
     178            keyList.push(key);
     179        }
     180    }
     181    return value;
     182};
     183
     184Engine.RegisterComponentType(IID_AuraManager, "AuraManager", AuraManager);
  • binaries/data/mods/public/simulation/components/Auras.js

     
    11function Auras() {}
    22
    33Auras.prototype.Schema =
    4     "<oneOrMore>" +
    5         "<element>" +
    6             "<choice>" +
    7                 "<name>Allure</name>" +
    8                 "<name>Infidelity</name>" +
    9                 "<name>Heal</name>" +
    10                 "<name>Courage</name>" +
    11                 "<name>Fear</name>" +
    12             "</choice>" +
    13             "<interleave>" +
    14                 "<element name='Radius'>" +
    15                     "<data type='nonNegativeInteger'/>" +
    16                 "</element>" +
    17                 "<optional>" +
    18                     "<element name='Bonus'>" +
    19                         "<data type='positiveInteger'/>" +
    20                     "</element>" +
    21                 "</optional>" +
    22                 "<optional>" +
    23                     "<element name='Time'>" +
    24                         "<data type='nonNegativeInteger'/>" +
    25                     "</element>" +
    26                 "</optional>" +
    27                 "<optional>" +
    28                     "<element name='Speed'>" +
    29                         "<data type='positiveInteger'/>" +
    30                     "</element>" +
    31                 "</optional>" +
    32             "</interleave>" +
    33         "</element>" +
    34     "</oneOrMore>";
     4    "<text/>";
    355
    36 /*
    37  * TODO: this all needs to be designed and implemented
     6Auras.prototype.Init = function()
     7{
     8    var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
     9    this.templateName = cmpTemplateManager.GetCurrentTemplateName(this.entity);
     10    var auraNames = this.GetAuraNames();
     11    this.auras = {};
     12    var cmpTechnologyTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TechnologyTemplateManager);
     13    for each (var name in auraNames)
     14        this.auras[name] = cmpTechnologyTemplateManager.GetAuraTemplate(name);
     15};
     16
     17Auras.prototype.GetAuraNames = function()
     18{
     19    return this.template.split(/\s+/);
     20};
     21
     22Auras.prototype.GetRange = function(name)
     23{
     24    if (!this.IsRangeAura(name))
     25        return undefined;
     26    if (this.IsTemplateAura(name))
     27        return -1; // -1 is infinite range
     28    return this.auras[name].range;
     29};
     30
     31Auras.prototype.GetClasses = function(name)
     32{
     33    return this.auras[name].affects;
     34};
     35
     36Auras.prototype.GetModifications = function(name)
     37{
     38    return this.auras[name].modifications;
     39};
     40
     41Auras.prototype.GetAffectedPlayers = function(name)
     42{
     43    if (this.auras[name].affectedPlayers)
     44        var affectedPlayers = this.auras[name].affectedPlayers;
     45    else
     46        var affectedPlayers = ["Player"];
     47
     48    var ret = [];
     49
     50    var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
     51
     52    if (!cmpPlayer)
     53        return ret;
     54
     55    var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     56    var numPlayers = cmpPlayerManager.GetNumPlayers();
     57
     58    for (var i = 0; i < numPlayers; ++i)
     59    {
     60        for each (var p in affectedPlayers)
     61        {
     62            if ((p == "Player" && cmpPlayer.GetPlayerID() == i) || cmpPlayer["Is"+p](i))
     63            {
     64                ret.push(i);
     65                break;
     66            }
     67        }
     68    }
     69    return ret;
     70};
     71
     72Auras.prototype.HasFormationAura = function()
     73{
     74    return this.GetAuraNames().some(this.IsGarrisonAura.bind(this))
     75};
     76
     77Auras.prototype.HasGarrisonAura = function()
     78{
     79    return this.GetAuraNames().some(this.IsGarrisonAura.bind(this))
     80};
     81
     82Auras.prototype.IsFormationAura = function(name)
     83{
     84    return this.auras[name].type == "Formation";
     85};
     86
     87Auras.prototype.IsGarrisonAura = function(name)
     88{
     89    return this.auras[name].type == "GarrisoningStructure";
     90};
     91
     92Auras.prototype.IsRangeAura = function(name)
     93{
     94    // a template aura is also treated as a range aura with infinite range.
     95    return this.auras[name].type == "Range" || this.auras[name].type == "Template";
     96};
     97
     98Auras.prototype.IsTemplateAura = function(name)
     99{
     100    return this.auras[name].type == "Template";
     101};
     102
     103/**
     104 * clean all bonuses. Remove the old ones and re-apply the new ones
    38105 */
     106Auras.prototype.Clean = function()
     107{
     108    var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
     109    var auraNames = this.GetAuraNames();
     110    // remove all bonuses
     111    for each (var name in auraNames)
     112    {
     113        if (!this[name])
     114            continue;
    39115
    40 Auras.prototype.Serialize = null; // we have no dynamic state to save
     116        if (this.IsTemplateAura(name))
     117            this.RemoveTemplateBonus(name);
     118       
     119        for each(var ent in this[name].targetUnits)
     120            this.RemoveBonus(name, ent);
    41121
     122        if (this[name].rangeQuery)
     123            cmpRangeManager.DestroyActiveQuery(this[name].rangeQuery);
     124    }
     125
     126    for each (var name in auraNames)
     127    {
     128        // initialise range query
     129        this[name] = {};
     130        this[name].targetUnits = [];
     131        var affectedPlayers = this.GetAffectedPlayers(name);
     132       
     133        if (!affectedPlayers.length)
     134            continue;
     135
     136        if (this.IsTemplateAura(name))
     137            this.ApplyTemplateBonus(name, affectedPlayers);
     138
     139        if (!this.IsRangeAura(name))
     140            continue;
     141        this[name].rangeQuery = cmpRangeManager.CreateActiveQuery(
     142            this.entity,
     143            0,
     144            this.GetRange(name),
     145            affectedPlayers,
     146            IID_Identity,
     147            cmpRangeManager.GetEntityFlagMask("normal")
     148        );
     149        cmpRangeManager.EnableActiveQuery(this[name].rangeQuery);
     150        // add self to your own query for consistency with templates
     151        this.OnRangeUpdate({"tag":this[name].rangeQuery, "added":[this.entity], "removed":[]});
     152    }
     153};
     154
     155Auras.prototype.GiveMembersWithValidClass = function(auraName, entityList)
     156{
     157    var validClasses = this.GetClasses(auraName);
     158    var r = [];
     159    for each (var ent in entityList)
     160    {
     161        var cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
     162        var targetClasses = cmpIdentity.GetClassesList();
     163        for each (var classCollection in validClasses)
     164        {
     165            if (classCollection.split(/\s+/).every(function(c) {return targetClasses.indexOf(c) > -1}))
     166            {
     167                r.push(ent);
     168                break;
     169            }
     170        }
     171    }
     172    return r;
     173}
     174
     175Auras.prototype.OnRangeUpdate = function(msg)
     176{
     177    var auraNames = this.GetAuraNames();
     178    for each (var n in auraNames)
     179    {
     180        if (msg.tag == this[n].rangeQuery)
     181        {
     182            var name = n;
     183            break;
     184        }
     185    }
     186
     187    if (!name)
     188        return;
     189   
     190    var targetUnits = this[name].targetUnits;
     191    var classes = this.GetClasses(name);
     192   
     193    if (msg.added.length > 0)
     194    {
     195        var validList = this.GiveMembersWithValidClass(name, msg.added);
     196        for each (var e in validList)
     197        {
     198            targetUnits.push(e);
     199            this.ApplyBonus(name,e);
     200        }
     201    }
     202
     203    if (msg.removed.length > 0)
     204    {
     205        for each (var e in msg.removed)
     206        {
     207            targetUnits.splice(targetUnits.indexOf(e), 1);
     208            this.RemoveBonus(name,e);
     209        }
     210    }
     211
     212};
     213
     214Auras.prototype.ApplyFormationBonus = function(memberList)
     215{
     216    var auraNames = this.GetAuraNames();
     217    for each (var name in auraNames)
     218    {
     219        if (!this.IsFormationAura(name))
     220            continue;
     221       
     222        var validList = this.GiveMembersWithValidClass(name, memberList);
     223        for each (var ent in validList)
     224        {
     225            targetUnits.push(e);
     226            this.ApplyBonus(name,e);
     227        }
     228    }
     229};
     230
     231Auras.prototype.ApplyGarrisonBonus = function(structure)
     232{
     233    var auraNames = this.GetAuraNames();
     234    for each (var name in auraNames)
     235    {
     236        if (!this.IsGarrisonAura(name))
     237            continue;
     238       
     239        var validList = this.GiveMembersWithValidClass(name, [structure]);
     240        if (validList.length)
     241        {
     242            targetUnits.push(validList[0]);
     243            this.ApplyBonus(name,validList[0]);
     244        }
     245    }
     246};
     247
     248Auras.prototype.ApplyTemplateBonus = function(name, players)
     249{
     250    if (!this.IsTemplateAura(name))
     251        return;
     252    var modifications = this.GetModifications(name);
     253    var cmpAuraManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_AuraManager);
     254    var classes = this.GetClasses(name);
     255
     256    for each (var mod in modifications)
     257        for each (var player in players)
     258            cmpAuraManager.ApplyTemplateBonus(mod.value, player, mod, classes, this.templateName+"/"+name+"/"+mod.value);   
     259};
     260
     261Auras.prototype.RemoveFormationBonus = function(memberList)
     262{
     263    var auraNames = this.GetAuraNames();
     264    for each (var name in auraName)
     265    {
     266        if (!this.IsFormationAura(name))
     267            continue;
     268
     269        for each (var ent in memberList)
     270        {
     271            this.RemoveBonus(name,ent);
     272            this[name].targetUnits.splice(this[name].targetUnits.indexOf(ent), 1);
     273        }
     274    }
     275};
     276
     277Auras.prototype.RemoveGarrisonBonus = function(structure)
     278{
     279    var auraNames = this.GetAuraNames();
     280    for each (var name in auraNames)
     281    {
     282        if (!this.IsGarrisonAura(name))
     283            continue;
     284
     285        this.RemoveBonus(name,structure);
     286        this[name].targetUnits.splice(this[name].targetUnits.indexOf(structure), 1);
     287    }
     288};
     289
     290Auras.prototype.RemoveTemplateBonus = function(name)
     291{
     292    if (!this.IsTemplateAura(name))
     293        return;
     294
     295    var modifications = this.GetModifications(name);
     296    var cmpAuraManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_AuraManager);
     297    var classes = this.GetClasses(name);
     298
     299    for each (var mod in modifications)
     300        for each (var player in this.GetAffectedPlayers())
     301            cmpAuraManager.RemoveTemplateBonus(mod.value, player, classes, this.templateName+"/"+name+"/"+mod.value);
     302};
     303
     304Auras.prototype.ApplyBonus = function(name,ent)
     305{
     306    var modifications = this.GetModifications(name);
     307    var cmpAuraManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_AuraManager);
     308   
     309    for each (mod in modifications)
     310        cmpAuraManager.ApplyBonus(mod.value, ent, mod, this.templateName+"/"+name+"/"+mod.value);   
     311
     312};
     313
     314Auras.prototype.RemoveBonus = function(name,ent)
     315{
     316    var modifications = this.GetModifications(name);
     317    var cmpAuraManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_AuraManager);
     318
     319    for each (mod in modifications)
     320        cmpAuraManager.RemoveBonus(mod.value, ent, this.templateName+"/"+name+"/"+value);   
     321
     322};
     323
     324Auras.prototype.OnOwnershipChanged = function(msg)
     325{
     326    this.Clean();
     327};
     328
     329Auras.prototype.OnDiplomacyChanged = function(msg)
     330{
     331    var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
     332    if (cmpOwnership && cmpOwnership.GetOwner() == msg.player)
     333        this.Clean();
     334};
     335
     336Auras.prototype.OnTechnologyModification = function(msg)
     337{
     338    if (msg.component =="Auras")
     339        this.Clean();
     340};
     341
    42342Engine.RegisterComponentType(IID_Auras, "Auras", Auras);
  • binaries/data/mods/public/simulation/components/EndGameManager.js

     
    1919    // Allied victory means allied players can win if victory conditions are met for each of them
    2020    // Would be false for a "last man standing" game (when diplomacy is fully implemented)
    2121    this.alliedVictory = true;
     22    this.activePlayers = [];
    2223};
    2324
    2425EndGameManager.prototype.SetGameType = function(newGameType)
     
    3132    this.alliedVictory = flag;
    3233};
    3334
    34 /**
    35  * Begin checking the end-game conditions.
    36  * Must be called once, after calling SetGameType.
    37  */
    38 EndGameManager.prototype.Start = function()
     35EndGameManager.prototype.OnUpdate = function()
    3936{
    40     if (this.gameType != "endless")
     37    if (this.gameType == "endless")
     38        return;
     39    // initialise the activePlayers array on the start of the game
     40    if (!this.activePlayers.length)
    4141    {
    42         var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
    43         this.timer = cmpTimer.SetTimeout(this.entity, IID_EndGameManager, "ProgressTimeout", g_ProgressInterval, {});
     42        this.UpdatePlayerStates();
     43        return;
    4444    }
    45 };
    4645
    47 EndGameManager.prototype.OnDestroy = function()
    48 {
    49     if (this.timer)
    50     {
    51         var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
    52         cmpTimer.CancelTimer(this.timer);
    53     }
    54 };
     46    if (!this.activePlayers.every(function(v){return v.GetConquestCriticalEntitiesCount()}))
     47        this.UpdatePlayerStates();
     48}
    5549
    56 EndGameManager.prototype.ProgressTimeout = function(data)
     50EndGameManager.prototype.UpdatePlayerStates = function()
    5751{
    58     this.UpdatePlayerStates();
    59    
    60     // Repeat the timer
    61     var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
    62     this.timer = cmpTimer.SetTimeout(this.entity, IID_EndGameManager, "ProgressTimeout", g_ProgressInterval, data);
    63 };
     52    if (this.gameType == "endless")
     53        return;
    6454
    65 EndGameManager.prototype.UpdatePlayerStates = function()
    66 {
    6755    var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
    68     switch (this.gameType)
     56    var numPlayers = cmpPlayerManager.GetNumPlayers();
     57    this.activePlayers = [];
     58
     59    // get all the active players (or won). Defeat players without the needed entities
     60    for (var i = 1; i < numPlayers; ++i)
    6961    {
    70     case "conquest":
     62        var playerEntity = cmpPlayerManager.GetPlayerByID(i);
     63        var cmpPlayer = Engine.QueryInterface(playerEntity, IID_Player);
     64        if (cmpPlayer.GetState() == "defeated")
     65            continue;
     66        if (cmpPlayer.GetConquestCriticalEntitiesCount())
     67            this.activePlayers.push(cmpPlayer);
     68        else
     69            Engine.PostMessage(playerEntity, MT_PlayerDefeated);
     70    }
    7171
    72         // Ignore gaia
    73         var numPlayers = cmpPlayerManager.GetNumPlayers() - 1;
    74         var cmpPlayers = new Array(numPlayers);
    75        
    76         // If a player is currently active but has no suitable units left,
    77         // mark that player as defeated
    78         for (var i = 0; i < numPlayers; i++)
    79         {
    80             var playerEntityId = cmpPlayerManager.GetPlayerByID(i+1);
    81             cmpPlayers[i] = Engine.QueryInterface(playerEntityId, IID_Player);
    82             if (cmpPlayers[i].GetState() == "active")
    83             {
    84                 if (cmpPlayers[i].GetConquestCriticalEntitiesCount() == 0)
    85                 {   // Defeated - notify AIs by sending playerId
    86                     Engine.PostMessage(playerEntityId, MT_PlayerDefeated, { "playerId": i } );
    87                 }
    88             }
    89         }
     72    if (!this.alliedVictory && this.activePlayers.length > 1)
     73        return;
    9074
    91         var onlyAlliesLeft = true;
    92         var allies = [];
    93         for (var i = 0; i < numPlayers && onlyAlliesLeft; i++)
    94         {
    95             if (cmpPlayers[i].GetState() == "active")
    96             {   //Active player
    97                 for (var j = 0; j < numPlayers && onlyAlliesLeft; j++)
    98                 {
    99                     if (cmpPlayers[j].GetState() == "active"
    100                         && (cmpPlayers[i].IsEnemy(j+1) || cmpPlayers[j].IsEnemy(i+1)
    101                             || cmpPlayers[i].IsNeutral(j+1) || cmpPlayers[j].IsNeutral(i+1)))
    102                     {   // Only need to find an active non-allied player
    103                         onlyAlliesLeft = false;
    104                     }
    105                 }
    106                
    107                 if (onlyAlliesLeft)
    108                     allies.push(i);
    109             }
    110         }
     75    for each (var cmpPlayer in this.activePlayers)
     76    {
     77        if (!this.activePlayers.every(function(v){return cmpPlayer == v || cmpPlayer.IsMutualAlly(v.GetPlayerID())}))
     78            return;
     79    }
    11180
    112         // If only allies left and allied victory set (or only one player left)
    113         if (onlyAlliesLeft && (this.alliedVictory || allies.length == 1))
    114         {
    115             for each (var p in allies)
    116             {
    117                 cmpPlayers[p].SetState("won");
    118             }
    119 
    120             // Reveal the map to all players
    121             var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
    122             cmpRangeManager.SetLosRevealAll(-1, true);
    123         }
    124 
    125         break;
    126 
    127     default:
    128         error("Invalid game type "+this.gameType);
    129         break;
    130     }
     81    var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
     82    cmpRangeManager.SetLosRevealAll(-1, true);
     83    for each (var cmpPlayer in this.activePlayers)
     84        cmpPlayer.SetState("won");
    13185};
    13286
    13387Engine.RegisterComponentType(IID_EndGameManager, "EndGameManager", EndGameManager);
  • binaries/data/mods/public/simulation/components/Formation.js

     
    1212    this.columnar = false; // whether we're travelling in column (vs box) formation
    1313    this.formationName = "Line Closed";
    1414    this.rearrange = true; // whether we should rearrange all formation members
     15    this.formationMemebersWithAura = []; // Members with a formation aura
    1516};
    1617
    1718Formation.prototype.GetMemberCount = function()
     
    8687    {
    8788        var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
    8889        cmpUnitAI.SetFormationController(this.entity);
     90       
     91        var cmpAuras = Engine.QueryInterface(ent, IID_Auras);
     92        if (cmpAuras && cmpAuras.HasFormationAura())
     93        {
     94            this.formationMemebersWithAura.push(ent);
     95            cmpAuras.ApplyFormationBonus(ents);
     96        }
    8997    }
    9098
    9199    // Locate this formation controller in the middle of its members
     
    92100    this.MoveToMembersCenter();
    93101
    94102    this.ComputeMotionParameters();
     103
    95104};
    96105
    97106/**
     
    109118        cmpUnitAI.SetFormationController(INVALID_ENTITY);
    110119    }
    111120
     121    for each (var ent in this.formationMemebersWithAura)
     122    {
     123        var cmpAuras = Engine.QueryInterface(ent, IID_Auras);
     124        cmpAuras.RemoveFormationBonus(ents);
     125
     126        // the unit with the aura is also removed from the formation
     127        if (ents.indexOf(ent) !== -1)
     128            cmpAuras.RemoveFormationBonus(this.members);
     129    }
     130
     131    this.formationMemebersWithAura = this.formationMemebersWithAura.filter(function(e) { return ents.indexOf(e) == -1; });
     132
    112133    // If there's nobody left, destroy the formation
    113134    if (this.members.length == 0)
    114135    {
     
    155176        cmpUnitAI.SetFormationController(INVALID_ENTITY);
    156177    }
    157178
     179    for each (var ent in this.formationMemebersWithAura)
     180    {
     181        var cmpAuras = Engine.QueryInterface(ent, IID_Auras);
     182        cmpAuras.RemoveFormationBonus(this.members);
     183    }
     184
     185
    158186    this.members = [];
    159187    this.inPosition = [];
     188    this.formationMemebersWithAura = [];
    160189
    161190    Engine.DestroyEntity(this.entity);
    162191};
  • binaries/data/mods/public/simulation/components/GarrisonHolder.js

     
    185185    if (cmpProductionQueue)
    186186        cmpProductionQueue.PauseProduction();
    187187
     188    var cmpAura = Engine.QueryInterface(entity, IID_Auras);
     189    if (cmpAura && cmpAura.HasGarrisonAura())
     190    {
     191        cmpAura.ApplyGarrisonBonus(this.entity);   
     192    }
     193
    188194    Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {});
    189195    return true;
    190196};
     
    228234    var cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue);
    229235    if (cmpProductionQueue)
    230236        cmpProductionQueue.UnpauseProduction();
     237
     238    var cmpAura = Engine.QueryInterface(entity, IID_Auras);
     239    if (cmpAura && cmpAura.HasGarrisonAura())
     240    {
     241        cmpAura.RemoveGarrisonBonus(this.entity);   
     242    }
     243
    231244   
    232245    var cmpNewPosition = Engine.QueryInterface(entity, IID_Position);
    233246    cmpNewPosition.JumpTo(pos.x, pos.z);
  • binaries/data/mods/public/simulation/components/TechnologyTemplateManager.js

     
    99TechnologyTemplateManager.prototype.Init = function()
    1010{
    1111    this.allTechs = {};
     12    this.allAuras = {};
    1213    var techNames = this.ListAllTechs();
    1314    for (var i in techNames)
    1415        this.GetTemplate(techNames[i]);
     
    2627    return this.allTechs[template];
    2728};
    2829
     30TechnologyTemplateManager.prototype.GetAuraTemplate = function(template)
     31{
     32    if (!this.allAuras[template])
     33    {
     34        this.allAuras[template] = Engine.ReadJSONFile("auras/" + template + ".json");
     35        if (! this.allAuras[template])
     36            error("Failed to load aura \"" + template + "\"");
     37    }
     38   
     39    return this.allAuras[template];
     40};
     41
    2942TechnologyTemplateManager.prototype.ListAllTechs = function()
    3043{
    3144    return Engine.FindJSONFiles("technologies", true);
  • binaries/data/mods/public/simulation/components/interfaces/AuraManager.js

     
     1Engine.RegisterInterface("AuraManager");
  • binaries/data/mods/public/simulation/components/tests/test_UnitAI.js

     
    22Engine.LoadHelperScript("Entity.js");
    33Engine.LoadHelperScript("Player.js");
    44Engine.LoadComponentScript("interfaces/Attack.js");
     5Engine.LoadComponentScript("interfaces/Auras.js");
    56Engine.LoadComponentScript("interfaces/DamageReceiver.js");
    67Engine.LoadComponentScript("interfaces/Formation.js");
    78Engine.LoadComponentScript("interfaces/Heal.js");
  • binaries/data/mods/public/simulation/helpers/Setup.js

     
    4141    {
    4242        cmpEndGameManager.SetGameType(settings.GameType);
    4343    }
    44     cmpEndGameManager.Start();
    4544}
    4645
    4746Engine.RegisterGlobal("LoadMapSettings", LoadMapSettings);
  • binaries/data/mods/public/simulation/helpers/Technology.js

     
    33function ApplyTechModificationsToEntity(tech_type, current_value, entity)
    44{
    55    var cmpTechMan = QueryOwnerInterface(entity, IID_TechnologyManager);
     6    if (cmpTechMan)
     7        var value = cmpTechMan.ApplyModificationsTemplate(tech_type, current_value, entity);
     8    else
     9        var value = current_value;
    610
    7     if (!cmpTechMan)
    8         return current_value;
    9 
    10     return cmpTechMan.ApplyModifications(tech_type, current_value, entity);
     11    var cmpAuraManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_AuraManager);
     12    if (!cmpAuraManager)
     13        return value;
     14    return cmpAuraManager.ApplyModifications(tech_type, value, entity);
    1115}
    1216
    1317function ApplyTechModificationsToPlayer(tech_type, current_value, player_entity)
     
    2327function ApplyTechModificationsToTemplate(tech_type, current_value, playerID, template)
    2428{
    2529    var cmpTechMan = QueryPlayerIDInterface(playerID, IID_TechnologyManager);
     30    if (cmpTechMan)
     31        var value = cmpTechMan.ApplyModificationsTemplate(tech_type, current_value, template);
     32    else
     33        var value = current_value;
    2634
    27     if (!cmpTechMan)
    28         return current_value;
    29 
    30     return cmpTechMan.ApplyModificationsTemplate(tech_type, current_value, template);
     35    var cmpAuraManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_AuraManager);
     36    if (!cmpAuraManager)
     37        return value;
     38    return cmpAuraManager.ApplyTemplateModifications(tech_type, value, playerID, template);
    3139}
    3240
    3341Engine.RegisterGlobal("ApplyTechModificationsToEntity", ApplyTechModificationsToEntity);
  • source/simulation2/Simulation2.cpp

     
    125125                LOGERROR(L"Can't find component type " L##name); \
    126126            componentManager.AddComponent(systemEntity, cid, noParam)
    127127
     128            LOAD_SCRIPTED_COMPONENT("AuraManager");
    128129            LOAD_SCRIPTED_COMPONENT("AIInterface");
    129130            LOAD_SCRIPTED_COMPONENT("Barter");
    130131            LOAD_SCRIPTED_COMPONENT("EndGameManager");