Offsets
From Data Realms Wiki
Offsets define relative positions of many things in Cortex Command. They describe individual points which the game engine maps to individual pixels within sprites as they move and rotate on screen. Those points are used to position a sprite in relation to another sprite, such as the shoulder joint on an arm sprite and the corresponding shoulder on its "parent" torso sprite. They define where things are, like the gun carried by a soldier, and also where things are emitted from, like the bullets from that gun.
You'll need to understand Cartesian coordinates and arithmetic with positive and negative numbers. Offset values are usually integers but Offsets accept float values (most often just "_.5"). Though you'll never see half a pixel, Cortex Command's math does. Inaccurate values create inaccuracies in drawing pixels.
And if you understand vectors, you'll understand positioning Offsets relative to other Offsets, almost always done relative to the SpriteOffset.
Contents |
SpriteOffset
If sprites in Cortex Command were paper drawings, cut out and pinned to a cork board, the SpriteOffset would be where the push pin goes though the cutout. If you spin the cutout, it spins around the pin. In physics, things spin around their own center of mass. The SpriteOffset provides something similar.
Coordinates & Pixels
Cortex Command uses pixels, not paper, and pixels have integer coordinates. A coordinate system needs an origin: X = 0, Y = 0. Cortex Command uses the SpriteOffset as the origin for each sprite, and all other Offsets are distances, or vectors, measured from the SpriteOffset measured in pixel lengths on the X and Y axes.
If you open a sprite's image file in an image editor (MS Paint, GIMP, Photoshop, etc.), the coordinates of every pixel is a positive integer value, and it's the pixel up in the top left which has the coordinate (0,0). But this pixel probably shouldn't represent the center of mass.
Instead of a push pin positioned over paper, think of positioning over the pixels of the image an invisible, purely mathematical pixel which, by default, is squarely over that top left pixel in the image. This is the SpriteOffset and it can be offset any distance along the X and Y axes, on or off the image, whole or decimal lengths from its natural starting place over (0,0).
Which Axis Is Flipped?
There are two ways of looking at how to find coordinates to position Offsets.
More mathematically true is the perspective of moving the pin/pixel over the paper/image from the natural origin in the top left. In Cortex Command, one axis has its positive and negative reversed from the Cartesian model; and in this "pin" perspective the X-axis is flipped so right is negative and left is positive. It also means measuring vectors of "child" Offsets back to the SpriteOffset of the parent sprite.
The other perspective is more true to how things look in game since Cortex Command moves sprites via their SpriteOffset and visually appear to extending down and to the right from it with X = 0 and Y = 0. This perspective holds the pin/pixel still while moving the paper/image underneath it, typically to the left and up. In this perspective the Y-axis is flipped so up is negative and down is positive. It also means you measure vectors out from the SpriteOffset out to any "child" Offsets.
Which perspective you use is irrelevant as the numbers you enter will be the same. Just be consistent.
Centering the Odds of Evening
Typically the SpriteOffset will define a pixel in the very center of the sprite, though official examples such as the Dummy infantry position it centered only on the X-axis and low to the hip on the Y-axis. Since sprites are horizontally mirrored, or "HFlipped", to face left, visual popping may occur if the X value of the SpriteOffset is off-center on the X-axis. The Y-axis is more forgiving.
Positioning the SpriteOffset can be tricky because image sizes are reported as a count of the total number of pixels. A 5x5 image has pixels ranging from (0,0) only up to (4,4). Typically it's easier to find the image size than the coordinate of the bottom right pixel. The middle can be found by subtracting 1 from width or height and dividing by 2. Offsets accept decimal, or float, values.
Even numbered WxH size, to have an equal number of pixels to either side (left & right, above & below) the SpriteOffset, would have _.5 values; or you can just divide width and height in half and it's good enough. Odd numbered widths more consistently map to a specific pixel even as the sprite spins around.
To put the center of mass where, visually, it ought to be and avoid visual popping, it may be wisest to enlarge the canvas as needed to keep an equal number of pixels horizontally (and perhaps vertically) on either side of the center of mass pixel when setting it as the SpriteOffset.
Offset
Used by Exit hatches on ACRockets and Terrain material bitmaps. Also used by the Gib entity; this is best left to the Gib Editor included in Cortex Command.
Bitmap Offset
Used for static elements on a map, including TerrainObject set pieces, Bunker Backgrounds and Bunker Bits, as well as the old Brain Vault, Rocket Silo, and Wall. Almost all of their vectors are 0,0 but certain Geology objects and the three old Bunker modules use negative vectors.
EmissionOffset
Used by AEmitter entities to define which pixel the things it emits are emitted from, in many ways similar to MuzzleOffset.
ParentOffset
Used when attaching a "child" sprite, the ParentOffset defines a point relative to the "parent" sprite's SpriteOffset which the child's JointOffset will attach to. For example, it defines a shoulder socket which the arm's shoulder forms a joint with. HDFirearms use ParentOffset to define a receiver which the Magazine's JointOffset will snap into. The child is typically a sprite or an AEmitter.
JointOffset
Used when attaching as a "child" to a "parent" sprite, the JointOffset defines a point relative to the child sprite's SpriteOffset which the parent can grab onto and position on itself using it's ParentOffset. Parts of an Actor's body are joined to each other with via JointOffset, as are various Devices like guns and tools. This applies to Actor types like ADoor, ACRocket, and ACDropShip. Attachable effects and AEmitter also use this.
For HDFirearms, the JointOffset is where the FGArm (foreground arm) Hand is positioned, typically where the trigger is drawn but it has no effect on firing the weapon or tool. If placed too far for an AHuman's Hand to reach, the arm will twitch, trying and failing to reach the JointOffset.
Device-Specific Offsets
These Offsets are used only by the various types of Devices: HeldDevices, HDFirearms, or TDExplosives.
SupportOffset
This defines where the BGArm (background arm) Hand of AHuman is positioned on a Device. Even one-handed devices specify a SupportOffset, though it tends to be close to the JointOffset. Excessive values have the same effect on the BGArm as excessive JointOffsets have on the FGArm.
StanceOffset
Adjustment where the SpriteOffset of a HeldDevice, HDFirearm, or ThrownDevice lines up with the SpriteOffset of the Actors carrying it. If a Device is meant to be carried high, slung low, held forward, or tucked back, this is where it should be specified, not SpriteOffset. Note that changing the StanceOffset does not change other Offsets-- they remain relative to SpriteOffset only. However, excessive values on StanceOffset can put other Offsets beyond reach of an AHuman's Hands.
SharpStanceOffset
Adjustments where a HeldDevice or HDFirearm and an Actor's SpriteOffsets align, but only when stopping to aim. Most weapons (and even the diggers, for some reason) are carried higher to "look down the sights" though it can be set arbitrarily. Like SupportOffset, all other Offsets on the Device stay relative to the SpriteOffset, thus the "move with" the Device.
MuzzleOffset
Defines the pixel where any Round an HDFirearm fires are emitted from. Typically this is the forward tip of the barrel, but it can be placed arbitrarily, even outside the sprite's pixel area.
EjectionOffset
The pixel where any Shell will be emitted from the sprite of an HDFirearm.
StartThrowOffset
Used with TDExplosives such as grenades. Almost always (-12,-5).
EndThrowOffset
Used with TDExplosives such as grenades. Almost always (-12,-5) but sometise (12,-5).
Actor-Specific Offsets
These Offsets are used only by the various types of Actors: AHumans, ACrabs, ACRockets, ACDropShips, or ADoors.
IdleOffset
Specified in Arm and Leg definitions to position their Hand and Foot respectively when those limbs are idle. Specifies a point relative to the JointOffset to position the Hand or Foot rather than a specific Parent-Joint attachment. Works in concert with MaxLength to keep Hands and Feet from visually separating from their Arm or Leg. Appears in all Actor definitions except ACDropship and ADoor and stationary Brains.
ExtendedOffset
Defines where the Foot of an Actor is positioned relative to the Leg's JointOffset when standing. Note that these coordinates assume the Leg being oriented horizontally as the sprites for them are.
ContractedOffset
Used when crouching, this defines where the Foot of an Actor is positioned relative to the Leg's JointOffset. Note that these coordinates assume the Leg being oriented horizontally as sprites for them are.
StartOffset
Used in the various LimbPath animation definitions, this specifies the hip joint ParentOffset of the Actor where the JointOffset of its Leg is attached [1].
HolsterOffset
Not commonly used, if at all. Cortex Command currently does not "holster" any items when unequipped. Appears in both AHuman and ACRocket definitions.
OpenOffset
Used by doors to specify where the "door" part moves to when it opens.
ClosedOffset
Used by doors to specify where the "door" part moves to when the door is closed.