mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-07-04 05:55:47 -07:00
Fix entities not retaining repair order after target transforms
Update this.repairTarget in UnitAI when target renames. Transfer builders among renamed entities. Differential Revision: https://code.wildfiregames.com/D2360 Patch by: @Freagarach Comments by: Stan, elexis This was SVN commit r23449.
This commit is contained in:
parent
82a5ab6d19
commit
17c9950cee
5 changed files with 102 additions and 26 deletions
|
|
@ -75,6 +75,16 @@ Foundation.prototype.GetBuildPercentage = function()
|
|||
return Math.floor(this.GetBuildProgress() * 100);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the current builders.
|
||||
*
|
||||
* @return {number[]} - An array containing the entity IDs of assigned builders.
|
||||
*/
|
||||
Foundation.prototype.GetBuilders = function()
|
||||
{
|
||||
return Array.from(this.builders.keys());
|
||||
};
|
||||
|
||||
Foundation.prototype.GetNumBuilders = function()
|
||||
{
|
||||
return this.builders.size;
|
||||
|
|
@ -116,23 +126,48 @@ Foundation.prototype.OnDestroy = function()
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds an array of builders.
|
||||
*
|
||||
* @param {number[]} builders - An array containing the entity IDs of builders to assign.
|
||||
*/
|
||||
Foundation.prototype.AddBuilders = function(builders)
|
||||
{
|
||||
let changed = false;
|
||||
for (let builder of builders)
|
||||
changed = this.AddBuilderHelper(builder) || changed;
|
||||
|
||||
if (changed)
|
||||
this.HandleBuildersChanged();
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a single builder to this entity.
|
||||
*
|
||||
* @param {number} builderEnt - The entity to add.
|
||||
* @return {boolean} - Whether the addition was successful.
|
||||
*/
|
||||
Foundation.prototype.AddBuilderHelper = function(builderEnt)
|
||||
{
|
||||
if (this.builders.has(builderEnt))
|
||||
return false;
|
||||
|
||||
let buildRate = Engine.QueryInterface(builderEnt, IID_Builder).GetRate();
|
||||
this.builders.set(builderEnt, buildRate);
|
||||
this.totalBuilderRate += buildRate;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a builder to the counter.
|
||||
*
|
||||
* @param {number} builderEnt - The entity to add.
|
||||
*/
|
||||
Foundation.prototype.AddBuilder = function(builderEnt)
|
||||
{
|
||||
if (this.builders.has(builderEnt))
|
||||
return;
|
||||
|
||||
this.builders.set(builderEnt, Engine.QueryInterface(builderEnt, IID_Builder).GetRate());
|
||||
this.totalBuilderRate += this.builders.get(builderEnt);
|
||||
this.SetBuildMultiplier();
|
||||
|
||||
let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual);
|
||||
if (cmpVisual)
|
||||
cmpVisual.SetVariable("numbuilders", this.builders.size);
|
||||
|
||||
Engine.PostMessage(this.entity, MT_FoundationBuildersChanged, { "to": Array.from(this.builders.keys()) });
|
||||
if (this.AddBuilderHelper(builderEnt))
|
||||
this.HandleBuildersChanged();
|
||||
};
|
||||
|
||||
Foundation.prototype.RemoveBuilder = function(builderEnt)
|
||||
|
|
@ -142,14 +177,22 @@ Foundation.prototype.RemoveBuilder = function(builderEnt)
|
|||
|
||||
this.totalBuilderRate -= this.builders.get(builderEnt);
|
||||
this.builders.delete(builderEnt);
|
||||
this.HandleBuildersChanged();
|
||||
};
|
||||
|
||||
/**
|
||||
* This has to be called whenever the number of builders change.
|
||||
*/
|
||||
Foundation.prototype.HandleBuildersChanged = function()
|
||||
{
|
||||
this.SetBuildMultiplier();
|
||||
|
||||
let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual);
|
||||
if (cmpVisual)
|
||||
cmpVisual.SetVariable("numbuilders", this.builders.size);
|
||||
|
||||
Engine.PostMessage(this.entity, MT_FoundationBuildersChanged, { "to": Array.from(this.builders.keys()) });
|
||||
};
|
||||
Engine.PostMessage(this.entity, MT_FoundationBuildersChanged, { "to": this.GetBuilders() });
|
||||
}
|
||||
|
||||
/**
|
||||
* The build multiplier is a penalty that is applied to each builder.
|
||||
|
|
|
|||
|
|
@ -33,11 +33,32 @@ Repairable.prototype.GetBuildProgress = function()
|
|||
return hitpoints / maxHitpoints;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the current builders.
|
||||
*
|
||||
* @return {number[]} - An array containing the entity IDs of assigned builders.
|
||||
*/
|
||||
Repairable.prototype.GetBuilders = function()
|
||||
{
|
||||
return Array.from(this.builders.keys());
|
||||
};
|
||||
|
||||
Repairable.prototype.GetNumBuilders = function()
|
||||
{
|
||||
return this.builders.size;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds an array of builders.
|
||||
*
|
||||
* @param {number[]} - An array containing the entity IDs of builders to assign.
|
||||
*/
|
||||
Repairable.prototype.AddBuilders = function(builders)
|
||||
{
|
||||
for (let builder of builders)
|
||||
this.AddBuilder(builder);
|
||||
}
|
||||
|
||||
Repairable.prototype.AddBuilder = function(builderEnt)
|
||||
{
|
||||
if (this.builders.has(builderEnt))
|
||||
|
|
|
|||
|
|
@ -2754,11 +2754,13 @@ UnitAI.prototype.UnitFsmSpec = {
|
|||
|
||||
this.order.data.force = false;
|
||||
|
||||
this.repairTarget = this.order.data.target; // temporary, deleted in "leave".
|
||||
// Check we can still reach and repair the target
|
||||
// Needed to remove the entity from the builder list when leaving this state.
|
||||
this.repairTarget = this.order.data.target;
|
||||
|
||||
// Check we can still reach and repair the target.
|
||||
if (!this.CanRepair(this.repairTarget))
|
||||
{
|
||||
// Can't reach it, no longer owned by ally, or it doesn't exist any more
|
||||
// Can't reach it, no longer owned by ally, or it doesn't exist any more.
|
||||
this.FinishOrder();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2768,8 +2770,8 @@ UnitAI.prototype.UnitFsmSpec = {
|
|||
this.SetNextState("APPROACHING");
|
||||
return true;
|
||||
}
|
||||
// Check if the target is still repairable
|
||||
var cmpHealth = Engine.QueryInterface(this.repairTarget, IID_Health);
|
||||
// Check if the target is still repairable.
|
||||
let cmpHealth = Engine.QueryInterface(this.repairTarget, IID_Health);
|
||||
if (cmpHealth && cmpHealth.GetHitpoints() >= cmpHealth.GetMaxHitpoints())
|
||||
{
|
||||
// The building was already finished/fully repaired before we arrived;
|
||||
|
|
@ -2784,7 +2786,7 @@ UnitAI.prototype.UnitFsmSpec = {
|
|||
if (cmpBuilderList)
|
||||
cmpBuilderList.AddBuilder(this.entity);
|
||||
|
||||
this.FaceTowardsTarget(this.order.data.target);
|
||||
this.FaceTowardsTarget(this.repairTarget);
|
||||
|
||||
this.SelectAnimation("build");
|
||||
this.StartTimer(1000, 1000);
|
||||
|
|
@ -2801,21 +2803,21 @@ UnitAI.prototype.UnitFsmSpec = {
|
|||
},
|
||||
|
||||
"Timer": function(msg) {
|
||||
// Check we can still reach and repair the target
|
||||
// Check we can still reach and repair the target.
|
||||
if (!this.CanRepair(this.repairTarget))
|
||||
{
|
||||
// No longer owned by ally, or it doesn't exist any more
|
||||
// No longer owned by ally, or it doesn't exist any more.
|
||||
this.FinishOrder();
|
||||
return;
|
||||
}
|
||||
|
||||
this.FaceTowardsTarget(this.order.data.target);
|
||||
this.FaceTowardsTarget(this.repairTarget);
|
||||
|
||||
let cmpBuilder = Engine.QueryInterface(this.entity, IID_Builder);
|
||||
cmpBuilder.PerformBuilding(this.repairTarget);
|
||||
// if the building is completed, the leave() function will be called
|
||||
// by the ConstructionFinished message
|
||||
// in that case, the repairTarget is deleted, and we can just return
|
||||
// If the building is completed, the leave() function will be called
|
||||
// by the ConstructionFinished message.
|
||||
// In that case, the repairTarget is deleted, and we can just return.
|
||||
if (!this.repairTarget)
|
||||
return;
|
||||
if (!this.CheckTargetRange(this.repairTarget, IID_Builder))
|
||||
|
|
@ -4093,6 +4095,9 @@ UnitAI.prototype.OnGlobalEntityRenamed = function(msg)
|
|||
order.data.formationTarget = msg.newentity;
|
||||
}
|
||||
}
|
||||
if (this.repairTarget && this.repairTarget == msg.entity)
|
||||
this.repairTarget = msg.newentity;
|
||||
|
||||
if (changed)
|
||||
Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() });
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,12 +4,14 @@ Engine.LoadHelperScript("Transform.js");
|
|||
Engine.LoadHelperScript("ValueModification.js");
|
||||
Engine.LoadComponentScript("interfaces/ModifiersManager.js");
|
||||
Engine.LoadComponentScript("interfaces/Capturable.js");
|
||||
Engine.LoadComponentScript("interfaces/Foundation.js");
|
||||
Engine.LoadComponentScript("interfaces/GarrisonHolder.js");
|
||||
Engine.LoadComponentScript("interfaces/Guard.js");
|
||||
Engine.LoadComponentScript("interfaces/Health.js");
|
||||
Engine.LoadComponentScript("interfaces/Pack.js");
|
||||
Engine.LoadComponentScript("interfaces/Player.js");
|
||||
Engine.LoadComponentScript("interfaces/Promotion.js");
|
||||
Engine.LoadComponentScript("interfaces/Repairable.js");
|
||||
Engine.LoadComponentScript("interfaces/ResourceGatherer.js");
|
||||
Engine.LoadComponentScript("interfaces/StatusEffectsReceiver.js");
|
||||
Engine.LoadComponentScript("interfaces/Timer.js");
|
||||
|
|
|
|||
|
|
@ -53,6 +53,11 @@ function ChangeEntityTemplate(oldEnt, newTemplate)
|
|||
cmpNewHealth.SetHitpoints(cmpNewHealth.GetMaxHitpoints() * healthLevel);
|
||||
}
|
||||
|
||||
let cmpBuilderList = QueryBuilderListInterface(oldEnt);
|
||||
let cmpNewBuilderList = QueryBuilderListInterface(newEnt);
|
||||
if (cmpBuilderList && cmpNewBuilderList)
|
||||
cmpNewBuilderList.AddBuilders(cmpBuilderList.GetBuilders());
|
||||
|
||||
var cmpUnitAI = Engine.QueryInterface(oldEnt, IID_UnitAI);
|
||||
var cmpNewUnitAI = Engine.QueryInterface(newEnt, IID_UnitAI);
|
||||
if (cmpUnitAI && cmpNewUnitAI)
|
||||
|
|
|
|||
Loading…
Reference in a new issue