1
1
forked from 0ad/0ad

Units promotion. Closes #697.

This was SVN commit r9391.
This commit is contained in:
fcxSanya 2011-05-02 15:03:01 +00:00
parent e8a2ed69f7
commit 7499b23991
84 changed files with 479 additions and 115 deletions

View File

@ -25,7 +25,7 @@
<animation file="infantry/general/forage.psa" name="gather_meat" speed="110"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_rock" speed="250"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_ore" speed="250"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_ruins" speed="250"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_ruins" speed="250"/>
<animation event="0.6" file="infantry/general/dude/dudebuild.psa" name="Build" speed="220"/>
<animation file="infantry/general/death/inf_01.psa" name="Death" speed="400"/>
<animation file="infantry/general/death/inf_02.psa" name="Death" speed="700"/>
@ -33,6 +33,7 @@
<animation file="infantry/general/death/inf_04.psa" name="Death" speed="400"/>
<animation file="infantry/general/death/inf_06.psa" name="Death" speed="500"/>
<animation file="infantry/general/death/inf_07.psa" name="Death" speed="400"/>
<animation file="biped/inf_salute_c.psa" name="Promotion" speed="288"/>
</animations>
<mesh>skeletal/m_pants.dae</mesh>
<props>
@ -135,7 +136,7 @@
<prop actor="props/units/tools/pick.xml" attachpoint="l_hand"/>
</props>
</variant>
<variant name="gather_ruins">
<variant name="gather_ruins">
<props>
<prop attachpoint="shield"/>
<prop attachpoint="r_hand"/>

View File

@ -23,7 +23,7 @@
<animation file="infantry/general/forage.psa" name="gather_meat" speed="110"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_rock" speed="250"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_ore" speed="250"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_ruins" speed="250"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_ruins" speed="250"/>
<animation event="0.6" file="infantry/general/dude/dudebuild.psa" name="Build" speed="220"/>
<animation file="infantry/general/death/inf_01.psa" name="Death" speed="400"/>
<animation file="infantry/general/death/inf_02.psa" name="Death" speed="700"/>
@ -31,6 +31,7 @@
<animation file="infantry/general/death/inf_04.psa" name="Death" speed="400"/>
<animation file="infantry/general/death/inf_06.psa" name="Death" speed="500"/>
<animation file="infantry/general/death/inf_07.psa" name="Death" speed="400"/>
<animation file="biped/inf_salute_c.psa" name="Promotion" speed="288"/>
</animations>
<mesh>skeletal/m_tights.dae</mesh>
<props>
@ -119,7 +120,7 @@
<prop attachpoint="helmet"/>
</props>
</variant>
<variant name="gather_ruins">
<variant name="gather_ruins">
<props>
<prop attachpoint="shield"/>
<prop attachpoint="r_hand"/>

View File

@ -22,7 +22,7 @@
<animation file="infantry/general/forage.psa" name="gather_meat" speed="110"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_rock" speed="250"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_ore" speed="250"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_ruins" speed="250"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_ruins" speed="250"/>
<animation event="0.6" file="infantry/general/dude/dudebuild.psa" name="Build" speed="220"/>
<animation file="infantry/general/death/inf_01.psa" name="Death" speed="400"/>
<animation file="infantry/general/death/inf_02.psa" name="Death" speed="700"/>
@ -30,6 +30,7 @@
<animation file="infantry/general/death/inf_04.psa" name="Death" speed="400"/>
<animation file="infantry/general/death/inf_06.psa" name="Death" speed="500"/>
<animation file="infantry/general/death/inf_07.psa" name="Death" speed="400"/>
<animation file="biped/inf_salute_c.psa" name="Promotion" speed="288"/>
</animations>
<mesh>skeletal/m_pants_celt.dae</mesh>
<props>
@ -127,7 +128,7 @@
<prop actor="props/units/tools/pick.xml" attachpoint="l_hand"/>
</props>
</variant>
<variant name="gather_ruins">
<variant name="gather_ruins">
<props>
<prop attachpoint="shield"/>
<prop attachpoint="r_hand"/>

View File

@ -23,7 +23,7 @@
<animation file="infantry/general/forage.psa" name="gather_meat" speed="110"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_rock" speed="250"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_ore" speed="250"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_ruins" speed="250"/>
<animation event="0.43" file="infantry/general/mine.psa" name="gather_ruins" speed="250"/>
<animation event="0.6" file="infantry/general/dude/dudebuild.psa" name="Build" speed="220"/>
<animation file="infantry/general/death/inf_01.psa" name="Death" speed="400"/>
<animation file="infantry/general/death/inf_02.psa" name="Death" speed="700"/>
@ -31,6 +31,7 @@
<animation file="infantry/general/death/inf_04.psa" name="Death" speed="400"/>
<animation file="infantry/general/death/inf_06.psa" name="Death" speed="500"/>
<animation file="infantry/general/death/inf_07.psa" name="Death" speed="400"/>
<animation file="biped/inf_salute_c.psa" name="Promotion" speed="288"/>
</animations>
<mesh>skeletal/m_pants_celt.dae</mesh>
<props>

View File

@ -4,11 +4,11 @@
<group>
<variant frequency="1" name="Base">
<animations>
<animation file="biped/not used/inf_salute_a.psa" name="Idle" speed="302"/>
<animation file="biped/not used/inf_salute_b.psa" name="Idle" speed="291"/>
<animation file="biped/not used/inf_salute_c.psa" name="Idle" speed="288"/>
<animation file="biped/not used/inf_salute_d.psa" name="Idle" speed="296"/>
<animation file="biped/not used/inf_salute_e.psa" name="Idle" speed="311"/>
<animation file="biped/inf_salute_a.psa" name="Idle" speed="302"/>
<animation file="biped/inf_salute_b.psa" name="Idle" speed="291"/>
<animation file="biped/inf_salute_c.psa" name="Idle" speed="288"/>
<animation file="biped/inf_salute_d.psa" name="Idle" speed="296"/>
<animation file="biped/inf_salute_e.psa" name="Idle" speed="311"/>
<animation file="biped/walk_spearshield.psa" name="Walk" speed="120"/>
<animation file="infantry/sword/move/run/isw_s_off_01.psa" name="Run" speed="40"/>
<animation event="0.5" file="infantry/sword/attack/isw_s_em_04.psa" name="Attack" speed="80"/>

View File

@ -28,6 +28,7 @@
<animation file="infantry/general/death/inf_04.psa" name="Death" speed="400"/>
<animation file="infantry/general/death/inf_06.psa" name="Death" speed="500"/>
<animation file="infantry/general/death/inf_07.psa" name="Death" speed="400"/>
<animation file="biped/inf_salute_c.psa" name="Promotion" speed="288"/>
</animations>
<mesh>skeletal/m_tunic_short.dae</mesh>
<props>

View File

@ -27,6 +27,7 @@
<animation file="infantry/general/death/inf_04.psa" name="Death" speed="400"/>
<animation file="infantry/general/death/inf_06.psa" name="Death" speed="500"/>
<animation file="infantry/general/death/inf_07.psa" name="Death" speed="400"/>
<animation file="biped/inf_salute_c.psa" name="Promotion" speed="288"/>
</animations>
<mesh>skeletal/m_tunic_long.dae</mesh>
<props>

View File

@ -27,9 +27,10 @@
<animation file="infantry/general/death/inf_02.psa" name="Death" speed="700"/>
<animation file="infantry/general/death/inf_03.psa" name="Death" speed="500"/>
<animation file="infantry/general/death/inf_04.psa" name="Death" speed="400"/>
<animation file="infantry/general/death/inf_05.psa" name="Death" speed="600"/>
<animation file="infantry/general/death/inf_05.psa" name="Death" speed="600"/>
<animation file="infantry/general/death/inf_06.psa" name="Death" speed="500"/>
<animation file="infantry/general/death/inf_07.psa" name="Death" speed="400"/>
<animation file="biped/inf_salute_c.psa" name="Promotion" speed="288"/>
</animations>
<props>
<prop actor="props/units/heads/floppy_b.xml" attachpoint="helmet"/>
@ -61,7 +62,7 @@
<variant name="Melee">
<props>
<prop attachpoint="r_hand"/>
<prop actor="props/units/weapons/jav.xml" attachpoint="l_hand"/>
<prop actor="props/units/weapons/jav.xml" attachpoint="l_hand"/>
<prop actor="props/units/weapons/jav.xml" attachpoint="loaded-r_hand"/>
<prop actor="props/units/weapons/jav_projectile.xml" attachpoint="projectile"/>
</props>
@ -69,23 +70,23 @@
<variant name="gather_tree">
<props>
<prop attachpoint="helmet"/>
<prop actor="" attachpoint="shield"/>
<prop actor="" attachpoint="r_hand"/>
<prop actor="" attachpoint="shield"/>
<prop actor="" attachpoint="r_hand"/>
<prop actor="props/units/tools/axe.xml" attachpoint="l_hand"/>
</props>
</variant>
<variant name="gather_grain">
<props>
<prop attachpoint="helmet"/>
<prop attachpoint="shield"/>
<prop attachpoint="shield"/>
<prop actor="props/units/tools/hoe.xml" attachpoint="l_hand"/>
</props>
</variant>
<variant name="gather_fruit">
<props>
<prop attachpoint="helmet"/>
<prop attachpoint="shield"/>
<prop attachpoint="r_hand"/>
<prop attachpoint="shield"/>
<prop attachpoint="r_hand"/>
<prop attachpoint="l_hand"/>
<prop actor="props/units/tools/basket.xml" attachpoint="l_leg"/>
</props>
@ -93,7 +94,7 @@
<variant name="gather_meat">
<props>
<prop attachpoint="helmet"/>
<prop attachpoint="shield"/>
<prop attachpoint="shield"/>
<prop attachpoint="r_hand"/>
<prop attachpoint="l_hand"/>
<prop actor="props/units/tools/basket.xml" attachpoint="l_leg"/>
@ -102,25 +103,25 @@
<variant name="gather_rock">
<props>
<prop attachpoint="helmet"/>
<prop actor="" attachpoint="shield"/>
<prop actor="" attachpoint="r_hand"/>
<prop actor="" attachpoint="shield"/>
<prop actor="" attachpoint="r_hand"/>
<prop actor="props/units/tools/pick.xml" attachpoint="l_hand"/>
</props>
</variant>
<variant name="gather_ore">
<props>
<prop attachpoint="helmet"/>
<prop attachpoint="shield"/>
<prop attachpoint="r_hand"/>
<prop attachpoint="shield"/>
<prop attachpoint="r_hand"/>
<prop actor="props/units/tools/pick.xml" attachpoint="l_hand"/>
<prop attachpoint=""/>
</props>
</variant>
<variant name="gather_ruins">
<variant name="gather_ruins">
<props>
<prop attachpoint="helmet"/>
<prop attachpoint="shield"/>
<prop attachpoint="r_hand"/>
<prop attachpoint="shield"/>
<prop attachpoint="r_hand"/>
<prop actor="props/units/tools/pick.xml" attachpoint="l_hand"/>
<prop attachpoint=""/>
</props>
@ -128,7 +129,7 @@
<variant name="Build">
<props>
<prop attachpoint="helmet"/>
<prop attachpoint="shield"/>
<prop attachpoint="shield"/>
<prop attachpoint="l_hand"/>
<prop actor="props/units/tools/mallet.xml" attachpoint="r_hand"/>
</props>

View File

@ -30,6 +30,7 @@
<animation file="infantry/general/death/inf_05.psa" name="Death" speed="600"/>
<animation file="infantry/general/death/inf_06.psa" name="Death" speed="500"/>
<animation file="infantry/general/death/inf_07.psa" name="Death" speed="400"/>
<animation file="biped/inf_salute_c.psa" name="Promotion" speed="288"/>
</animations>
<mesh>skeletal/m_tunic_long.dae</mesh>
<props>

View File

@ -27,6 +27,7 @@
<animation file="infantry/general/death/inf_04.psa" name="Death" speed="400"/>
<animation file="infantry/general/death/inf_06.psa" name="Death" speed="500"/>
<animation file="infantry/general/death/inf_07.psa" name="Death" speed="400"/>
<animation file="biped/inf_salute_c.psa" name="Promotion" speed="288"/>
</animations>
<mesh>skeletal/m_tunic_short.dae</mesh>
<props>

View File

@ -27,6 +27,7 @@
<animation file="infantry/general/death/inf_04.psa" name="Death" speed="400"/>
<animation file="infantry/general/death/inf_06.psa" name="Death" speed="500"/>
<animation file="infantry/general/death/inf_07.psa" name="Death" speed="400"/>
<animation file="biped/inf_salute_c.psa" name="Promotion" speed="288"/>
</animations>
<mesh>skeletal/m_tunic_short.dae</mesh>
<props>

View File

@ -203,6 +203,7 @@ EntitySelection.prototype.getTemplateNames = function()
// Update the selection to take care of changes (like units that have been killed)
EntitySelection.prototype.update = function()
{
this.checkRenamedEntities();
for each (var ent in this.selected)
{
var entState = GetEntityState(ent);
@ -231,6 +232,30 @@ EntitySelection.prototype.update = function()
}
};
/**
* Update selection if some selected entities was renamed
* (in case of unit promotion or finishing building structure)
*/
EntitySelection.prototype.checkRenamedEntities = function()
{
var renamedEntities = Engine.GuiInterfaceCall("GetRenamedEntities", true);
if (renamedEntities.length > 0)
{
var removeFromSelectionList = [];
var addToSelectionList = [];
for each (var renamedEntity in renamedEntities)
{
if (this.selected[renamedEntity.entity])
{
removeFromSelectionList.push(renamedEntity.entity);
addToSelectionList.push(renamedEntity.newentity);
}
}
this.removeList(removeFromSelectionList);
this.addList(addToSelectionList);
}
}
EntitySelection.prototype.addList = function(ents)
{
var selectionSize = this.toList().length;

View File

@ -65,6 +65,25 @@ function displaySingle(entState, template)
{
getGUIObjectByName("health").hidden = true;
}
// Experience
if (entState.promotion)
{
var experienceBar = getGUIObjectByName("experienceBar");
var experienceSize = experienceBar.size;
experienceSize.rtop = 100 - 100 * Math.max(0, Math.min(1, 1.0 * entState.promotion.curr / entState.promotion.req));
experienceBar.size = experienceSize;
var experience = "[font=\"serif-bold-13\"]XP [/font]" + entState.promotion.curr;
if (entState.promotion.curr < entState.promotion.req)
experience += "/" + entState.promotion.req;
getGUIObjectByName("experience").tooltip = experience;
getGUIObjectByName("experience").hidden = false;
}
else
{
getGUIObjectByName("experience").hidden = true;
}
// Resource stats
var resources = "";
@ -256,7 +275,7 @@ function updateSelectionDetails()
supplementalDetailsPanel.hidden = false;
detailsPanel.hidden = false;
commandsPanel.hidden = false;
// Fill out commands panel for specific unit selected (or first unit of primary group)
updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, selection);
}

View File

@ -538,6 +538,13 @@
<object type="image" sprite="resourceForeground" ghost="true" name="resourceBar"/>
<object type="image" sprite="statsBarShader" ghost="true"/>
</object>
<!-- Experience bar -->
<object size="46 0 58 100%" type="image" name="experience" tooltip="XP" tooltip_style="snToolTip">
<object type="image" sprite="experienceBackground" ghost="true"/>
<object type="image" sprite="experienceForeground" ghost="true" name="experienceBar"/>
<object type="image" sprite="statsBarShader" ghost="true"/>
</object>
</object>
<!-- Specific Name -->

View File

@ -714,6 +714,14 @@
<sprite name="staminaForeground">
<image backcolor="blue"/>
</sprite>
<sprite name="experienceBackground">
<image backcolor="darkgray"/>
</sprite>
<sprite name="experienceForeground">
<image backcolor="white"/>
</sprite>
<!-- ================================ ================================ -->
<!-- Chat -->

View File

@ -19,12 +19,20 @@ Armour.prototype.Schema =
Armour.prototype.Init = function()
{
this.invulnerable = false;
};
Armour.prototype.Serialize = null; // we have no dynamic state to save
Armour.prototype.SetInvulnerability = function(invulnerability)
{
this.invulnerable = invulnerability;
};
Armour.prototype.TakeDamage = function(hack, pierce, crush)
{
if (this.invulnerable)
return { "killed": false };
// Adjust damage values based on armour
var adjHack = Math.max(0, hack - this.template.Hack);
var adjPierce = Math.max(0, pierce - this.template.Pierce);

View File

@ -211,7 +211,6 @@ Attack.prototype.PerformAttack = function(type, target)
/**
* Called when some units kills something (another unit, building, animal etc)
* update player statistics only for now
*/
Attack.prototype.TargetKilled = function(killerEntity, targetEntity)
{
@ -219,6 +218,13 @@ Attack.prototype.TargetKilled = function(killerEntity, targetEntity)
if (cmpKillerPlayerStatisticsTracker) cmpKillerPlayerStatisticsTracker.KilledEntity(targetEntity);
var cmpTargetPlayerStatisticsTracker = QueryOwnerInterface(targetEntity, IID_StatisticsTracker);
if (cmpTargetPlayerStatisticsTracker) cmpTargetPlayerStatisticsTracker.LostEntity(targetEntity);
// if unit can collect loot, lets try to collect it
var cmpLooter = Engine.QueryInterface(killerEntity, IID_Looter);
if (cmpLooter)
{
cmpLooter.Collect(targetEntity);
}
}
/**

View File

@ -599,6 +599,20 @@ Formation.prototype.OnGlobalOwnershipChanged = function(msg)
this.RemoveMembers([msg.entity]);
};
Formation.prototype.OnGlobalEntityRenamed = function(msg)
{
if (this.members.indexOf(msg.entity) != -1)
{
this.members[this.members.indexOf(msg.entity)] = msg.newentity;
var cmpOldUnitAI = Engine.QueryInterface(msg.entity, IID_UnitAI);
cmpOldUnitAI.SetFormationController(INVALID_ENTITY);
var cmpNewUnitAI = Engine.QueryInterface(msg.newentity, IID_UnitAI);
cmpNewUnitAI.SetFormationController(this.entity);
}
}
Formation.prototype.LoadFormation = function(formationName)
{
this.formationName = formationName;

View File

@ -185,7 +185,7 @@ Foundation.prototype.Build = function(builderEnt, work)
var cmpPlayerStatisticsTracker = QueryOwnerInterface(this.entity, IID_StatisticsTracker);
cmpPlayerStatisticsTracker.IncreaseConstructedBuildingsCounter();
var cmpIdentity = Engine.QueryInterface(building, IID_Identity);
if (cmpIdentity.GetClassesList().indexOf("CivCentre") != -1) cmpPlayerStatisticsTracker.IncreaseBuiltCivCentresCounter();
@ -196,6 +196,8 @@ Foundation.prototype.Build = function(builderEnt, work)
Engine.PostMessage(this.entity, MT_ConstructionFinished,
{ "entity": this.entity, "newentity": building });
Engine.BroadcastMessage(MT_EntityRenamed, { entity: this.entity, newentity: building });
Engine.DestroyEntity(this.entity);
}
};

View File

@ -288,4 +288,12 @@ GarrisonHolder.prototype.OnDestroy = function()
}
};
GarrisonHolder.prototype.OnGlobalEntityRenamed = function(msg)
{
if (this.entities.indexOf(msg.entity) != -1)
{
this.entities[this.entities.indexOf(msg.entity)] = msg.newentity;
}
}
Engine.RegisterComponentType(IID_GarrisonHolder, "GarrisonHolder", GarrisonHolder);

View File

@ -20,6 +20,7 @@ GuiInterface.prototype.Init = function()
this.placementEntity = undefined; // = undefined or [templateName, entityID]
this.rallyPoints = undefined;
this.notifications = [];
this.renamedEntities = [];
};
/*
@ -91,6 +92,14 @@ GuiInterface.prototype.GetExtendedSimulationState = function(player)
return ret;
};
GuiInterface.prototype.GetRenamedEntities = function(player, clearList)
{
var result = this.renamedEntities;
if (clearList)
this.renamedEntities = [];
return result;
};
GuiInterface.prototype.GetEntityState = function(player, ent)
{
var cmpTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
@ -210,6 +219,15 @@ GuiInterface.prototype.GetEntityState = function(player, ent)
};
}
var cmpPromotion = Engine.QueryInterface(ent, IID_Promotion);
if (cmpPromotion)
{
ret.promotion = {
"curr": cmpPromotion.GetCurrentXp(),
"req": cmpPromotion.GetRequiredXp()
};
}
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
ret.visibility = cmpRangeManager.GetLosVisibility(ent, player);
@ -502,6 +520,11 @@ GuiInterface.prototype.SetRangeDebugOverlay = function(player, enabled)
cmpRangeManager.SetDebugOverlay(enabled);
};
GuiInterface.prototype.OnGlobalEntityRenamed = function(msg)
{
this.renamedEntities.push(msg);
}
// List the GuiInterface functions that can be safely called by GUI scripts.
// (GUI scripts are non-deterministic and untrusted, so these functions must be
// appropriately careful. They are called with a first argument "player", which is
@ -511,6 +534,7 @@ var exposedFunctions = {
"GetSimulationState": 1,
"GetExtendedSimulationState": 1,
"GetRenamedEntities": 1,
"GetEntityState": 1,
"GetTemplateData": 1,
"GetNextNotification": 1,

View File

@ -118,9 +118,7 @@ Identity.prototype.GetCiv = function()
Identity.prototype.GetRank = function()
{
if (this.template.Rank)
return this.template.Rank;
return "";
return (this.template.Rank || "");
};
Identity.prototype.GetClassesList = function()

View File

@ -17,10 +17,21 @@ Loot.prototype.Schema =
"<element name='metal'><data type='nonNegativeInteger'/></element>" +
"</optional>";
/*
* TODO: this all needs to be designed and implemented
*/
Loot.prototype.Serialize = null; // we have no dynamic state to save
Loot.prototype.GetXp = function()
{
return this.template.xp;
};
Loot.prototype.GetResources = function()
{
return {
"food": +(this.template.food || 0),
"wood": +(this.template.wood || 0),
"metal": +(this.template.metal || 0),
"stone": +(this.template.stone || 0)
};
};
Engine.RegisterComponentType(IID_Loot, "Loot", Loot);

View File

@ -2,10 +2,26 @@ function Looter() {}
Looter.prototype.Schema =
"<empty/>";
/*
* TODO: this all needs to be designed and implemented
/**
* Try to collect loot from target entity
*/
Looter.prototype.Collect = function(targetEntity)
{
var cmpLoot = Engine.QueryInterface(targetEntity, IID_Loot);
if (!cmpLoot)
return;
var xp = cmpLoot.GetXp();
if (xp > 0)
{
var cmpPromotion = Engine.QueryInterface(this.entity, IID_Promotion);
if (cmpPromotion)
cmpPromotion.IncreaseXp(xp);
}
var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
cmpPlayer.AddResources(cmpLoot.GetResources());
}
Engine.RegisterComponentType(IID_Looter, "Looter", Looter);

View File

@ -4,12 +4,95 @@ Promotion.prototype.Schema =
"<element name='Entity'>" +
"<text/>" +
"</element>" +
"<element name='Req'>" +
"<element name='RequiredXp'>" +
"<data type='positiveInteger'/>" +
"</element>";
/*
* TODO: this all needs to be designed and implemented
*/
Promotion.prototype.Init = function()
{
this.currentXp = 0;
}
Promotion.prototype.GetRequiredXp = function()
{
return +(this.template.RequiredXp);
};
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());
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.Cheer();
var orders = cmpCurrentUnitAI.GetOrders();
cmpPromotedUnitAI.AddOrders(orders);
Engine.BroadcastMessage(MT_EntityRenamed, { entity: this.entity, newentity: promotedUnitEntity });
// Destroy current entity
Engine.DestroyEntity(this.entity);
}
Promotion.prototype.IncreaseXp = function(amount)
{
this.currentXp += +(amount);
if (this.currentXp >= this.template.RequiredXp)
{
var promotionTemplate = this.template;
do
{
this.currentXp -= promotionTemplate.RequiredXp;
var promotedTemplateName = promotionTemplate.Entity;
var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
var template = cmpTemplateManager.GetTemplate(promotedTemplateName);
promotionTemplate = template.Promotion || null;
}
while (promotionTemplate != null && this.currentXp >= promotionTemplate.RequiredXp);
this.Promote(promotedTemplateName);
}
}
Engine.RegisterComponentType(IID_Promotion, "Promotion", Promotion);

View File

@ -85,6 +85,18 @@ ResourceGatherer.prototype.GetCarryingStatus = function()
return ret;
};
/**
* Used to instantly give resources to unit
* @param resources The same structure as returned form GetCarryingStatus
*/
ResourceGatherer.prototype.GiveResources = function(resources)
{
for each (var resource in resources)
{
this.carrying[resource.type] = +(resource.amount);
}
};
/**
* Returns the generic type of one particular resource this unit is
* currently carrying, or undefined if none.

View File

@ -110,6 +110,10 @@ var UnitFsmSpec = {
// ignore
},
"EntityRenamed": function(msg) {
// ignore
},
// Formation handlers:
"FormationLeave": function(msg) {
@ -305,6 +309,10 @@ var UnitFsmSpec = {
this.SetNextState("INDIVIDUAL.GARRISON.GARRISONED");
}
},
"Order.Cheering": function(msg) {
this.SetNextState("INDIVIDUAL.CHEERING");
},
// States for the special entity representing a group of units moving in formation:
"FORMATIONCONTROLLER": {
@ -533,6 +541,11 @@ var UnitFsmSpec = {
},
"COMBAT": {
"EntityRenamed": function(msg) {
if (this.order.data.target == msg.entity)
this.order.data.target = msg.newentity;
},
"Attacked": function(msg) {
// If we're already in combat mode, ignore anyone else
// who's attacking us
@ -980,6 +993,26 @@ var UnitFsmSpec = {
},
},
"CHEERING": {
"enter": function() {
// Unit is invulnerable while cheering
var cmpDamageReceiver = Engine.QueryInterface(this.entity, IID_DamageReceiver);
cmpDamageReceiver.SetInvulnerability(true);
this.SelectAnimation("promotion");
this.StartTimer(4000, 4000);
return false;
},
"leave": function() {
this.StopTimer();
var cmpDamageReceiver = Engine.QueryInterface(this.entity, IID_DamageReceiver);
cmpDamageReceiver.SetInvulnerability(false);
},
"Timer": function(msg) {
this.FinishOrder();
},
},
},
"ANIMAL": {
@ -1323,18 +1356,49 @@ UnitAI.prototype.PushOrder = function(type, data)
UnitAI.prototype.PushOrderFront = function(type, data)
{
var order = { "type": type, "data": data };
this.orderQueue.unshift(order);
this.order = order;
UnitFsm.ProcessMessage(this, {"type": "Order."+this.order.type, "data": this.order.data});
// If current order is cheering then add new order after it
if (this.order && this.order.type == "Cheering")
{
var cheeringOrder = this.orderQueue.shift();
this.orderQueue.unshift(cheeringOrder, order);
}
else
{
this.orderQueue.unshift(order);
this.order = order;
UnitFsm.ProcessMessage(this, {"type": "Order."+this.order.type, "data": this.order.data});
}
};
UnitAI.prototype.ReplaceOrder = function(type, data)
{
this.orderQueue = [];
this.PushOrder(type, data);
// If current order is cheering then add new order after it
if (this.order && this.order.type == "Cheering")
{
var order = { "type": type, "data": data };
var cheeringOrder = this.orderQueue.shift();
this.orderQueue = [ cheeringOrder, order ];
}
else
{
this.orderQueue = [];
this.PushOrder(type, data);
}
};
UnitAI.prototype.GetOrders = function()
{
return this.orderQueue.slice();
}
UnitAI.prototype.AddOrders = function(orders)
{
for each (var order in orders)
{
this.PushOrder(order.type, order.data);
}
}
UnitAI.prototype.TimerHandler = function(data, lateness)
{
// Reset the timer
@ -1402,6 +1466,11 @@ UnitAI.prototype.OnGlobalConstructionFinished = function(msg)
UnitFsm.ProcessMessage(this, {"type": "ConstructionFinished", "data": msg});
};
UnitAI.prototype.OnGlobalEntityRenamed = function(msg)
{
UnitFsm.ProcessMessage(this, {"type": "EntityRenamed", "entity": msg.entity, "newentity": msg.newentity});
}
UnitAI.prototype.OnAttacked = function(msg)
{
UnitFsm.ProcessMessage(this, {"type": "Attacked", "data": msg});
@ -1918,6 +1987,11 @@ UnitAI.prototype.Repair = function(target, autocontinue, queued)
this.AddOrder("Repair", { "target": target, "autocontinue": autocontinue }, queued);
};
UnitAI.prototype.Cheer = function()
{
this.AddOrder("Cheering", null, false);
};
UnitAI.prototype.SetStance = function(stance)
{
if (g_Stances[stance])

View File

@ -5,6 +5,7 @@ Engine.LoadComponentScript("interfaces/Foundation.js");
Engine.LoadComponentScript("interfaces/GarrisonHolder.js");
Engine.LoadComponentScript("interfaces/Health.js");
Engine.LoadComponentScript("interfaces/Identity.js");
Engine.LoadComponentScript("interfaces/Promotion.js");
Engine.LoadComponentScript("interfaces/RallyPoint.js");
Engine.LoadComponentScript("interfaces/ResourceDropsite.js");
Engine.LoadComponentScript("interfaces/ResourceGatherer.js");

View File

@ -92,6 +92,7 @@
<RetainInFog>false</RetainInFog>
<AlwaysVisible>false</AlwaysVisible>
</Vision>
<Looter/>
<VisualActor>
<SilhouetteDisplay>true</SilhouetteDisplay>
<SilhouetteOccluder>false</SilhouetteOccluder>

View File

@ -3,10 +3,10 @@
<Identity>
<GenericName>Cavalry</GenericName>
<Classes datatype="tokens">Cavalry CitizenSoldier Organic</Classes>
<Rank>Basic</Rank>
<Rank>Basic</Rank>
</Identity>
<Promotion>
<Req>900</Req>
<RequiredXp>900</RequiredXp>
</Promotion>
<Position>
<Anchor>pitch</Anchor>

View File

@ -3,10 +3,10 @@
<Identity>
<GenericName>Infantry</GenericName>
<Classes datatype="tokens">Infantry CitizenSoldier Organic</Classes>
<Rank>Basic</Rank>
<Rank>Basic</Rank>
</Identity>
<Promotion>
<Req>600</Req>
<RequiredXp>600</RequiredXp>
</Promotion>
<Cost>
<BuildTime>9</BuildTime>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/celt_cavalry_javelinist_b">
<Identity>
<Rank>Advanced</Rank>
<Rank>Advanced</Rank>
</Identity>
<Promotion>
<Entity>celt_cavalry_javelinist_e</Entity>
<Entity>units/celt_cavalry_javelinist_e</Entity>
</Promotion>
<ResourceGatherer>
<BaseSpeed>0.75</BaseSpeed>

View File

@ -8,7 +8,7 @@
<Icon>units/celt_cavalry_javelinist.png</Icon>
</Identity>
<Promotion>
<Entity>celt_cavalry_javelinist_a</Entity>
<Entity>units/celt_cavalry_javelinist_a</Entity>
</Promotion>
<Armour>
<Hack>2.0</Hack>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/celt_cavalry_javelinist_a">
<Identity>
<Rank>Elite</Rank>
<Rank>Elite</Rank>
</Identity>
<ResourceGatherer>
<BaseSpeed>0.5</BaseSpeed>
@ -29,4 +29,5 @@
<VisualActor>
<Actor>units/celts/cavalry_javelinist_e.xml</Actor>
</VisualActor>
<Promotion disable=""/>
</Entity>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/celt_cavalry_spearman_b">
<Identity>
<Rank>Advanced</Rank>
<Rank>Advanced</Rank>
</Identity>
<Promotion>
<Entity>celt_cavalry_spearman_e</Entity>
<Entity>units/celt_cavalry_spearman_e</Entity>
</Promotion>
<ResourceGatherer>
<BaseSpeed>0.75</BaseSpeed>

View File

@ -10,7 +10,7 @@
<Icon>units/celt_cavalry_spearman.png</Icon>
</Identity>
<Promotion>
<Entity>celt_cavalry_spearman_a</Entity>
<Entity>units/celt_cavalry_spearman_a</Entity>
</Promotion>
<Cost>
<BuildTime>10</BuildTime>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/celt_cavalry_spearman_a">
<Identity>
<Rank>Elite</Rank>
<Rank>Elite</Rank>
</Identity>
<ResourceGatherer>
<BaseSpeed>0.5</BaseSpeed>
@ -28,4 +28,5 @@
<VisualActor>
<Actor>units/celts/cavalry_spearman_e.xml</Actor>
</VisualActor>
<Promotion disable=""/>
</Entity>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/celt_cavalry_swordsman_b">
<Identity>
<Rank>Advanced</Rank>
<Rank>Advanced</Rank>
</Identity>
<Promotion>
<Entity>celt_cavalry_swordsman_e</Entity>
<Entity>units/celt_cavalry_swordsman_e</Entity>
</Promotion>
<ResourceGatherer>
<BaseSpeed>0.75</BaseSpeed>

View File

@ -8,7 +8,7 @@
<Icon>units/celt_cavalry_swordsman.png</Icon>
</Identity>
<Promotion>
<Entity>celt_cavalry_swordsman_a</Entity>
<Entity>units/celt_cavalry_swordsman_a</Entity>
</Promotion>
<Armour>
<Hack>3.0</Hack>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/celt_cavalry_swordsman_a">
<Identity>
<Rank>Elite</Rank>
<Rank>Elite</Rank>
</Identity>
<ResourceGatherer>
<BaseSpeed>0.5</BaseSpeed>
@ -31,4 +31,5 @@
<VisualActor>
<Actor>units/celts/cavalry_swordsman_e.xml</Actor>
</VisualActor>
<Promotion disable=""/>
</Entity>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/celt_infantry_javelinist_b">
<Identity>
<Rank>Advanced</Rank>
<Rank>Advanced</Rank>
</Identity>
<Promotion>
<Entity>celt_infantry_javelinist_e</Entity>
<Entity>units/celt_infantry_javelinist_e</Entity>
</Promotion>
<ResourceGatherer>
<BaseSpeed>0.75</BaseSpeed>

View File

@ -8,7 +8,7 @@
<Icon>units/celt_infantry_javelinist.png</Icon>
</Identity>
<Promotion>
<Entity>celt_infantry_javelinist_a</Entity>
<Entity>units/celt_infantry_javelinist_a</Entity>
</Promotion>
<Armour>
<Hack>2.0</Hack>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/celt_infantry_javelinist_a">
<Identity>
<Rank>Elite</Rank>
<Rank>Elite</Rank>
</Identity>
<ResourceGatherer>
<BaseSpeed>0.5</BaseSpeed>
@ -29,4 +29,5 @@
<VisualActor>
<Actor>units/celts/infantry_javelinist_e.xml</Actor>
</VisualActor>
<Promotion disable=""/>
</Entity>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/celt_infantry_spearman_b">
<Identity>
<Rank>Advanced</Rank>
<Rank>Advanced</Rank>
</Identity>
<Promotion>
<Entity>celt_infantry_spearman_e</Entity>
<Entity>units/celt_infantry_spearman_e</Entity>
</Promotion>
<ResourceGatherer>
<BaseSpeed>0.75</BaseSpeed>

View File

@ -8,7 +8,7 @@
<Icon>units/celt_infantry_spearman.png</Icon>
</Identity>
<Promotion>
<Entity>celt_infantry_spearman_a</Entity>
<Entity>units/celt_infantry_spearman_a</Entity>
</Promotion>
<Armour>
<Hack>3.0</Hack>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/celt_infantry_spearman_a">
<Identity>
<Rank>Elite</Rank>
<Rank>Elite</Rank>
</Identity>
<ResourceGatherer>
<BaseSpeed>0.5</BaseSpeed>
@ -33,4 +33,5 @@
<VisualActor>
<Actor>units/celts/infantry_spearman_e.xml</Actor>
</VisualActor>
<Promotion disable=""/>
</Entity>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/hele_cavalry_javelinist_b">
<Identity>
<Rank>Advanced</Rank>
<Rank>Advanced</Rank>
</Identity>
<Promotion>
<Entity>hele_cavalry_javelinist_e</Entity>
<Entity>units/hele_cavalry_javelinist_e</Entity>
</Promotion>
<ResourceGatherer>
<BaseSpeed>0.75</BaseSpeed>

View File

@ -8,7 +8,7 @@
<Icon>units/hele_cavalry_javelinist.png</Icon>
</Identity>
<Promotion>
<Entity>hele_cavalry_javelinist_a</Entity>
<Entity>units/hele_cavalry_javelinist_a</Entity>
</Promotion>
<Vision>
<Range>110</Range>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/hele_cavalry_javelinist_a">
<Identity>
<Rank>Elite</Rank>
<Rank>Elite</Rank>
</Identity>
<ResourceGatherer>
<BaseSpeed>0.5</BaseSpeed>
@ -29,5 +29,5 @@
<VisualActor>
<Actor>units/hellenes/cavalry_javelinist_e.xml</Actor>
</VisualActor>
<Promotion disable=""/>
</Entity>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/hele_cavalry_swordsman_b">
<Identity>
<Rank>Advanced</Rank>
<Rank>Advanced</Rank>
</Identity>
<Promotion>
<Entity>hele_cavalry_swordsman_e</Entity>
<Entity>units/hele_cavalry_swordsman_e</Entity>
</Promotion>
<ResourceGatherer>
<BaseSpeed>0.75</BaseSpeed>

View File

@ -8,7 +8,7 @@
<Icon>units/hele_cavalry_swordsman.png</Icon>
</Identity>
<Promotion>
<Entity>hele_cavalry_swordsman_a</Entity>
<Entity>units/hele_cavalry_swordsman_a</Entity>
</Promotion>
<Vision>
<Range>110</Range>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/hele_cavalry_swordsman_a">
<Identity>
<Rank>Elite</Rank>
<Rank>Elite</Rank>
</Identity>
<ResourceGatherer>
<BaseSpeed>0.5</BaseSpeed>
@ -31,5 +31,5 @@
<VisualActor>
<Actor>units/hellenes/cavalry_swordsman_e.xml</Actor>
</VisualActor>
<Promotion disable=""/>
</Entity>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/hele_infantry_archer_b">
<Identity>
<Rank>Advanced</Rank>
<Rank>Advanced</Rank>
</Identity>
<Promotion>
<Entity>hele_infantry_archer_e</Entity>
<Entity>units/hele_infantry_archer_e</Entity>
</Promotion>
<ResourceGatherer>
<BaseSpeed>0.75</BaseSpeed>

View File

@ -9,7 +9,7 @@
<Icon>units/hele_infantry_archer.png</Icon>
</Identity>
<Promotion>
<Entity>hele_infantry_archer_a</Entity>
<Entity>units/hele_infantry_archer_a</Entity>
</Promotion>
<Cost>
<Resources>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/hele_infantry_archer_a">
<Identity>
<Rank>Elite</Rank>
<Rank>Elite</Rank>
</Identity>
<ResourceGatherer>
<BaseSpeed>0.5</BaseSpeed>
@ -33,4 +33,5 @@
<VisualActor>
<Actor>units/hellenes/infantry_archer_e.xml</Actor>
</VisualActor>
<Promotion disable=""/>
</Entity>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/hele_infantry_javelinist_b">
<Identity>
<Rank>Advanced</Rank>
<Rank>Advanced</Rank>
</Identity>
<Promotion>
<Entity>hele_infantry_javelinist_e</Entity>
<Entity>units/hele_infantry_javelinist_e</Entity>
</Promotion>
<ResourceGatherer>
<BaseSpeed>0.75</BaseSpeed>

View File

@ -8,7 +8,7 @@
<Icon>units/hele_infantry_javelinist.png</Icon>
</Identity>
<Promotion>
<Entity>hele_infantry_javelinist_a</Entity>
<Entity>units/hele_infantry_javelinist_a</Entity>
</Promotion>
<Cost>
<Resources>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/hele_infantry_javelinist_a">
<Identity>
<Rank>Elite</Rank>
<Rank>Elite</Rank>
</Identity>
<ResourceGatherer>
<BaseSpeed>0.5</BaseSpeed>
@ -18,6 +18,7 @@
<VisualActor>
<Actor>units/hellenes/infantry_javelinist_e.xml</Actor>
</VisualActor>
<Promotion disable=""/>
<Health>
<Max>110</Max>
</Health>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/hele_infantry_spearman_b">
<Identity>
<Rank>Advanced</Rank>
<Rank>Advanced</Rank>
</Identity>
<Promotion>
<Entity>hele_infantry_spearman_e</Entity>
<Entity>units/hele_infantry_spearman_e</Entity>
</Promotion>
<ResourceGatherer>
<BaseSpeed>0.75</BaseSpeed>

View File

@ -8,7 +8,7 @@
<Icon>units/hele_infantry_spearman.png</Icon>
</Identity>
<Promotion>
<Entity>hele_infantry_spearman_a</Entity>
<Entity>units/hele_infantry_spearman_a</Entity>
</Promotion>
<Cost>
<Resources>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/hele_infantry_spearman_a">
<Identity>
<Rank>Elite</Rank>
<Rank>Elite</Rank>
</Identity>
<ResourceGatherer>
<BaseSpeed>0.5</BaseSpeed>
@ -33,5 +33,5 @@
<VisualActor>
<Actor>units/hellenes/infantry_spearman_e.xml</Actor>
</VisualActor>
<Promotion disable=""/>
</Entity>

View File

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/iber_cavalry_spearman_b">
<Identity>
<Rank>Advanced</Rank>
</Identity>
<Promotion>
<Entity>iber_cavalry_spearman_e</Entity>
<Entity>units/iber_cavalry_spearman_e</Entity>
</Promotion>
<VisualActor>
<Actor>units/iberians/cavalry_spearman_a.xml</Actor>

View File

@ -7,7 +7,7 @@
<History>Armed like the light infantry, Iberian cavalry were often pursued as mercenaries, especially by the Carthaginians. Mounted on excellent horses and wielding high-grade swords they were capable of taking on heavy or light cavalry. As with all Iberians armor was scarce, but they wore the ubiquitous sinew caps made famous by the peoples of the peninsula.</History>
</Identity>
<Promotion>
<Entity>iber_cavalry_spearman_a</Entity>
<Entity>units/iber_cavalry_spearman_a</Entity>
</Promotion>
<VisualActor>
<Actor>units/iberians/cavalry_spearman_b.xml</Actor>

View File

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/iber_cavalry_spearman_a">
<Identity>
<Rank>Elite</Rank>
</Identity>
<VisualActor>
<Actor>units/iberians/cavalry_spearman_e.xml</Actor>
</VisualActor>

View File

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/iber_infantry_javelinist_b">
<Identity>
<Rank>Advanced</Rank>
</Identity>
<Promotion>
<Entity>iber_infantry_javelinist_e</Entity>
<Entity>units/iber_infantry_javelinist_e</Entity>
</Promotion>
<VisualActor>
<Actor>units/iberians/infantry_javelinist_a.xml</Actor>

View File

@ -7,7 +7,7 @@
<Icon>units/cart_cavalry_javelinist.png</Icon>
</Identity>
<Promotion>
<Entity>iber_infantry_javelinist_a</Entity>
<Entity>units/iber_infantry_javelinist_a</Entity>
</Promotion>
<VisualActor>
<Actor>units/iberians/infantry_javelinist_b.xml</Actor>

View File

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/iber_infantry_javelinist_a">
<Identity>
<Rank>Elite</Rank>
</Identity>
<VisualActor>
<Actor>units/iberians/infantry_javelinist_e.xml</Actor>
</VisualActor>

View File

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/iber_infantry_slinger_b">
<Identity>
<Rank>Advanced</Rank>
</Identity>
<Promotion>
<Entity>iber_infantry_slinger_e</Entity>
<Entity>units/iber_infantry_slinger_e</Entity>
</Promotion>
<VisualActor>
<Actor>units/iberians/infantry_slinger_a.xml</Actor>

View File

@ -7,7 +7,7 @@
<History>Iberian slingers were the undisputed masters of the weapon and extracted a high toll of the enemy. Going into combat scantily clad at best, the slinger carried three slings tied around his waist, each of a different length allowing him to attack opponents from all ranges. Unlike other cultures, the Iberian slingers threw rocks instead of specially made lead shot.</History>
</Identity>
<Promotion>
<Entity>iber_infantry_slinger_a</Entity>
<Entity>units/iber_infantry_slinger_a</Entity>
</Promotion>
<VisualActor>
<Actor>units/iberians/infantry_slinger_b.xml</Actor>

View File

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/iber_infantry_slinger_a">
<Identity>
<Rank>Elite</Rank>
</Identity>
<VisualActor>
<Actor>units/iberians/infantry_slinger_e.xml</Actor>
</VisualActor>

View File

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/iber_infantry_spearman_b">
<Identity>
<Rank>Advanced</Rank>
</Identity>
<Promotion>
<Entity>iber_infantry_spearman_e</Entity>
<Entity>units/iber_infantry_spearman_e</Entity>
</Promotion>
<VisualActor>
<Actor>units/iberians/infantry_spearman_a.xml</Actor>

View File

@ -7,7 +7,7 @@
<History>A long-bladed spear was a chief melee weapon of the Iberian infantry, often used after the javelins had been thrown. Typically carried by infantry known as scutarii for their long oval body shields, the spearmen would close in formation to attack their opponents. Usually lightly armored, they were quick and had a ferocious reputation.</History>
</Identity>
<Promotion>
<Entity>iber_infantry_spearman_a</Entity>
<Entity>units/iber_infantry_spearman_a</Entity>
</Promotion>
<VisualActor>
<Actor>units/iberians/infantry_spearman_b.xml</Actor>

View File

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/iber_infantry_spearman_a">
<Identity>
<Rank>Elite</Rank>
</Identity>
<VisualActor>
<Actor>units/iberians/infantry_spearman_e.xml</Actor>
</VisualActor>

View File

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/iber_infantry_swordsman_b">
<Identity>
<Rank>Advanced</Rank>
</Identity>
<Promotion>
<Entity>iber_infantry_swordsman_e</Entity>
<Entity>units/iber_infantry_swordsman_e</Entity>
</Promotion>
<VisualActor>
<Actor>units/iberians/infantry_swordsman_a.xml</Actor>

View File

@ -7,7 +7,7 @@
<History>The Iberians were master sword-smiths and the falcata was their greatest creation. Wielded by superb swordsmen equipped with light armor and a buckler known as a caetra, they caused untold carnage. Thanks to this Iberian infantry were fast and agile unlike many of their opponents and could bite hard when they attacked. Their skill with sword and buckler were legendary, allowing them to go toe-to-toe with heavy infantry.</History>
</Identity>
<Promotion>
<Entity>iber_infantry_swordsman_a</Entity>
<Entity>units/iber_infantry_swordsman_a</Entity>
</Promotion>
<VisualActor>
<Actor>units/iberians/infantry_swordsman_b.xml</Actor>

View File

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Entity parent="units/iber_infantry_swordsman_a">
<Identity>
<Rank>Elite</Rank>
</Identity>
<VisualActor>
<Actor>units/iberians/infantry_swordsman_e.xml</Actor>
</VisualActor>

View File

@ -8,8 +8,8 @@
<Icon>units/macedonian_hypaspist.png</Icon>
</Identity>
<Promotion>
<Entity>mace_argyraspis</Entity>
<Req>500</Req>
<Entity>units/mace_argyraspis</Entity>
<RequiredXp>500</RequiredXp>
</Promotion>
<Cost>
<Resources>

View File

@ -8,8 +8,8 @@
<Icon>units/rome_super_legion_imperial.png</Icon>
</Identity>
<Promotion>
<Entity>rome_centurio_imperial</Entity>
<Req>700</Req>
<Entity>units/rome_centurio_imperial</Entity>
<RequiredXp>700</RequiredXp>
</Promotion>
<Armour>
<Hack>10.0</Hack>

View File

@ -9,8 +9,8 @@
<Icon>units/rome_super_legion_marian.png</Icon>
</Identity>
<Promotion>
<Entity>rome_legionnaire_imperial</Entity>
<Req>500</Req>
<Entity>units/rome_legionnaire_imperial</Entity>
<RequiredXp>500</RequiredXp>
</Promotion>
<VisualActor>
<Actor>units/romans/super_unit_3.xml</Actor>