Index: binaries/data/mods/public/simulation/components/BuildingAI.js
===================================================================
--- binaries/data/mods/public/simulation/components/BuildingAI.js	(revision 13617)
+++ binaries/data/mods/public/simulation/components/BuildingAI.js	(working copy)
@@ -1,30 +1,47 @@
 //Number of rounds of firing per 2 seconds
 const roundCount = 10;
 const timerInterval = 2000 / roundCount;
+const attackType = "Ranged";
+// chance an arrow will be aimed at the forced target
+const forcedTargetHitChance = 0.5;
+// chance an arrow will be aimed at a target from the first preferred class
+// exponentially lowered for the later preferred classes
+const preferredTargetHitChance = 0.8;
 
 function BuildingAI() {}
 
 BuildingAI.prototype.Schema = 
-	"<element name='DefaultArrowCount'>" +
+	"<element name='DefaultProjectileCount'>" +
 		"<data type='nonNegativeInteger'/>" +
 	"</element>" +
-	"<element name='GarrisonArrowMultiplier'>" +
+	"<element name='GarrisonProjectileMultiplier'>" +
 		"<ref name='nonNegativeDecimal'/>" +
+	"</element>" +
+	"<element name='MaxNumberOfProjectiles'>" +
+		"<data type='nonNegativeInteger'/>" +
+	"</element>" +
+	"<element name='GarrisonProjectileClasses'>" +
+		"<attribute name='datatype'>" +
+			"<value>tokens</value>" +
+		"</attribute>" +
+		"<text/>" +
 	"</element>";
 
+
+	
+
 /**
  * Initialize BuildingAI Component
  */
 BuildingAI.prototype.Init = function()
 {
-	if (this.GetDefaultArrowCount() > 0 || this.GetGarrisonArrowMultiplier() > 0)
+	if (this.GetDefaultProjectileCount() > 0 || this.GetGarrisonProjectileMultiplier() > 0)
 	{
-		var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
 		this.currentRound = 0;
-		//Arrows left to fire
-		this.arrowsLeft = 0;
-		this.timer = cmpTimer.SetTimeout(this.entity, IID_BuildingAI, "FireArrows", timerInterval, {});
+		//Projectiles left to fire
+		this.projectilesLeft = 0;
 		this.targetUnits = [];
+		this.targetUnitsPerPreference = [];
 	}
 };
 
@@ -32,6 +49,7 @@
 {
 	// Remove current targets, to prevent them from being added twice
 	this.targetUnits = [];
+	this.targetUnitsPerPreference = [];
 
 	if (msg.to != -1)
 		this.SetupRangeQuery(msg.to);
@@ -48,6 +66,7 @@
 	{
 		// Remove maybe now allied/neutral units
 		this.targetUnits = [];
+		this.targetUnitsPerPreference = [];
 		this.SetupRangeQuery(msg.player);
 	}
 };
@@ -96,12 +115,12 @@
 			players.push(i);
 	}
 	var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
-	if (cmpAttack)
-	{
-		var range = cmpAttack.GetRange("Ranged");
-		this.enemyUnitsQuery = cmpRangeManager.CreateActiveQuery(this.entity, range.min, range.max, players, IID_DamageReceiver, cmpRangeManager.GetEntityFlagMask("normal"));
-		cmpRangeManager.EnableActiveQuery(this.enemyUnitsQuery);
-	}
+	if (!cmpAttack)
+		return;
+	
+	var range = cmpAttack.GetRange(attackType);
+	this.enemyUnitsQuery = cmpRangeManager.CreateActiveQuery(this.entity, range.min, range.max, players, IID_DamageReceiver, cmpRangeManager.GetEntityFlagMask("normal"));
+	cmpRangeManager.EnableActiveQuery(this.enemyUnitsQuery);
 };
 
 // Set up a range query for Gaia units within LOS range which can be attacked.
@@ -111,12 +130,12 @@
 	var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
 	var owner = cmpOwnership.GetOwner();
 
-	var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
+	var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
 	var playerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
 
 	if (this.gaiaUnitsQuery)
 	{
-		rangeMan.DestroyActiveQuery(this.gaiaUnitsQuery);
+		cmpRangeManager.DestroyActiveQuery(this.gaiaUnitsQuery);
 		this.gaiaUnitsQuery = undefined;
 	}
 
@@ -128,14 +147,14 @@
 		return;
 
 	var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
-	if (cmpAttack)
-	{
-		var range = cmpAttack.GetRange("Ranged");
+	if (!cmpAttack)
+		return;
+	
+	var range = cmpAttack.GetRange(attackType);
 
-		// This query is only interested in Gaia entities that can attack.
-		this.gaiaUnitsQuery = rangeMan.CreateActiveQuery(this.entity, range.min, range.max, [0], IID_Attack, rangeMan.GetEntityFlagMask("normal"));
-		rangeMan.EnableActiveQuery(this.gaiaUnitsQuery);
-	}
+	// This query is only interested in Gaia entities that can attack.
+	this.gaiaUnitsQuery = cmpRangeManager.CreateActiveQuery(this.entity, range.min, range.max, [0], IID_Attack, cmpRangeManager.GetEntityFlagMask("normal"));
+	cmpRangeManager.EnableActiveQuery(this.gaiaUnitsQuery);
 };
 
 /**
@@ -143,6 +162,11 @@
  */
 BuildingAI.prototype.OnRangeUpdate = function(msg)
 {
+
+	var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
+	if (!cmpAttack)
+		return;
+
 	if (msg.tag == this.gaiaUnitsQuery)
 	{
 		const filter = function(e) {
@@ -161,11 +185,31 @@
 	else if (msg.tag != this.enemyUnitsQuery)
 		return;
 
+	const restrictedClasses = cmpAttack.GetRestrictedClasses(attackType);
+    const preferredClasses = cmpAttack.GetPreferredClasses(attackType);
+
 	if (msg.added.length > 0)
 	{
 		for each (var entity in msg.added)
 		{
-			this.targetUnits.push(entity);
+			var cmpIdentity = Engine.QueryInterface(entity, IID_Identity);
+			var targetClasses = cmpIdentity.GetClassesList();
+
+			if (!targetClasses.some(function(c){return restrictedClasses.indexOf(c) > -1;}))
+			{
+				for (var i = 0; i < preferredClasses.length; ++i)
+				{
+					if (targetClasses.indexOf(preferredClasses[i]) > -1)
+					{
+						if (!targetUnitsPerPreference[i])
+							targetUnitsPerPreference[i] = [];
+
+						this.targetUnitsPerPreference[i].push(entity);
+					}
+				}
+				// also add all targets to index -1 for easy accessing
+				this.targetUnits.push(entity);
+			}
 		}
 	}
 	if (msg.removed.length > 0)
@@ -172,84 +216,156 @@
 	{
 		for each (var entity in msg.removed)
 		{
-			this.targetUnits.splice(this.targetUnits.indexOf(entity), 1);
+			for (var i = 0 ; i < preferredClasses.length; ++i)
+			{
+				if (!targetUnitsPerPreference[i])
+					continue;
+
+				var index = this.targetUnitsPerPreference[i].indexOf(entity);
+				if (index > -1)
+					this.targetUnitsPerPreference[i].splice(index, 1);
+			}
+			var index = this.targetUnits.indexOf(entity);
+			if (index > -1)
+				this.targetUnits.splice(index, 1);
 		}
 	}
+	
+	if (!this.targetUnits.length || this.timer)
+		return;
+	// units entered the range, prepare to shoot	
+	var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
+	var attackTimers = cmpAttack.GetTimers(attackType);
+	this.timer = cmpTimer.SetInterval(this.entity, IID_BuildingAI, "FireProjectiles", attackTimers.prepare, attackTimers.repeat / roundCount, {});
+	
 };
 
-BuildingAI.prototype.GetDefaultArrowCount = function()
+BuildingAI.prototype.GetDefaultProjectileCount = function()
 {
-	var arrowCount = +this.template.DefaultArrowCount;
-	return ApplyTechModificationsToEntity("BuildingAI/DefaultArrowCount", arrowCount, this.entity);
+	var projectileCount = +this.template.DefaultProjectileCount;
+	return ApplyTechModificationsToEntity("BuildingAI/DefaultProjectileCount", projectileCount, this.entity);
 };
 
-BuildingAI.prototype.GetGarrisonArrowMultiplier = function()
+BuildingAI.prototype.GetGarrisonProjectileMultiplier = function()
 {
-	var arrowMult = +this.template.GarrisonArrowMultiplier;
-	return ApplyTechModificationsToEntity("BuildingAI/GarrisonArrowMultiplier", arrowMult, this.entity);
+	var projectileMult = +this.template.GarrisonProjectileMultiplier;
+	return ApplyTechModificationsToEntity("BuildingAI/GarrisonProjectileMultiplier", projectileMult, this.entity);
 };
 
+BuildingAI.prototype.GetMaxNumberOfProjectiles = function()
+{
+	var maxNum = +this.template.MaxNumberOfProjectiles;
+	return ApplyTechModificationsToEntity("BuildingAI/MaxNumberOfProjectiles", maxNum, this.entity);
+};
+
+BuildingAI.prototype.GetGarrisonProjectileClasses = function()
+{
+	var string = this.template.GarrisonProjectileClasses._string || "";
+	return string.split(/\s+/);
+};
+
 /**
- * Returns the number of arrows which needs to be fired.
- * DefaultArrowCount + Garrisoned Archers(ie., any unit capable 
- * of shooting arrows from inside buildings)
+ * Returns the number of projectiles which needs to be fired.
+ * DefaultProjectileCount + Garrisoned Archers(ie., any unit capable 
+ * of shooting projectiles from inside buildings)
  */
-BuildingAI.prototype.GetArrowCount = function()
+BuildingAI.prototype.GetProjectileCount = function()
 {
-	var count = this.GetDefaultArrowCount();
+	var count = this.GetDefaultProjectileCount();
 	var cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder);
 	if (cmpGarrisonHolder)
 	{
-		count += Math.round(cmpGarrisonHolder.GetGarrisonedArcherCount() * this.GetGarrisonArrowMultiplier());
+		count += Math.round(cmpGarrisonHolder.GetGarrisonedArcherCount(this.GetGarrisonProjectileClasses()) * this.GetGarrisonProjectileMultiplier());
 	}
-	return count;
+	return Math.min(this.GetMaxNumberOfProjectiles(), count);
 };
 
 /**
- * Fires arrows. Called every N times every 2 seconds
- * where N is the number of Arrows
+ * Fires projectiles. Called 'roundCount' times every 'RepeatTime' seconds when there are units in the range
  */
-BuildingAI.prototype.FireArrows = function()
+BuildingAI.prototype.FireProjectiles = function()
 {
+
+	
+	if (!this.targetUnits.length && this.timer)
+	{
+		// stop the timer
+		var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
+		cmpTimer.CancelTimer(this.timer);
+		this.timer = undefined;
+		return;
+	}
+
 	var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
-	if (cmpAttack)
+	if (!cmpAttack)
+		return;
+
+	var numberOfPreferredClasses = cmpAttack.GetPreferredClasses().length;
+
+	var cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI);
+	if (cmpUnitAI)
 	{
-		var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
-		this.timer = cmpTimer.SetTimeout(this.entity, IID_BuildingAI, "FireArrows", timerInterval, {});
-		var arrowsToFire = 0;
-		if (this.currentRound > (roundCount - 1))
+		var orders = cmpUnitAI.GetOrders();
+		if (orders.length && orders[0].type == 'Attack' && orders[0].data.force)
+			// user is forcing this entity to attack a certian target
+			this.forcedTarget = +orders[0].data.target;
+		else
+			this.forcedTarget = undefined;
+	}
+
+	var projectilesToFire = 0;
+	
+	if (this.currentRound === 0)
+		this.projectilesLeft = this.GetProjectileCount();
+	
+	if (this.currentRound === (roundCount - 1))
+	{
+		//Last round. Need to fire all left-over projectiles
+		projectilesToFire = this.projectilesLeft;
+	}
+	else
+	{
+		//Fire N projectiles, 0 <= N <= Number of projectiles left
+		projectilesToFire = Math.min( 
+		    Math.round(2*Math.random() * this.GetProjectileCount()/roundCount),  
+		    this.projectilesLeft 
+		); 
+	}
+	
+	for (var i = 0; i < projectilesToFire; ++i)
+	{
+		var target;
+		var hitFactor = Math.random();
+		if (this.forcedTarget 
+		       && this.targetUnits.indexOf(forcedTarget) > -1 
+		       && hitFactor < forcedTargetHitChance)
 		{
-			//Reached end of rounds. Reset count
-			this.currentRound = 0;
+			// user forced to attack a certain one, and we're able to attack the target 
+			target = this.forcedTarget;
 		}
-		
-		if (this.currentRound == 0)
-		{
-			//First round. Calculate arrows to fire
-			this.arrowsLeft = this.GetArrowCount();
-		}
-		
-		if (this.currentRound == (roundCount - 1))
-		{
-			//Last round. Need to fire all left-over arrows
-			arrowsToFire = this.arrowsLeft;
-		}
 		else
 		{
-			//Fire N arrows, 0 <= N <= Number of arrows left
-			arrowsToFire = Math.floor(Math.random() * this.arrowsLeft);
+			var preferredClass = -1;
+			while (hitFactor > preferredTargetHitChance && preferredClass++ < numberOfPreferredClasses)
+				hitFactor *= hitFactor;
+			
+			if (preferredClass < numberOfPreferredClasses 
+			       && this.targetUnitsPerPreference[preferredClass])
+				target = this.targetUnitsPerPreference[preferredClass]
+				    [Math.floor(Math.random() * this.targetUnitsPerPreference[preferredClass].length)];
+			else
+				target = this.targetUnits
+				    [Math.floor(Math.random() * this.targetUnits.length)];
 		}
-		if (this.targetUnits.length > 0)
-		{
-			for (var i = 0;i < arrowsToFire;i++)
-			{
-				cmpAttack.PerformAttack("Ranged", this.targetUnits[Math.floor(Math.random() * this.targetUnits.length)]);
-				PlaySound("arrowfly", this.entity);
-			}
-			this.arrowsLeft -= arrowsToFire;
-		}
-		this.currentRound++;
+
+		cmpAttack.PerformAttack(attackType, target);
+		// TODO use Sound.js sounds
+		PlaySound("projectilefly", this.entity); 
 	}
+	this.projectilesLeft -= projectilesToFire;
+	
+	this.currentRound = ++this.currentRound % roundCount;
+	
 };
 
 Engine.RegisterComponentType(IID_BuildingAI, "BuildingAI", BuildingAI);
Index: binaries/data/mods/public/simulation/components/GarrisonHolder.js
===================================================================
--- binaries/data/mods/public/simulation/components/GarrisonHolder.js	(revision 13617)
+++ binaries/data/mods/public/simulation/components/GarrisonHolder.js	(working copy)
@@ -78,7 +78,7 @@
  * Get number of garrisoned units capable of shooting arrows
  * Not necessarily archers
  */
-GarrisonHolder.prototype.GetGarrisonedArcherCount = function()
+GarrisonHolder.prototype.GetGarrisonedArcherCount = function(garrisonProjectileClasses)
 {
 	var count = 0;
 	for each (var entity in this.entities)
@@ -85,7 +85,7 @@
 	{
 		var cmpIdentity = Engine.QueryInterface(entity, IID_Identity);
 		var classes = cmpIdentity.GetClassesList();
-		if (classes.indexOf("Infantry") != -1 || classes.indexOf("Ranged") != -1)
+		if (classes.some(function(c){return garrisonProjectileClasses.indexOf(c) > -1;}))
 			count++;
 	}
 	return count;
Index: binaries/data/mods/public/simulation/templates/campaigns/campaign_city_minor_test.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/campaigns/campaign_city_minor_test.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/campaigns/campaign_city_minor_test.xml	(working copy)
@@ -13,8 +13,8 @@
     </Ranged>
   </Attack>
   <BuildingAI>
-    <DefaultArrowCount>3</DefaultArrowCount>
-    <GarrisonArrowMultiplier>0.5</GarrisonArrowMultiplier>
+    <DefaultProjectileCount>3</DefaultProjectileCount>
+    <GarrisonProjectileMultiplier>0.5</GarrisonProjectileMultiplier>
   </BuildingAI>
   <Footprint replace="">
     <Circle radius="26.0"/>
Index: binaries/data/mods/public/simulation/templates/campaigns/campaign_city_test.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/campaigns/campaign_city_test.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/campaigns/campaign_city_test.xml	(working copy)
@@ -13,8 +13,8 @@
     </Ranged>
   </Attack>
   <BuildingAI>
-    <DefaultArrowCount>5</DefaultArrowCount>
-    <GarrisonArrowMultiplier>0.5</GarrisonArrowMultiplier>
+    <DefaultProjectileCount>5</DefaultProjectileCount>
+    <GarrisonProjectileMultiplier>0.5</GarrisonProjectileMultiplier>
   </BuildingAI>
   <Footprint replace="">
     <Circle radius="26.0"/>
Index: binaries/data/mods/public/simulation/templates/structures/brit_crannog.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/brit_crannog.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/structures/brit_crannog.xml	(working copy)
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Entity parent="template_structure_civic_civil_centre">
   <BuildingAI>
-    <DefaultArrowCount>3</DefaultArrowCount>
-    <GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
+    <DefaultProjectileCount>3</DefaultProjectileCount>
+    <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier>
   </BuildingAI>
   <BuildRestrictions>
 	<Territory>own ally neutral</Territory>
Index: binaries/data/mods/public/simulation/templates/structures/iber_defense_tower.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/iber_defense_tower.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/structures/iber_defense_tower.xml	(working copy)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Entity parent="template_structure_defense_defense_tower">
   <BuildingAI>
-    <DefaultArrowCount>2</DefaultArrowCount>
+    <DefaultProjectileCount>2</DefaultProjectileCount>
   </BuildingAI>
   <Cost>
     <PopulationBonus>5</PopulationBonus>
Index: binaries/data/mods/public/simulation/templates/structures/rome_army_camp.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/rome_army_camp.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/structures/rome_army_camp.xml	(working copy)
@@ -20,18 +20,19 @@
       <ProjectileSpeed>75.0</ProjectileSpeed>
       <PrepareTime>1200</PrepareTime>
       <RepeatTime>2000</RepeatTime>
-      <Spread>1.5</Spread>
-    </Ranged>
-  </Attack>
-  <BuildingAI>
-    <DefaultArrowCount>3</DefaultArrowCount>
-    <GarrisonArrowMultiplier>0.5</GarrisonArrowMultiplier>
-  </BuildingAI>
-  <BuildRestrictions>
-    <Territory>own neutral enemy</Territory>
-    <Category>Fortress</Category>
-  </BuildRestrictions>
-  <Cost>
+      <Spread>1.5</Spread>
+    </Ranged>
+  </Attack>
+  <BuildingAI>
+    <DefaultProjectileCount>3</DefaultProjectileCount>
+    <GarrisonProjectileMultiplier>0.5</GarrisonProjectileMultiplier>
+	<GarrisonProjectileClasses datatype="tokens">Infanty Ranged</GarrisonProjectileClasses>
+  </BuildingAI>
+  <BuildRestrictions>
+    <Territory>own neutral enemy</Territory>
+    <Category>Fortress</Category>
+  </BuildRestrictions>
+  <Cost>
     <PopulationBonus>5</PopulationBonus>
     <BuildTime>160</BuildTime>
     <Resources>
Index: binaries/data/mods/public/simulation/templates/template_structure.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/template_structure.xml	(working copy)
@@ -11,8 +11,10 @@
     </Foundation>
   </Armour>
   <BuildingAI>
-    <DefaultArrowCount>0</DefaultArrowCount>
-    <GarrisonArrowMultiplier>0</GarrisonArrowMultiplier>
+    <DefaultProjectileCount>0</DefaultProjectileCount>
+    <GarrisonProjectileMultiplier>0</GarrisonProjectileMultiplier>
+    <MaxNumberOfProjectiles>20</MaxNumberOfProjectiles>
+	<GarrisonProjectileClasses datatype="tokens">Infanty Ranged</GarrisonProjectileClasses>
   </BuildingAI>
   <BuildRestrictions>
     <PlacementType>land</PlacementType>
Index: binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml	(working copy)
@@ -14,8 +14,8 @@
     </Ranged>
   </Attack>
   <BuildingAI>
-    <DefaultArrowCount>3</DefaultArrowCount>
-    <GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
+    <DefaultProjectileCount>3</DefaultProjectileCount>
+    <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier>
   </BuildingAI>
   <BuildRestrictions>
     <Territory>own neutral</Territory>
Index: binaries/data/mods/public/simulation/templates/template_structure_defense_defense_tower.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure_defense_defense_tower.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/template_structure_defense_defense_tower.xml	(working copy)
@@ -7,21 +7,22 @@
       <Crush>0.0</Crush>
       <MaxRange>70.0</MaxRange>
       <MinRange>16.0</MinRange>
-      <ProjectileSpeed>75.0</ProjectileSpeed>
-      <PrepareTime>1200</PrepareTime>
-      <RepeatTime>2000</RepeatTime>
-      <Spread>1.5</Spread>
-    </Ranged>
-  </Attack>
-  <BuildingAI>
-    <DefaultArrowCount>1</DefaultArrowCount>
-    <GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
-  </BuildingAI>
-  <BuildRestrictions>
-    <Category>DefenseTower</Category>
-  </BuildRestrictions>
-  <Cost>
-    <BuildTime>120</BuildTime>
+      <ProjectileSpeed>75.0</ProjectileSpeed>
+      <PrepareTime>1200</PrepareTime>
+      <RepeatTime>2000</RepeatTime>
+      <RestrictedClasses datatype="tokens">Structure</RestrictedClasses>
+      <Spread>1.5</Spread>
+    </Ranged>
+  </Attack>
+  <BuildingAI>
+    <DefaultProjectileCount>1</DefaultProjectileCount>
+    <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier>
+  </BuildingAI>
+  <BuildRestrictions>
+    <Category>DefenseTower</Category>
+  </BuildRestrictions>
+  <Cost>
+    <BuildTime>120</BuildTime>
     <Resources>
       <wood>100</wood>
       <stone>100</stone>
Index: binaries/data/mods/public/simulation/templates/template_structure_defense_outpost.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure_defense_outpost.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/template_structure_defense_outpost.xml	(working copy)
@@ -20,11 +20,12 @@
       <ProjectileSpeed>75.0</ProjectileSpeed>
       <PrepareTime>1200</PrepareTime>
       <RepeatTime>2000</RepeatTime>
+      <RestrictedClasses datatype="tokens">Structure</RestrictedClasses>
       <Spread>2.0</Spread>
     </Ranged>
   </Attack>
   <BuildingAI>
-    <GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
+    <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier>
   </BuildingAI>
   <BuildRestrictions>
     <Territory>own neutral</Territory>
Index: binaries/data/mods/public/simulation/templates/template_structure_defense_wall_tower.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure_defense_wall_tower.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/template_structure_defense_wall_tower.xml	(working copy)
@@ -14,8 +14,8 @@
     </Ranged>
   </Attack>
   <BuildingAI>
-    <DefaultArrowCount>1</DefaultArrowCount>
-    <GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
+    <DefaultProjectileCount>1</DefaultProjectileCount>
+    <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier>
   </BuildingAI>
   <BuildRestrictions>
     <PlacementType>land-shore</PlacementType>
Index: binaries/data/mods/public/simulation/templates/template_structure_military_fortress.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure_military_fortress.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/template_structure_military_fortress.xml	(working copy)
@@ -10,12 +10,13 @@
       <ProjectileSpeed>75.0</ProjectileSpeed>
       <PrepareTime>1200</PrepareTime>
       <RepeatTime>2000</RepeatTime>
+      <RestrictedClasses datatype="tokens">Structure</RestrictedClasses>
       <Spread>1.5</Spread>
     </Ranged>
   </Attack>
   <BuildingAI>
-    <DefaultArrowCount>3</DefaultArrowCount>
-    <GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
+    <DefaultProjectileCount>3</DefaultProjectileCount>
+    <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier>
   </BuildingAI>
   <BuildRestrictions>
     <Category>Fortress</Category>
Index: binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_bireme.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_bireme.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_bireme.xml	(working copy)
@@ -14,8 +14,10 @@
     </Ranged>
   </Attack>
   <BuildingAI>
-    <DefaultArrowCount>2</DefaultArrowCount>
-    <GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
+    <DefaultProjectileCount>2</DefaultProjectileCount>
+    <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier>
+    <GarrisonProjectileClasses datatype="tokens">Infanty Ranged</GarrisonProjectileClasses>
+    <MaxNumberOfProjectiles>20</MaxNumberOfProjectiles>
   </BuildingAI>
   <Cost>
     <Population>2</Population>
Index: binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_quinquereme.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_quinquereme.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_quinquereme.xml	(working copy)
@@ -2,13 +2,13 @@
 <Entity parent="template_unit_mechanical_ship">
   <Attack>
     <Ranged>
-      <Hack>0.0</Hack>
-      <Pierce>40.0</Pierce>
-      <Crush>100.0</Crush>
+      <Hack>30.0</Hack>
+      <Pierce>10.0</Pierce>
+      <Crush>30.0</Crush>
       <MaxRange>65.0</MaxRange>
       <MinRange>20.0</MinRange>
       <ProjectileSpeed>40.0</ProjectileSpeed>
-      <PrepareTime>2000</PrepareTime>
+      <PrepareTime>5000</PrepareTime>
       <RepeatTime>4000</RepeatTime>
       <Spread>1.5</Spread>
     </Ranged>
@@ -21,6 +21,12 @@
       <metal>200</metal>
     </Resources>
   </Cost>
+  <BuildingAI>
+    <DefaultProjectileCount>0</DefaultProjectileCount>
+    <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier>
+    <GarrisonProjectileClasses datatype="tokens">Ballista</GarrisonProjectileClasses>
+    <MaxNumberOfProjectiles>6</MaxNumberOfProjectiles>
+  </BuildingAI>
   <Footprint>
     <Square width="12.0" depth="48.0"/>
     <Height>8.0</Height>
Index: binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_trireme.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_trireme.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_trireme.xml	(working copy)
@@ -14,8 +14,10 @@
     </Ranged>
   </Attack>
   <BuildingAI>
-    <DefaultArrowCount>3</DefaultArrowCount>
-    <GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
+    <DefaultProjectileCount>3</DefaultProjectileCount>
+    <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier>
+    <GarrisonProjectileClasses datatype="tokens">Infanty Ranged</GarrisonProjectileClasses>
+    <MaxNumberOfProjectiles>20</MaxNumberOfProjectiles>
   </BuildingAI>
   <Cost>
     <Population>3</Population>
Index: binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_onager.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_onager.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_onager.xml	(working copy)
@@ -53,6 +53,7 @@
   <Identity>
     <GenericName>Siege Catapult</GenericName>
     <Tooltip>Bonused vs. Structures and Massed Infantry.</Tooltip>
+    <Classes datatype="tokens">Ballista</Classes>
   </Identity>
   <Loot>
     <xp>300</xp>
Index: binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_tower.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_tower.xml	(revision 13617)
+++ binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_tower.xml	(working copy)
@@ -15,12 +15,15 @@
       <ProjectileSpeed>75.0</ProjectileSpeed>
       <PrepareTime>1200</PrepareTime>
       <RepeatTime>2000</RepeatTime>
+      <RestrictedClasses datatype="tokens">Structure</RestrictedClasses>
       <Spread>1.5</Spread>
     </Ranged>
   </Attack>
   <BuildingAI>
-    <DefaultArrowCount>1</DefaultArrowCount>
-    <GarrisonArrowMultiplier>1</GarrisonArrowMultiplier>
+    <DefaultProjectileCount>1</DefaultProjectileCount>
+    <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier>
+    <GarrisonProjectileClasses datatype="tokens">Infanty Ranged</GarrisonProjectileClasses>
+    <MaxNumberOfProjectiles>20</MaxNumberOfProjectiles>
   </BuildingAI>
   <Cost>
     <Population>5</Population>
