restore random arrows.
This commit is contained in:
parent
ce2febaeba
commit
e8ba5dffcf
File diff suppressed because it is too large
Load Diff
@ -22,42 +22,34 @@ BuildingAI.prototype.Schema =
|
|||||||
|
|
||||||
BuildingAI.prototype.MAX_PREFERENCE_BONUS = 2;
|
BuildingAI.prototype.MAX_PREFERENCE_BONUS = 2;
|
||||||
|
|
||||||
BuildingAI.prototype.Init = function()
|
BuildingAI.prototype.Init = function () {
|
||||||
{
|
|
||||||
this.currentRound = 0;
|
this.currentRound = 0;
|
||||||
this.archersGarrisoned = 0;
|
this.archersGarrisoned = 0;
|
||||||
this.arrowsLeft = 0;
|
this.arrowsLeft = 0;
|
||||||
this.targetUnits = [];
|
this.targetUnits = [];
|
||||||
this.focusTargets = [];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
BuildingAI.prototype.OnGarrisonedUnitsChanged = function(msg)
|
BuildingAI.prototype.OnGarrisonedUnitsChanged = function (msg) {
|
||||||
{
|
|
||||||
let classes = this.template.GarrisonArrowClasses;
|
let classes = this.template.GarrisonArrowClasses;
|
||||||
for (let ent of msg.added)
|
for (let ent of msg.added) {
|
||||||
{
|
|
||||||
let cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
|
let cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
|
||||||
if (cmpIdentity && MatchesClassList(cmpIdentity.GetClassesList(), classes))
|
if (cmpIdentity && MatchesClassList(cmpIdentity.GetClassesList(), classes))
|
||||||
++this.archersGarrisoned;
|
++this.archersGarrisoned;
|
||||||
}
|
}
|
||||||
for (let ent of msg.removed)
|
for (let ent of msg.removed) {
|
||||||
{
|
|
||||||
let cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
|
let cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
|
||||||
if (cmpIdentity && MatchesClassList(cmpIdentity.GetClassesList(), classes))
|
if (cmpIdentity && MatchesClassList(cmpIdentity.GetClassesList(), classes))
|
||||||
--this.archersGarrisoned;
|
--this.archersGarrisoned;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BuildingAI.prototype.OnOwnershipChanged = function(msg)
|
BuildingAI.prototype.OnOwnershipChanged = function (msg) {
|
||||||
{
|
|
||||||
this.targetUnits = [];
|
this.targetUnits = [];
|
||||||
this.focusTargets = [];
|
|
||||||
this.SetupRangeQuery();
|
this.SetupRangeQuery();
|
||||||
this.SetupGaiaRangeQuery();
|
this.SetupGaiaRangeQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
BuildingAI.prototype.OnDiplomacyChanged = function(msg)
|
BuildingAI.prototype.OnDiplomacyChanged = function (msg) {
|
||||||
{
|
|
||||||
if (!IsOwnedByPlayer(msg.player, this.entity))
|
if (!IsOwnedByPlayer(msg.player, this.entity))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -67,10 +59,8 @@ BuildingAI.prototype.OnDiplomacyChanged = function(msg)
|
|||||||
this.SetupGaiaRangeQuery();
|
this.SetupGaiaRangeQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
BuildingAI.prototype.OnDestroy = function()
|
BuildingAI.prototype.OnDestroy = function () {
|
||||||
{
|
if (this.timer) {
|
||||||
if (this.timer)
|
|
||||||
{
|
|
||||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||||
cmpTimer.CancelTimer(this.timer);
|
cmpTimer.CancelTimer(this.timer);
|
||||||
this.timer = undefined;
|
this.timer = undefined;
|
||||||
@ -87,8 +77,7 @@ BuildingAI.prototype.OnDestroy = function()
|
|||||||
/**
|
/**
|
||||||
* React on Attack value modifications, as it might influence the range.
|
* React on Attack value modifications, as it might influence the range.
|
||||||
*/
|
*/
|
||||||
BuildingAI.prototype.OnValueModification = function(msg)
|
BuildingAI.prototype.OnValueModification = function (msg) {
|
||||||
{
|
|
||||||
if (msg.component != "Attack")
|
if (msg.component != "Attack")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -100,15 +89,13 @@ BuildingAI.prototype.OnValueModification = function(msg)
|
|||||||
/**
|
/**
|
||||||
* Setup the Range Query to detect units coming in & out of range.
|
* Setup the Range Query to detect units coming in & out of range.
|
||||||
*/
|
*/
|
||||||
BuildingAI.prototype.SetupRangeQuery = function()
|
BuildingAI.prototype.SetupRangeQuery = function () {
|
||||||
{
|
|
||||||
var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
|
var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
|
||||||
if (!cmpAttack)
|
if (!cmpAttack)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
||||||
if (this.enemyUnitsQuery)
|
if (this.enemyUnitsQuery) {
|
||||||
{
|
|
||||||
cmpRangeManager.DestroyActiveQuery(this.enemyUnitsQuery);
|
cmpRangeManager.DestroyActiveQuery(this.enemyUnitsQuery);
|
||||||
this.enemyUnitsQuery = undefined;
|
this.enemyUnitsQuery = undefined;
|
||||||
}
|
}
|
||||||
@ -137,15 +124,13 @@ BuildingAI.prototype.SetupRangeQuery = function()
|
|||||||
|
|
||||||
// Set up a range query for Gaia units within LOS range which can be attacked.
|
// Set up a range query for Gaia units within LOS range which can be attacked.
|
||||||
// This should be called whenever our ownership changes.
|
// This should be called whenever our ownership changes.
|
||||||
BuildingAI.prototype.SetupGaiaRangeQuery = function()
|
BuildingAI.prototype.SetupGaiaRangeQuery = function () {
|
||||||
{
|
|
||||||
var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
|
var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
|
||||||
if (!cmpAttack)
|
if (!cmpAttack)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
||||||
if (this.gaiaUnitsQuery)
|
if (this.gaiaUnitsQuery) {
|
||||||
{
|
|
||||||
cmpRangeManager.DestroyActiveQuery(this.gaiaUnitsQuery);
|
cmpRangeManager.DestroyActiveQuery(this.gaiaUnitsQuery);
|
||||||
this.gaiaUnitsQuery = undefined;
|
this.gaiaUnitsQuery = undefined;
|
||||||
}
|
}
|
||||||
@ -169,16 +154,14 @@ BuildingAI.prototype.SetupGaiaRangeQuery = function()
|
|||||||
/**
|
/**
|
||||||
* Called when units enter or leave range.
|
* Called when units enter or leave range.
|
||||||
*/
|
*/
|
||||||
BuildingAI.prototype.OnRangeUpdate = function(msg)
|
BuildingAI.prototype.OnRangeUpdate = function (msg) {
|
||||||
{
|
|
||||||
|
|
||||||
var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
|
var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
|
||||||
if (!cmpAttack)
|
if (!cmpAttack)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Target enemy units except non-dangerous animals.
|
// Target enemy units except non-dangerous animals.
|
||||||
if (msg.tag == this.gaiaUnitsQuery)
|
if (msg.tag == this.gaiaUnitsQuery) {
|
||||||
{
|
|
||||||
msg.added = msg.added.filter(e => {
|
msg.added = msg.added.filter(e => {
|
||||||
let cmpUnitAI = Engine.QueryInterface(e, IID_UnitAI);
|
let cmpUnitAI = Engine.QueryInterface(e, IID_UnitAI);
|
||||||
return cmpUnitAI && (!cmpUnitAI.IsAnimal() || cmpUnitAI.IsDangerousAnimal());
|
return cmpUnitAI && (!cmpUnitAI.IsAnimal() || cmpUnitAI.IsDangerousAnimal());
|
||||||
@ -193,8 +176,7 @@ BuildingAI.prototype.OnRangeUpdate = function(msg)
|
|||||||
this.targetUnits.push(entity);
|
this.targetUnits.push(entity);
|
||||||
|
|
||||||
// Remove targets outside of vision-range.
|
// Remove targets outside of vision-range.
|
||||||
for (let entity of msg.removed)
|
for (let entity of msg.removed) {
|
||||||
{
|
|
||||||
let index = this.targetUnits.indexOf(entity);
|
let index = this.targetUnits.indexOf(entity);
|
||||||
if (index > -1)
|
if (index > -1)
|
||||||
this.targetUnits.splice(index, 1);
|
this.targetUnits.splice(index, 1);
|
||||||
@ -204,8 +186,7 @@ BuildingAI.prototype.OnRangeUpdate = function(msg)
|
|||||||
this.StartTimer();
|
this.StartTimer();
|
||||||
};
|
};
|
||||||
|
|
||||||
BuildingAI.prototype.StartTimer = function()
|
BuildingAI.prototype.StartTimer = function () {
|
||||||
{
|
|
||||||
if (this.timer)
|
if (this.timer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -220,14 +201,12 @@ BuildingAI.prototype.StartTimer = function()
|
|||||||
attackTimers.prepare, attackTimers.repeat / roundCount, null);
|
attackTimers.prepare, attackTimers.repeat / roundCount, null);
|
||||||
};
|
};
|
||||||
|
|
||||||
BuildingAI.prototype.GetDefaultArrowCount = function()
|
BuildingAI.prototype.GetDefaultArrowCount = function () {
|
||||||
{
|
|
||||||
var arrowCount = +this.template.DefaultArrowCount;
|
var arrowCount = +this.template.DefaultArrowCount;
|
||||||
return Math.round(ApplyValueModificationsToEntity("BuildingAI/DefaultArrowCount", arrowCount, this.entity));
|
return Math.round(ApplyValueModificationsToEntity("BuildingAI/DefaultArrowCount", arrowCount, this.entity));
|
||||||
};
|
};
|
||||||
|
|
||||||
BuildingAI.prototype.GetMaxArrowCount = function()
|
BuildingAI.prototype.GetMaxArrowCount = function () {
|
||||||
{
|
|
||||||
if (!this.template.MaxArrowCount)
|
if (!this.template.MaxArrowCount)
|
||||||
return Infinity;
|
return Infinity;
|
||||||
|
|
||||||
@ -235,14 +214,12 @@ BuildingAI.prototype.GetMaxArrowCount = function()
|
|||||||
return Math.round(ApplyValueModificationsToEntity("BuildingAI/MaxArrowCount", maxArrowCount, this.entity));
|
return Math.round(ApplyValueModificationsToEntity("BuildingAI/MaxArrowCount", maxArrowCount, this.entity));
|
||||||
};
|
};
|
||||||
|
|
||||||
BuildingAI.prototype.GetGarrisonArrowMultiplier = function()
|
BuildingAI.prototype.GetGarrisonArrowMultiplier = function () {
|
||||||
{
|
|
||||||
var arrowMult = +this.template.GarrisonArrowMultiplier;
|
var arrowMult = +this.template.GarrisonArrowMultiplier;
|
||||||
return ApplyValueModificationsToEntity("BuildingAI/GarrisonArrowMultiplier", arrowMult, this.entity);
|
return ApplyValueModificationsToEntity("BuildingAI/GarrisonArrowMultiplier", arrowMult, this.entity);
|
||||||
};
|
};
|
||||||
|
|
||||||
BuildingAI.prototype.GetGarrisonArrowClasses = function()
|
BuildingAI.prototype.GetGarrisonArrowClasses = function () {
|
||||||
{
|
|
||||||
var string = this.template.GarrisonArrowClasses;
|
var string = this.template.GarrisonArrowClasses;
|
||||||
if (string)
|
if (string)
|
||||||
return string.split(/\s+/);
|
return string.split(/\s+/);
|
||||||
@ -254,45 +231,25 @@ BuildingAI.prototype.GetGarrisonArrowClasses = function()
|
|||||||
* DefaultArrowCount + Garrisoned Archers (i.e., any unit capable
|
* DefaultArrowCount + Garrisoned Archers (i.e., any unit capable
|
||||||
* of shooting arrows from inside buildings).
|
* of shooting arrows from inside buildings).
|
||||||
*/
|
*/
|
||||||
BuildingAI.prototype.GetArrowCount = function()
|
BuildingAI.prototype.GetArrowCount = function () {
|
||||||
{
|
|
||||||
let count = this.GetDefaultArrowCount() +
|
let count = this.GetDefaultArrowCount() +
|
||||||
Math.round(this.archersGarrisoned * this.GetGarrisonArrowMultiplier());
|
Math.round(this.archersGarrisoned * this.GetGarrisonArrowMultiplier());
|
||||||
|
|
||||||
return Math.min(count, this.GetMaxArrowCount());
|
return Math.min(count, this.GetMaxArrowCount());
|
||||||
};
|
};
|
||||||
|
|
||||||
BuildingAI.prototype.SetUnitAITarget = function(ent)
|
BuildingAI.prototype.SetUnitAITarget = function (ent) {
|
||||||
{
|
|
||||||
this.unitAITarget = ent;
|
this.unitAITarget = ent;
|
||||||
if (ent)
|
if (ent)
|
||||||
this.StartTimer();
|
this.StartTimer();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds index to keep track of the user-targeted units supporting a queue
|
|
||||||
* @param {ent} - Target of rallypoint selection when selection is an enemy unit from unit_actions.js
|
|
||||||
*/
|
|
||||||
BuildingAI.prototype.AddFocusTarget = function(ent, queued, push)
|
|
||||||
{
|
|
||||||
if (!ent || this.targetUnits.indexOf(ent) === -1)
|
|
||||||
return;
|
|
||||||
if (queued)
|
|
||||||
this.focusTargets.push({"entityId": ent});
|
|
||||||
else if (push)
|
|
||||||
this.focusTargets.unshift({"entityId": ent});
|
|
||||||
else
|
|
||||||
this.focusTargets = [{"entityId": ent}];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fire arrows with random temporal distribution on prefered targets.
|
* Fire arrows with random temporal distribution on prefered targets.
|
||||||
* Called 'roundCount' times every 'RepeatTime' seconds when there are units in the range.
|
* Called 'roundCount' times every 'RepeatTime' seconds when there are units in the range.
|
||||||
*/
|
*/
|
||||||
BuildingAI.prototype.FireArrows = function()
|
BuildingAI.prototype.FireArrows = function () {
|
||||||
{
|
if (!this.targetUnits.length && !this.unitAITarget) {
|
||||||
if (!this.targetUnits.length && !this.unitAITarget)
|
|
||||||
{
|
|
||||||
if (!this.timer)
|
if (!this.timer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -321,38 +278,29 @@ BuildingAI.prototype.FireArrows = function()
|
|||||||
this.arrowsLeft
|
this.arrowsLeft
|
||||||
);
|
);
|
||||||
|
|
||||||
if (arrowsToFire <= 0)
|
if (arrowsToFire <= 0) {
|
||||||
{
|
|
||||||
++this.currentRound;
|
++this.currentRound;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add targets to a list.
|
// Add targets to a weighted list, to allow preferences.
|
||||||
let targets = [];
|
let targets = new WeightedList();
|
||||||
let addTarget = function(target)
|
let maxPreference = this.MAX_PREFERENCE_BONUS;
|
||||||
{
|
let addTarget = function (target) {
|
||||||
const pref = (cmpAttack.GetPreference(target) ?? 49);
|
let preference = cmpAttack.GetPreference(target);
|
||||||
targets.push({"entityId": target, "preference": pref});
|
let weight = 1;
|
||||||
|
|
||||||
|
if (preference !== null && preference !== undefined)
|
||||||
|
weight += maxPreference / (1 + preference);
|
||||||
|
|
||||||
|
targets.push(target, weight);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add the UnitAI target separately, as the UnitMotion and RangeManager implementations differ.
|
// Add the UnitAI target separately, as the UnitMotion and RangeManager implementations differ.
|
||||||
if (this.unitAITarget && this.targetUnits.indexOf(this.unitAITarget) == -1)
|
if (this.unitAITarget && this.targetUnits.indexOf(this.unitAITarget) == -1)
|
||||||
addTarget(this.unitAITarget);
|
addTarget(this.unitAITarget);
|
||||||
else if (this.unitAITarget && this.targetUnits.indexOf(this.unitAITarget) != -1)
|
|
||||||
this.focusTargets = [{"entityId": this.unitAITarget}];
|
|
||||||
if (!this.focusTargets.length)
|
|
||||||
{
|
|
||||||
for (let target of this.targetUnits)
|
for (let target of this.targetUnits)
|
||||||
addTarget(target);
|
addTarget(target);
|
||||||
// Sort targets by preference and then by proximity.
|
|
||||||
targets.sort( (a,b) => {
|
|
||||||
if (a.preference > b.preference) return 1;
|
|
||||||
else if (a.preference < b.preference) return -1;
|
|
||||||
else if (PositionHelper.DistanceBetweenEntities(this.entity,a.entityId) > PositionHelper.DistanceBetweenEntities(this.entity,b.entityId)) return 1;
|
|
||||||
return -1;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
targets = this.focusTargets;
|
|
||||||
|
|
||||||
// The obstruction manager performs approximate range checks.
|
// The obstruction manager performs approximate range checks.
|
||||||
// so we need to verify them here.
|
// so we need to verify them here.
|
||||||
@ -362,32 +310,25 @@ BuildingAI.prototype.FireArrows = function()
|
|||||||
const yOrigin = cmpAttack.GetAttackYOrigin(attackType);
|
const yOrigin = cmpAttack.GetAttackYOrigin(attackType);
|
||||||
|
|
||||||
let firedArrows = 0;
|
let firedArrows = 0;
|
||||||
let killedTargets = 0;
|
while (firedArrows < arrowsToFire && targets.length()) {
|
||||||
while (firedArrows < arrowsToFire && killedTargets < targets.length)
|
const selectedTarget = targets.randomItem();
|
||||||
{
|
|
||||||
|
|
||||||
let selectedTarget = targets[killedTargets].entityId;
|
|
||||||
if (this.CheckTargetVisible(selectedTarget) && cmpObstructionManager.IsInTargetParabolicRange(
|
if (this.CheckTargetVisible(selectedTarget) && cmpObstructionManager.IsInTargetParabolicRange(
|
||||||
this.entity,
|
this.entity,
|
||||||
selectedTarget,
|
selectedTarget,
|
||||||
range.min,
|
range.min,
|
||||||
range.max,
|
range.max,
|
||||||
yOrigin,
|
yOrigin,
|
||||||
false))
|
false)) {
|
||||||
{
|
|
||||||
cmpAttack.PerformAttack(attackType, selectedTarget);
|
cmpAttack.PerformAttack(attackType, selectedTarget);
|
||||||
PlaySound("attack_" + attackType.toLowerCase(), this.entity);
|
PlaySound("attack_" + attackType.toLowerCase(), this.entity);
|
||||||
++firedArrows;
|
++firedArrows;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Could not attack target, try a different target.
|
// Could not attack target, try a different target.
|
||||||
++killedTargets;
|
targets.remove(selectedTarget);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
targets.splice(0,killedTargets);
|
|
||||||
killedTargets = 0;//not sure if this is necessary
|
|
||||||
this.arrowsLeft -= firedArrows;
|
this.arrowsLeft -= firedArrows;
|
||||||
++this.currentRound;
|
++this.currentRound;
|
||||||
};
|
};
|
||||||
@ -395,8 +336,7 @@ BuildingAI.prototype.FireArrows = function()
|
|||||||
/**
|
/**
|
||||||
* Returns true if the target entity is visible through the FoW/SoD.
|
* Returns true if the target entity is visible through the FoW/SoD.
|
||||||
*/
|
*/
|
||||||
BuildingAI.prototype.CheckTargetVisible = function(target)
|
BuildingAI.prototype.CheckTargetVisible = function (target) {
|
||||||
{
|
|
||||||
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
|
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
|
||||||
if (!cmpOwnership)
|
if (!cmpOwnership)
|
||||||
return false;
|
return false;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -9,10 +9,6 @@
|
|||||||
<GarrisonHolder>
|
<GarrisonHolder>
|
||||||
<Max op="mul">1.5</Max>
|
<Max op="mul">1.5</Max>
|
||||||
</GarrisonHolder>
|
</GarrisonHolder>
|
||||||
<BuildingAI>
|
|
||||||
<DefaultArrowCount>10</DefaultArrowCount>
|
|
||||||
<MaxArrowCount>24</MaxArrowCount>
|
|
||||||
</BuildingAI>
|
|
||||||
<Health>
|
<Health>
|
||||||
<Max op="mul">1.5</Max>
|
<Max op="mul">1.5</Max>
|
||||||
</Health>
|
</Health>
|
||||||
@ -34,7 +30,7 @@
|
|||||||
</Technologies>
|
</Technologies>
|
||||||
</Researcher>
|
</Researcher>
|
||||||
<Trainer>
|
<Trainer>
|
||||||
<BatchTimeModifier op="mul">0.75</BatchTimeModifier>
|
<BatchTimeModifier op="mul">0.5</BatchTimeModifier>
|
||||||
<Entities datatype="tokens">
|
<Entities datatype="tokens">
|
||||||
units/{civ}/hero_han_xin_horse
|
units/{civ}/hero_han_xin_horse
|
||||||
units/{civ}/hero_liu_bang_horse
|
units/{civ}/hero_liu_bang_horse
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
</Ranged>
|
</Ranged>
|
||||||
</Attack>
|
</Attack>
|
||||||
<BuildingAI>
|
<BuildingAI>
|
||||||
<DefaultArrowCount>4</DefaultArrowCount>
|
<DefaultArrowCount>2</DefaultArrowCount>
|
||||||
</BuildingAI>
|
</BuildingAI>
|
||||||
<Cost>
|
<Cost>
|
||||||
<BuildTime>200</BuildTime>
|
<BuildTime>200</BuildTime>
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
</Damage>
|
</Damage>
|
||||||
<MaxRange>60</MaxRange>
|
<MaxRange>60</MaxRange>
|
||||||
<PrepareTime>1200</PrepareTime>
|
<PrepareTime>1200</PrepareTime>
|
||||||
<RepeatTime>4000</RepeatTime>
|
<RepeatTime>2000</RepeatTime>
|
||||||
<Projectile>
|
<Projectile>
|
||||||
<Speed>100</Speed>
|
<Speed>100</Speed>
|
||||||
<Spread>2</Spread>
|
<Spread>1.5</Spread>
|
||||||
<Gravity>50</Gravity>
|
<Gravity>50</Gravity>
|
||||||
<FriendlyFire>false</FriendlyFire>
|
<FriendlyFire>false</FriendlyFire>
|
||||||
<LaunchPoint y="3"/>
|
<LaunchPoint y="3"/>
|
||||||
@ -39,10 +39,9 @@
|
|||||||
</Distance>
|
</Distance>
|
||||||
</BuildRestrictions>
|
</BuildRestrictions>
|
||||||
<BuildingAI>
|
<BuildingAI>
|
||||||
<DefaultArrowCount>8</DefaultArrowCount>
|
<DefaultArrowCount>3</DefaultArrowCount>
|
||||||
<GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
|
<GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
|
||||||
<GarrisonArrowClasses>Soldier</GarrisonArrowClasses>
|
<GarrisonArrowClasses>Soldier</GarrisonArrowClasses>
|
||||||
<MaxArrowCount>18</MaxArrowCount>
|
|
||||||
</BuildingAI>
|
</BuildingAI>
|
||||||
<Capturable>
|
<Capturable>
|
||||||
<CapturePoints>2500</CapturePoints>
|
<CapturePoints>2500</CapturePoints>
|
||||||
|
@ -9,8 +9,7 @@
|
|||||||
</Distance>
|
</Distance>
|
||||||
</BuildRestrictions>
|
</BuildRestrictions>
|
||||||
<BuildingAI>
|
<BuildingAI>
|
||||||
<DefaultArrowCount>6</DefaultArrowCount>
|
<DefaultArrowCount>1</DefaultArrowCount>
|
||||||
<MaxArrowCount>16</MaxArrowCount>
|
|
||||||
</BuildingAI>
|
</BuildingAI>
|
||||||
<Cost>
|
<Cost>
|
||||||
<BuildTime>300</BuildTime>
|
<BuildTime>300</BuildTime>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<MaxRange>60</MaxRange>
|
<MaxRange>60</MaxRange>
|
||||||
<MinRange>10</MinRange>
|
<MinRange>10</MinRange>
|
||||||
<PrepareTime>1200</PrepareTime>
|
<PrepareTime>1200</PrepareTime>
|
||||||
<RepeatTime>4000</RepeatTime>
|
<RepeatTime>2000</RepeatTime>
|
||||||
<Projectile>
|
<Projectile>
|
||||||
<Speed>100</Speed>
|
<Speed>100</Speed>
|
||||||
<Spread>1.5</Spread>
|
<Spread>1.5</Spread>
|
||||||
@ -26,7 +26,7 @@
|
|||||||
</Ranged>
|
</Ranged>
|
||||||
</Attack>
|
</Attack>
|
||||||
<BuildingAI>
|
<BuildingAI>
|
||||||
<DefaultArrowCount>2</DefaultArrowCount>
|
<DefaultArrowCount>1</DefaultArrowCount>
|
||||||
<GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
|
<GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
|
||||||
<GarrisonArrowClasses>Infantry</GarrisonArrowClasses>
|
<GarrisonArrowClasses>Infantry</GarrisonArrowClasses>
|
||||||
</BuildingAI>
|
</BuildingAI>
|
||||||
|
@ -10,12 +10,12 @@
|
|||||||
</Ranged>
|
</Ranged>
|
||||||
</Attack>
|
</Attack>
|
||||||
<BuildingAI>
|
<BuildingAI>
|
||||||
<MaxArrowCount>5</MaxArrowCount>
|
<MaxArrowCount>4</MaxArrowCount>
|
||||||
</BuildingAI>
|
</BuildingAI>
|
||||||
<Cost>
|
<Cost>
|
||||||
<BuildTime>40</BuildTime>
|
<BuildTime>40</BuildTime>
|
||||||
<Resources>
|
<Resources>
|
||||||
<wood>125</wood>
|
<wood>100</wood>
|
||||||
</Resources>
|
</Resources>
|
||||||
</Cost>
|
</Cost>
|
||||||
<Footprint>
|
<Footprint>
|
||||||
@ -37,7 +37,7 @@
|
|||||||
<RequiredTechnology>phase_village</RequiredTechnology>
|
<RequiredTechnology>phase_village</RequiredTechnology>
|
||||||
</Identity>
|
</Identity>
|
||||||
<Loot>
|
<Loot>
|
||||||
<wood>25</wood>
|
<wood>20</wood>
|
||||||
</Loot>
|
</Loot>
|
||||||
<Obstruction>
|
<Obstruction>
|
||||||
<Static width="9.0" depth="7.5"/>
|
<Static width="9.0" depth="7.5"/>
|
||||||
@ -59,7 +59,7 @@
|
|||||||
<Tooltip>Reinforce with stone and upgrade to a defense tower.</Tooltip>
|
<Tooltip>Reinforce with stone and upgrade to a defense tower.</Tooltip>
|
||||||
<RequiredTechnology>phase_town</RequiredTechnology>
|
<RequiredTechnology>phase_town</RequiredTechnology>
|
||||||
<Cost>
|
<Cost>
|
||||||
<wood>25</wood>
|
<wood>50</wood>
|
||||||
<stone>100</stone>
|
<stone>100</stone>
|
||||||
</Cost>
|
</Cost>
|
||||||
<Variant>upgrading</Variant>
|
<Variant>upgrading</Variant>
|
||||||
|
@ -20,9 +20,6 @@
|
|||||||
<Square width="10.0" depth="10.0"/>
|
<Square width="10.0" depth="10.0"/>
|
||||||
<Height>15.0</Height>
|
<Height>15.0</Height>
|
||||||
</Footprint>
|
</Footprint>
|
||||||
<BuildingAI>
|
|
||||||
<DefaultArrowCount>3</DefaultArrowCount>
|
|
||||||
</BuildingAI>
|
|
||||||
<GarrisonHolder>
|
<GarrisonHolder>
|
||||||
<Max>5</Max>
|
<Max>5</Max>
|
||||||
</GarrisonHolder>
|
</GarrisonHolder>
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
</Damage>
|
</Damage>
|
||||||
<MaxRange>60</MaxRange>
|
<MaxRange>60</MaxRange>
|
||||||
<PrepareTime>1200</PrepareTime>
|
<PrepareTime>1200</PrepareTime>
|
||||||
<RepeatTime>4000</RepeatTime>
|
<RepeatTime>2000</RepeatTime>
|
||||||
<Projectile>
|
<Projectile>
|
||||||
<Speed>100</Speed>
|
<Speed>100</Speed>
|
||||||
<Spread>2.5</Spread>
|
<Spread>1.5</Spread>
|
||||||
<Gravity>50</Gravity>
|
<Gravity>50</Gravity>
|
||||||
<FriendlyFire>false</FriendlyFire>
|
<FriendlyFire>false</FriendlyFire>
|
||||||
<LaunchPoint y="3"/>
|
<LaunchPoint y="3"/>
|
||||||
@ -32,7 +32,7 @@
|
|||||||
</Distance>
|
</Distance>
|
||||||
</BuildRestrictions>
|
</BuildRestrictions>
|
||||||
<BuildingAI>
|
<BuildingAI>
|
||||||
<DefaultArrowCount>12</DefaultArrowCount>
|
<DefaultArrowCount>4</DefaultArrowCount>
|
||||||
<GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
|
<GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
|
||||||
<GarrisonArrowClasses>Soldier</GarrisonArrowClasses>
|
<GarrisonArrowClasses>Soldier</GarrisonArrowClasses>
|
||||||
</BuildingAI>
|
</BuildingAI>
|
||||||
|
Loading…
Reference in New Issue
Block a user