You'd think making a moving platform that engineers can build upon would be an easy enough thing to implement: Detect when a building is placed on it, and parent to the platform. Alas, we can take nothing for granted when it comes to this acursed engine! Yet! Even in the face of fearsome spaghetti code, there is always a way forward...
This prefab contains all the information and nuances a mapper may need to smoothly implement moving platforms that engineers can build on. The main feature of this prefab is a fix for the issue of a dispenser's healing zone not moving with the dispenser, which is applied to all player-placed dispensers in the map. The fix parents the dispenser's healing zone to the dispenser itself, such that any movement by the dispenser is mimicked by the healing zone.
The downloadable ZIP file contains all of the following:
-prefab_movebuild_v1.vmf : A heavily-commented and fully functional implementation of multiple moving platforms. Comment bubbles explain important details and nuances for implementing moving buildable platforms and the dispenser healing zone fix. Comments within various entities explain what each entity actually does and how certain things work, for those who wish to learn more about the internal workings of the prefab and/or modify it.
-prefab_movebuild.bsp : A compiled version of prefab_movebuild_v1.vmf. It has a different name so that mappers may compile prefab_movebuild_v1.vmf without overriding this map. Copy this to your /tf/maps or /tf/download/maps folder.
-Prefabs/ : A folder of Hammer Prefabs containing a simple, copy-paste implementation of the dispenser healing zone fix. Merge this folder with your /bin/Prefabs folder and insert the contents into your map using the Entity Tool.
-DispFix Entity Room.vmf : The entity room for the dispenser healing zone fix. This also contains the necessary filters. Any map implementing this fix needs exactly one set of these. The room is self-sealing. Simply place it into your map, and position it outside of your map's playable space.
-DispFix Triggers.vmf : Two map-wide triggers, a func_movelinear, and a logic_auto, for the dispenser healing zone fix. Any map implementing this fix needs exactly one set of these. After placing it into your map, resize the map-wide triggers such that they cover the entirety of your map's playable space.
IMPORTANT: The dispenser healing zone fix does not function in Mann vs Machine or Mannpower, as the fix takes advantage of the dispenser's construction/redeployment period and buildings redeploy instantly in these gamemodes. These gamemodes would require a totally alternate method for fixing the bug.
How do I install the prefab and add it to my map?
Merge the Prefabs/ folder with the /bin/Prefabs folder in your game files. Once you've done so, you'll see the prefabs listed under Hammer's Prefabs category when using the Entity Tool to insert prefabs. Place down one copy of DispFix Entity Room and DispFix Triggers. Move the entity room outside your map, and resize the triggers to cover your entire map.
How do I actually create moving platforms?
Use func_tanktrain to create the moving platforms. It's a variant of func_tracktrain that allows engineer buildings to be placed on it, and which buildings are automatically parented to when placed down. func_tanktrain can be used nearly identically to func_tracktrain (as a path-following brush entity), or it can be parented to another moving entity. Whichever you choose, it is advised to ensure that the entity controlling movement uses the BSP collisions method (as opposed to VPhysics), otherwise the entity may slow down when buildings are attached to it.
How do I tell if an entity uses the BSP collisions method?
Depends on what entity you're using. Many rotating entities, as well as some entities like func_brush, have a keyvalue which defines the collision method they use. func_tracktrain and func_tanktrain use VPhysics by default, but can be forced to use BSP by selecting the "Rideable Train" spawnflag (sometimes alternatively labelled "HL1 Train"). Some entities, such as func_door and func_movelinear, always use VPhysics with no option to use BSP. If you're unsure, the best way to figure out is to test if the platform slows. I'd advise testing the entity by placing an active teleporter on it; that seems to provide the most noticeable slowing effect.
Does the prefab account for methods of moving dispensers outside of func_tanktrain?
Yes! Because the healing zone is parented to the dispenser and not to the dispenser's parent, the healing zone will stay with the dispenser no matter what. Changing the dispenser's parent wildly, using logic_measure_movement, and even teleporting the dispenser will not break the healing zone.
Can I rotate buildings using these methods?
Buildings can be given any Yaw rotation (rotation around the vertical [Z] axis) with virtually no issues. Rotating around other axes may cause some issues, mostly visual. All buildings' visual models will be offset from their collision model. Sentries may not visually aim at their target correctly. If either the teleporter entrance or exit is flatly positioned against a platform which has rotated to become a slope/wall/ceiling, the teleporters may become unusable. You can experiment with this and other issues yourself using the rotating platform located on the east wall of the prefab_movebuild map.
Will the dispenser fix interfere with any dispenser entities that are part of my map?
The prefab will only interfere with obj_dispenser entities that are either unnamed or have any targetname starting with "dispfix_", so if you have any of those, just give them a name that isn't already in use. Dispenser entities of other classes, such as mapobj_cart_dispenser, are not affected.
Are there any other limitations I should adhere to?
Any targetnames that begin with "dispfix_" should be avoided, as well as the targetname "touch_trigger dispfix_healzone". Some filters also have reserved names: "filter_sentrygun", "filter_dispenser", "filter_teleporter", "filter_obj", and "filter_nameless". While you should avoid creating other entities with these names, you may use these filters for your own purposes.
I found a bug!
Great! Well, it's not great that there's a bug. But it's good that someone found it! If it's not already on the list below, let me know and I'll see if I can fix it. However, keep in mind that my tools are limited and I may not be able to fix every issue.
-The dispenser fix does not work in Mann vs Machine or Mannpower.
-When a dispenser is redeployed and its redeployment speed is wrench-boosted, there may be a slight delay of up to a second before the dispenser begins healing/providing ammo to players already in the healing zone.
-Players standing on top of a dispenser, or walking into the side of a dispenser, after it has moved from its placement position will not be healed (but will receive ammo/metal).
-Players that jump while on top of a dispenser that has moved may be lightly pushed in a certain direction, for reasons unknown.
-When a dispenser is redeployed, it's healing zone trigger will be offset from its proper position by a few Hammer Units.
-A wrangled sentry gun's shield bubble will not move with the sentry gun.
-Teleporter entrance arrows will not update to continuously aim at the exit if it moves.
Note that many of these are simply quirks of Source and which probably won't ever wholly be fixed.