LCOV - code coverage report
Current view: top level - simulation/components - Resistance.js (source / functions) Hit Total Coverage
Test: lcov.info Lines: 47 71 66.2 %
Date: 2023-04-02 12:52:40 Functions: 7 17 41.2 %

          Line data    Source code
       1             : function Resistance() {}
       2             : 
       3             : /**
       4             :  * Builds a RelaxRNG schema of possible attack effects.
       5             :  *
       6             :  * @return {string} - RelaxNG schema string.
       7             :  */
       8           1 : Resistance.prototype.BuildResistanceSchema = function()
       9             : {
      10           2 :         return "" +
      11             :                 "<oneOrMore>" +
      12             :                         "<choice>" +
      13             :                                 "<element name='Damage'>" +
      14             :                                         "<oneOrMore>" +
      15             :                                                 "<element a:help='Resistance against any number of damage types affecting health.'>" +
      16             :                                                         "<anyName/>" +
      17             :                                                         "<ref name='nonNegativeDecimal'/>" +
      18             :                                                 "</element>" +
      19             :                                         "</oneOrMore>" +
      20             :                                 "</element>" +
      21             :                                 "<element name='Capture' a:help='Resistance against Capture attacks.'>" +
      22             :                                         "<ref name='nonNegativeDecimal'/>" +
      23             :                                 "</element>" +
      24             :                                 "<element name='ApplyStatus' a:help='Resistance against StatusEffects.'>" +
      25             :                                         "<oneOrMore>" +
      26             :                                                 "<element a:help='Resistance against any number of status effects.'>" +
      27             :                                                         "<anyName/>" +
      28             :                                                         "<interleave>" +
      29             :                                                                 "<optional>" +
      30             :                                                                         "<element name='Duration' a:help='The reduction in duration of the status. The normal duration time is multiplied by this factor.'>" +
      31             :                                                                                 "<ref name='nonNegativeDecimal'/>" +
      32             :                                                                         "</element>" +
      33             :                                                                 "</optional>" +
      34             :                                                                 "<optional>" +
      35             :                                                                         "<element name='BlockChance' a:help='The chance of blocking the status. In the interval [0,1].'><ref name='nonNegativeDecimal'/></element>" +
      36             :                                                                 "</optional>" +
      37             :                                                         "</interleave>" +
      38             :                                                 "</element>" +
      39             :                                         "</oneOrMore>" +
      40             :                                 "</element>" +
      41             :                         "</choice>" +
      42             :                 "</oneOrMore>";
      43             : };
      44             : 
      45           1 : Resistance.prototype.Schema =
      46             :         "<a:help>Controls the damage resistance of the unit.</a:help>" +
      47             :         "<a:example>" +
      48             :                 "<Foundation>" +
      49             :                         "<Damage>" +
      50             :                                 "<Hack>10.0</Hack>" +
      51             :                                 "<Pierce>0.0</Pierce>" +
      52             :                                 "<Crush>5.0</Crush>" +
      53             :                         "</Damage>" +
      54             :                         "<Capture>10</Capture>" +
      55             :                 "</Foundation>" +
      56             :                 "<Entity>" +
      57             :                         "<Damage>" +
      58             :                                 "<Poison>5</Poison>" +
      59             :                         "</Damage>" +
      60             :                 "</Entity>" +
      61             :         "</a:example>" +
      62             :         "<zeroOrMore>" +
      63             :                 "<choice>" +
      64             :                         "<element name='Foundation' a:help='Resistance of an unfinished structure (i.e. a foundation).'>" +
      65             :                                 Resistance.prototype.BuildResistanceSchema() +
      66             :                         "</element>" +
      67             :                         "<element name='Entity' a:help='Resistance of an entity.'>" +
      68             :                                 Resistance.prototype.BuildResistanceSchema() +
      69             :                         "</element>" +
      70             :                 "</choice>" +
      71             :         "</zeroOrMore>";
      72             : 
      73           1 : Resistance.prototype.Init = function()
      74             : {
      75           9 :         this.invulnerable = false;
      76           9 :         this.attackers = new Set();
      77             : };
      78             : 
      79           1 : Resistance.prototype.IsInvulnerable = function()
      80             : {
      81          12 :         return this.invulnerable;
      82             : };
      83             : 
      84             : /**
      85             :  * @param {number} attacker - The entity ID of the attacker to add.
      86             :  * @return {boolean} - Whether the attacker was added sucessfully.
      87             :  */
      88           1 : Resistance.prototype.AddAttacker = function(attacker)
      89             : {
      90           0 :         if (this.attackers.has(attacker))
      91           0 :                 return false;
      92             : 
      93           0 :         this.attackers.add(attacker);
      94           0 :         return true;
      95             : };
      96             : 
      97             : /**
      98             :  * @param {number} attacker - The entity ID of the attacker to remove.
      99             :  * @return {boolean} - Whether the attacker was attacking us previously.
     100             :  */
     101           1 : Resistance.prototype.RemoveAttacker = function(attacker)
     102             : {
     103           0 :         return this.attackers.delete(attacker);
     104             : };
     105             : 
     106           1 : Resistance.prototype.SetInvulnerability = function(invulnerability)
     107             : {
     108           1 :         this.invulnerable = invulnerability;
     109           1 :         Engine.PostMessage(this.entity, MT_InvulnerabilityChanged, { "entity": this.entity, "invulnerability": invulnerability });
     110             : };
     111             : 
     112             : /**
     113             :  * Calculate the effective resistance of an entity to a particular effect.
     114             :  * ToDo: Support resistance against status effects.
     115             :  * @param {string} effectType - The type of attack effect the resistance has to be calculated for (e.g. "Damage", "Capture").
     116             :  * @return {Object} - An object of the type { "Damage": { "Crush": number, "Hack": number }, "Capture": number }.
     117             :  */
     118           1 : Resistance.prototype.GetEffectiveResistanceAgainst = function(effectType)
     119             : {
     120          10 :         let ret = {};
     121             : 
     122          10 :         let template = this.GetResistanceOfForm(Engine.QueryInterface(this.entity, IID_Foundation) ? "Foundation" : "Entity");
     123          10 :         if (template[effectType])
     124           7 :                 ret[effectType] = template[effectType];
     125             : 
     126          10 :         return ret;
     127             : };
     128             : 
     129             : /**
     130             :  * Get all separate resistances for showing in the GUI.
     131             :  * @return {Object} - All resistances ordered by type.
     132             :  */
     133           1 : Resistance.prototype.GetFullResistance = function()
     134             : {
     135           0 :         let ret = {};
     136           0 :         for (let entityForm in this.template)
     137           0 :                 ret[entityForm] = this.GetResistanceOfForm(entityForm);
     138             : 
     139           0 :         return ret;
     140             : };
     141             : 
     142             : /**
     143             :  * Get the resistance of a particular type, i.e. Foundation or Entity.
     144             :  * @param {string} entityForm - The form of the entity to query.
     145             :  * @return {Object} - An object containing the resistances.
     146             :  */
     147           1 : Resistance.prototype.GetResistanceOfForm = function(entityForm)
     148             : {
     149          10 :         let ret = {};
     150          10 :         let template = this.template && this.template[entityForm];
     151          10 :         if (!template)
     152           2 :                 return ret;
     153             : 
     154           8 :         if (template.Damage)
     155             :         {
     156           2 :                 ret.Damage = {};
     157           2 :                 for (let damageType in template.Damage)
     158           2 :                         ret.Damage[damageType] = ApplyValueModificationsToEntity("Resistance/" + entityForm + "/Damage/" + damageType, +this.template[entityForm].Damage[damageType], this.entity);
     159             :         }
     160             : 
     161           8 :         if (template.Capture)
     162           3 :                 ret.Capture = ApplyValueModificationsToEntity("Resistance/" + entityForm + "/Capture", +this.template[entityForm].Capture, this.entity);
     163             : 
     164           8 :         if (template.ApplyStatus)
     165             :         {
     166           3 :                 ret.ApplyStatus = {};
     167           3 :                 for (let effect in template.ApplyStatus)
     168           4 :                         ret.ApplyStatus[effect] = {
     169             :                                 "duration": ApplyValueModificationsToEntity("Resistance/" + entityForm + "/ApplyStatus/" + effect + "/Duration", +(template.ApplyStatus[effect].Duration || 1), this.entity),
     170             :                                 "blockChance": ApplyValueModificationsToEntity("Resistance/" + entityForm + "/ApplyStatus/" + effect + "/BlockChance", +(template.ApplyStatus[effect].BlockChance || 0), this.entity)
     171             :                         };
     172             :         }
     173             : 
     174           8 :         return ret;
     175             : };
     176             : 
     177           1 : Resistance.prototype.OnOwnershipChanged = function(msg)
     178             : {
     179           0 :         if (msg.to === INVALID_PLAYER)
     180           0 :                 for (let attacker of this.attackers)
     181           0 :                         Engine.QueryInterface(attacker, IID_Attack)?.StopAttacking("TargetInvalidated");
     182             : };
     183             : 
     184             : 
     185             : function ResistanceMirage() {}
     186           1 : ResistanceMirage.prototype.Init = function(cmpResistance)
     187             : {
     188           0 :         this.invulnerable = cmpResistance.invulnerable;
     189           0 :         this.isFoundation = !!Engine.QueryInterface(cmpResistance.entity, IID_Foundation);
     190           0 :         this.resistanceOfForm = {};
     191           0 :         for (const entityForm in cmpResistance.template)
     192           0 :                 this.resistanceOfForm[entityForm] = cmpResistance.GetResistanceOfForm(entityForm);
     193           0 :         this.attackers = new Set();
     194             : };
     195             : 
     196           1 : ResistanceMirage.prototype.IsInvulnerable = Resistance.prototype.IsInvulnerable;
     197           1 : ResistanceMirage.prototype.AddAttacker = Resistance.prototype.AddAttacker;
     198           1 : ResistanceMirage.prototype.RemoveAttacker = Resistance.prototype.RemoveAttacker;
     199             : 
     200           1 : ResistanceMirage.prototype.GetEffectiveResistanceAgainst = function(entityForm)
     201             : {
     202           0 :         return this.GetResistanceOfForm(this.isFoundation ? "Foundation" : "Entity");
     203             : };
     204             : 
     205           1 : ResistanceMirage.prototype.GetResistanceOfForm = function(entityForm)
     206             : {
     207           0 :         return this.resistanceOfForm[entityForm] || {};
     208             : };
     209             : 
     210           1 : ResistanceMirage.prototype.GetFullResistance = function()
     211             : {
     212           0 :         return this.resistanceOfForm;
     213             : };
     214             : 
     215           1 : Engine.RegisterGlobal("ResistanceMirage", ResistanceMirage);
     216             : 
     217           1 : Resistance.prototype.Mirage = function()
     218             : {
     219           0 :         const mirage = new ResistanceMirage();
     220           0 :         mirage.Init(this);
     221           0 :         return mirage;
     222             : };
     223             : 
     224           1 : Engine.RegisterComponentType(IID_Resistance, "Resistance", Resistance);

Generated by: LCOV version 1.14