9.7 KiB
Property Files
A few files don't have an archive format, and instead are flat files consisting directly serialized tables.
Texture Properties (textprop.dat)
This file contains a single table of texture property entries, after a header.
The table appears to be truncated. Since the game only uses 273 textures, this may have never been detected. The file has 4004 bytes on disk, meaning 4000 bytes are available for the table. In a test, the original engine appeared to be fine to read a smaller file with exactly 273 entries (3007 bytes) - which had the unknown fields set to zero.
The original source explains the difference: The texture property system would support up to 400 textures. It also assumed a property structure size of 10 bytes (hardcoded value), while the actual structure is 11 bytes long. In other words, one could feed the engine more than 273 textures, yet no more than 363. More than 363 would simply be ignored and the extra textures would just have their default properties. This also explains why the Mac port reads exactly 363 textures, as reading more would exhaust the file.
Header
The file starts with a 4-byte header.
Texture Properties File Header (4 bytes)
0000 int32 file version number, value 0x09
The engine rejects a properties file with a different version number.
Properties Entry
Texture Property Entry (11 bytes)
0000 byte family (unused)
0001 byte target (unused)
0002 sint16 resilience (unused); Default: 10
0004 sint16 distance modifier; Default: 0
0006 byte Climbable. 0x00: not climbable; != 0x00: wall can be climbed (original name: friction)
0007 byte friction walk (unused); Always 0x00
0008 byte Transparency control (original name: force_dir)
0009 byte Animation group
000A byte Animation index - if texture is animated
The two bytes at the beginning (family and target) almost always are each set to the low-byte of the index. A few exceptions have both bytes 0x00. Since they are unused, it is unclear what they mean.
The resilience is nearly always 0x0A; The one existing exception has it 0. Since it is unused, it is unclear what it means.
The distance modifier always zero. It is used in the renderer to determine which texture resolution to use, based on distance from the camera. A higher modifier causes the smaller resolutions to be chosen at larger distances; A negative value causes an earlier switch.
See Texture Animation for details on animated textures.
Transparency Control
0x00 Regular texture; transparent pixel (palette index 0x00) are drawn black
0x01 Space texture (pixel data of image is ignored)
0x02 Texture with space background for transparent pixels
Object Properties (objprop.dat)
The object properties file contains several tables about properties of level objects. It has the following format:
| Header | Class 0 Tables | Class 1 Tables | ... | Common Table |
Header
The file starts with a 4-byte header containing the version number.
Object Properties File Header (4 bytes)
0000 int32 file version number, value 0x2D
The engine rejects a properties file with a different version number.
Class Tables
For each object class, one entry exists with a table of class-generic properties and a further table, subclass-specific:
| Class N Tables |
| Generic | Subclass 0 | Subclass 1 | ... | Subclass N |
The sizes of the generic and specific tables are dependent on the object class, subclass and type amount. The generic table contains one entry per object type of this class. The specific tables contain one entry per object type of the subclass.
See Level Objects for an overview of the amount of types and their entry sizes.
Common Table
At the end of the file is the table with common properties. For each object type one entry.
Common Object Properties (27 bytes)
0000 int32 Mass
0004 int16 Default hitpoints
0006 uint8 Armour
0007 byte Render type
0008 byte Physics type; 0x00: none (insubstantial), 0x01: regular, 0x02: special
0009 byte Hardness; 0..253
000A byte Unused; Internally called "pep", this value appears to not be used by the engine.
000B byte Physics XR; 0..253
000C byte Unused; Internally called "physics_y". These values are set (almost) identical to 000B and have no effect.
000D byte Physics Z; Set to 0x30 for all barriers (10/x/x).
000E byte Vulnerabilities
000F byte Special vulnerabilities
0010 [2]byte Unused
0012 byte Defence value
0013 byte Toughness; 0x03: Invincible
0014 int16 Flags
0016 int16 MFD/Mesh ID
0018 [2]byte Bitmap 3D field model index
001A byte Destruction effect
Physics type governs how collisions shall be handled. 0x00 makes the object insubstantial, ignoring forces applied to it. For instance, most scenery stays where it was put. 0x01 is for regular objects meant to react "normal" in a physical world. 0x02 behaves strange is set for exactly one object (14/0/6, "SONIC THE HEDGEHOG", an unused critter). Objects with a physics type of 0x02 aren't affected by gravity for instance, but are repelled if hacker runs into them.
The hardness acts as repulsion force on the object if it collides with the ground or walls - or on the hacker if hacker runs into it.
Hardness depends on the mass; Objects with more mass bounce around less.
The physics xr value is applied to vertically center (animated) sprites on their position. If 0x00, the sprites are rendered with their bottom anchored at the object's position. Higher values will move the sprites downwards.
Related, the physics z value is inconsistently used as a height value. Only if this value is 0x00 (most of the time), then physics xr is used for height calculation. Still, the XR value is used far more often than the Z value.
The vulnerabilities and special vulnerabilities match the corresponding damage type fields from Generic Weapon Info.
The engine, internally, calls this field
resistances, yet the code does the opposite. Furthermore, thisresistancesfield covers the four bytes from000E.
The field of special vulnerabilities is split up into 0x0F primary vulnerabilities (double damage) and 0xF0 super vulnerabilities (quad damage). Damage is multiplied only if the originating special force equals the vulnerabilities in these fields.
Quad damage is reduced to triple damage on difficulty level 3 (either for real-world, or cyber, wherever it is calculated).
The defence value is compared to the offence value of a weapon or projectile to determine a "critical hit" (or critical reduction). Higher defence values will decrease the damage, higher offence values will increase the damage. If it is 0xFF, then the target is invulnerable to critical hits.
The toughness determines how much damage, after most of the calculation, goes through - this still requires the object to be solid to register damage. The value of 0x03 reduces the damage to zero. Otherwise, this value is considered to be a shift factor, so a value of 0x01 halves damage, 0x02 quarters it.
This value is set to
0x04only for the non-used SHODAN critter14/3/5. This one would have been affected by only the strongest weapons. Probably this value was intended to be in range of 0..3 only.
MFD/Mesh ID identifies the MFD to open for this type of object, if selected from inventory. For 3D objects in the world, this value identifies the 3D mesh to render, based on resource 0x08FC.
Render Type Enumeration (1 byte)
0x01 3D object
0x02 Sprite
0x03 Screen
0x04 Critter
0x06 Fragments (e.g. the Cyberdog)
0x07 Not drawn
0x08 Oriented surface (door, wall decoration)
0x0B Special
0x0C Force door
Common Object Flags (2 byte)
0x0001 Useful inventory object (green font)
0x0002 Solid - can't be passed through
0x000C Use mode (see below)
0x0010 Usable inventory object - object is triggered on double-click in inventory list
0x0020 Blocks 3D rendering if closed (set for opaque doors)
0x00C0 Light type (see below)
0x0100 Solid if closed (set for barriers and repulsor object)
0x0200 Flat solid (objects can be placed on it)
0x0400 Doubled bitmap size (set for various explosion animations)
0x0800 Destroy on contact
0x7000 Class-specific flags
0x8000 Useless object. Unless specifically marked useful otherwise, object can be removed to make room
Use Mode Enumeration (2 bit)
0x00 Pickup - items can be taken
0x01 Use - items are used, not taken
0x02 undefined
0x03 "Null" - can't be used
Light Type Enumeration (2 bit)
0x00 Normal, simple lighting
0x01 Complex lighting
0x02 Ignore darkness
0x03 Deferred light type (instance-specific)
Bitmap 3D Bitfield (2 byte)
0x03FF Bitmap number low mask
0x8000 Bitmap number high mask
0x0400 Animation
0x0800 Repeat
0x7000 Frame number mask
Object Destruction Effect (1 byte)
This byte is a bitmask field with the following layout:
0x1F Animation frame index -- refers to different types of animations
0x20 Play destruction sound
0x40 Play destruction sound (not used in main game)
0x80 Actual explosion (with damage) -- requires Animation frame index to be 0x0F
Some objects have their "private" destruction sounds and have none of the sound bits set. The
actual explosion, set for larger electrical appliances, works only if the full value is0x8F.