0ad/binaries/data/mods/public/simulation/components/Promotion.js
Mythos_Ruler 4658cfa775 Mythos_Ruler's Christmas update for SVN users!
Includes:

- Unit rank upgrades, based on a patch by Sanderd. Not all civs get all
rank upgrades. For instance, Spartans get the Infantry rank upgrades,
but not the cavalry rank upgrades. Conversely, the Persians get the
cavalry rank upgrades, but not the infantry rank upgrades. Carthaginians
get rank upgrades for their mercenaries, but not their native units.
etc.

- Updated and tweaked many of the skirmish maps. Too many tweaks to
mention. But I did add Iberian circuit walls to many of them! New
"Bactria" Skirmish Map. Will continue to tweak this one to make it more
unique. It's based on modern-day Afghanistan, which the ancients called
"Bactria." A 2nd Ptolemies sandbox demo map.

- Moved the Ptolemaic Lighthouse to Town Phase to have more impact for
the Ptolemy player on maps with water.

- New Thureos shield patterns by Enrique for a NEW unit: Mercenary
Thureos Spearman.

- TECHNOLOGIES: Some techs renamed and tweaked. Plus, a new "Iron Armor"
tech for Heroes. A new "Roman Logistics" tech for the Roman Army Camp
and Siege Walls. A new "Battlefield Medics" tech for the temple that
unlocks (slow) health regeneration for units. The portrait for this tech
is placeholder and needs replaced ASAP.

- Cavalry now have oval selection rings. Eventually I will implement a
selection ring system where the citizen-soldiers and support units have
round rings, while champions have arrows, and heroes have stars. This
helps visually differentiate the roles of these 3 classes of units. Not
yet implemented.

- Vision radius for infantry slightly reduced.

- Fixed sounds for Persian Wonder.

- Fixed footprint sizes for a few buildings and Ptolemaic walls.

- Ptolemies now have the "Military Settlement" system in place. But this
system might go to the Seleucids instead later for historical reasons.

- Cost of fields reduced. Gathering rates for grain reduced.

- Fixed some selection group names for some templates. (Double clicking
didn't select them all as it should have).

- Fixed/Changed/Added some unit and building names, specifically for the
Ptolemies, but for some others as well.

- Some new temp portraits for Ptolemaic units. Ongoing task.

Lastly, I hope these changes don't break anything. They are heavily
tested on my end, but I can't promise I caught all bugs.

This was SVN commit r14388.
2013-12-25 15:49:49 +00:00

142 lines
5.3 KiB
JavaScript

function Promotion() {}
Promotion.prototype.Schema =
"<element name='Entity'>" +
"<text/>" +
"</element>" +
"<element name='RequiredXp'>" +
"<data type='positiveInteger'/>" +
"</element>";
Promotion.prototype.Init = function()
{
this.currentXp = 0;
};
Promotion.prototype.GetRequiredXp = function()
{
return ApplyValueModificationsToEntity("Promotion/RequiredXp", +this.template.RequiredXp, this.entity);
};
Promotion.prototype.GetCurrentXp = function()
{
return this.currentXp;
};
Promotion.prototype.GetPromotedTemplateName = function()
{
return this.template.Entity;
};
Promotion.prototype.Promote = function(promotedTemplateName)
{
// Create promoted unit entity
var promotedUnitEntity = Engine.AddEntity(promotedTemplateName);
// Copy parameters from current entity to promoted one
var cmpCurrentUnitPosition = Engine.QueryInterface(this.entity, IID_Position);
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);
var cmpPromotedUnitOwnership = Engine.QueryInterface(promotedUnitEntity, IID_Ownership);
cmpPromotedUnitOwnership.SetOwner(cmpCurrentUnitOwnership.GetOwner());
// change promoted unit health to the same percent of hitpoints as unit had before promotion
var cmpCurrentUnitHealth = Engine.QueryInterface(this.entity, IID_Health);
var cmpPromotedUnitHealth = Engine.QueryInterface(promotedUnitEntity, IID_Health);
var healthFraction = Math.max(0, Math.min(1, cmpCurrentUnitHealth.GetHitpoints() / cmpCurrentUnitHealth.GetMaxHitpoints()));
var promotedUnitHitpoints = Math.round(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);
cmpPromotedUnitAI.SetHeldPosition(cmpCurrentUnitAI.GetHeldPosition());
if (cmpCurrentUnitAI.GetStanceName())
cmpPromotedUnitAI.SwitchToStance(cmpCurrentUnitAI.GetStanceName());
cmpPromotedUnitAI.Cheer();
var orders = cmpCurrentUnitAI.GetOrders();
cmpPromotedUnitAI.AddOrders(orders);
var workOrders = cmpCurrentUnitAI.GetWorkOrders();
cmpPromotedUnitAI.SetWorkOrders(workOrders);
cmpPromotedUnitAI.SetGuardOf(cmpCurrentUnitAI.IsGuardOf());
var cmpCurrentUnitGuard = Engine.QueryInterface(this.entity, IID_Guard);
var cmpPromotedUnitGuard = Engine.QueryInterface(promotedUnitEntity, IID_Guard);
if (cmpCurrentUnitGuard && cmpPromotedUnitGuard)
cmpPromotedUnitGuard.SetEntities(cmpCurrentUnitGuard.GetEntities());
Engine.BroadcastMessage(MT_EntityRenamed, { entity: this.entity, newentity: promotedUnitEntity });
// Destroy current entity
Engine.DestroyEntity(this.entity);
// save the entity id
this.promotedUnitEntity = promotedUnitEntity;
};
Promotion.prototype.IncreaseXp = function(amount)
{
// if the unit was already promoted, but is waiting for the engine to be destroyed
// transfer the gained xp to the promoted unit if applicable
if (this.promotedUnitEntity)
{
var cmpPromotion = Engine.QueryInterface(this.promotedUnitEntity, IID_Promotion);
if (cmpPromotion)
cmpPromotion.IncreaseXp(amount);
return;
}
this.currentXp += +(amount);
var requiredXp = this.GetRequiredXp();
if (this.currentXp >= requiredXp)
{
var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
var playerID = QueryOwnerInterface(this.entity, IID_Player).GetPlayerID();
this.currentXp -= requiredXp;
var promotedTemplateName = this.GetPromotedTemplateName();
// check if we can upgrade a second time (or even more)
while (true)
{
var template = cmpTemplateManager.GetTemplate(promotedTemplateName);
if (!template.Promotion)
break;
requiredXp = ApplyValueModificationsToTemplate("Promotion/RequiredXp", +template.Promotion.RequiredXp, playerID, template);
// compare the current xp to the required xp of the promoted entity
if (this.currentXp < requiredXp)
break;
this.currentXp -= requiredXp;
promotedTemplateName = template.Promotion.Entity;
}
this.Promote(promotedTemplateName);
}
};
Promotion.prototype.OnValueModification = function(msg)
{
if (msg.component == "Promotion")
this.IncreaseXp(0);
};
Engine.RegisterComponentType(IID_Promotion, "Promotion", Promotion);