LCOV - code coverage report
Current view: top level - simulation/components - VisionSharing.js (source / functions) Hit Total Coverage
Test: lcov.info Lines: 80 91 87.9 %
Date: 2023-04-02 12:52:40 Functions: 8 10 80.0 %

          Line data    Source code
       1             : function VisionSharing() {}
       2             : 
       3           1 : VisionSharing.prototype.Schema =
       4             :         "<element name='Bribable'>" +
       5             :                 "<data type='boolean'/>" +
       6             :         "</element>" +
       7             :         "<optional>" +
       8             :                 "<element name='Duration' a:help='Duration (in second) of the vision sharing for spies'>" +
       9             :                         "<ref name='positiveDecimal'/>" +
      10             :                 "</element>" +
      11             :         "</optional>" +
      12             :         "<optional>" +
      13             :                 "<element name='FailureCostRatio' a:help='Fraction of the bribe cost that will be incured if a bribe failed'>" +
      14             :                         "<ref name='nonNegativeDecimal'/>" +
      15             :                 "</element>" +
      16             :         "</optional>";
      17             : 
      18           1 : VisionSharing.prototype.Init = function()
      19             : {
      20           1 :         this.activated = false;
      21           1 :         this.shared = undefined;
      22           1 :         this.spyId = 0;
      23           1 :         this.spies = undefined;
      24             : };
      25             : 
      26             : /**
      27             :  * As entities have not necessarily the VisionSharing component, it has to be activated
      28             :  * before use so that the rangeManager can register it
      29             :  */
      30           1 : VisionSharing.prototype.Activate = function()
      31             : {
      32           6 :         if (this.activated)
      33           5 :                 return;
      34           1 :         let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
      35           1 :         if (!cmpOwnership || cmpOwnership.GetOwner() <= 0)
      36           0 :                 return;
      37           1 :         this.shared = new Set([cmpOwnership.GetOwner()]);
      38           1 :         Engine.PostMessage(this.entity, MT_VisionSharingChanged,
      39             :                 { "entity": this.entity, "player": cmpOwnership.GetOwner(), "add": true });
      40           1 :         this.activated = true;
      41             : };
      42             : 
      43           1 : VisionSharing.prototype.CheckVisionSharings = function()
      44             : {
      45           6 :         let shared = new Set();
      46             : 
      47           6 :         let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
      48           6 :         let owner = cmpOwnership ? cmpOwnership.GetOwner() : INVALID_PLAYER;
      49           6 :         if (owner >= 0)
      50             :         {
      51             :                 // The owner has vision
      52           6 :                 if (owner > 0)
      53           6 :                         shared.add(owner);
      54             : 
      55             :                 // Vision sharing due to garrisoned units
      56           6 :                 let cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder);
      57           6 :                 if (cmpGarrisonHolder)
      58             :                 {
      59           6 :                         for (let ent of cmpGarrisonHolder.GetEntities())
      60             :                         {
      61           5 :                                 let cmpEntOwnership = Engine.QueryInterface(ent, IID_Ownership);
      62           5 :                                 if (!cmpEntOwnership)
      63           0 :                                         continue;
      64           5 :                                 let entOwner = cmpEntOwnership.GetOwner();
      65           5 :                                 if (entOwner > 0 && entOwner != owner)
      66             :                                 {
      67           3 :                                         shared.add(entOwner);
      68             :                                         // if shared by another player than the owner and not yet activated, do it
      69           3 :                                         this.Activate();
      70             :                                 }
      71             :                         }
      72             :                 }
      73             : 
      74             :                 // vision sharing due to spies
      75           6 :                 if (this.spies)
      76           3 :                         for (let spy of this.spies.values())
      77           7 :                                 if (spy > 0 && spy != owner)
      78           7 :                                         shared.add(spy);
      79             :         }
      80             : 
      81           6 :         if (!this.activated)
      82           0 :                 return;
      83             : 
      84             :         // compare with previous vision sharing, and update if needed
      85           6 :         for (let player of shared)
      86          16 :                 if (!this.shared.has(player))
      87           3 :                         Engine.PostMessage(this.entity, MT_VisionSharingChanged,
      88             :                                 { "entity": this.entity, "player": player, "add": true });
      89           6 :         for (let player of this.shared)
      90          15 :                 if (!shared.has(player))
      91           2 :                         Engine.PostMessage(this.entity, MT_VisionSharingChanged,
      92             :                                 { "entity": this.entity, "player": player, "add": false });
      93           6 :         this.shared = shared;
      94             : };
      95             : 
      96           1 : VisionSharing.prototype.IsBribable = function()
      97             : {
      98           4 :         return this.template.Bribable == "true";
      99             : };
     100             : 
     101           1 : VisionSharing.prototype.OnGarrisonedUnitsChanged = function(msg)
     102             : {
     103           0 :         this.CheckVisionSharings();
     104             : };
     105             : 
     106           1 : VisionSharing.prototype.OnOwnershipChanged = function(msg)
     107             : {
     108           0 :         if (this.activated)
     109           0 :                 this.CheckVisionSharings();
     110             : };
     111             : 
     112           1 : VisionSharing.prototype.AddSpy = function(player, timeLength)
     113             : {
     114           3 :         if (!this.IsBribable())
     115           0 :                 return 0;
     116             : 
     117           3 :         let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
     118           3 :         if (!cmpOwnership || cmpOwnership.GetOwner() == player || player <= 0)
     119           0 :                 return 0;
     120             : 
     121           3 :         let cmpTechnologyManager = QueryPlayerIDInterface(player, IID_TechnologyManager);
     122           3 :         if (!cmpTechnologyManager || !cmpTechnologyManager.CanProduce("special/spy"))
     123           0 :                 return 0;
     124             : 
     125           3 :         let template = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager).GetTemplate("special/spy");
     126           3 :         if (!IncurBribeCost(template, player, cmpOwnership.GetOwner(), false))
     127           1 :                 return 0;
     128             : 
     129             :         // If no duration given, take it from the spy template and scale it with the ent vision
     130             :         // When no duration argument nor in spy template, it is a permanent spy
     131           2 :         let duration = timeLength;
     132           2 :         if (!duration && template.VisionSharing && template.VisionSharing.Duration)
     133             :         {
     134           1 :                 duration = ApplyValueModificationsToTemplate("VisionSharing/Duration", +template.VisionSharing.Duration, player, template);
     135           1 :                 let cmpVision = Engine.QueryInterface(this.entity, IID_Vision);
     136           1 :                 if (cmpVision)
     137           1 :                         duration *= 60 / Math.max(30, cmpVision.GetRange());
     138             :         }
     139             : 
     140           2 :         if (!this.spies)
     141           0 :                 this.spies = new Map();
     142             : 
     143           2 :         this.spies.set(++this.spyId, player);
     144           2 :         if (duration)
     145             :         {
     146           2 :                 let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     147           2 :                 cmpTimer.SetTimeout(this.entity, IID_VisionSharing, "RemoveSpy", duration * 1000, { "id": this.spyId });
     148             :         }
     149           2 :         this.Activate();
     150           2 :         this.CheckVisionSharings();
     151             : 
     152             :         // update statistics for successful bribes
     153           2 :         let cmpBribesStatisticsTracker = QueryPlayerIDInterface(player, IID_StatisticsTracker);
     154           2 :         if (cmpBribesStatisticsTracker)
     155           0 :                 cmpBribesStatisticsTracker.IncreaseSuccessfulBribesCounter();
     156             : 
     157           2 :         return this.spyId;
     158             : };
     159             : 
     160           1 : VisionSharing.prototype.RemoveSpy = function(data)
     161             : {
     162           1 :         this.spies.delete(data.id);
     163           1 :         this.CheckVisionSharings();
     164             : };
     165             : 
     166             : /**
     167             :  * Returns true if this entity share its vision with player
     168             :  */
     169           1 : VisionSharing.prototype.ShareVisionWith = function(player)
     170             : {
     171           6 :         if (this.activated)
     172           4 :                 return this.shared.has(player);
     173             : 
     174           2 :         let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
     175           2 :         return cmpOwnership && cmpOwnership.GetOwner() == player;
     176             : };
     177             : 
     178           1 : Engine.RegisterComponentType(IID_VisionSharing, "VisionSharing", VisionSharing);

Generated by: LCOV version 1.14