- turretHead: The part that actually moves and shoots.
- Parts for the socket:
Infos for levelmakers
<?lua include("templates/standardTurret.oxt") ?>
for the standard turret (the only one at this point) to your file, and you're pretty much good to go. Add a turret with
<Turret> <templates> <Template link=standardturret /> </templates> </Turret>
It supports all the xml parameters up to and including the ones for pawns.
Additional xml parameters:
- rotationThrust: Controls the rotation speed of the turret
- maxAttackRadius: Determines the largest distance the turret can shoot.
- minAttackRadius: Determines the smalles distance the turret can shoot.
- maxYaw: Determines, how far the turret can rotate around the y-axis (in one direction, in degrees)
- maxPitch: Determines, how far the turret can rotate around the x-axis (in one direction, in degrees)
Note: The standardTurret template doesn't support these parameters directly, because internally the actual turret is attached once again (look at the template for more details)
The magic happens all in the main turret file. Internally, there's a coordinate system that adapts itself to the parent's rotation (if there is one), but not to the turret's rotation. This is done due to the following reasons:
- Rotations done in xml are not done in the local, but in the global coordinate system. This means the turret already starts with and offset (not necessarily, but very likely), and this makes things needlessly complicated. Changing that rotation to a global one seemed like too big a change, because it's done quite high up in the hierarchy.
- Ogre already has a local coordinate system for every object, but it's a pain to figure out how exactly it is orientated in the world. Doing it myself, it's clear where each vector points to. (It would be cleaner to use Ogre's stuff, though)
With this coordinate system, it's easy to find out, if a certain point is inside the turret's range, limited by pitch (rotations around the x-axis), yaw (rotations around the y-axis), and distance. Take a look at the function isInRange in Turret.cc, it should be pretty straightforward (the initial facing direction for an object in Ogre is always 0,0,-1).
The controller is pretty simple. To find a target for the turret, it loops through all pawns, and asks the turret, if it is in range. To make this a bit more intelligent, it chooses the pawn that is the closest and has the fewest health left, though this isn't perfect yet. The distance is currently weighed about a thousand times more than the health (…). If the turret has a parent, and the parent has a target, the controller tries to choose the same and gives it precendece to all other enemies. To make it simple for people making levels and/or ship templates, the controller copies the team it belongs to from the parent, if it exists. This allows for "plug'n'play" functionality, and you only have to worry about how the turret appears in the game, not how it works.
- The rotations are completely free right now, but this works only okay with turrets that are completely symmetric like the one we're currently using. If someone wanted to make something like a cannon with a barrel that moves "up and down" and a base that rotates, it would require some serious changes to the code for rotations.
- Maybe it would be a good idea to split the turret into two or three parts, consisting of a barrel, a base and maybe a socket, so that you can easily replace or make special parts (a barrel that rotates like a gatling gun, for example).
- Network functionality is completely missing.
- Look at the source files for some additional TODOs.