LCOV - code coverage report
Current view: top level - simulation/components - BattleDetection.js (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 71 0.0 %
Date: 2023-04-02 12:52:40 Functions: 0 9 0.0 %

          Line data    Source code
       1             : function BattleDetection() {}
       2             : 
       3           0 : BattleDetection.prototype.Schema =
       4             :         "<a:help>Detects the occurence of battles.</a:help>" +
       5             :         "<a:example/>" +
       6             :         "<element name='TimerInterval' a:help='Duration of one timer period. Interval over which damage should be recorded in milliseconds'>" +
       7             :                 "<data type='positiveInteger'/>" +
       8             :         "</element>" +
       9             :         "<element name='RecordLength' a:help='Record length. Number of timer cycles over which damage rate should be calculated'>" +
      10             :                 "<data type='positiveInteger'/>" +
      11             :         "</element>" +
      12             :         "<element name='DamageRateThreshold' a:help='Damage rate at which alertness is increased'>" +
      13             :                 "<ref name='positiveDecimal'/>" +
      14             :         "</element>" +
      15             :         "<element name='AlertnessBattleThreshold' a:help='Alertness at which the player is considered in battle'>" +
      16             :                 "<ref name='positiveDecimal'/>" +
      17             :         "</element>" +
      18             :         "<element name='AlertnessPeaceThreshold' a:help='Alertness at which the player is considered at peace'>" +
      19             :                 "<ref name='nonNegativeDecimal'/>" +
      20             :         "</element>" +
      21             :         "<element name='AlertnessMax' a:help='Maximum alertness level'>" +
      22             :                 "<ref name='positiveDecimal'/>" +
      23             :         "</element>";
      24             : 
      25           0 : BattleDetection.prototype.Init = function()
      26             : {
      27             :         // Load values from template.
      28           0 :         this.interval = +this.template.TimerInterval;
      29           0 :         this.recordLength = +this.template.RecordLength;
      30           0 :         this.damageRateThreshold = +this.template.DamageRateThreshold;
      31           0 :         this.alertnessBattleThreshold = +this.template.AlertnessBattleThreshold;
      32           0 :         this.alertnessPeaceThreshold = +this.template.AlertnessPeaceThreshold;
      33           0 :         this.alertnessMax = +this.template.AlertnessMax;
      34             : 
      35             :         // Initialize variables.
      36           0 :         this.damage = 0; // Damage counter. Accumulative damage done over the current timer period.
      37           0 :         this.damageRecord = []; // Damage record. Array of elements representing total damage done in a given timer cycle.
      38           0 :         this.alertness = 0; // Alertness level. Incremented if damage rate exceeds 'damageRateThreshold' over a given timer period and decremented if it does not.
      39           0 :         this.state = "PEACE";
      40             : };
      41             : 
      42           0 : BattleDetection.prototype.SetState = function(state)
      43             : {
      44           0 :         if (state == this.state)
      45           0 :                 return;
      46             : 
      47           0 :         this.state = state;
      48           0 :         var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);
      49           0 :         Engine.PostMessage(this.entity, MT_BattleStateChanged, { "player": cmpPlayer.GetPlayerID(), "to": this.state });
      50             : };
      51             : 
      52           0 : BattleDetection.prototype.GetState = function()
      53             : {
      54           0 :         return this.state;
      55             : };
      56             : 
      57           0 : BattleDetection.prototype.TimerHandler = function(data, lateness)
      58             : {
      59             :         // Reset the timer
      60           0 :         if (data.timerRepeat === undefined)
      61             :         {
      62           0 :                 this.timer = undefined;
      63             :         }
      64             : 
      65           0 :         this.damageRecord.unshift(this.damage);
      66           0 :         if (this.damageRecord.length > this.recordLength)
      67           0 :                 this.damageRecord.splice(this.recordLength, this.damageRecord.length-1); // Discard any elements beyond 'recordLength'.
      68           0 :         this.damage = 0; // Reset damage counter for the next timer period.
      69             : 
      70             :         // Always update alertness if not already alert, or once per 'recordLength' otherwise.
      71           0 :         if (!this.alertness || this.recordControl++ == this.recordLength-1)
      72             :         {
      73           0 :                 var recordDamage = this.damageRecord.reduce(function(a, b) {return a + b;}, 0); // Sum up all values in the damage record.
      74           0 :                 var damageRate = recordDamage / (this.recordLength * this.interval);
      75             : 
      76           0 :                 if (damageRate > this.damageRateThreshold)
      77           0 :                         this.alertness = Math.min(this.alertnessMax, this.alertness+1); // Increment alertness up to 'alertnessMax'.
      78             :                 else
      79           0 :                         this.alertness = Math.max(0, this.alertness-1); // Decrement alertness down to zero.
      80             : 
      81             :                 // Stop the damage rate timer if we're no longer alert.
      82           0 :                 if (!this.alertness)
      83           0 :                         this.StopTimer();
      84             : 
      85           0 :                 if (this.alertness >= this.alertnessBattleThreshold)
      86           0 :                         this.SetState("BATTLE");
      87           0 :                 else if (this.alertness <= this.alertnessPeaceThreshold)
      88           0 :                         this.SetState("PEACE");
      89             : 
      90             :         }
      91           0 :         if (this.recordControl > this.recordLength-1)
      92           0 :                 this.recordControl = 0;
      93             : };
      94             : 
      95             : /**
      96             :  * Set up the damage rate timer to run after 'offset' msecs, and then optionally
      97             :  * every 'repeat' msecs until StopTimer is called, if 'repeat' is set. A "Timer" message
      98             :  * will be sent each time the timer runs. Must not be called if a timer is already active.
      99             :  */
     100           0 : BattleDetection.prototype.StartTimer = function(offset, repeat)
     101             : {
     102           0 :         if (this.timer)
     103             :         {
     104           0 :                 this.StopTimer();
     105           0 :                 error("Called StartTimer when there's already an active timer.");
     106             :         }
     107             : 
     108           0 :         this.recordControl = 0;
     109           0 :         this.damage = 0; // Reset damage counter for the first timer period.
     110             : 
     111           0 :         var data = { "timerRepeat": repeat };
     112           0 :         var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     113           0 :         if (repeat === undefined)
     114           0 :                 this.timer = cmpTimer.SetTimeout(this.entity, IID_BattleDetection, "TimerHandler", offset, data);
     115             :         else
     116           0 :                 this.timer = cmpTimer.SetInterval(this.entity, IID_BattleDetection, "TimerHandler", offset, repeat, data);
     117             : };
     118             : 
     119             : /**
     120             :  * Stop the current damage rate timer.
     121             :  */
     122           0 : BattleDetection.prototype.StopTimer = function()
     123             : {
     124           0 :         if (!this.timer)
     125           0 :                 return;
     126             : 
     127           0 :         var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     128           0 :         cmpTimer.CancelTimer(this.timer);
     129           0 :         this.timer = undefined;
     130             : };
     131             : 
     132           0 : BattleDetection.prototype.OnGlobalAttacked = function(msg)
     133             : {
     134           0 :         var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);
     135             :         // Only register attacks dealt by myself.
     136           0 :         var cmpAttackerOwnership = Engine.QueryInterface(msg.attacker, IID_Ownership);
     137           0 :         if (!cmpAttackerOwnership || cmpAttackerOwnership.GetOwner() != cmpPlayer.GetPlayerID())
     138           0 :                 return;
     139             :         // Don't register attacks dealt against Gaia or invalid player or myself.
     140           0 :         var cmpTargetOwnership = Engine.QueryInterface(msg.target, IID_Ownership);
     141           0 :         if (!cmpTargetOwnership || cmpTargetOwnership.GetOwner() <= 0 || cmpTargetOwnership.GetOwner() == cmpPlayer.GetPlayerID())
     142           0 :                 return;
     143             : 
     144             :         // If the damage rate timer isn't already started, start it now.
     145           0 :         if (!this.timer)
     146           0 :                 this.StartTimer(0, this.interval);
     147             :         // Add damage of this attack to the damage counter.
     148           0 :         if (msg.damage)
     149           0 :                 this.damage += msg.damage;
     150             : };
     151             : 
     152           0 : Engine.RegisterComponentType(IID_BattleDetection, "BattleDetection", BattleDetection);
     153             : 

Generated by: LCOV version 1.14