197 lines
9.7 KiB
Markdown
197 lines
9.7 KiB
Markdown
## 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](../archives/textureAnimation.md) 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](../levelObjects/index.md). 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](../levelObjects/index.md) 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](../levelObjects/GenericWeaponInfo.md).
|
|
> The engine, internally, calls this field `resistances`, yet the code does the opposite. Furthermore, this `resistances` field covers the four bytes from `000E`.
|
|
|
|
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 `0x04` only for the non-used SHODAN critter `14/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 is `0x8F`.
|