Index: binaries/data/mods/public/simulation/components/TerrainModifier.js
===================================================================
--- binaries/data/mods/public/simulation/components/TerrainModifier.js	(revision 0)
+++ binaries/data/mods/public/simulation/components/TerrainModifier.js	(working copy)
@@ -0,0 +1,115 @@
+function TerrainModifier() {};
+
+/*
+ * A component to calculate the height of different vertices for a height changing entity
+ */
+TerrainModifier.prototype.Schema =
+	"<element name='Type'>" +
+		"<choice>" +
+			"<value>flatten</value>" +
+			"<value>slopeWall</value>" +
+		"</choice>" +
+	"</element>";
+
+TerrainModifier.prototype.GetType = function()
+{
+	return this.template.Type;
+};
+
+/**
+ * All queried vertices will be in a relative square around this entity, 
+ * with as size the value from this method.
+ */
+TerrainModifier.prototype.GetBBox = function()
+{
+	if (this.bBox != undefined)
+		return this.bBox;
+
+	if (!this.footprint)
+	{
+		var cmpFootprint = Engine.QueryInterface(this.entity, IID_Footprint);
+		this.footprint = cmpFootprint.GetShape();
+	}
+	if (this.footprint.type == "square")
+		var max = Math.max(this.footprint.width, this.footprint.depth) + 6;
+	else
+		var max = this.footprint.radius * 2 + 6;
+	if (this.GetType() == "flatten")
+		this.bBox = max
+	else
+		this.bBox = Math.max(max, 100);
+	return this.bBox;
+};
+
+/**
+ * Calculate the new height for the relative point
+ * the oldHeight for that point, and the default entity height are given to save CPU time
+ *
+ * Note that the entity height will change when vertices near the centre 
+ * are modified in height
+ */
+TerrainModifier.prototype.GetNewHeight = function(point, oldHeight, entHeight)
+{
+	var r = {"height": oldHeight, "weight":0};
+	switch (this.GetType())
+	{
+	case "flatten":
+		var w = 0;
+		var fp = this.footprint;
+		// get the max distance from the footprint
+		if (fp.type == "square")
+			w = Math.max(Math.abs(point.x) - fp.width/2, Math.abs(point.y) - fp.depth/2);
+		else
+			w = Math.sqrt(Math.pow(point.x,2) + Math.pow(point.y,2)) - fp.radius;
+
+		// convert to a weight, where w == 1 is inside the footprint, 
+		// and w == 0 is far away from the footprint
+		// TODO: turn '6' into a variable, it's the cutoff from which point nothing is changed 
+		w = Math.max(Math.min(1 - w/6, 1), 0); 
+		r = {"height": (1 - w)*oldHeight + w*entHeight, "weight": w};
+		break;
+
+	case "slopeWall":
+		if (point.y <= 0 )
+		{
+			if (point.y > -8 && Math.abs(point.x) < 4)
+				r.weight = 10;
+			break;
+		}
+		var l = 50;// TODO put in variable, and bind with the bbox
+		var newHeight = this.footprint.height*(Math.atan(-7*point.y/l + 3.5) + 1.4)/2.6;
+		if (Math.abs(point.x) > this.footprint.width/2)
+		{
+			var mult = 1/(Math.abs(point.x) - this.footprint.width/2 + 2);
+			r.weight = mult/10;
+			r.height = mult*newHeight + oldHeight;
+		}
+		else
+		{
+			r.weight = (l-Math.abs(point.y))/l;
+			r.height = newHeight + (entHeight*(l - point.y) + oldHeight*point.y)/l;
+		}
+		break;
+	default:
+		warn("unknown terrain modifier type");
+		break;
+	}
+	return {"x": r.height, "y": r.weight}
+};
+
+TerrainModifier.prototype.OnPositionChanged = function(msg)
+{
+	var cmpTerrain = Engine.QueryInterface(SYSTEM_ENTITY, IID_Terrain);
+	cmpTerrain.MakeVisualTerrainDirty(this.entity, this.bBox);
+};
+
+TerrainModifier.prototype.OnDestroy = function(msg)
+{
+	var bBox = this.bBox;
+	this.bBox = 0; // disable terrain modifying capabilities of this entity
+	var cmpTerrain = Engine.QueryInterface(SYSTEM_ENTITY, IID_Terrain);
+	cmpTerrain.MakeVisualTerrainDirty(this.entity, bBox);
+};
+
+Engine.RegisterComponentType(IID_TerrainModifier, "TerrainModifier", TerrainModifier);
+
Index: binaries/data/mods/public/simulation/templates/structures/brit_wall_gate.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/brit_wall_gate.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/brit_wall_gate.xml	(working copy)
@@ -11,6 +11,9 @@
     <Square width="38.5" depth="9.0"/>
     <Height>9.0</Height>
   </Footprint>
+  <Health>
+    <Max>1500</Max>
+  </Health>
   <Identity>
     <Civ>brit</Civ>
     <SpecificName>Dor</SpecificName>
Index: binaries/data/mods/public/simulation/templates/structures/brit_wall_long.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/brit_wall_long.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/brit_wall_long.xml	(working copy)
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Entity parent="template_structure_defense_wall_long">
+  <Armour>
+    <Crush>20</Crush>
+  </Armour>
   <Footprint>
-    <Square width="38.5" depth="8.5"/>
+    <Square width="38.5" depth="12.5"/>
     <Height>9.0</Height>
   </Footprint>
   <Identity>
@@ -11,8 +14,13 @@
     <History>The Romans called this wall 'Murus Gallicus'. Translated, it means 'Gaulish wall'. It was extremely resistant to assault by battering ram. Julius Caesar described a type of wood and stone wall, known as a Murus Gallicus, in his account of the Gallic Wars. These walls were made of a stone wall filled with rubble, with wooden logs inside for stability. Caesar noted how the flexibility of the wood added to the strength of the fort in case of battering ram attack.</History>
   </Identity>
   <Obstruction>
-    <Static width="37.0" depth="7.0"/>
+    <Static width="37.0" depth="10.0"/>
   </Obstruction>
+  <TerrainModifier>
+    <Type>
+      slopeWall
+    </Type>
+  </TerrainModifier>
   <VisualActor>
     <Actor>structures/celts/wall_long.xml</Actor>
   </VisualActor>
Index: binaries/data/mods/public/simulation/templates/structures/brit_wall_medium.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/brit_wall_medium.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/brit_wall_medium.xml	(working copy)
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Entity parent="template_structure_defense_wall_medium">
+  <Armour>
+    <Crush>20</Crush>
+  </Armour>
   <Footprint>
-    <Square width="26.5" depth="8.5"/>
+    <Square width="26.5" depth="12.5"/>
     <Height>9.0</Height>
   </Footprint>
   <Health>
@@ -14,8 +17,13 @@
     <History>The Romans called this wall 'Murus Gallicus'. Translated, it means 'Gaulish wall'. It was extremely resistant to assault by battering ram. Julius Caesar described a type of wood and stone wall, known as a Murus Gallicus, in his account of the Gallic Wars. These walls were made of a stone wall filled with rubble, with wooden logs inside for stability. Caesar noted how the flexibility of the wood added to the strength of the fort in case of battering ram attack.</History>
   </Identity>
   <Obstruction>
-    <Static width="25.0" depth="7.0"/>
+    <Static width="25.0" depth="10.0"/>
   </Obstruction>
+  <TerrainModifier>
+    <Type>
+      slopeWall
+    </Type>
+  </TerrainModifier>
   <VisualActor>
     <Actor>structures/celts/wall_medium.xml</Actor>
   </VisualActor>
Index: binaries/data/mods/public/simulation/templates/structures/brit_wall_short.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/brit_wall_short.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/brit_wall_short.xml	(working copy)
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Entity parent="template_structure_defense_wall_short">
+  <Armour>
+    <Crush>20</Crush>
+  </Armour>
   <Footprint>
-    <Square width="14.5" depth="8.5"/>
+    <Square width="14.5" depth="12.5"/>
     <Height>9.0</Height>
   </Footprint>
   <Health>
@@ -14,8 +17,13 @@
     <History>The Romans called this wall 'Murus Gallicus'. Translated, it means 'Gaulish wall'. It was extremely resistant to assault by battering ram. Julius Caesar described a type of wood and stone wall, known as a Murus Gallicus, in his account of the Gallic Wars. These walls were made of a stone wall filled with rubble, with wooden logs inside for stability. Caesar noted how the flexibility of the wood added to the strength of the fort in case of battering ram attack.</History>
   </Identity>
   <Obstruction>
-    <Static width="13.0" depth="7.0"/>
+    <Static width="13.0" depth="10.0"/>
   </Obstruction>
+  <TerrainModifier>
+    <Type>
+      slopeWall
+    </Type>
+  </TerrainModifier>
   <VisualActor>
     <Actor>structures/celts/wall_short.xml</Actor>
   </VisualActor>
Index: binaries/data/mods/public/simulation/templates/structures/brit_wall_tower.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/brit_wall_tower.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/brit_wall_tower.xml	(working copy)
@@ -1,9 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Entity parent="template_structure_defense_wall_tower">
   <Attack disable=""/>
+  <Armour>
+    <Crush>20</Crush>
+  </Armour>
   <Footprint>
-    <Square width="10.0" depth="10.0"/>
-    <Height>20.0</Height>
+    <Square width="10.0" depth="13.0"/>
+    <Height>9.0</Height>
   </Footprint>
   <GarrisonHolder disable=""/>
   <Identity>
@@ -13,8 +16,13 @@
     <Tooltip>Does not shoot or garrison.</Tooltip>
   </Identity>
   <Obstruction>
-    <Static width="9.0" depth="9.0"/>
+    <Static width="9.0" depth="12.0"/>
   </Obstruction>
+  <TerrainModifier>
+    <Type>
+      slopeWall
+    </Type>
+  </TerrainModifier>
   <RallyPoint disable=""/>
   <VisualActor>
     <Actor>structures/celts/wall_tower.xml</Actor>
Index: binaries/data/mods/public/simulation/templates/structures/celt_wall_gate.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/celt_wall_gate.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/celt_wall_gate.xml	(working copy)
@@ -11,6 +11,9 @@
     <Square width="38.5" depth="9.0"/>
     <Height>9.0</Height>
   </Footprint>
+  <Health>
+    <Max>1500</Max>
+  </Health>
   <Identity>
     <Civ>celt</Civ>
     <SpecificName>Gate</SpecificName>
Index: binaries/data/mods/public/simulation/templates/structures/celt_wall_long.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/celt_wall_long.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/celt_wall_long.xml	(working copy)
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Entity parent="template_structure_defense_wall_long">
+  <Armour>
+    <Crush>20</Crush>
+  </Armour>
   <Footprint>
-    <Square width="38.5" depth="8.5"/>
+    <Square width="38.5" depth="12.5"/>
     <Height>9.0</Height>
   </Footprint>
   <Identity>
@@ -11,8 +14,13 @@
     <History>The Romans called this wall 'Murus Gallicus'. Translated, it means 'Gaulish wall'. It was extremely resistant to assault by battering ram. Julius Caesar described a type of wood and stone wall, known as a Murus Gallicus, in his account of the Gallic Wars. These walls were made of a stone wall filled with rubble, with wooden logs inside for stability. Caesar noted how the flexibility of the wood added to the strength of the fort in case of battering ram attack.</History>
   </Identity>
   <Obstruction>
-    <Static width="37.0" depth="7.0"/>
+    <Static width="37.0" depth="10.0"/>
   </Obstruction>
+  <TerrainModifier>
+    <Type>
+      slopeWall
+    </Type>
+  </TerrainModifier>
   <VisualActor>
     <Actor>structures/celts/wall_long.xml</Actor>
   </VisualActor>
Index: binaries/data/mods/public/simulation/templates/structures/celt_wall_medium.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/celt_wall_medium.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/celt_wall_medium.xml	(working copy)
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Entity parent="template_structure_defense_wall_medium">
+  <Armour>
+    <Crush>20</Crush>
+  </Armour>
   <Footprint>
-    <Square width="26.5" depth="8.5"/>
+    <Square width="26.5" depth="12.5"/>
     <Height>9.0</Height>
   </Footprint>
   <Health>
@@ -14,8 +17,13 @@
     <History>The Romans called this wall 'Murus Gallicus'. Translated, it means 'Gaulish wall'. It was extremely resistant to assault by battering ram. Julius Caesar described a type of wood and stone wall, known as a Murus Gallicus, in his account of the Gallic Wars. These walls were made of a stone wall filled with rubble, with wooden logs inside for stability. Caesar noted how the flexibility of the wood added to the strength of the fort in case of battering ram attack.</History>
   </Identity>
   <Obstruction>
-    <Static width="25.0" depth="7.0"/>
+    <Static width="25.0" depth="10.0"/>
   </Obstruction>
+  <TerrainModifier>
+    <Type>
+      slopeWall
+    </Type>
+  </TerrainModifier>
   <VisualActor>
     <Actor>structures/celts/wall_medium.xml</Actor>
   </VisualActor>
Index: binaries/data/mods/public/simulation/templates/structures/celt_wall_short.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/celt_wall_short.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/celt_wall_short.xml	(working copy)
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Entity parent="template_structure_defense_wall_short">
+  <Armour>
+    <Crush>20</Crush>
+  </Armour>
   <Footprint>
-    <Square width="14.5" depth="8.5"/>
+    <Square width="14.5" depth="12.5"/>
     <Height>9.0</Height>
   </Footprint>
   <Health>
@@ -14,8 +17,13 @@
     <History>The Romans called this wall 'Murus Gallicus'. Translated, it means 'Gaulish wall'. It was extremely resistant to assault by battering ram. Julius Caesar described a type of wood and stone wall, known as a Murus Gallicus, in his account of the Gallic Wars. These walls were made of a stone wall filled with rubble, with wooden logs inside for stability. Caesar noted how the flexibility of the wood added to the strength of the fort in case of battering ram attack.</History>
   </Identity>
   <Obstruction>
-    <Static width="13.0" depth="7.0"/>
+    <Static width="13.0" depth="10.0"/>
   </Obstruction>
+  <TerrainModifier>
+    <Type>
+      slopeWall
+    </Type>
+  </TerrainModifier>
   <VisualActor>
     <Actor>structures/celts/wall_short.xml</Actor>
   </VisualActor>
Index: binaries/data/mods/public/simulation/templates/structures/celt_wall_tower.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/celt_wall_tower.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/celt_wall_tower.xml	(working copy)
@@ -1,9 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Entity parent="template_structure_defense_wall_tower">
   <Attack disable=""/>
+  <Armour>
+    <Crush>20</Crush>
+  </Armour>
   <Footprint>
-    <Square width="10.0" depth="10.0"/>
-    <Height>20.0</Height>
+    <Square width="10.0" depth="13.0"/>
+    <Height>9.0</Height>
   </Footprint>
   <GarrisonHolder disable=""/>
   <Identity>
@@ -13,9 +16,14 @@
     <Tooltip>Does not shoot or garrison.</Tooltip>
   </Identity>
   <Obstruction>
-    <Static width="9.0" depth="9.0"/>
+    <Static width="9.0" depth="12.0"/>
   </Obstruction>
   <RallyPoint disable=""/>
+  <TerrainModifier>
+    <Type>
+      slopeWall
+    </Type>
+  </TerrainModifier>
   <VisualActor>
     <Actor>structures/celts/wall_tower.xml</Actor>
   </VisualActor>
Index: binaries/data/mods/public/simulation/templates/structures/gaul_wall_gate.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/gaul_wall_gate.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/gaul_wall_gate.xml	(working copy)
@@ -11,6 +11,9 @@
     <Square width="38.5" depth="9.0"/>
     <Height>9.0</Height>
   </Footprint>
+  <Health>
+    <Max>1500</Max>
+  </Health>
   <Identity>
     <Civ>gaul</Civ>
     <SpecificName>Duro</SpecificName>
Index: binaries/data/mods/public/simulation/templates/structures/gaul_wall_long.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/gaul_wall_long.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/gaul_wall_long.xml	(working copy)
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Entity parent="template_structure_defense_wall_long">
+  <Armour>
+    <Crush>20</Crush>
+  </Armour>
   <Footprint>
-    <Square width="38.5" depth="8.5"/>
+    <Square width="38.5" depth="12.5"/>
     <Height>9.0</Height>
   </Footprint>
   <Identity>
@@ -11,8 +14,13 @@
     <History>The Romans called this wall 'Murus Gallicus'. Translated, it means 'Gaulish wall'. It was extremely resistant to assault by battering ram. Julius Caesar described a type of wood and stone wall, known as a Murus Gallicus, in his account of the Gallic Wars. These walls were made of a stone wall filled with rubble, with wooden logs inside for stability. Caesar noted how the flexibility of the wood added to the strength of the fort in case of battering ram attack.</History>
   </Identity>
   <Obstruction>
-    <Static width="37.0" depth="7.0"/>
+    <Static width="37.0" depth="10.0"/>
   </Obstruction>
+  <TerrainModifier>
+    <Type>
+      slopeWall
+    </Type>
+  </TerrainModifier>
   <VisualActor>
     <Actor>structures/celts/wall_long.xml</Actor>
   </VisualActor>
Index: binaries/data/mods/public/simulation/templates/structures/gaul_wall_medium.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/gaul_wall_medium.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/gaul_wall_medium.xml	(working copy)
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Entity parent="template_structure_defense_wall_medium">
+  <Armour>
+    <Crush>20</Crush>
+  </Armour>
   <Footprint>
-    <Square width="26.5" depth="8.5"/>
+    <Square width="26.5" depth="12.5"/>
     <Height>9.0</Height>
   </Footprint>
   <Health>
@@ -14,8 +17,13 @@
     <History>The Romans called this wall 'Murus Gallicus'. Translated, it means 'Gaulish wall'. It was extremely resistant to assault by battering ram. Julius Caesar described a type of wood and stone wall, known as a Murus Gallicus, in his account of the Gallic Wars. These walls were made of a stone wall filled with rubble, with wooden logs inside for stability. Caesar noted how the flexibility of the wood added to the strength of the fort in case of battering ram attack.</History>
   </Identity>
   <Obstruction>
-    <Static width="25.0" depth="7.0"/>
+    <Static width="25.0" depth="10.0"/>
   </Obstruction>
+  <TerrainModifier>
+    <Type>
+      slopeWall
+    </Type>
+  </TerrainModifier>
   <VisualActor>
     <Actor>structures/celts/wall_medium.xml</Actor>
   </VisualActor>
Index: binaries/data/mods/public/simulation/templates/structures/gaul_wall_short.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/gaul_wall_short.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/gaul_wall_short.xml	(working copy)
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Entity parent="template_structure_defense_wall_short">
+  <Armour>
+    <Crush>20</Crush>
+  </Armour>
   <Footprint>
-    <Square width="14.5" depth="8.5"/>
+    <Square width="14.5" depth="12.5"/>
     <Height>9.0</Height>
   </Footprint>
   <Health>
@@ -14,8 +17,13 @@
     <History>The Romans called this wall 'Murus Gallicus'. Translated, it means 'Gaulish wall'. It was extremely resistant to assault by battering ram. Julius Caesar described a type of wood and stone wall, known as a Murus Gallicus, in his account of the Gallic Wars. These walls were made of a stone wall filled with rubble, with wooden logs inside for stability. Caesar noted how the flexibility of the wood added to the strength of the fort in case of battering ram attack.</History>
   </Identity>
   <Obstruction>
-    <Static width="13.0" depth="7.0"/>
+    <Static width="13.0" depth="10.0"/>
   </Obstruction>
+  <TerrainModifier>
+    <Type>
+      slopeWall
+    </Type>
+  </TerrainModifier>
   <VisualActor>
     <Actor>structures/celts/wall_short.xml</Actor>
   </VisualActor>
Index: binaries/data/mods/public/simulation/templates/structures/gaul_wall_tower.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/gaul_wall_tower.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/gaul_wall_tower.xml	(working copy)
@@ -1,9 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Entity parent="template_structure_defense_wall_tower">
   <Attack disable=""/>
+  <Armour>
+    <Crush>20</Crush>
+  </Armour>
   <Footprint>
-    <Square width="10.0" depth="10.0"/>
-    <Height>20.0</Height>
+    <Square width="10.0" depth="13.0"/>
+    <Height>9.0</Height>
   </Footprint>
   <GarrisonHolder disable=""/>
   <Identity>
@@ -13,8 +16,13 @@
     <Tooltip>Does not shoot or garrison.</Tooltip>
   </Identity>
   <Obstruction>
-    <Static width="9.0" depth="9.0"/>
+    <Static width="9.0" depth="12.0"/>
   </Obstruction>
+  <TerrainModifier>
+    <Type>
+      slopeWall
+    </Type>
+  </TerrainModifier>
   <RallyPoint disable=""/>
   <VisualActor>
     <Actor>structures/celts/wall_tower.xml</Actor>
Index: binaries/data/mods/public/simulation/templates/structures/iber_house.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/structures/iber_house.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/structures/iber_house.xml	(working copy)
@@ -19,6 +19,11 @@
     <Radius>16</Radius>
     <Weight>65536</Weight>
   </TerritoryInfluence>
+  <TerrainModifier>
+    <Type>
+      flatten
+    </Type>
+  </TerrainModifier>
   <VisualActor>
     <Actor>structures/iberians/house.xml</Actor>
     <FoundationActor>structures/fndn_2x2.xml</FoundationActor>
Index: binaries/data/mods/public/simulation/templates/template_structure_defense_wall.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure_defense_wall.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/template_structure_defense_wall.xml	(working copy)
@@ -48,6 +48,7 @@
     <Radius>20</Radius>
     <Weight>65536</Weight>
   </TerritoryInfluence>
+  <TerrainModifier disable=""/>
   <Vision>
     <Range>20</Range>
   </Vision>
Index: binaries/data/mods/public/simulation/templates/template_structure_defense_wall_long.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure_defense_wall_long.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/template_structure_defense_wall_long.xml	(working copy)
@@ -10,7 +10,7 @@
 	<SpawnEntityOnDeath>rubble/rubble_stone_wall_long</SpawnEntityOnDeath>
   </Health>
   <Identity>
-    <Classes datatype="tokens">LongWall</Classes>
-    <Tooltip>Long wall segments can be converted to gates.</Tooltip>
-  </Identity>
-</Entity>
+    <Classes datatype="tokens">LongWall</Classes>
+    <Tooltip>Long wall segments can be converted to gates.</Tooltip>
+  </Identity>
+</Entity>
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 14232)
+++ binaries/data/mods/public/simulation/templates/template_structure_defense_wall_tower.xml	(working copy)
@@ -85,6 +85,7 @@
   <StatusBars>
     <HeightOffset>20.0</HeightOffset>
   </StatusBars>
+  <TerrainModifier disable=""/>
   <TerritoryInfluence>
     <Root>false</Root>
     <Radius>20</Radius>
Index: binaries/data/mods/public/simulation/templates/template_structure_military_dock.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure_military_dock.xml	(revision 14232)
+++ binaries/data/mods/public/simulation/templates/template_structure_military_dock.xml	(working copy)
@@ -53,6 +53,7 @@
     </SoundGroups>
   </Sound>
   <TerritoryDecay disable=""/>
+  <TerrainModifier disable=""/>
   <ProductionQueue>
     <BatchTimeModifier>0.8</BatchTimeModifier>
     <Entities datatype="tokens">
Index: source/graphics/MapReader.cpp
===================================================================
--- source/graphics/MapReader.cpp	(revision 14232)
+++ source/graphics/MapReader.cpp	(working copy)
@@ -218,6 +218,7 @@
 //		- data: map size, heightmap, list of textures used by map, texture tile assignments
 int CMapReader::UnpackTerrain()
 {
+	printf("start unpackTerrain\n");
 	// yield after this time is reached. balances increased progress bar
 	// smoothness vs. slowing down loading.
 	const double end_time = timer_Time() + 200e-3;
@@ -260,6 +261,7 @@
 
 	// reset generator state.
 	cur_terrain_tex = 0;
+	printf("stop unpackTerrain\n");
 
 	return 0;
 }
@@ -267,6 +269,7 @@
 // ApplyData: take all the input data, and rebuild the scene from it
 int CMapReader::ApplyData()
 {
+	printf("start ApplyData\n");
 	if (m_PatchesPerSide == 0)
 	{
 		// we'll probably crash when trying to use this map later
@@ -330,6 +333,7 @@
 	CmpPtr<ICmpTerrain> cmpTerrain(*pSimContext, SYSTEM_ENTITY);
 	if (cmpTerrain)
 		cmpTerrain->ReloadTerrain();
+	printf("stop ApplyData\n");
 
 	return 0;
 }
Index: source/graphics/Terrain.cpp
===================================================================
--- source/graphics/Terrain.cpp	(revision 14232)
+++ source/graphics/Terrain.cpp	(working copy)
@@ -40,7 +40,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // CTerrain constructor
 CTerrain::CTerrain()
-: m_Heightmap(0), m_Patches(0), m_MapSize(0), m_MapSizePatches(0),
+: m_VisualHeightmap(0), m_OrigHeightmap(0), m_Patches(0), m_MapSize(0), m_MapSizePatches(0),
 m_BaseColour(255, 255, 255, 255)
 {
 }
@@ -59,7 +59,8 @@
 {
 	m_HeightMipmap.ReleaseData();
 
-	delete[] m_Heightmap;
+	delete[] m_VisualHeightmap;
+	delete[] m_OrigHeightmap;
 	delete[] m_Patches;
 }
 
@@ -76,7 +77,9 @@
 	m_MapSize = patchesPerSide*PATCH_SIZE+1;
 	m_MapSizePatches = patchesPerSide;
 	// allocate data for new terrain
-	m_Heightmap = new u16[m_MapSize*m_MapSize];
+	m_VisualHeightmap = new u16[m_MapSize*m_MapSize];
+	m_OrigHeightmap = new u16[m_MapSize*m_MapSize];
+	m_Heightmap = m_VisualHeightmap;
 	m_Patches = new CPatch[m_MapSizePatches*m_MapSizePatches];
 
 	// given a heightmap?
@@ -83,12 +86,14 @@
 	if (data)
 	{
 		// yes; keep a copy of it
-		memcpy(m_Heightmap, data, m_MapSize*m_MapSize*sizeof(u16));
+		memcpy(m_OrigHeightmap, data, m_MapSize*m_MapSize*sizeof(u16));
+		memcpy(m_VisualHeightmap, data, m_MapSize*m_MapSize*sizeof(u16));
 	}
 	else
 	{
 		// build a flat terrain
-		memset(m_Heightmap, 0, m_MapSize*m_MapSize*sizeof(u16));
+		memset(m_OrigHeightmap, 0, m_MapSize*m_MapSize*sizeof(u16));
+		memset(m_VisualHeightmap, 0, m_MapSize*m_MapSize*sizeof(u16));
 	}
 
 	// setup patch parents, indices etc
@@ -95,13 +100,24 @@
 	InitialisePatches();
 
 	// initialise mipmap
-	m_HeightMipmap.Initialize(m_MapSize, m_Heightmap);
+	m_HeightMipmap.Initialize(m_MapSize, m_VisualHeightmap);
 
 	return true;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// Switch between querying the original height map or the visual height map
+// For most purposes, querying the visual height map is best as it confirms what the player sees
+void CTerrain::WorkOnOrigHeightMap(bool f)
+{
+	if (f) 
+		m_Heightmap = m_OrigHeightmap;
+	else
+		m_Heightmap = m_VisualHeightmap;
+}
 
+//////////////////////////////////////////////////////////////////////////////
+// Get the 8-bit movement class used in the pathfinder
 CStr8 CTerrain::GetMovementClass(ssize_t i, ssize_t j) const
 {
 	CMiniPatch* tile = GetTile(i, j);
@@ -460,27 +476,35 @@
 
 	// allocate data for new terrain
 	ssize_t newMapSize=size*PATCH_SIZE+1;
-	u16* newHeightmap=new u16[newMapSize*newMapSize];
+	u16* newOrigHeightmap=new u16[newMapSize*newMapSize];
+	u16* newVisualHeightmap=new u16[newMapSize*newMapSize];
 	CPatch* newPatches=new CPatch[size*size];
 
 	if (size>m_MapSizePatches) {
 		// new map is bigger than old one - zero the heightmap so we don't get uninitialised
 		// height data along the expanded edges
-		memset(newHeightmap,0,newMapSize*newMapSize*sizeof(u16));
+		memset(newOrigHeightmap,0,newMapSize*newMapSize*sizeof(u16));
+		memset(newVisualHeightmap,0,newMapSize*newMapSize*sizeof(u16));
 	}
 
 	// now copy over rows of data
-	u16* src=m_Heightmap;
-	u16* dst=newHeightmap;
+	u16* src1=m_VisualHeightmap;
+	u16* src2=m_OrigHeightmap;
+	u16* dst1=newVisualHeightmap;
+	u16* dst2=newOrigHeightmap;
 	ssize_t copysize=std::min(newMapSize, m_MapSize);
 	for (ssize_t j=0;j<copysize;j++) {
-		memcpy(dst,src,copysize*sizeof(u16));
-		dst+=copysize;
-		src+=m_MapSize;
+		memcpy(dst1,src1,copysize*sizeof(u16));
+		memcpy(dst2,src2,copysize*sizeof(u16));
+		dst1+=copysize;
+		dst2+=copysize;
+		src1+=m_MapSize;
+		src2+=m_MapSize;
 		if (newMapSize>m_MapSize) {
 			// extend the last height to the end of the row
 			for (size_t i=0;i<newMapSize-(size_t)m_MapSize;i++) {
-				*dst++=*(src-1);
+				*dst1++=*(src1-1);
+				*dst2++=*(src2-1);
 			}
 		}
 	}
@@ -488,11 +512,15 @@
 
 	if (newMapSize>m_MapSize) {
 		// copy over heights of the last row to any remaining rows
-		src=newHeightmap+((m_MapSize-1)*newMapSize);
-		dst=src+newMapSize;
+		src1=newVisualHeightmap+((m_MapSize-1)*newMapSize);
+		src2=newOrigHeightmap+((m_MapSize-1)*newMapSize);
+		dst1=src1+newMapSize;
+		dst2=src2+newMapSize;
 		for (ssize_t i=0;i<newMapSize-m_MapSize;i++) {
-			memcpy(dst,src,newMapSize*sizeof(u16));
-			dst+=newMapSize;
+			memcpy(dst1,src1,newMapSize*sizeof(u16));
+			memcpy(dst2,src2,newMapSize*sizeof(u16));
+			dst1+=newMapSize;
+			dst2+=newMapSize;
 		}
 	}
 
@@ -543,7 +571,9 @@
 	ReleaseData();
 
 	// store new data
-	m_Heightmap=newHeightmap;
+	m_VisualHeightmap=newVisualHeightmap;
+	m_OrigHeightmap=newOrigHeightmap;
+	m_Heightmap=newVisualHeightmap;
 	m_Patches=newPatches;
 	m_MapSize=(ssize_t)newMapSize;
 	m_MapSizePatches=(ssize_t)size;
@@ -575,7 +605,8 @@
 void CTerrain::SetHeightMap(u16* heightmap)
 {
 	// keep a copy of the given heightmap
-	memcpy(m_Heightmap, heightmap, m_MapSize*m_MapSize*sizeof(u16));
+	memcpy(m_VisualHeightmap, heightmap, m_MapSize*m_MapSize*sizeof(u16));
+	memcpy(m_OrigHeightmap, heightmap, m_MapSize*m_MapSize*sizeof(u16));
 
 	// recalculate patch bounds, invalidate vertices
 	for (ssize_t j = 0; j < m_MapSizePatches; j++)
Index: source/graphics/Terrain.h
===================================================================
--- source/graphics/Terrain.h	(revision 14232)
+++ source/graphics/Terrain.h	(working copy)
@@ -101,7 +101,11 @@
 	void SetHeightMap(u16* heightmap);
 	// return a pointer to the heightmap
 	u16* GetHeightMap() const { return m_Heightmap; }
+	u16* GetVisualHeightMap() const { return m_VisualHeightmap; }
+	u16* GetOrigHeightMap() const { return m_OrigHeightmap; }
 
+	void WorkOnOrigHeightMap(bool f);
+
 	// get patch at given coordinates, expressed in patch-space; return 0 if
 	// coordinates represent patch off the edge of the map
 	CPatch* GetPatch(ssize_t i, ssize_t j) const; 
@@ -169,6 +173,8 @@
 	CPatch*	m_Patches;
 	// 16-bit heightmap data
 	u16* m_Heightmap;
+	u16* m_VisualHeightmap;
+	u16* m_OrigHeightmap;
 	// base colour (usually white)
 	SColor4ub m_BaseColour;
 	// heightmap mipmap
Index: source/simulation2/TypeList.h
===================================================================
--- source/simulation2/TypeList.h	(revision 14232)
+++ source/simulation2/TypeList.h	(working copy)
@@ -148,6 +148,9 @@
 INTERFACE(Terrain)
 COMPONENT(Terrain)
 
+INTERFACE(TerrainModifier)
+COMPONENT(TerrainModifierScripted)
+
 INTERFACE(TerritoryInfluence)
 COMPONENT(TerritoryInfluence)
 
Index: source/simulation2/components/CCmpTerrain.cpp
===================================================================
--- source/simulation2/components/CCmpTerrain.cpp	(revision 14232)
+++ source/simulation2/components/CCmpTerrain.cpp	(working copy)
@@ -20,13 +20,18 @@
 #include "simulation2/system/Component.h"
 #include "ICmpTerrain.h"
 
+#include "ICmpTerrainModifier.h"
 #include "ICmpObstructionManager.h"
 #include "ICmpRangeManager.h"
+#include "ICmpPosition.h"
 #include "simulation2/MessageTypes.h"
+#include "simulation2/helpers/Geometry.h"
 
 #include "graphics/Terrain.h"
 #include "renderer/Renderer.h"
 #include "renderer/WaterManager.h"
+#include "graphics/Patch.h"
+#include "maths/MathUtil.h"
 #include "maths/Vector3D.h"
 
 class CCmpTerrain : public ICmpTerrain
@@ -68,6 +73,18 @@
 		return m_Terrain->GetVerticesPerSide() != 0;
 	}
 
+
+	virtual u16* GetSimHeightMap()
+	{
+		return m_Terrain->GetOrigHeightMap();
+	}
+
+	virtual void MakeVisualTerrainDirty(entity_id_t ent, fixed bBox)
+	{
+		if (m_Terrain->GetPatchesPerSide())
+			RecalculateVisualHeightmap(ent, bBox);
+	}
+
 	virtual CFixedVector3D CalcNormal(entity_pos_t x, entity_pos_t z)
 	{
 		CFixedVector3D normal;
@@ -83,7 +100,6 @@
 	virtual entity_pos_t GetGroundLevel(entity_pos_t x, entity_pos_t z)
 	{
 		// TODO: this can crash if the terrain heightmap isn't initialised yet
-
 		return m_Terrain->GetExactGroundLevelFixed(x, z);
 	}
 
@@ -102,7 +118,7 @@
 	virtual u16 GetVerticesPerSide()
 	{
 		ssize_t vertices = m_Terrain->GetVerticesPerSide();
-		ENSURE(1 <= vertices && vertices <= 65535);
+		ENSURE(1 < vertices && vertices <= 65535);
 		return (u16)vertices;
 	}
 
@@ -111,10 +127,150 @@
 		return m_Terrain;
 	}
 
+	struct IterateHeightmapAverage
+	{
+		u16* resultHeightmap;
+		int pitch;
+
+		// weighted sum of the wanted heights
+		fixed* avgHeightmap;
+		// sum of the weights
+		fixed* sumWeightmap;
+
+		void operator()(int i, int j, fixed weight, fixed newHeight)
+		{
+			if (weight > fixed::Zero())
+			{
+				fixed sumWeight = sumWeightmap[i+j*pitch] + weight;
+				// avoid overflows by dividing before multiplying
+				avgHeightmap[i+j*pitch] = (avgHeightmap[i+j*pitch]/sumWeight).Multiply(sumWeightmap[i+j*pitch]) + (newHeight/sumWeight).Multiply(weight);
+				
+				sumWeightmap[i+j*pitch] = sumWeight;
+				int h = HEIGHT_UNITS_PER_METRE*avgHeightmap[i+j*pitch].ToInt_RoundToNearest();
+				resultHeightmap[i + j*pitch] = Clamp(h, 0, 65535);
+			}
+		}
+	};
+
+	template<typename T>
+	void IterateHeightmap(T& callback, CFixedVector2D pos, fixed angle, entity_id_t ent, int iMin, int jMin, int iMax, int jMax)
+	{
+		CmpPtr<ICmpTerrainModifier> CCmpTerrainModifier(GetSimContext(), ent);
+		// get the bbox, multiply by sqrt(2)/2 (rounded up) to get half the size and take
+		// account of possible rotations
+		fixed BBoxSize = CCmpTerrainModifier->GetBBox()/2;
+		fixed maxBBoxSize = BBoxSize*142/100;
+		int numVerts = GetVerticesPerSide();
+
+		int i0 = ((pos.X - maxBBoxSize) / TERRAIN_TILE_SIZE).ToInt_RoundToNegInfinity();
+		int i1 = ((pos.X + maxBBoxSize) / TERRAIN_TILE_SIZE).ToInt_RoundToInfinity();
+		int j0 = ((pos.Y - maxBBoxSize) / TERRAIN_TILE_SIZE).ToInt_RoundToNegInfinity();
+		int j1 = ((pos.Y + maxBBoxSize) / TERRAIN_TILE_SIZE).ToInt_RoundToInfinity();
+		i0 = Clamp(i0, iMin, numVerts);
+		i1 = Clamp(i1, 0, iMax);
+		j0 = Clamp(j0, jMin, numVerts);
+		j1 = Clamp(j1, 0, jMax);
+
+		fixed entHeight = m_Terrain->GetExactGroundLevelFixed(pos.X, pos.Y);
+		for (int j = j0; j <= j1; ++j)
+		{
+			for (int i = i0; i <= i1; ++i)
+			{
+				CFixedVector2D pt = CFixedVector2D(fixed::FromInt(i*TERRAIN_TILE_SIZE), fixed::FromInt(j*TERRAIN_TILE_SIZE)) - CFixedVector2D(pos.X, pos.Y);
+				pt = pt.Rotate(-angle);
+				if (pt.X.Absolute() > BBoxSize || pt.Y.Absolute() > BBoxSize)
+					continue;
+				fixed oldHeight = m_Terrain->GetVertexGroundLevelFixed(i, j);
+				fixed newHeight, weight;
+				CCmpTerrainModifier->GetNewHeight(pt, oldHeight, entHeight, newHeight, weight);
+				callback(i, j, weight, newHeight);
+			}
+		}
+		MakeDirty(i0, j0, i1, j1);
+	}
+
+	void RecalculateVisualHeightmap(entity_id_t ent, fixed bBox)
+	{
+		u16* origHeightmap = m_Terrain->GetOrigHeightMap();
+		u16* visualHeightmap = m_Terrain->GetVisualHeightMap();
+		m_Terrain->WorkOnOrigHeightMap(true);
+		int pitch = GetVerticesPerSide();
+
+		IterateHeightmapAverage callback;
+		callback.resultHeightmap = visualHeightmap;
+		callback.pitch = pitch;
+		std::vector<fixed> avgHeightmap(pitch * pitch, fixed::Zero());
+		callback.avgHeightmap = &avgHeightmap[0];
+		std::vector<fixed> sumWeightmap(pitch * pitch, fixed::Zero());
+		callback.sumWeightmap = &sumWeightmap[0];
+
+		int iMin, jMin, iMax, jMax;
+		iMin = jMin = 0;
+		iMax = jMax = GetVerticesPerSide();
+		// TODO Halp, why does it CRASHSSSHSSHS?
+		/*if (ent != INVALID_ENTITY)
+		{
+			CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), ent);
+			if (cmpPosition && cmpPosition->IsInWorld())
+			{
+				CFixedVector2D posMin, posMax; 
+				posMin = cmpPosition->GetPosition2D();
+				posMax = cmpPosition->GetPreviousPosition2D();
+				if (posMin.X > posMax.X)
+				{
+					fixed c = posMax.X;
+					posMax.X = posMin.X;
+					posMin.X = c;
+				}
+				if (posMin.Y > posMax.Y)
+				{
+					fixed c = posMax.Y;
+					posMax.Y = posMin.Y;
+					posMin.Y = c;
+				}
+				
+				fixed maxBBoxSize = bBox*142/200;
+				int numVerts = GetVerticesPerSide();
+
+				iMin = ((posMin.X - maxBBoxSize) / TERRAIN_TILE_SIZE).ToInt_RoundToNegInfinity();
+				iMax = ((posMax.X + maxBBoxSize) / TERRAIN_TILE_SIZE).ToInt_RoundToInfinity() + 1;
+				jMin = ((posMin.Y - maxBBoxSize) / TERRAIN_TILE_SIZE).ToInt_RoundToNegInfinity();
+				jMax = ((posMax.Y + maxBBoxSize) / TERRAIN_TILE_SIZE).ToInt_RoundToInfinity() + 1;
+				iMin = Clamp(iMin, 0, numVerts);
+				iMax = Clamp(iMax, 0, numVerts);
+				jMin = Clamp(jMin, 0, numVerts);
+				jMax = Clamp(jMax, 0, numVerts);
+			}
+		}
+		// reset the visual heightmap for the found region
+		for (int j = jMin; j < jMax; ++j)
+			for (int i = iMin; i < iMax; ++i)
+				visualHeightmap[i + j*pitch] = origHeightmap[i + j*pitch];
+		*/
+		memcpy(visualHeightmap, origHeightmap, pitch*pitch*sizeof(u16));
+
+		// recalculate the visual heightmap by iterating over all entities with the 
+		// TerrainModifier component
+		CComponentManager::InterfaceList ents = GetSimContext().GetComponentManager().GetEntitiesWithInterface(IID_TerrainModifier);
+		for (CComponentManager::InterfaceList::const_iterator it = ents.begin(); it != ents.end(); ++it)
+		{
+			CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), it->first);
+			if (cmpPosition && cmpPosition->IsInWorld())
+			{
+				CFixedVector2D pos = cmpPosition->GetPosition2D();
+				fixed angle = cmpPosition->GetRotation().Y;
+
+				IterateHeightmap(callback, pos, angle, it->first, iMin, jMin, iMax, jMax);
+			}
+		}
+
+		m_Terrain->WorkOnOrigHeightMap(false);
+		m_Terrain->MakeDirty(RENDERDATA_UPDATE_VERTICES);
+	}
+
 	virtual void ReloadTerrain()
 	{
 		// TODO: should refactor this code to be nicer
-
 		u16 tiles = GetTilesPerSide();
 		u16 vertices = GetVerticesPerSide();
 
@@ -138,7 +294,8 @@
 		if (CRenderer::IsInitialised())
 			g_Renderer.GetWaterManager()->SetMapSize(vertices);
 
-		MakeDirty(0, 0, tiles+1, tiles+1);
+		MakeDirty(0, 0, tiles + 1, tiles + 1);
+		MakeVisualTerrainDirty(INVALID_ENTITY, fixed::Zero());
 	}
 
 	virtual void MakeDirty(i32 i0, i32 j0, i32 i1, i32 j1)
Index: source/simulation2/components/ICmpTerrain.cpp
===================================================================
--- source/simulation2/components/ICmpTerrain.cpp	(revision 14232)
+++ source/simulation2/components/ICmpTerrain.cpp	(working copy)
@@ -25,4 +25,5 @@
 DEFINE_INTERFACE_METHOD_2("GetGroundLevel", entity_pos_t, ICmpTerrain, GetGroundLevel, entity_pos_t, entity_pos_t)
 DEFINE_INTERFACE_METHOD_2("CalcNormal", CFixedVector3D, ICmpTerrain, CalcNormal, entity_pos_t, entity_pos_t)
 DEFINE_INTERFACE_METHOD_0("GetTilesPerSide", u16, ICmpTerrain, GetTilesPerSide)
+DEFINE_INTERFACE_METHOD_2("MakeVisualTerrainDirty", void, ICmpTerrain, MakeVisualTerrainDirty, entity_id_t, fixed)
 END_INTERFACE_WRAPPER(Terrain)
Index: source/simulation2/components/ICmpTerrain.h
===================================================================
--- source/simulation2/components/ICmpTerrain.h	(revision 14232)
+++ source/simulation2/components/ICmpTerrain.h	(working copy)
@@ -32,6 +32,10 @@
 public:
 	virtual bool IsLoaded() = 0;
 
+	virtual u16* GetSimHeightMap() = 0;
+
+	virtual void MakeVisualTerrainDirty(entity_id_t ent, entity_pos_t bBox) = 0;
+
 	virtual CFixedVector3D CalcNormal(entity_pos_t x, entity_pos_t z) = 0;
 
 	virtual CVector3D CalcExactNormal(float x, float z) = 0;
Index: source/simulation2/components/ICmpTerrainModifier.cpp
===================================================================
--- source/simulation2/components/ICmpTerrainModifier.cpp	(revision 0)
+++ source/simulation2/components/ICmpTerrainModifier.cpp	(working copy)
@@ -0,0 +1,49 @@
+/* Copyright (C) 2013 Wildfire Games. 
+* This file is part of 0 A.D. 
+* 
+* 0 A.D. is free software: you can redistribute it and/or modify 
+* it under the terms of the GNU General Public License as published by 
+* the Free Software Foundation, either version 2 of the License, or 
+* (at your option) any later version. 
+* 
+* 0 A.D. is distributed in the hope that it will be useful, 
+* but WITHOUT ANY WARRANTY; without even the implied warranty of 
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+* GNU General Public License for more details. 
+* 
+* You should have received a copy of the GNU General Public License 
+* along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>. 
+*/ 
+
+#include "precompiled.h" 
+
+#include "ICmpTerrainModifier.h" 
+
+#include "simulation2/system/InterfaceScripted.h" 
+#include "simulation2/scripting/ScriptComponent.h" 
+
+BEGIN_INTERFACE_WRAPPER(TerrainModifier) 
+END_INTERFACE_WRAPPER(TerrainModifier) 
+
+
+class CCmpTerrainModifierScripted : public ICmpTerrainModifier 
+{ 
+public: 
+	DEFAULT_SCRIPT_WRAPPER(TerrainModifierScripted) 
+
+	virtual fixed GetBBox() 
+	{ 
+		return m_Script.Call<fixed>("GetBBox"); 
+	} 
+
+	virtual void GetNewHeight(CFixedVector2D relPt, fixed oldHeight, fixed entHeight, fixed& newHeight, fixed& weight) 
+	{ 
+		// TODO Use std::vector<float> instead??? 
+		CFixedVector2D v = m_Script.Call<CFixedVector2D>("GetNewHeight", relPt, oldHeight, entHeight); 
+		newHeight = v.X; 
+		weight = v.Y; 
+	} 
+}; 
+
+REGISTER_COMPONENT_SCRIPT_WRAPPER(TerrainModifierScripted)
+
Index: source/simulation2/components/ICmpTerrainModifier.h
===================================================================
--- source/simulation2/components/ICmpTerrainModifier.h	(revision 0)
+++ source/simulation2/components/ICmpTerrainModifier.h	(working copy)
@@ -0,0 +1,42 @@
+/* Copyright (C) 2013 Wildfire Games. 
+ * This file is part of 0 A.D. 
+ * 
+ * 0 A.D. is free software: you can redistribute it and/or modify 
+ * it under the terms of the GNU General Public License as published by 
+ * the Free Software Foundation, either version 2 of the License, or 
+ * (at your option) any later version. 
+ * 
+ * 0 A.D. is distributed in the hope that it will be useful, 
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ * GNU General Public License for more details. 
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>. 
+ */ 
+
+#ifndef INCLUDED_ICMPTERRAINMODIFIER 
+#define INCLUDED_ICMPTERRAINMODIFIER 
+
+#include "simulation2/system/Interface.h" 
+
+#include "simulation2/helpers/Position.h" 
+#include "maths/FixedVector2D.h" 
+
+class ICmpTerrainModifier : public IComponent 
+{ 
+public: 
+
+	/** 
+	 * the BBox size of vertices that certainly need to be queried 
+	 * other vertices outside the BBox can also be queried, but shouldn't influence the terrain 
+	 */ 
+	virtual fixed GetBBox() = 0; 
+
+
+	virtual void GetNewHeight(CFixedVector2D relPt, fixed oldHeight, fixed entHeight, fixed& newHeight, fixed& weight) = 0; 
+
+	DECLARE_INTERFACE_TYPE(TerrainModifier) 
+}; 
+
+#endif // INCLUDED_ICMPTERRAINMODIFIER 
Index: source/simulation2/system/ComponentTest.h
===================================================================
--- source/simulation2/system/ComponentTest.h	(revision 14232)
+++ source/simulation2/system/ComponentTest.h	(working copy)
@@ -229,4 +229,13 @@
 	virtual void ReloadTerrain()
 	{
 	}
+
+	virtual void MakeVisualTerrainDirty(entity_id_t UNUSED(ent), entity_pos_t UNUSED(bBox))
+	{
+	}
+
+	virtual u16* GetSimHeightMap()
+	{
+		return NULL;
+	}
 };
Index: source/tools/atlas/GameInterface/Handlers/ElevationHandlers.cpp
===================================================================
--- source/tools/atlas/GameInterface/Handlers/ElevationHandlers.cpp	(revision 14232)
+++ source/tools/atlas/GameInterface/Handlers/ElevationHandlers.cpp	(working copy)
@@ -41,6 +41,9 @@
 	void Init()
 	{
 		m_Heightmap = g_Game->GetWorld()->GetTerrain()->GetHeightMap();
+		CmpPtr<ICmpTerrain> cmpTerrain(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
+		if (cmpTerrain)
+			m_SimHeightmap = cmpTerrain->GetSimHeightMap();
 		m_VertsPerSide = g_Game->GetWorld()->GetTerrain()->GetVerticesPerSide();
 	}
 
@@ -90,9 +93,12 @@
 	void setNew(ssize_t x, ssize_t y, const u16& val)
 	{
 		m_Heightmap[y*m_VertsPerSide + x] = val;
+		if (m_SimHeightmap)
+			m_SimHeightmap[y*m_VertsPerSide + x] = val;
 	}
 
 	u16* m_Heightmap;
+	u16* m_SimHeightmap;
 	ssize_t m_VertsPerSide;
 };
 
