Ticket #2048: auras_js.diff

File auras_js.diff, 17.5 KB (added by sanderd17, 11 years ago)
  • binaries/data/mods/public/simulation/components/Auras.js

     
    33Auras.prototype.Schema =
    44    "<oneOrMore>" +
    55        "<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>" +
     6            "<anyName/>" +
    137            "<interleave>" +
    14                 "<element name='Radius'>" +
    15                     "<data type='nonNegativeInteger'/>" +
     8                "<element name='Modification'>" +
     9                    "<interleave>" +
     10                        "<element name='Value'>" +
     11                            "<text/>" +
     12                        "</element>" +
     13                        "<optional>" +
     14                            "<element name='Add'>" +
     15                                "<data type='decimal'/>" +
     16                            "</element>" +
     17                        "</optional>" +
     18                        "<optional>" +
     19                            "<element name='Multiply'>" +
     20                                "<data type='decimal'/>" +
     21                            "</element>" +
     22                        "</optional>" +
     23                    "</interleave>" +
    1624                "</element>" +
    1725                "<optional>" +
    18                     "<element name='Bonus'>" +
    19                         "<data type='positiveInteger'/>" +
     26                    "<element name='AffectedPlayers'>" +
     27                        "<text/>" +
    2028                    "</element>" +
    2129                "</optional>" +
    22                 "<optional>" +
    23                     "<element name='Time'>" +
     30                "<element name='Classes'>" +
     31                    "<text/>" +
     32                "</element>" +
     33                "<choice>" +
     34                    "<element name='Radius'>" +
    2435                        "<data type='nonNegativeInteger'/>" +
    2536                    "</element>" +
    26                 "</optional>" +
    27                 "<optional>" +
    28                     "<element name='Speed'>" +
    29                         "<data type='positiveInteger'/>" +
     37                    "<element name='Formation'>" +
     38                        "<value/>" +
    3039                    "</element>" +
    31                 "</optional>" +
     40                    "<element name='GarrisoningStructure'>" +
     41                        "<value/>" +
     42                    "</element>" +
     43                    "<element name='Template'>" +
     44                        "<value/>" +
     45                    "</element>" +
     46                "</choice>" +
    3247            "</interleave>" +
    3348        "</element>" +
    3449    "</oneOrMore>";
    3550
    36 /*
    37  * TODO: this all needs to be designed and implemented
    38  */
    3951
    4052Auras.prototype.Serialize = null; // we have no dynamic state to save
    4153
     54Auras.prototype.Init = function()
     55{
     56    var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
     57    this.templateName = cmpTemplateManager.GetCurrentTemplateName(this.entity);
     58};
     59
     60Auras.prototype.GetAuraTypes = function()
     61{
     62    return Object.keys(this.template);
     63};
     64
     65Auras.prototype.GetRadius = function(type)
     66{
     67    if (!this.IsRangeAura(type))
     68        return undefined;
     69    if (this.IsTemplateAura(type))
     70        return -1;
     71    var radius = +this.template[type].Radius;
     72    return ApplyTechModificationsToEntity("Auras/"+type+"/Radius",radius, this.entity);
     73};
     74
     75Auras.prototype.GetClasses = function(type)
     76{
     77    var string = this.template[type].Classes || "";
     78    return string.split(/\s+/);
     79};
     80
     81Auras.prototype.GetModification = function(type)
     82{
     83    var ret = {};
     84    ret.values = this.template[type].Modification.Value.split(/\s+/);
     85    if (this.template[type].Modification.Add)
     86    {
     87        ret.add = +this.template[type].Modification.Add;
     88        ret.add = ApplyTechModificationsToEntity("Auras/"+type+"/Modification/Add", ret.add, this.entity);
     89    }
     90    if (this.template[type].Modification.Multiply)
     91    {
     92        ret.multiply = +this.template[type].Modification.Multiply;
     93        ret.multiply = ApplyTechModificationsToEntity("Auras/"+type+"/Modification/Multiply", ret.multiply, this.entity);
     94    }
     95    return ret;
     96};
     97
     98Auras.prototype.GetAffectedPlayers = function(type)
     99{
     100    if (this.template[type].AffectedPlayers)
     101        var affectedPlayers = this.template[type].AffectedPlayers.split(/\s+/);
     102    else
     103        var affectedPlayers = ["Player"];
     104
     105    var ret = [];
     106
     107    var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
     108    warn(uneval(cmpPlayer));
     109
     110    if (!cmpPlayer)
     111        return ret;
     112
     113    var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     114    var numPlayers = cmpPlayerManager.GetNumPlayers();
     115    var enemies = [];
     116    var mutualAllies = [];
     117
     118    for (var i = 0; i < numPlayers; ++i)
     119    {
     120        if (affectedPlayers.indexOf("Player") != -1 && cmpPlayer.GetPlayerID() == i)
     121            ret.push(i);
     122        else if (affectedPlayers.indexOf("Enemy") != -1 && cmpPlayer.IsEnemy(i))
     123            ret.push(i);
     124        else if (affectedPlayers.indexOf("MutualAlly") != -1 && cmpPlayer.IsMutualAlly(i))
     125            ret.push(i);
     126        else if (affectedPlayers.indexOf("Ally") != -1 && cmpPlayer.IsAlly(i))
     127            ret.push(i);
     128        else if (affectedPlayers.indexOf("Neutral") != -1 && cmpPlayer.IsNeutral(i))
     129            ret.push(i);
     130    }
     131    // return and store the value
     132    this[type].affectedPlayers = ret;
     133    return ret;
     134};
     135
     136Auras.prototype.HasFormationAura = function()
     137{
     138    var auraTypes = this.GetAuraTypes();
     139    for each (var type in auraTypes)
     140    {
     141        if (this.IsFormationAura(type))
     142            return true;
     143    }
     144    return false;
     145};
     146
     147Auras.prototype.HasGarrisonAura = function()
     148{
     149    var auraTypes = this.GetAuraTypes();
     150    for each (var type in auraTypes)
     151    {
     152        if (this.IsGarrisonAura(type))
     153            return true;
     154    }
     155    return false;
     156};
     157
     158Auras.prototype.IsFormationAura = function(type)
     159{
     160    return 'Formation' in this.template[type];
     161};
     162
     163Auras.prototype.IsGarrisonAura = function(type)
     164{
     165    return 'GarrisoningStructure' in this.template[type];
     166};
     167
     168Auras.prototype.IsRangeAura = function(type)
     169{
     170    return 'Radius' in this.template[type] || "Template" in this.template[type];
     171};
     172
     173Auras.prototype.IsTemplateAura = function(type)
     174{
     175    return "Template" in this.template[type];
     176};
     177
     178/**
     179 * clean all bonuses. Remove the old ones and re-apply the new ones
     180 */
     181Auras.prototype.Clean = function()
     182{
     183    var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
     184    var auraTypes = this.GetAuraTypes();
     185    // remove all bonuses
     186    for each (var type in auraTypes)
     187    {
     188        if (!this[type])
     189            continue;
     190
     191        if (this.IsTemplateAura(type))
     192            this.RemoveTemplateBonus(type);
     193       
     194        for each(var ent in this[type].targetUnits)
     195            this.RemoveBonus(type, ent);
     196
     197        if (this[type].rangeQuery)
     198            cmpRangeManager.DestroyActiveQuery(this[type].rangeQuery);
     199    }
     200
     201    for each (var type in auraTypes)
     202    {
     203        // initialise range query
     204        this[type] = {};
     205        this[type].targetUnits = [];
     206        var affectedPlayers = this.GetAffectedPlayers(type);
     207       
     208        if (!affectedPlayers.length)
     209            continue;
     210
     211        if (this.IsTemplateAura(type))
     212            this.ApplyTemplateBonus(type, affectedPlayers);
     213
     214        if (!this.IsRangeAura(type))
     215            continue;
     216        warn("add range query");
     217        this[type].rangeQuery = cmpRangeManager.CreateActiveQuery(
     218            this.entity,
     219            0,
     220            this.GetRadius(type),
     221            affectedPlayers,
     222            IID_Identity,
     223            cmpRangeManager.GetEntityFlagMask("normal")
     224        );
     225        cmpRangeManager.EnableActiveQuery(this[type].rangeQuery);
     226        // add self to your own query for consistency with templates
     227        this.OnRangeUpdate({"tag":this[type].rangeQuery, "added":[this.entity], "removed":[]});
     228    }
     229};
     230
     231Auras.prototype.OnRangeUpdate = function(msg)
     232{
     233    var auraTypes = this.GetAuraTypes();
     234    for each (var t in auraTypes)
     235    {
     236        if (msg.tag == this[t].rangeQuery)
     237        {
     238            var type = t;
     239            break;
     240        }
     241    }
     242
     243    if (!type)
     244        return;
     245   
     246    var targetUnits = this[type].targetUnits;
     247    var classes = this.GetClasses(type);
     248   
     249    if (msg.added.length > 0)
     250    {
     251        for each (var e in msg.added)
     252        {
     253            var cmpIdentity = Engine.QueryInterface(e, IID_Identity);
     254            var targetClasses = cmpIdentity.GetClassesList();
     255
     256            if (targetClasses.some(function(c){return classes.indexOf(c) > -1;}))
     257            {
     258                targetUnits.push(e);
     259                this.ApplyBonus(type,e);
     260            }
     261        }
     262    }
     263
     264    if (msg.removed.length > 0)
     265    {
     266        for each (var e in msg.removed)
     267        {
     268            targetUnits.splice(targetUnits.indexOf(e), 1);
     269            this.RemoveBonus(type,e);
     270        }
     271    }
     272
     273};
     274
     275Auras.prototype.ApplyFormationBonus = function(memberList)
     276{
     277    var auraTypes = this.GetAuraTypes();
     278    for each (var type in auraTypes)
     279    {
     280        if (!this.IsFormationAura(type))
     281            continue;
     282        var classes = this.GetClasses(type);
     283       
     284        for each (var ent in memberList)
     285        {
     286            var cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
     287            var targetClasses = cmpIdentity.GetClassesList();
     288            if (targetClasses.some(function(c){return classes.indexOf(c) > -1;}))
     289            {
     290                this[type].targetUnits.push(ent);
     291                this.ApplyBonus(type,ent);
     292            }
     293        }
     294    }
     295};
     296
     297Auras.prototype.ApplyGarrisonBonus = function(structure)
     298{
     299    var auraTypes = this.GetAuraTypes();
     300    for each (var type in auraTypes)
     301    {
     302        if (!this.IsGarrisonAura(type))
     303            continue;
     304        var classes = this.GetClasses(type);
     305
     306       
     307        var cmpIdentity = Engine.QueryInterface(structure, IID_Identity);
     308        var targetClasses = cmpIdentity.GetClassesList();
     309        if (targetClasses.some(function(c){return classes.indexOf(c) > -1;}))
     310        {
     311            this[type].targetUnits.push(structure);
     312            this.ApplyBonus(type,structure);
     313        }
     314    }
     315};
     316
     317Auras.prototype.ApplyTemplateBonus = function(type, players)
     318{
     319    if (!this.IsTemplateAura(type))
     320        return;
     321    var modification = this.GetModification(type);
     322    var cmpAuraManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_AuraManager);
     323    var classes = this.GetClasses(type);
     324
     325    for each (var value in modification.values)
     326        for each (var player in players)
     327            cmpAuraManager.ApplyTemplateBonus(value, player, classes, modification, this.templateName+"/"+type+"/"+value); 
     328};
     329
     330Auras.prototype.RemoveFormationBonus = function(memberList)
     331{
     332    var auraTypes = this.GetAuraTypes();
     333    for each (var type in auraTypes)
     334    {
     335        if (!this.IsFormationAura(type))
     336            continue;
     337
     338        for each (var ent in memberList)
     339        {
     340            this.RemoveBonus(type,ent);
     341            this[type].targetUnits.splice(this[type].targetUnits.indexOf(ent), 1);
     342        }
     343    }
     344};
     345
     346Auras.prototype.RemoveGarrisonBonus = function(structure)
     347{
     348    var auraTypes = this.GetAuraTypes();
     349    for each (var type in auraTypes)
     350    {
     351        if (!this.IsGarrisonAura(type))
     352            continue;
     353
     354        this.RemoveBonus(type,structure);
     355        this[type].targetUnits.splice(this[type].targetUnits.indexOf(structure), 1);
     356    }
     357};
     358
     359Auras.prototype.RemoveTemplateBonus = function(type)
     360{
     361    if (!this.IsTemplateAura(type))
     362        return;
     363
     364    var modification = this.GetModification(type);
     365    var cmpAuraManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_AuraManager);
     366    var classes = this.GetClasses(type);
     367
     368    for each (var value in modification.values)
     369        for each (var player in this[type].affectedPlayers)
     370            cmpAuraManager.RemoveTemplateBonus(value, player, classes, this.templateName+"/"+type+"/"+value);
     371};
     372
     373Auras.prototype.ApplyBonus = function(type,ent)
     374{
     375    var modification = this.GetModification(type);
     376    var cmpAuraManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_AuraManager);
     377   
     378    for each (value in modification.values)
     379        cmpAuraManager.ApplyBonus(value, ent,modification,this.templateName+"/"+type+"/"+value);   
     380
     381};
     382
     383Auras.prototype.RemoveBonus = function(type,ent)
     384{
     385    var modification = this.GetModification(type);
     386    var cmpAuraManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_AuraManager);
     387
     388    for each (value in modification.values)
     389        cmpAuraManager.RemoveBonus(value, ent, this.templateName+"/"+type+"/"+value);   
     390
     391};
     392
     393Auras.prototype.OnOwnershipChanged = function(msg)
     394{
     395    warn("ownership" +uneval(msg));
     396    this.Clean();
     397};
     398
     399Auras.prototype.OnDiplomacyChanged = function(msg)
     400{
     401    warn("diplo" +uneval(msg));
     402    var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
     403    if (cmpOwnership && cmpOwnership.GetOwner() == msg.player)
     404        this.Clean();
     405};
     406
     407Auras.prototype.OnTechnologyModification = function(msg)
     408{
     409    if (msg.component =="Auras")
     410        this.Clean();
     411};
     412
    42413Engine.RegisterComponentType(IID_Auras, "Auras", Auras);
  • 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

     
    189189    if (cmpProductionQueue)
    190190        cmpProductionQueue.PauseProduction();
    191191
     192    var cmpAura = Engine.QueryInterface(entity, IID_Auras);
     193    if (cmpAura && cmpAura.HasGarrisonAura())
     194    {
     195        cmpAura.ApplyGarrisonBonus(this.entity);   
     196    }
     197
    192198    Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {});
    193199    return true;
    194200};
     
    233239    var cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue);
    234240    if (cmpProductionQueue)
    235241        cmpProductionQueue.UnpauseProduction();
     242
     243    var cmpAura = Engine.QueryInterface(entity, IID_Auras);
     244    if (cmpAura && cmpAura.HasGarrisonAura())
     245    {
     246        cmpAura.RemoveGarrisonBonus(this.entity);   
     247    }
     248
    236249   
    237250    var cmpNewPosition = Engine.QueryInterface(entity, IID_Position);
    238251    cmpNewPosition.JumpTo(pos.x, pos.z);
  • 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/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, template);
     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

     
    122122                LOGERROR(L"Can't find component type " L##name); \
    123123            componentManager.AddComponent(SYSTEM_ENTITY, cid, noParam)
    124124
     125            LOAD_SCRIPTED_COMPONENT("AuraManager");
    125126            LOAD_SCRIPTED_COMPONENT("AIInterface");
    126127            LOAD_SCRIPTED_COMPONENT("Barter");
    127128            LOAD_SCRIPTED_COMPONENT("EndGameManager");