LCOV - code coverage report
Current view: top level - simulation/components - Barter.js (source / functions) Hit Total Coverage
Test: lcov.info Lines: 57 67 85.1 %
Date: 2023-04-02 12:52:40 Functions: 5 5 100.0 %

          Line data    Source code
       1             : function Barter() {}
       2             : 
       3           1 : Barter.prototype.Schema =
       4             :         "<a:component type='system'/><empty/>";
       5             : 
       6             : /**
       7             :  * The "true price" is a base price of 100 units of resource (for the case of some resources being of more worth than others).
       8             :  * With current bartering system only relative values makes sense so if for example stone is two times more expensive than wood,
       9             :  * there will 2:1 exchange rate.
      10             :  *
      11             :  * Constant part of price percentage difference between true price and buy/sell price.
      12             :  * Buy price equal to true price plus constant difference.
      13             :  * Sell price equal to true price minus constant difference.
      14             :  */
      15           1 : Barter.prototype.CONSTANT_DIFFERENCE = 10;
      16             : /**
      17             :  * Additional difference of prices in percents, added after each deal to specified resource price.
      18             :  */
      19           1 : Barter.prototype.DIFFERENCE_PER_DEAL = 2;
      20             : /**
      21             :  * Price difference percentage which restored each restore timer tick
      22             :  */
      23           1 : Barter.prototype.DIFFERENCE_RESTORE = 0.5;
      24             : /**
      25             :  * Interval of timer which slowly restore prices after deals
      26             :  */
      27           1 : Barter.prototype.RESTORE_TIMER_INTERVAL = 5000;
      28             : 
      29           1 : Barter.prototype.Init = function()
      30             : {
      31           1 :         this.priceDifferences = {};
      32           1 :         for (let resource of Resources.GetBarterableCodes())
      33           3 :                 this.priceDifferences[resource] = 0;
      34           1 :         this.restoreTimer = undefined;
      35             : };
      36             : 
      37           1 : Barter.prototype.GetPrices = function(cmpPlayer)
      38             : {
      39           8 :         let prices = { "buy": {}, "sell": {} };
      40           8 :         let multiplier = cmpPlayer.GetBarterMultiplier();
      41           8 :         for (let resource of Resources.GetBarterableCodes())
      42             :         {
      43          24 :                 let truePrice = Resources.GetResource(resource).truePrice;
      44          24 :                 prices.buy[resource] = truePrice * (100 + this.CONSTANT_DIFFERENCE + this.priceDifferences[resource]) * multiplier.buy[resource] / 100;
      45          24 :                 prices.sell[resource] = truePrice * (100 - this.CONSTANT_DIFFERENCE + this.priceDifferences[resource]) * multiplier.sell[resource] / 100;
      46             :         }
      47           8 :         return prices;
      48             : };
      49             : 
      50           1 : Barter.prototype.ExchangeResources = function(playerID, resourceToSell, resourceToBuy, amount)
      51             : {
      52           6 :         if (amount <= 0)
      53             :         {
      54           0 :                 warn("ExchangeResources: incorrect amount: " + uneval(amount));
      55           0 :                 return;
      56             :         }
      57             : 
      58           6 :         let availResources = Resources.GetBarterableCodes();
      59           6 :         if (availResources.indexOf(resourceToSell) == -1)
      60             :         {
      61           0 :                 warn("ExchangeResources: incorrect resource to sell: " + uneval(resourceToSell));
      62           0 :                 return;
      63             :         }
      64             : 
      65           6 :         if (availResources.indexOf(resourceToBuy) == -1)
      66             :         {
      67           0 :                 warn("ExchangeResources: incorrect resource to buy: " + uneval(resourceToBuy));
      68           0 :                 return;
      69             :         }
      70             : 
      71           6 :         if (amount != 100 && amount != 500)
      72           2 :                 return;
      73             : 
      74           4 :         let cmpPlayer = QueryPlayerIDInterface(playerID);
      75           4 :         if (!cmpPlayer || !cmpPlayer.CanBarter())
      76           0 :                 return;
      77             : 
      78           4 :         let prices = this.GetPrices(cmpPlayer);
      79           4 :         let amountsToSubtract = {};
      80           4 :         amountsToSubtract[resourceToSell] = amount;
      81           4 :         if (cmpPlayer.TrySubtractResources(amountsToSubtract))
      82             :         {
      83           3 :                 let amountToAdd = Math.round(prices.sell[resourceToSell] / prices.buy[resourceToBuy] * amount);
      84           3 :                 cmpPlayer.AddResource(resourceToBuy, amountToAdd);
      85             : 
      86             :                 // Display chat message to observers.
      87           3 :                 let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
      88           3 :                 if (cmpGUIInterface)
      89           0 :                         cmpGUIInterface.PushNotification({
      90             :                                 "type": "barter",
      91             :                                 "players": [playerID],
      92             :                                 "amountGiven": amount,
      93             :                                 "amountGained": amountToAdd,
      94             :                                 "resourceGiven": resourceToSell,
      95             :                                 "resourceGained": resourceToBuy
      96             :                         });
      97             : 
      98           3 :                 let cmpStatisticsTracker = QueryPlayerIDInterface(playerID, IID_StatisticsTracker);
      99           3 :                 if (cmpStatisticsTracker)
     100             :                 {
     101           0 :                         cmpStatisticsTracker.IncreaseResourcesSoldCounter(resourceToSell, amount);
     102           0 :                         cmpStatisticsTracker.IncreaseResourcesBoughtCounter(resourceToBuy, amountToAdd);
     103             :                 }
     104             : 
     105           3 :                 let difference = this.DIFFERENCE_PER_DEAL * amount / 100;
     106             :                 // Increase price difference for both exchange resources.
     107             :                 // Overall price difference (dynamic +/- constant) can't exceed +-99%.
     108           3 :                 this.priceDifferences[resourceToSell] -= difference;
     109           3 :                 this.priceDifferences[resourceToSell] = Math.min(99 - this.CONSTANT_DIFFERENCE, Math.max(this.CONSTANT_DIFFERENCE - 99, this.priceDifferences[resourceToSell]));
     110           3 :                 this.priceDifferences[resourceToBuy] += difference;
     111           3 :                 this.priceDifferences[resourceToBuy] = Math.min(99 - this.CONSTANT_DIFFERENCE, Math.max(this.CONSTANT_DIFFERENCE - 99, this.priceDifferences[resourceToBuy]));
     112             :         }
     113             : 
     114           4 :         if (this.restoreTimer === undefined)
     115           2 :                 this.restoreTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).SetInterval(this.entity, IID_Barter, "ProgressTimeout", this.RESTORE_TIMER_INTERVAL, this.RESTORE_TIMER_INTERVAL, {});
     116             : };
     117             : 
     118           1 : Barter.prototype.ProgressTimeout = function(data)
     119             : {
     120           2 :         let needRestore = false;
     121           2 :         for (let resource of Resources.GetBarterableCodes())
     122             :         {
     123             :                 // Calculate value to restore, it should be limited to [-DIFFERENCE_RESTORE; DIFFERENCE_RESTORE] interval
     124           6 :                 let differenceRestore = Math.min(this.DIFFERENCE_RESTORE, Math.max(-this.DIFFERENCE_RESTORE, this.priceDifferences[resource]));
     125           6 :                 differenceRestore = -differenceRestore;
     126           6 :                 this.priceDifferences[resource] += differenceRestore;
     127             :                 // If price difference still exists then set flag to run timer again
     128           6 :                 if (this.priceDifferences[resource] != 0)
     129           1 :                         needRestore = true;
     130             :         }
     131             : 
     132           2 :         if (!needRestore)
     133             :         {
     134           1 :                 let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     135           1 :                 cmpTimer.CancelTimer(this.restoreTimer);
     136           1 :                 this.restoreTimer = undefined;
     137             :         }
     138             : };
     139             : 
     140           1 : Engine.RegisterSystemComponentType(IID_Barter, "Barter", Barter);

Generated by: LCOV version 1.14