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

          Line data    Source code
       1           0 : const g_NaturalColor = "255 255 255 255"; // pure white
       2             : 
       3             : function StatusBars() {}
       4             : 
       5           0 : StatusBars.prototype.Schema =
       6             :         "<element name='BarWidth'>" +
       7             :                 "<data type='decimal'/>" +
       8             :         "</element>" +
       9             :         "<element name='BarHeight' a:help='Height of a normal sized bar. Some bars are scaled accordingly.'>" +
      10             :                 "<data type='decimal'/>" +
      11             :         "</element>" +
      12             :         "<element name='HeightOffset'>" +
      13             :                 "<data type='decimal'/>" +
      14             :         "</element>";
      15             : 
      16             : /**
      17             :  * For every sprite, the code will call their "Add" method when regenerating
      18             :  * the sprites. Every sprite adder should return the height it needs.
      19             :  *
      20             :  * Modders who need extra sprites can just modify this array, and
      21             :  * provide the right methods.
      22             :  */
      23           0 : StatusBars.prototype.Sprites = [
      24             :         "ExperienceBar",
      25             :         "PackBar",
      26             :         "UpgradeBar",
      27             :         "ResourceSupplyBar",
      28             :         "CaptureBar",
      29             :         "HealthBar",
      30             :         "AuraIcons",
      31             :         "RankIcon"
      32             : ];
      33             : 
      34           0 : StatusBars.prototype.Init = function()
      35             : {
      36           0 :         this.enabled = false;
      37           0 :         this.showRank = false;
      38           0 :         this.showExperience = false;
      39             : 
      40             :         // Whether the status bars used the player colors anywhere (e.g. in the capture bar)
      41           0 :         this.usedPlayerColors = false;
      42             : 
      43           0 :         this.auraSources = new Map();
      44             : };
      45             : 
      46             : /**
      47             :  * Don't serialise this.enabled since it's modified by the GUI.
      48             :  */
      49           0 : StatusBars.prototype.Serialize = function()
      50             : {
      51           0 :         return { "auraSources": this.auraSources };
      52             : };
      53             : 
      54           0 : StatusBars.prototype.Deserialize = function(data)
      55             : {
      56           0 :         this.Init();
      57           0 :         this.auraSources = data.auraSources;
      58             : };
      59             : 
      60           0 : StatusBars.prototype.SetEnabled = function(enabled, showRank, showExperience)
      61             : {
      62             :         // Quick return if no change
      63           0 :         if (enabled == this.enabled && showRank == this.showRank && showExperience == this.showExperience)
      64           0 :                 return;
      65             : 
      66           0 :         this.enabled = enabled;
      67           0 :         this.showRank = showRank;
      68           0 :         this.showExperience = showExperience;
      69             : 
      70             :         // Update the displayed sprites
      71           0 :         this.RegenerateSprites();
      72             : };
      73             : 
      74           0 : StatusBars.prototype.AddAuraSource = function(source, auraName)
      75             : {
      76           0 :         if (this.auraSources.has(source))
      77           0 :                 this.auraSources.get(source).push(auraName);
      78             :         else
      79           0 :                 this.auraSources.set(source, [auraName]);
      80           0 :         this.RegenerateSprites();
      81             : };
      82             : 
      83           0 : StatusBars.prototype.RemoveAuraSource = function(source, auraName)
      84             : {
      85           0 :         let names = this.auraSources.get(source);
      86           0 :         names.splice(names.indexOf(auraName), 1);
      87           0 :         this.RegenerateSprites();
      88             : };
      89             : 
      90           0 : StatusBars.prototype.OnHealthChanged = function(msg)
      91             : {
      92           0 :         if (this.enabled)
      93           0 :                 this.RegenerateSprites();
      94             : };
      95             : 
      96           0 : StatusBars.prototype.OnCapturePointsChanged = function(msg)
      97             : {
      98           0 :         if (this.enabled)
      99           0 :                 this.RegenerateSprites();
     100             : };
     101             : 
     102           0 : StatusBars.prototype.OnResourceSupplyChanged = function(msg)
     103             : {
     104           0 :         if (this.enabled)
     105           0 :                 this.RegenerateSprites();
     106             : };
     107             : 
     108           0 : StatusBars.prototype.OnPackProgressUpdate = function(msg)
     109             : {
     110           0 :         if (this.enabled)
     111           0 :                 this.RegenerateSprites();
     112             : };
     113             : 
     114           0 : StatusBars.prototype.OnUpgradeProgressUpdate = function(msg)
     115             : {
     116           0 :         if (this.enabled)
     117           0 :                 this.RegenerateSprites();
     118             : };
     119             : 
     120           0 : StatusBars.prototype.OnExperienceChanged = function()
     121             : {
     122           0 :         if (this.enabled)
     123           0 :                 this.RegenerateSprites();
     124             : };
     125             : 
     126           0 : StatusBars.prototype.UpdateColor = function()
     127             : {
     128           0 :         if (this.usedPlayerColors)
     129           0 :                 this.RegenerateSprites();
     130             : };
     131             : 
     132           0 : StatusBars.prototype.OnPlayerColorChanged = function(msg)
     133             : {
     134           0 :         if (this.enabled)
     135           0 :                 this.RegenerateSprites();
     136             : };
     137             : 
     138           0 : StatusBars.prototype.RegenerateSprites = function()
     139             : {
     140           0 :         let cmpOverlayRenderer = Engine.QueryInterface(this.entity, IID_OverlayRenderer);
     141           0 :         cmpOverlayRenderer.Reset();
     142             : 
     143           0 :         let yoffset = 0;
     144           0 :         for (let sprite of this.Sprites)
     145           0 :                 yoffset += this["Add" + sprite](cmpOverlayRenderer, yoffset);
     146             : };
     147             : 
     148             : // Internal helper functions
     149             : /**
     150             :  * Generic piece of code to add a bar.
     151             :  */
     152           0 : StatusBars.prototype.AddBar = function(cmpOverlayRenderer, yoffset, type, amount, heightMultiplier = 1)
     153             : {
     154             :         // Size of health bar (in world-space units)
     155           0 :         let width = +this.template.BarWidth;
     156           0 :         let height = +this.template.BarHeight * heightMultiplier;
     157             : 
     158             :         // World-space offset from the unit's position
     159           0 :         let offset = { "x": 0, "y": +this.template.HeightOffset, "z": 0 };
     160             : 
     161             :         // background
     162           0 :         cmpOverlayRenderer.AddSprite(
     163             :                 "art/textures/ui/session/icons/" + type + "_bg.png",
     164             :                 { "x": -width / 2, "y": yoffset },
     165             :                 { "x": width / 2, "y": height + yoffset },
     166             :                 offset,
     167             :                 g_NaturalColor
     168             :         );
     169             : 
     170             :         // foreground
     171           0 :         cmpOverlayRenderer.AddSprite(
     172             :                 "art/textures/ui/session/icons/" + type + "_fg.png",
     173             :                 { "x": -width / 2, "y": yoffset },
     174             :                 { "x": width * (amount - 0.5), "y": height + yoffset },
     175             :                 offset,
     176             :                 g_NaturalColor
     177             :         );
     178             : 
     179           0 :         return height * 1.2;
     180             : };
     181             : 
     182           0 : StatusBars.prototype.AddExperienceBar = function(cmpOverlayRenderer, yoffset)
     183             : {
     184           0 :         if (!this.enabled || !this.showExperience)
     185           0 :                 return 0;
     186             : 
     187           0 :         let cmpPromotion = Engine.QueryInterface(this.entity, IID_Promotion);
     188           0 :         if (!cmpPromotion || !cmpPromotion.GetCurrentXp() || !cmpPromotion.GetRequiredXp())
     189           0 :                 return 0;
     190             : 
     191           0 :         return this.AddBar(cmpOverlayRenderer, yoffset, "pack", cmpPromotion.GetCurrentXp() / cmpPromotion.GetRequiredXp(), 2/3);
     192             : };
     193             : 
     194           0 : StatusBars.prototype.AddPackBar = function(cmpOverlayRenderer, yoffset)
     195             : {
     196           0 :         if (!this.enabled)
     197           0 :                 return 0;
     198             : 
     199           0 :         let cmpPack = Engine.QueryInterface(this.entity, IID_Pack);
     200           0 :         if (!cmpPack || !cmpPack.IsPacking())
     201           0 :                 return 0;
     202             : 
     203           0 :         return this.AddBar(cmpOverlayRenderer, yoffset, "pack", cmpPack.GetProgress());
     204             : };
     205             : 
     206           0 : StatusBars.prototype.AddUpgradeBar = function(cmpOverlayRenderer, yoffset)
     207             : {
     208           0 :         if (!this.enabled)
     209           0 :                 return 0;
     210             : 
     211           0 :         let cmpUpgrade = Engine.QueryInterface(this.entity, IID_Upgrade);
     212           0 :         if (!cmpUpgrade || !cmpUpgrade.IsUpgrading())
     213           0 :                 return 0;
     214             : 
     215           0 :         return this.AddBar(cmpOverlayRenderer, yoffset, "upgrade", cmpUpgrade.GetProgress());
     216             : };
     217             : 
     218           0 : StatusBars.prototype.AddHealthBar = function(cmpOverlayRenderer, yoffset)
     219             : {
     220           0 :         if (!this.enabled)
     221           0 :                 return 0;
     222             : 
     223           0 :         let cmpHealth = QueryMiragedInterface(this.entity, IID_Health);
     224           0 :         if (!cmpHealth || cmpHealth.GetHitpoints() <= 0)
     225           0 :                 return 0;
     226             : 
     227           0 :         return this.AddBar(cmpOverlayRenderer, yoffset, "health", cmpHealth.GetHitpoints() / cmpHealth.GetMaxHitpoints());
     228             : };
     229             : 
     230           0 : StatusBars.prototype.AddResourceSupplyBar = function(cmpOverlayRenderer, yoffset)
     231             : {
     232           0 :         if (!this.enabled)
     233           0 :                 return 0;
     234             : 
     235           0 :         let cmpResourceSupply = QueryMiragedInterface(this.entity, IID_ResourceSupply);
     236           0 :         if (!cmpResourceSupply)
     237           0 :                 return 0;
     238           0 :         let value = cmpResourceSupply.IsInfinite() ? 1 : cmpResourceSupply.GetCurrentAmount() / cmpResourceSupply.GetMaxAmount();
     239           0 :         return this.AddBar(cmpOverlayRenderer, yoffset, "supply", value);
     240             : };
     241             : 
     242           0 : StatusBars.prototype.AddCaptureBar = function(cmpOverlayRenderer, yoffset)
     243             : {
     244           0 :         if (!this.enabled)
     245           0 :                 return 0;
     246             : 
     247           0 :         let cmpCapturable = QueryMiragedInterface(this.entity, IID_Capturable);
     248           0 :         if (!cmpCapturable)
     249           0 :                 return 0;
     250             : 
     251           0 :         let cmpOwnership = QueryMiragedInterface(this.entity, IID_Ownership);
     252           0 :         if (!cmpOwnership)
     253           0 :                 return 0;
     254             : 
     255           0 :         let owner = cmpOwnership.GetOwner();
     256           0 :         if (owner == INVALID_PLAYER)
     257           0 :                 return 0;
     258             : 
     259           0 :         this.usedPlayerColors = true;
     260           0 :         let capturePoints = cmpCapturable.GetCapturePoints();
     261             : 
     262             :         // Size of health bar (in world-space units)
     263           0 :         let width = +this.template.BarWidth;
     264           0 :         let height = +this.template.BarHeight;
     265             : 
     266             :         // World-space offset from the unit's position
     267           0 :         let offset = { "x": 0, "y": +this.template.HeightOffset, "z": 0 };
     268             : 
     269           0 :         let setCaptureBarPart = function(playerID, startSize)
     270             :         {
     271           0 :                 let c = QueryPlayerIDInterface(playerID).GetDisplayedColor();
     272           0 :                 let strColor = (c.r * 255) + " " + (c.g * 255) + " " + (c.b * 255) + " 255";
     273           0 :                 let size = width * capturePoints[playerID] / cmpCapturable.GetMaxCapturePoints();
     274             : 
     275           0 :                 cmpOverlayRenderer.AddSprite(
     276             :                         "art/textures/ui/session/icons/capture_bar.png",
     277             :                         { "x": startSize, "y": yoffset },
     278             :                         { "x": startSize + size, "y": height + yoffset },
     279             :                         offset,
     280             :                         strColor
     281             :                 );
     282             : 
     283           0 :                 return size + startSize;
     284             :         };
     285             : 
     286             :         // First handle the owner's points, to keep those points on the left for clarity
     287           0 :         let size = setCaptureBarPart(owner, -width / 2);
     288           0 :         for (let i in capturePoints)
     289           0 :                 if (i != owner && capturePoints[i] > 0)
     290           0 :                         size = setCaptureBarPart(i, size);
     291             : 
     292           0 :         return height * 1.2;
     293             : };
     294             : 
     295           0 : StatusBars.prototype.AddAuraIcons = function(cmpOverlayRenderer, yoffset)
     296             : {
     297           0 :         let cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
     298           0 :         let sources = cmpGuiInterface.GetEntitiesWithStatusBars().filter(e => this.auraSources.has(e) && this.auraSources.get(e).length);
     299             : 
     300           0 :         if (!sources.length)
     301           0 :                 return 0;
     302             : 
     303           0 :         let iconSet = new Set();
     304           0 :         for (let ent of sources)
     305             :         {
     306           0 :                 let cmpAuras = Engine.QueryInterface(ent, IID_Auras);
     307           0 :                 if (!cmpAuras) // probably the ent just died
     308           0 :                         continue;
     309           0 :                 for (let name of this.auraSources.get(ent))
     310           0 :                         iconSet.add(cmpAuras.GetOverlayIcon(name));
     311             :         }
     312             : 
     313             :         // World-space offset from the unit's position
     314           0 :         let offset = { "x": 0, "y": +this.template.HeightOffset + yoffset, "z": 0 };
     315             : 
     316           0 :         let iconSize = +this.template.BarWidth / 2;
     317           0 :         let xoffset = -iconSize * (iconSet.size - 1) * 0.6;
     318           0 :         for (let icon of iconSet)
     319             :         {
     320           0 :                 cmpOverlayRenderer.AddSprite(
     321             :                         icon,
     322             :                         { "x": xoffset - iconSize / 2, "y": yoffset },
     323             :                         { "x": xoffset + iconSize / 2, "y": iconSize + yoffset },
     324             :                         offset,
     325             :                         g_NaturalColor
     326             :                 );
     327           0 :                 xoffset += iconSize * 1.2;
     328             :         }
     329             : 
     330           0 :         return iconSize + this.template.BarHeight / 2;
     331             : };
     332             : 
     333           0 : StatusBars.prototype.AddRankIcon = function(cmpOverlayRenderer, yoffset)
     334             : {
     335           0 :         if (!this.enabled || !this.showRank)
     336           0 :                 return 0;
     337             : 
     338           0 :         let cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity);
     339           0 :         if (!cmpIdentity || !cmpIdentity.GetRank())
     340           0 :                 return 0;
     341             : 
     342           0 :         let iconSize = +this.template.BarWidth / 2;
     343           0 :         cmpOverlayRenderer.AddSprite(
     344             :                 "art/textures/ui/session/icons/ranks/" + cmpIdentity.GetRank() + ".png",
     345             :                 { "x": -iconSize / 2, "y": yoffset },
     346             :                 { "x": iconSize / 2, "y": iconSize + yoffset },
     347             :                 { "x": 0, "y": +this.template.HeightOffset + 0.1, "z": 0 },
     348             :                 g_NaturalColor);
     349             : 
     350           0 :         return iconSize + this.template.BarHeight / 2;
     351             : };
     352             : 
     353           0 : Engine.RegisterComponentType(IID_StatusBars, "StatusBars", StatusBars);

Generated by: LCOV version 1.14