Index: binaries/data/mods/public/simulation/components/Fogging.js =================================================================== --- binaries/data/mods/public/simulation/components/Fogging.js +++ binaries/data/mods/public/simulation/components/Fogging.js @@ -109,6 +109,8 @@ error("Failed to copy the visual data of the fogged entity " + this.entity); return; } + + cmpMirageVisualActor.RecomputeActorName(); cmpMirageVisualActor.SetActorSeed(cmpParentVisualActor.GetActorSeed()); // Store valuable information into the mirage component (especially for the GUI) Index: binaries/data/mods/public/simulation/components/Mirage.js =================================================================== --- binaries/data/mods/public/simulation/components/Mirage.js +++ binaries/data/mods/public/simulation/components/Mirage.js @@ -73,9 +73,10 @@ Mirage.prototype.CopyIdentity = function(cmpIdentity) { this.miragedIids.add(IID_Identity); - // In almost all cases we want to ignore mirage entities when querying Identity components of owned entities. - // To avoid adding a test everywhere, we don't transfer the classeslist in the template but here. - // We clone this since the classes list is not synchronized and since the mirage should be a snapshot of the entity at the given time. + // Mirages don't get identity classes via the template-filter, so that code can query + // identity components via Engine.QueryInterface without having to explicitly check for mirages. + // This is cloned as otherwise we get a reference to Identity's property, + // and that array is deleted when serializing (as it's not seralized), which ends in OOS. this.classesList = clone(cmpIdentity.GetClassesList()); }; Index: binaries/data/mods/public/simulation/components/ModifiersManager.js =================================================================== --- binaries/data/mods/public/simulation/components/ModifiersManager.js +++ binaries/data/mods/public/simulation/components/ModifiersManager.js @@ -161,7 +161,7 @@ newValue = originalValue; - let cmpIdentity = Engine.QueryInterface(entity, IID_Identity); + let cmpIdentity = QueryMiragedInterface(entity, IID_Identity); if (!cmpIdentity) return originalValue; let classesList = cmpIdentity.GetClassesList(); Index: binaries/data/mods/public/simulation/templates/special/filter/construction.xml =================================================================== --- binaries/data/mods/public/simulation/templates/special/filter/construction.xml +++ binaries/data/mods/public/simulation/templates/special/filter/construction.xml @@ -1,6 +1,7 @@ + Index: binaries/data/mods/public/simulation/templates/special/filter/mirage.xml =================================================================== --- binaries/data/mods/public/simulation/templates/special/filter/mirage.xml +++ binaries/data/mods/public/simulation/templates/special/filter/mirage.xml @@ -9,6 +9,8 @@ + Index: source/simulation2/components/CCmpVisualActor.cpp =================================================================== --- source/simulation2/components/CCmpVisualActor.cpp +++ source/simulation2/components/CCmpVisualActor.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -24,12 +24,13 @@ #include "ICmpFootprint.h" #include "ICmpIdentity.h" -#include "ICmpUnitRenderer.h" +#include "ICmpMirage.h" #include "ICmpOwnership.h" #include "ICmpPosition.h" #include "ICmpTemplateManager.h" #include "ICmpTerrain.h" #include "ICmpUnitMotion.h" +#include "ICmpUnitRenderer.h" #include "ICmpValueModificationManager.h" #include "ICmpVisibility.h" #include "ICmpSound.h" @@ -295,11 +296,14 @@ { case MT_OwnershipChanged: { + RecomputeActorName(); + if (!m_Unit) break; const CMessageOwnershipChanged& msgData = static_cast (msg); m_Unit->GetModel().SetPlayerID(msgData.to); + break; } case MT_TerrainChanged: @@ -313,20 +317,17 @@ } case MT_ValueModification: { + // Mirages don't respond to technology modifications. + CmpPtr cmpMirage(GetEntityHandle()); + if (cmpMirage) + return; + const CMessageValueModification& msgData = static_cast (msg); if (msgData.component != L"VisualActor") break; - CmpPtr cmpValueModificationManager(GetSystemEntity()); - std::wstring newActorName; - if (m_IsFoundationActor) - newActorName = cmpValueModificationManager->ApplyModifications(L"VisualActor/FoundationActor", m_BaseActorName, GetEntityId()); - else - newActorName = cmpValueModificationManager->ApplyModifications(L"VisualActor/Actor", m_BaseActorName, GetEntityId()); - if (newActorName != m_ActorName) - { - ParseActorName(newActorName); - ReloadActor(); - } + + RecomputeActorName(); + break; } case MT_InterpolatedPositionChanged: @@ -528,6 +529,22 @@ ReloadActor(); } + virtual void RecomputeActorName() + { + CmpPtr cmpValueModificationManager(GetSystemEntity()); + std::wstring newActorName; + if (m_IsFoundationActor) + newActorName = cmpValueModificationManager->ApplyModifications(L"VisualActor/FoundationActor", m_BaseActorName, GetEntityId()); + else + newActorName = cmpValueModificationManager->ApplyModifications(L"VisualActor/Actor", m_BaseActorName, GetEntityId()); + + if (newActorName != m_ActorName) + { + ParseActorName(newActorName); + ReloadActor(); + } + } + virtual bool HasConstructionPreview() const { return m_ConstructionPreview; Index: source/simulation2/components/ICmpVisual.h =================================================================== --- source/simulation2/components/ICmpVisual.h +++ source/simulation2/components/ICmpVisual.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -152,6 +152,11 @@ */ virtual void SetActorSeed(u32 seed) = 0; + /** + * Recalculate the actor name, applying modifiers. + */ + virtual void RecomputeActorName() = 0; + /** * Returns true if this entity should have a construction preview */ Index: source/simulation2/components/ICmpVisual.cpp =================================================================== --- source/simulation2/components/ICmpVisual.cpp +++ source/simulation2/components/ICmpVisual.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -33,5 +33,6 @@ DEFINE_INTERFACE_METHOD_2("SetVariable", void, ICmpVisual, SetVariable, std::string, float) DEFINE_INTERFACE_METHOD_CONST_0("GetActorSeed", u32, ICmpVisual, GetActorSeed) DEFINE_INTERFACE_METHOD_1("SetActorSeed", void, ICmpVisual, SetActorSeed, u32) +DEFINE_INTERFACE_METHOD_0("RecomputeActorName", void, ICmpVisual, RecomputeActorName) DEFINE_INTERFACE_METHOD_CONST_0("HasConstructionPreview", bool, ICmpVisual, HasConstructionPreview) END_INTERFACE_WRAPPER(Visual)