1
0
forked from 0ad/0ad

Make Promotion.js use the common Transform helper, add resource gatherer and promotion to said helper.

Fixes #4334

Differential Revision: https://code.wildfiregames.com/D2026
This was SVN commit r22753.
This commit is contained in:
wraitii 2019-08-22 17:25:44 +00:00
parent 1d1471aba9
commit cc1ea7cca0
4 changed files with 86 additions and 155 deletions

View File

@ -31,103 +31,18 @@ Promotion.prototype.GetPromotedTemplateName = function()
Promotion.prototype.Promote = function(promotedTemplateName) Promotion.prototype.Promote = function(promotedTemplateName)
{ {
// If the unit is dead, don't promote it // If the unit is dead, don't promote it
var cmpCurrentUnitHealth = Engine.QueryInterface(this.entity, IID_Health); let cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
if (cmpCurrentUnitHealth.GetHitpoints() == 0) if (cmpHealth && cmpHealth.GetHitpoints() == 0)
return; return;
// Create promoted unit entity // Save the entity id.
var promotedUnitEntity = Engine.AddEntity(promotedTemplateName); this.promotedUnitEntity = ChangeEntityTemplate(this.entity, promotedTemplateName);
// Copy parameters from current entity to promoted one let cmpPosition = Engine.QueryInterface(this.promotedUnitEntity, IID_Position);
var cmpCurrentUnitPosition = Engine.QueryInterface(this.entity, IID_Position); let cmpUnitAI = Engine.QueryInterface(this.promotedUnitEntity, IID_UnitAI);
var cmpPromotedUnitPosition = Engine.QueryInterface(promotedUnitEntity, IID_Position);
if (cmpCurrentUnitPosition.IsInWorld())
{
var pos = cmpCurrentUnitPosition.GetPosition2D();
cmpPromotedUnitPosition.JumpTo(pos.x, pos.y);
}
var rot = cmpCurrentUnitPosition.GetRotation();
cmpPromotedUnitPosition.SetYRotation(rot.y);
cmpPromotedUnitPosition.SetXZRotation(rot.x, rot.z);
var heightOffset = cmpCurrentUnitPosition.GetHeightOffset();
cmpPromotedUnitPosition.SetHeightOffset(heightOffset);
var cmpCurrentUnitOwnership = Engine.QueryInterface(this.entity, IID_Ownership); if (cmpPosition && cmpPosition.IsInWorld() && cmpUnitAI)
var cmpPromotedUnitOwnership = Engine.QueryInterface(promotedUnitEntity, IID_Ownership); cmpUnitAI.Cheer();
cmpPromotedUnitOwnership.SetOwner(cmpCurrentUnitOwnership.GetOwner());
// change promoted unit health to the same percent of hitpoints as unit had before promotion
var cmpPromotedUnitHealth = Engine.QueryInterface(promotedUnitEntity, IID_Health);
var healthFraction = Math.max(0, Math.min(1, cmpCurrentUnitHealth.GetHitpoints() / cmpCurrentUnitHealth.GetMaxHitpoints()));
var promotedUnitHitpoints = cmpPromotedUnitHealth.GetMaxHitpoints() * healthFraction;
cmpPromotedUnitHealth.SetHitpoints(promotedUnitHitpoints);
var cmpPromotedUnitPromotion = Engine.QueryInterface(promotedUnitEntity, IID_Promotion);
if (cmpPromotedUnitPromotion)
cmpPromotedUnitPromotion.IncreaseXp(this.currentXp);
var cmpCurrentUnitResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer);
var cmpPromotedUnitResourceGatherer = Engine.QueryInterface(promotedUnitEntity, IID_ResourceGatherer);
if (cmpCurrentUnitResourceGatherer && cmpPromotedUnitResourceGatherer)
{
var carriedResorces = cmpCurrentUnitResourceGatherer.GetCarryingStatus();
cmpPromotedUnitResourceGatherer.GiveResources(carriedResorces);
}
var cmpCurrentUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI);
var cmpPromotedUnitAI = Engine.QueryInterface(promotedUnitEntity, IID_UnitAI);
var heldPos = cmpCurrentUnitAI.GetHeldPosition();
if (heldPos)
cmpPromotedUnitAI.SetHeldPosition(heldPos.x, heldPos.z);
if (cmpCurrentUnitAI.GetStanceName())
cmpPromotedUnitAI.SwitchToStance(cmpCurrentUnitAI.GetStanceName());
var orders = cmpCurrentUnitAI.GetOrders();
if (cmpCurrentUnitPosition.IsInWorld()) // do not cheer if not visibly garrisoned
cmpPromotedUnitAI.Cheer();
if (cmpCurrentUnitAI.IsGarrisoned())
cmpPromotedUnitAI.SetGarrisoned();
cmpPromotedUnitAI.AddOrders(orders);
var workOrders = cmpCurrentUnitAI.GetWorkOrders();
cmpPromotedUnitAI.SetWorkOrders(workOrders);
if (cmpCurrentUnitAI.IsGuardOf())
{
let guarded = cmpCurrentUnitAI.IsGuardOf();
let cmpGuard = Engine.QueryInterface(guarded, IID_Guard);
if (cmpGuard)
{
cmpGuard.RenameGuard(this.entity, promotedUnitEntity);
cmpPromotedUnitAI.SetGuardOf(guarded);
}
}
let cmpCurrentUnitGuard = Engine.QueryInterface(this.entity, IID_Guard);
let cmpPromotedUnitGuard = Engine.QueryInterface(promotedUnitEntity, IID_Guard);
if (cmpCurrentUnitGuard && cmpPromotedUnitGuard)
{
let entities = cmpCurrentUnitGuard.GetEntities();
if (entities.length)
{
cmpPromotedUnitGuard.SetEntities(entities);
for (let ent of entities)
{
let cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
if (cmpUnitAI)
cmpUnitAI.SetGuardOf(promotedUnitEntity);
}
}
}
Engine.PostMessage(this.entity, MT_EntityRenamed, { "entity": this.entity, "newentity": promotedUnitEntity });
// Destroy current entity
if (cmpCurrentUnitPosition && cmpCurrentUnitPosition.IsInWorld())
cmpCurrentUnitPosition.MoveOutOfWorld();
Engine.DestroyEntity(this.entity);
// save the entity id
this.promotedUnitEntity = promotedUnitEntity;
}; };
Promotion.prototype.IncreaseXp = function(amount) Promotion.prototype.IncreaseXp = function(amount)
@ -136,7 +51,7 @@ Promotion.prototype.IncreaseXp = function(amount)
// transfer the gained xp to the promoted unit if applicable // transfer the gained xp to the promoted unit if applicable
if (this.promotedUnitEntity) if (this.promotedUnitEntity)
{ {
var cmpPromotion = Engine.QueryInterface(this.promotedUnitEntity, IID_Promotion); let cmpPromotion = Engine.QueryInterface(this.promotedUnitEntity, IID_Promotion);
if (cmpPromotion) if (cmpPromotion)
cmpPromotion.IncreaseXp(amount); cmpPromotion.IncreaseXp(amount);
return; return;
@ -165,6 +80,9 @@ Promotion.prototype.IncreaseXp = function(amount)
promotedTemplateName = template.Promotion.Entity; promotedTemplateName = template.Promotion.Entity;
} }
this.Promote(promotedTemplateName); this.Promote(promotedTemplateName);
let cmpPromotion = Engine.QueryInterface(this.promotedUnitEntity, IID_Promotion);
if (cmpPromotion)
cmpPromotion.IncreaseXp(this.currentXp);
} }
Engine.PostMessage(this.entity, MT_ExperienceChanged, {}); Engine.PostMessage(this.entity, MT_ExperienceChanged, {});

View File

@ -10,6 +10,8 @@ Engine.LoadComponentScript("interfaces/Guard.js");
Engine.LoadComponentScript("interfaces/Health.js"); Engine.LoadComponentScript("interfaces/Health.js");
Engine.LoadComponentScript("interfaces/Pack.js"); Engine.LoadComponentScript("interfaces/Pack.js");
Engine.LoadComponentScript("interfaces/Player.js"); Engine.LoadComponentScript("interfaces/Player.js");
Engine.LoadComponentScript("interfaces/Promotion.js");
Engine.LoadComponentScript("interfaces/ResourceGatherer.js");
Engine.LoadComponentScript("interfaces/Timer.js"); Engine.LoadComponentScript("interfaces/Timer.js");
Engine.LoadComponentScript("interfaces/UnitAI.js"); Engine.LoadComponentScript("interfaces/UnitAI.js");
Engine.LoadComponentScript("Pack.js"); Engine.LoadComponentScript("Pack.js");

View File

@ -1,69 +1,66 @@
Engine.LoadComponentScript("interfaces/Guard.js");
Engine.LoadComponentScript("interfaces/Health.js"); Engine.LoadComponentScript("interfaces/Health.js");
Engine.LoadComponentScript("interfaces/Promotion.js"); Engine.LoadComponentScript("interfaces/Promotion.js");
Engine.LoadComponentScript("interfaces/ResourceGatherer.js");
Engine.LoadComponentScript("interfaces/UnitAI.js"); Engine.LoadComponentScript("interfaces/UnitAI.js");
Engine.LoadComponentScript("Promotion.js"); Engine.LoadComponentScript("Promotion.js");
Engine.RegisterGlobal("MT_EntityRenamed", "entityRenamed");
// Test Promote (function testMultipleXPIncrease()
let cmpPromotion = ConstructComponent(60, "Promotion", {
"Entity": "infantry_melee_spearman_a",
"RequiredXP": 1000
});
// Health, Position, Ownership, UnitAI are mandatory in the Promotion code
AddMock(60, IID_Health, {
"GetHitpoints": () => 102,
"GetMaxHitpoints": () => 102,
});
AddMock(60, IID_Position, {
"GetPosition2D": () => new Vector2D(1, 0, 0),
"GetRotation": () => new Vector3D(3, 4, 5),
"GetHeightOffset": () => {},
"IsInWorld": () => true,
"MoveOutOfWorld": () => {}
});
AddMock(60, IID_Ownership, {
"GetOwner": () => 1,
});
AddMock(60, IID_UnitAI, {
"GetHeldPosition": () => {},
"GetStanceName": () => {},
"GetOrders": () => {},
"IsGarrisoned": () => {},
"GetWorkOrders": () => {},
"IsGuardOf": () => {},
});
Engine.AddEntity = function(name)
{ {
if (name != "infantry_melee_spearman_a") let ApplyValueModificationsToEntity = (_, val) => val;
return undefined; Engine.RegisterGlobal("ApplyValueModificationsToEntity", ApplyValueModificationsToEntity);
AddMock(61, IID_Health, { Engine.RegisterGlobal("ApplyValueModificationsToTemplate", ApplyValueModificationsToEntity);
"GetMaxHitpoints": () => 102 * 1.2,
"SetHitpoints": hp => TS_ASSERT_EQUALS(hp, 102 * 1.2) let QueryOwnerInterface = () => ({ "GetPlayerID": () => 2 });
}); Engine.RegisterGlobal("QueryOwnerInterface", QueryOwnerInterface);
AddMock(61, IID_Position, {
"JumpTo": () => {}, const ENT_ID = 60;
"SetYRotation": () => {},
"SetXZRotation": () => {}, let entTemplates = {
"SetHeightOffset": () => {}, "60": "template_b",
"IsInWorld": () => true, "61": "template_f",
}); "62": "end",
AddMock(61, IID_Ownership, {
"SetOwner": id => TS_ASSERT_EQUALS(id, 1),
});
AddMock(61, IID_UnitAI, {
"Cheer": () => {},
"AddOrders": () => {},
"SetWorkOrders": () => {},
});
return 61;
}; };
cmpPromotion.Promote("infantry_melee_spearman_a"); let promote = {
"template_b": "template_c",
"template_c": "template_d",
"template_d": "template_e",
"template_e": "template_f",
};
AddMock(SYSTEM_ENTITY, IID_TemplateManager, {
"GetTemplate": (t) => ({
"Promotion": {
"Entity": promote[t],
"RequiredXp": 1000
},
}),
});
let cmpPromotion = ConstructComponent(ENT_ID, "Promotion", {
"Entity": "template_b",
"RequiredXp": 1000
});
let ChangeEntityTemplate = function(ent, template)
{
cmpPromotion = ConstructComponent(ent + 1, "Promotion", {
"Entity": entTemplates[ent + 1],
"RequiredXp": 1000
});
return ent + 1;
};
Engine.RegisterGlobal("ChangeEntityTemplate", ChangeEntityTemplate);
TS_ASSERT_EQUALS(cmpPromotion.GetCurrentXp(), 0);
cmpPromotion.IncreaseXp(200);
TS_ASSERT_EQUALS(cmpPromotion.GetCurrentXp(), 200);
cmpPromotion.IncreaseXp(800);
TS_ASSERT_EQUALS(cmpPromotion.entity, 61);
TS_ASSERT_EQUALS(cmpPromotion.GetCurrentXp(), 0);
TS_ASSERT_EQUALS(cmpPromotion.GetRequiredXp(), 1000);
cmpPromotion.IncreaseXp(4200);
TS_ASSERT_EQUALS(cmpPromotion.entity, 62);
TS_ASSERT_EQUALS(cmpPromotion.template.Entity, "end");
TS_ASSERT_EQUALS(cmpPromotion.GetCurrentXp(), 200);
})();

View File

@ -75,6 +75,20 @@ function ChangeEntityTemplate(oldEnt, newTemplate)
} }
} }
let cmpPromotion = Engine.QueryInterface(oldEnt, IID_Promotion);
let cmpNewPromotion = Engine.QueryInterface(newEnt, IID_Promotion);
if (cmpPromotion && cmpNewPromotion)
cmpNewPromotion.IncreaseXp(cmpPromotion.GetCurrentXp());
let cmpResGatherer = Engine.QueryInterface(oldEnt, IID_ResourceGatherer);
let cmpNewResGatherer = Engine.QueryInterface(newEnt, IID_ResourceGatherer);
if (cmpResGatherer && cmpNewResGatherer)
{
let carriedResources = cmpResGatherer.GetCarryingStatus();
cmpNewResGatherer.GiveResources(carriedResources);
}
// Maintain the list of guards // Maintain the list of guards
let cmpGuard = Engine.QueryInterface(oldEnt, IID_Guard); let cmpGuard = Engine.QueryInterface(oldEnt, IID_Guard);
let cmpNewGuard = Engine.QueryInterface(newEnt, IID_Guard); let cmpNewGuard = Engine.QueryInterface(newEnt, IID_Guard);