diff --git a/OpenRA.Mods.TS/OpenRA.Mods.TS.csproj b/OpenRA.Mods.TS/OpenRA.Mods.TS.csproj
index 8fc3330016..4072b6c537 100644
--- a/OpenRA.Mods.TS/OpenRA.Mods.TS.csproj
+++ b/OpenRA.Mods.TS/OpenRA.Mods.TS.csproj
@@ -64,6 +64,7 @@
+
diff --git a/OpenRA.Mods.TS/Traits/Render/WithVoxelWaterBody.cs b/OpenRA.Mods.TS/Traits/Render/WithVoxelWaterBody.cs
new file mode 100644
index 0000000000..3a7a199f07
--- /dev/null
+++ b/OpenRA.Mods.TS/Traits/Render/WithVoxelWaterBody.cs
@@ -0,0 +1,81 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2015 The OpenRA Developers (see AUTHORS)
+ * This file is part of OpenRA, which is free software. It is made
+ * available to you under the terms of the GNU General Public License
+ * as published by the Free Software Foundation. For more information,
+ * see COPYING.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using OpenRA.Graphics;
+using OpenRA.Mods.Common.Graphics;
+using OpenRA.Traits;
+
+namespace OpenRA.Mods.TS.Traits
+{
+ public class WithVoxelWaterBodyInfo : ITraitInfo, IQuantizeBodyOrientationInfo, IRenderActorPreviewVoxelsInfo, Requires
+ {
+ public readonly string WaterSequence = "water";
+ public readonly string LandSequence = "idle";
+
+ public object Create(ActorInitializer init) { return new WithVoxelWaterBody(init.Self, this); }
+
+ public IEnumerable RenderPreviewVoxels(ActorPreviewInitializer init, RenderVoxelsInfo rv, string image, WRot orientation, int facings, PaletteReference p)
+ {
+ var sequence = LandSequence;
+ if (init.Contains())
+ {
+ var location = init.Get().Value(init.World);
+ var onWater = init.World.Map.GetTerrainInfo(location).IsWater;
+ sequence = onWater ? WaterSequence : LandSequence;
+ }
+
+ var body = init.Actor.Traits.Get();
+ var voxel = VoxelProvider.GetVoxel(image, sequence);
+ yield return new VoxelAnimation(voxel, () => WVec.Zero,
+ () => new[] { body.QuantizeOrientation(orientation, facings) },
+ () => false, () => 0);
+ }
+
+ public int QuantizedBodyFacings(ActorInfo ai, SequenceProvider sequenceProvider, string race) { return 0; }
+ }
+
+ public class WithVoxelWaterBody : IAutoSelectionSize
+ {
+ readonly Actor self;
+ readonly int2 size;
+
+ bool OverWater { get { return self.World.Map.GetTerrainInfo(self.Location).IsWater; } }
+
+ public WithVoxelWaterBody(Actor self, WithVoxelWaterBodyInfo info)
+ {
+ this.self = self;
+
+ var body = self.Trait();
+ var rv = self.Trait();
+
+ var landVoxel = VoxelProvider.GetVoxel(rv.Image, info.LandSequence);
+ rv.Add(new VoxelAnimation(landVoxel, () => WVec.Zero,
+ () => new[] { body.QuantizeOrientation(self, self.Orientation) },
+ () => OverWater,
+ () => 0));
+
+ // Selection size
+ var rvi = self.Info.Traits.Get();
+ var s = (int)(rvi.Scale * landVoxel.Size.Aggregate(Math.Max));
+ size = new int2(s, s);
+
+ var waterVoxel = VoxelProvider.GetVoxel(rv.Image, info.WaterSequence);
+ rv.Add(new VoxelAnimation(waterVoxel, () => WVec.Zero,
+ () => new[] { body.QuantizeOrientation(self, self.Orientation) },
+ () => !OverWater,
+ () => 0));
+ }
+
+ public int2 SelectionSize(Actor self) { return size; }
+ }
+}
diff --git a/mods/ts/rules/gdi-vehicles.yaml b/mods/ts/rules/gdi-vehicles.yaml
index d3647c947c..bad3e0193a 100644
--- a/mods/ts/rules/gdi-vehicles.yaml
+++ b/mods/ts/rules/gdi-vehicles.yaml
@@ -12,6 +12,8 @@ APC:
Mobile:
ROT: 5
Speed: 113
+ TerrainSpeeds:
+ Water: 80
Health:
HP: 200
Armor:
@@ -26,7 +28,7 @@ APC:
PipCount: 5
RenderSprites:
RenderVoxels:
- WithVoxelBody:
+ WithVoxelWaterBody:
LeavesTrails:
Image: wake
Palette: effect
diff --git a/mods/ts/sequences/voxels.yaml b/mods/ts/sequences/voxels.yaml
index 08f3a54140..0d66f8a43c 100644
--- a/mods/ts/sequences/voxels.yaml
+++ b/mods/ts/sequences/voxels.yaml
@@ -5,8 +5,9 @@ harv:
idle:
unload: horv
-apc: # TODO apcw in water
+apc:
idle:
+ water: apcw
art2:
idle:
diff --git a/mods/ts/tilesets/snow.yaml b/mods/ts/tilesets/snow.yaml
index c36a310cd9..5e6c2dff7d 100644
--- a/mods/ts/tilesets/snow.yaml
+++ b/mods/ts/tilesets/snow.yaml
@@ -29,6 +29,7 @@ Terrain:
Type: Water
Color: 61, 65, 72
TargetTypes: Water
+ IsWater: True
TerrainType@DirtRoad:
Type: DirtRoad
Color: 130,131,143
diff --git a/mods/ts/tilesets/temperat.yaml b/mods/ts/tilesets/temperat.yaml
index 03fed23302..17ca38b1d5 100644
--- a/mods/ts/tilesets/temperat.yaml
+++ b/mods/ts/tilesets/temperat.yaml
@@ -29,6 +29,7 @@ Terrain:
Type: Water
Color: 116, 85, 55
TargetTypes: Water
+ IsWater: True
TerrainType@DirtRoad:
Type: DirtRoad
Color: 116, 85, 55