Handle phenotype in Transform, tweak SetPhenotype logic

This commit is contained in:
Lancelot de Ferrière 2024-11-28 09:32:52 +01:00 committed by wraitii
parent 7aa5890236
commit 533429e800
4 changed files with 44 additions and 29 deletions

View file

@ -337,18 +337,6 @@ Foundation.prototype.Build = function(builderEnt, work)
let building = ChangeEntityTemplate(this.entity, this.finalTemplateName);
const cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity);
const cmpBuildingIdentity = Engine.QueryInterface(building, IID_Identity);
if (cmpIdentity && cmpBuildingIdentity)
{
const oldPhenotype = cmpIdentity.GetPhenotype();
if (cmpBuildingIdentity.GetPhenotype() !== oldPhenotype)
{
cmpBuildingIdentity.SetPhenotype(oldPhenotype);
Engine.QueryInterface(building, IID_Visual)?.RecomputeActorName();
}
}
if (cmpPlayerStatisticsTracker)
cmpPlayerStatisticsTracker.IncreaseConstructedBuildingsCounter(building);

View file

@ -368,6 +368,15 @@ Health.prototype.CreateCorpse = function()
if (cmpOwnership && cmpOwnershipCorpse)
cmpOwnershipCorpse.SetOwner(cmpOwnership.GetOwner());
const cmpIdentityCorpse = Engine.QueryInterface(entCorpse, IID_Identity);
if (cmpIdentityCorpse)
{
const cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity);
if (cmpIdentity)
// NB: Rely on cmpVisualCorpse below to call RecomputeActorName
cmpIdentityCorpse.SetPhenotype(cmpIdentity.GetPhenotype());
}
let cmpVisualCorpse = Engine.QueryInterface(entCorpse, IID_Visual);
if (cmpVisualCorpse)
{
@ -378,22 +387,6 @@ Health.prototype.CreateCorpse = function()
cmpVisualCorpse.SelectAnimation("death", true, 1);
}
const cmpIdentityCorpse = Engine.QueryInterface(entCorpse, IID_Identity);
if (cmpIdentityCorpse)
{
const cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity);
if (cmpIdentity)
{
const oldPhenotype = cmpIdentity.GetPhenotype();
if (cmpIdentityCorpse.GetPhenotype() !== oldPhenotype)
{
cmpIdentityCorpse.SetPhenotype(oldPhenotype);
if (cmpVisualCorpse)
cmpVisualCorpse.RecomputeActorName();
}
}
}
if (resource)
Engine.PostMessage(this.entity, MT_EntityRenamed, {
"entity": this.entity,

View file

@ -92,13 +92,30 @@ Identity.prototype.Init = function()
this.classesList = GetIdentityClasses(this.template);
this.visibleClassesList = GetVisibleIdentityClasses(this.template);
if (this.template.Phenotype)
this.phenotype = pickRandom(this.GetPossiblePhenotypes());
{
const phenotypes = this.GetPossiblePhenotypes();
// TODO: this is a workaround to avoid calling Math.random,
// which causes out of sync RNG caused by preview entities.
// However, it's not random enough. Perhaps use the actor seed.
this.phenotype = phenotypes[this.entity % phenotypes.length];
}
else
this.phenotype = "default";
this.controllable = this.template.Controllable ? this.template.Controllable == "true" : true;
};
Identity.prototype.Deserialize = function (data)
{
this.Init();
this.phenotype = data.phenotype;
};
Identity.prototype.Serialize = function()
{
return { "phenotype": this.phenotype };
};
Identity.prototype.GetCiv = function()
{
return this.template.Civ;
@ -177,9 +194,20 @@ Identity.prototype.SetControllable = function(controllability)
this.controllable = controllability;
};
/**
* Change the phenotype of the entity.
* @param {string} phenotype
* @returns {boolean} Whether the phenotype was changed.
* If yes, check if VisualActor::RecomputeActorName needs to be called.
*/
Identity.prototype.SetPhenotype = function(phenotype)
{
if (this.phenotype == phenotype)
return false;
if (this.GetPossiblePhenotypes().indexOf(phenotype) === -1)
return false;
this.phenotype = phenotype;
return true;
};
/**

View file

@ -13,6 +13,12 @@ function ChangeEntityTemplate(oldEnt, newTemplate)
Engine.ProfileStart("Transform");
const cmpIdentity = Engine.QueryInterface(oldEnt, IID_Identity);
const cmpNewIdentity = Engine.QueryInterface(newEnt, IID_Identity);
if (cmpIdentity && cmpNewIdentity)
// No need to call visualactor::recomputeactorname, will be called below.
cmpNewIdentity.SetPhenotype(cmpIdentity.GetPhenotype());
const cmpVisual = Engine.QueryInterface(oldEnt, IID_Visual);
const cmpNewVisual = Engine.QueryInterface(newEnt, IID_Visual);
if (cmpVisual && cmpNewVisual)