Allan Posted June 3 Author Report Share Posted June 3 I did this to the UpdateColor function : UpdateColor() { // warn("UpdateColor"); let cmpFoundationOwnership = Engine.QueryInterface(this.entity, IID_Ownership); if (cmpFoundationOwnership) { cmpFoundationOwnership.SetOwner(cmpFoundationOwnership.GetOwner()); } warn("Owner : " + cmpFoundationOwnership.GetOwner()) let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual); if (!cmpVisual) return; const color = QueryOwnerInterface(this.entity, IID_Player).GetColor(); cmpVisual.SetVariable("colorr", color.r); cmpVisual.SetVariable("colorg", color.g); cmpVisual.SetVariable("colorb", color.b); // warn("red : "+color.r); // warn("green : "+color.g); // warn("blue : "+color.b); } I try to SetOwner at this moment but I think i'm doing it bad. I saw this function comes from a .cpp compoment and is quite simple. But how can I SetOwner the final building AND the foundation AND the preview ? I'm testing many things but I don't understand why when I print the owner of my 2 civil_centre at the beginning of the game I have this : It seems like the owner is changing 3 times before getting the right owner, maybe that is the problem Moreover, I'm not the best programmer in the team, that's why it's harder for me to understand these things, sorry for being a noob (Steph is not available) Quote Link to comment Share on other sites More sharing options...
Stan` Posted June 3 Report Share Posted June 3 It's okay. Perserverance is all you need Regarding your interrogation I think by default everything is INVALID_PLAYER = -1 You might also print this.entity so you know which is which. Ideally in one statement warn("entity: " + this.entity + " Owner: " + cmpFoundationOwnership.GetOwner()); Or use string interpolation warn(`entity: ${this.entity} Owner: ${cmpFoundationOwnership.GetOwner()}`); Maybe we forgot the edge case of QueryOwnerInterface not having an actual player Quote Link to comment Share on other sites More sharing options...
Allan Posted June 4 Author Report Share Posted June 4 (edited) I think I found something but I don't know how to use the UpdateColor function in another file. I tried this : let cmpParticlePlayerColor = Engine.RegisterInterface("ParticlePlayerColor"); if (cmpParticlePlayerColor) { cmpParticlePlayerColor.UpdateColor(); } And this : let cmpParticlePlayerColor = Engine.QueryInterface(this.entity, IID_ParticlePlayerColor); if (cmpParticlePlayerColor) { cmpParticlePlayerColor.UpdateColor(); } I think I understand why the second one doesn't work (wrong interface) but why the first one ? I'm trying this because i saw that the UpdateColor function is called before the owner is set, and I think that's the problem. Edited June 4 by Allan Quote Link to comment Share on other sites More sharing options...
Stan` Posted June 4 Report Share Posted June 4 Weird because the second one is correct The first one registers a new interface for the engine. So it should never be called outside of the first initialisation of the component in the js file (Although you could create runtime components for nefarious purposes, I would advise against it) If the first one doesn't work, it means that whatever is calling that code doesn't have that component attached, which could mean the template is invalid. Quote Link to comment Share on other sites More sharing options...
Allan Posted June 4 Author Report Share Posted June 4 Ok, I've got these errors with the second one : So yes, itu says that is null, so how can I call my UpdateColor function if this is null ? Quote Link to comment Share on other sites More sharing options...
Stan` Posted June 4 Report Share Posted June 4 2 hours ago, Allan said: Ok, I've got these errors with the second one : So yes, itu says that is null, so how can I call my UpdateColor function if this is null ? The error means it cannot find the owner, (probably cause it doesn't have one) It's this code that fails: const color = QueryOwnerInterface(this.entity, IID_Player).GetColor(); cmpVisual.SetVariable("colorr", color.r); cmpVisual.SetVariable("colorg", color.g); cmpVisual.SetVariable("colorb", color.b); You can replace it with const cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); if (cmpPlayer) { const color = cmpPlayer.GetColor(); cmpVisual.SetVariable("colorr", color.r); cmpVisual.SetVariable("colorg", color.g); cmpVisual.SetVariable("colorb", color.b); } but then since it cannot find the player it will not set the color Quote Link to comment Share on other sites More sharing options...
Allan Posted June 4 Author Report Share Posted June 4 After testing many things I think that it's true 18 hours ago, Stan` said: Maybe we forgot the edge case of QueryOwnerInterface not having an actual player But how this works for the civili-centre (building placed at the beginning of the game) and not for other buildings being constructed during the game ? And if I can't pick my player from here, how can I do ? Quote Link to comment Share on other sites More sharing options...
Stan` Posted June 4 Report Share Posted June 4 Usually that's why we have a call on Ownershipchanged but maybe there is a message we're not listening to Quote Link to comment Share on other sites More sharing options...
Stan` Posted June 4 Report Share Posted June 4 The preplaced buildings probably work because they down change ownership when they are being skirmish replaced. Quote Link to comment Share on other sites More sharing options...
Allan Posted June 4 Author Report Share Posted June 4 (edited) Ok I think I found something interesting. I found this message in Player.js : Player.prototype.OnGlobalOwnershipChanged = function(msg) { if (msg.from != this.playerID && msg.to != this.playerID) return; let cmpCost = Engine.QueryInterface(msg.entity, IID_Cost); if (msg.from == this.playerID) { if (cmpCost) this.popUsed -= cmpCost.GetPopCost(); let panelIndex = this.panelEntities.indexOf(msg.entity); if (panelIndex >= 0) this.panelEntities.splice(panelIndex, 1); let barterIndex = this.barterEntities.indexOf(msg.entity); if (barterIndex >= 0) this.barterEntities.splice(barterIndex, 1); } if (msg.to == this.playerID) { if (cmpCost) this.popUsed += cmpCost.GetPopCost(); let cmpIdentity = Engine.QueryInterface(msg.entity, IID_Identity); if (!cmpIdentity) return; if (MatchesClassList(cmpIdentity.GetClassesList(), panelEntityClasses)) this.panelEntities.push(msg.entity); if (cmpIdentity.HasClass("Barter") && !Engine.QueryInterface(msg.entity, IID_Foundation)) this.barterEntities.push(msg.entity); } }; It's always called when you build something so I decided to test this in ParticlePlayer.js : OnGlobalOwnershipChanged(msg) { if (msg.to == INVALID_PLAYER) return; this.UpdateColor(); } And it works ! The building switch from gaia to player color during the building or when it's constructed BUT the UpdateColor function is being called 3-4 times every 5 seconds, which can be a problem ? I don't know + I understood how it works : Everytime I build something, the previous building is being Color updated. It means that if un build a large wall (with two towers), only the first tower will be color updated. To update the second one, I have to build another building Edited June 4 by Allan Quote Link to comment Share on other sites More sharing options...
Stan` Posted June 4 Report Share Posted June 4 You can filter the entity // msg data is {"entity": ent, "from": playerId, "to": playerId} Quote Link to comment Share on other sites More sharing options...
Allan Posted June 4 Author Report Share Posted June 4 (edited) 9 minutes ago, Stan` said: You can filter the entity // msg data is {"entity": ent, "from": playerId, "to": playerId} Ok but how to use it ? I tried this but it makes the code not working again (does nothing without error) OnOwnershipChanged(msg) { warn("OwnershipChanged"); if (msg.to == INVALID_PLAYER) return; if (msg.ent) this.UpdateColor(); // warn("OwnershipChangedUpdateColor"); } And will it be really useful ? I mean is the problem comes from this or not ? + I don't know if my last post was clear after reading it :/ Edited June 4 by Allan Quote Link to comment Share on other sites More sharing options...
Allan Posted June 4 Author Report Share Posted June 4 Here is the "final" version of my UpdateColor function : UpdateColor() { const cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); let owner = Engine.QueryInterface(this.entity, IID_Ownership).GetOwner(); warn("Entity : " + this.entity + "Owner : " + owner); let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual); if (!cmpVisual) return; if (cmpPlayer) { const color = cmpPlayer.GetColor(); cmpVisual.SetVariable("colorr", color.r); cmpVisual.SetVariable("colorg", color.g); cmpVisual.SetVariable("colorb", color.b); } } OnOwnershipChanged(msg) { if (msg.to == INVALID_PLAYER) return; this.UpdateColor(); } OnGlobalOwnershipChanged(msg) { if (msg.to == INVALID_PLAYER) return; this.UpdateColor(); } OnEntityRenamed(msg) { if (msg.to == INVALID_PLAYER) return; this.UpdateColor(); } OnHealthChanged(msg) { if (msg.to == INVALID_PLAYER) return; this.UpdateColor(); } OnGlobalInitGame(msg) { if (msg.to == INVALID_PLAYER) return; this.UpdateColor(); } When I build a large wall (Tower + Wall + Tower), the particles of the first tower is gaia colored. When the wall is constructed, the first tower particles turns player colored. The third tower stays gaia colored since I build something else. I don't understand how is this possible to be honest Quote Link to comment Share on other sites More sharing options...
Stan` Posted June 4 Report Share Posted June 4 if (msg.ent === this.entity) this.UpdateColor(); I meant doing this in OnGlobalOwnershipChanged the global functions are called for every unit anytime anything changes. It's a bit better than OnUpdate but it still isn't great for performance. 33 minutes ago, Allan said: en the wall is constructed, the first tower particles turns player colored. I suppose it triggers one of the global functions and causes the old buildings to reupdate. I didn't know you were using wals, there might be something different in Wall.js or Wallset.js Quote Link to comment Share on other sites More sharing options...
Allan Posted June 4 Author Report Share Posted June 4 1 hour ago, Stan` said: if (msg.ent === this.entity) this.UpdateColor(); If I put this in OnGlobalOwnershipChanged it doesn't work anymore, the color is not updated. 1 hour ago, Stan` said: I suppose it triggers one of the global functions and causes the old buildings to reupdate. I didn't know you were using wals, there might be something different in Wall.js or Wallset.js The wallset.js in kind of empty to be honest, and I can't find another file attached to walls. Moreover, I don't understand why i've got a good preview (with the good color) with my wall tower but not with my other building (spacedock) I'll see this tomorrow I take a break Quote Link to comment Share on other sites More sharing options...
Stan` Posted June 4 Report Share Posted June 4 4 minutes ago, Allan said: If I put this in OnGlobalOwnershipChanged it doesn't work anymore, the color is not updated. The wallset.js in kind of empty to be honest, and I can't find another file attached to walls. Moreover, I don't understand why i've got a good preview (with the good color) with my wall tower but not with my other building (spacedock) I'll see this tomorrow I take a break Can you push it in the branch of the mod git so I can take a look tomorrow ? 1 Quote Link to comment Share on other sites More sharing options...
Allan Posted June 4 Author Report Share Posted June 4 (edited) Done Edited June 4 by Allan 1 Quote Link to comment Share on other sites More sharing options...
Allan Posted June 5 Author Report Share Posted June 5 (edited) UpdateColor() { // warn("UpdateColor"); // let cmpFoundationOwnership = Engine.QueryInterface(this.entity, IID_Ownership); // let owner = cmpFoundationOwnership.GetOwner(); // if (cmpFoundationOwnership) // { // cmpFoundationOwnership.SetOwner(owner); // } // warn("Entity : " + this.entity + "Owner : " + owner) // var owner = Engine.QueryInterface(this.entity, IID_Ownership).GetOwner(); const cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); let owner = Engine.QueryInterface(this.entity, IID_Ownership).GetOwner(); warn("Entity : " + this.entity + "Owner : " + owner); let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual); if (!cmpVisual) return; if (cmpPlayer) { const color = cmpPlayer.GetColor(); cmpVisual.SetVariable("colorr", color.r); cmpVisual.SetVariable("colorg", color.g); cmpVisual.SetVariable("colorb", color.b); } // warn("red : "+color.r); // warn("green : "+color.g); // warn("blue : "+color.b); } I think it doesn't get the good color untli the building is finally constructed, so that's why it applies the gaia color. But how to collect the owner of a building before its construction ? Something that I don't understand is that I call all the messages during the construction, it should be good but it's not Edited June 5 by Allan Quote Link to comment Share on other sites More sharing options...
Allan Posted June 5 Author Report Share Posted June 5 20 hours ago, Stan` said: Can you push it in the branch of the mod git so I can take a look tomorrow ? Hey ! Did you find something ? My exams are tomorrow and Friday so I'll be back on this after my exams Quote Link to comment Share on other sites More sharing options...
Stan` Posted June 5 Report Share Posted June 5 No sorry busy day ^^" 1 Quote Link to comment Share on other sites More sharing options...
Stan` Posted June 6 Report Share Posted June 6 Hey, I have some good news and some bad news... The good news is that I found the potential culprit for that messy behavior okay preview -> broken construction -> broken final. The problem is that Foundation.js sets the scaffold animation on buildings. That breaks the construction (If you remove the lines in Foundation.js the color is correct until completion) After that it switches animation again to Idle I suppose and that breaks the final state. It "works" for buildings that have been placed at the start of the map because I suppose they don't change anims. Unfortunately there is no way to force colors to update after each animation change... This might be a C++ "bug". Which means we can't fix it without hacks.... One could add 8 variants of the particle to every single actor and switch them in the component we made. Each particle variant would have a color that you need to guess from the rgb values (fun heh) Another solution is to get the animation name using a timer periodically and if it changed to force the color to update again. Quote Link to comment Share on other sites More sharing options...
Allan Posted June 10 Author Report Share Posted June 10 (edited) Ok thank you ! On 06/06/2024 at 10:35 PM, Stan` said: One could add 8 variants of the particle to every single actor and switch them in the component we made. Each particle variant would have a color that you need to guess from the rgb values (fun heh) I only have one week left to do it, so I don't think I will follow this solution. On 06/06/2024 at 10:35 PM, Stan` said: Another solution is to get the animation name using a timer periodically and if it changed to force the color to update again. I think I can do this, I just don't know where can I put this timer ? In what file ? Maybe these particules are only a detail, I'm hesitating, it's already working to be honest, I don't know if I will take time for this, because I have a lot of things to do :/ Edited June 10 by Allan Quote Link to comment Share on other sites More sharing options...
Stan` Posted June 10 Report Share Posted June 10 In init you can do something like const refreshInterval = 1000; // 1s let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); cmpTimer.SetInterval(this.entity, IID_PlayerParticleColor, "TimerTick", refreshInterval, refreshInterval, undefined); Then you need to add function like TimerTick = function() { this.UpdateColor(); }; You can be a bit smarter and check what is the current animation and if it differs from the previous one but that's a bit more elaborate 1 Quote Link to comment Share on other sites More sharing options...
Allan Posted June 11 Author Report Share Posted June 11 (edited) Nice it's working ! Are you sure that it will not be too expensive for the engine ? I mean updating the color every 1 sec, maybe we have to put this on 3 or 4 sec ? Edited June 11 by Allan Quote Link to comment Share on other sites More sharing options...
Stan` Posted June 11 Report Share Posted June 11 22 minutes ago, Allan said: I mean updating the color every 1 sec, maybe we have to put this on 3 or 4 sec ? It's not perfect but it should be okay. You might also reduce the amount of entities with such particles 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.