MNpx loader
parent
961e0d6de0
commit
4edd1af472
161
MarathonData.md
161
MarathonData.md
|
@ -1077,6 +1077,69 @@ Projectile Definition is 48 bytes.
|
|||
- `Damage` is a Damage Definition structure.
|
||||
- `Flags` is a Projectile Flags bit field.
|
||||
|
||||
### Monster Definition ###
|
||||
|
||||
Monster Definition is 156 bytes.
|
||||
|
||||
| Name | Type | Offset |
|
||||
| ---- | ---- | ------ |
|
||||
| `Collection` | `u16` | `0` |
|
||||
| `Vitality` | `u16` | `2` |
|
||||
| `ImmuneTo` | `u32` | `4` |
|
||||
| `WeakTo` | `u32` | `8` |
|
||||
| `Flags` | `u32` | `12` |
|
||||
| `MonsterClass` | `u32` | `16` |
|
||||
| `FriendTo` | `u32` | `20` |
|
||||
| `EnemyTo` | `u32` | `24` |
|
||||
| `SndPitch` | `fixed` | `28` |
|
||||
| `SndSeeEnemy` | `u16opt` | `32` |
|
||||
| `SndSeeFriend` | `u16opt` | `34` |
|
||||
| `SndSeeClear` | `u16opt` | `36` |
|
||||
| `SndKill` | `u16opt` | `38` |
|
||||
| `SndApologize` | `u16opt` | `40` |
|
||||
| `SndAmicide` | `u16opt` | `42` |
|
||||
| `SndFlaming` | `u16opt` | `44` |
|
||||
| `SndActive` | `u16opt` | `46` |
|
||||
| `ActiveMask` | `u16` | `48` |
|
||||
| `DropItem` | `u16opt` | `50` |
|
||||
| `Radius` | `unit` | `52` |
|
||||
| `Height` | `unit` | `54` |
|
||||
| `HoverHeight` | `unit` | `56` |
|
||||
| `LedgeMin` | `unit` | `58` |
|
||||
| `LedgeMax` | `unit` | `60` |
|
||||
| `ExtVelScale` | `fixed` | `62` |
|
||||
| `FxImpact` | `u16opt` | `66` |
|
||||
| `FxMeleeImpact`| `u16opt` | `68` |
|
||||
| `FxTrail` | `u16opt` | `70` |
|
||||
| `HalfFOVHorz` | `u16` | `72` |
|
||||
| `HalfFOVVert` | `u16` | `74` |
|
||||
| `ViewRange` | `unit` | `76` |
|
||||
| `ViewRangeDark`| `unit` | `78` |
|
||||
| `Intelligence` | `u16` | `80` |
|
||||
| `Speed` | `u16` | `82` |
|
||||
| `Gravity` | `u16` | `84` |
|
||||
| `TerminalVel` | `u16` | `86` |
|
||||
| `DoorTryMask` | `u16` | `88` |
|
||||
| `ExplodeRadius`| `u16opt` | `90` |
|
||||
| `ExplodeDamage`| `struct` | `92` |
|
||||
| `SeqHit` | `u16opt` | `104` |
|
||||
| `SeqHardDying` | `u16opt` | `106` |
|
||||
| `SeqSoftDying` | `u16opt` | `108` |
|
||||
| `SeqHardDead` | `u16opt` | `110` |
|
||||
| `SeqSoftDead` | `u16opt` | `112` |
|
||||
| `SeqStanding` | `u16` | `114` |
|
||||
| `SeqMoving` | `u16` | `116` |
|
||||
| `SeqTeleIn` | `u16opt` | `118` |
|
||||
| `SeqTeleOut` | `u16opt` | `120` |
|
||||
| `AtkFrequency` | `u16` | `122` |
|
||||
| `AtkMelee` | `struct` | `124` |
|
||||
| `AtkRange` | `struct` | `140` |
|
||||
|
||||
- `Flags` is a Monster Flags bit field.
|
||||
- `MonsterClass` is a Monster Class bit field.
|
||||
- `ExplodeDamage` is a Damage Definition structure.
|
||||
- `AtkMelee` and `AtkRange` are Attack Definition structures.
|
||||
|
||||
### Damage Definition ###
|
||||
|
||||
Damage Definition is 12 bytes.
|
||||
|
@ -1092,6 +1155,21 @@ Damage Definition is 12 bytes.
|
|||
- `Type` is a Damage Type enumeration.
|
||||
- `Flags` is a Damage Flags enumeration.
|
||||
|
||||
### Attack Definition ###
|
||||
|
||||
Attack Definition is 16 bytes.
|
||||
|
||||
| Name | Type | Offset |
|
||||
| ---- | ---- | ------ |
|
||||
| `Type` | `u16opt` | `0` |
|
||||
| `Repetitions` | `u16` | `2` |
|
||||
| `Error` | `angle` | `4` |
|
||||
| `Range` | `unit` | `6` |
|
||||
| `Shape` | `u16` | `8` |
|
||||
| `OfsX` | `unit` | `10` |
|
||||
| `OfsY` | `unit` | `12` |
|
||||
| `OfsZ` | `unit` | `14` |
|
||||
|
||||
## Images ##
|
||||
|
||||
### Picture Resource ###
|
||||
|
@ -2150,4 +2228,87 @@ this actually hurts my head.
|
|||
| `UseLowGrav` | `19` |
|
||||
| `PassMedia` | `20` |
|
||||
|
||||
### Monster Flags ###
|
||||
|
||||
| Name | Bit |
|
||||
| ---- | --- |
|
||||
| `IgnoreLOS` | `0` |
|
||||
| `Flying` | `1` |
|
||||
| `Alien` | `2` |
|
||||
| `Major` | `3` |
|
||||
| `Minor` | `4` |
|
||||
| `NoOmit` | `5` |
|
||||
| `Floats` | `6` |
|
||||
| `NoAttack` | `7` |
|
||||
| `Snipe` | `8` |
|
||||
| `Invisible` | `9` |
|
||||
| `SubtlyInvisible` | `10` |
|
||||
| `Kamikaze` | `11` |
|
||||
| `Berserker` | `12` |
|
||||
| `Enlarged` | `13` |
|
||||
| `DelayedDeath` | `14` |
|
||||
| `FireSymmetrical` | `15` |
|
||||
| `NuclearDeath` | `16` |
|
||||
| `NoFireBackwards` | `17` |
|
||||
| `CanDieInFlames` | `18` |
|
||||
| `WaitForGoodShot` | `19` |
|
||||
| `Tiny` | `20` |
|
||||
| `FastAttack` | `21` |
|
||||
| `LikesWater` | `22` |
|
||||
| `LikesSewage` | `23` |
|
||||
| `LikesLava` | `24` |
|
||||
| `LikesGoo` | `25` |
|
||||
| `TeleUnderMedia` | `26` |
|
||||
| `UseRandomWeapon` | `27` |
|
||||
|
||||
### Monster Class ###
|
||||
|
||||
| Name | Bit |
|
||||
| ---- | --- |
|
||||
| `Player` | `0` |
|
||||
| `Civilian` | `1` |
|
||||
| `Madd` | `2` |
|
||||
| `PossessedHummer` | `3` |
|
||||
| `Defender` | `4` |
|
||||
| `Fighter` | `5` |
|
||||
| `Trooper` | `6` |
|
||||
| `Hunter` | `7` |
|
||||
| `Enforcer` | `8` |
|
||||
| `Juggernaut` | `9` |
|
||||
| `Hummer` | `10` |
|
||||
| `Compiler` | `11` |
|
||||
| `Cyborg` | `12` |
|
||||
| `Assimilated` | `13` |
|
||||
| `Tick` | `14` |
|
||||
| `Yeti` | `15` |
|
||||
|
||||
### Damage Type Flag ###
|
||||
|
||||
| Name | Bit |
|
||||
| ---- | --- |
|
||||
| `Explosion` | `0` |
|
||||
| `ElectricalStaff` | `1` |
|
||||
| `Projectile` | `2` |
|
||||
| `Absorbed` | `3` |
|
||||
| `Flame` | `4` |
|
||||
| `HoundClaws` | `5` |
|
||||
| `AlienProjectile` | `6` |
|
||||
| `HulkSlap` | `7` |
|
||||
| `CompilerBolt` | `8` |
|
||||
| `FusionBolt` | `9` |
|
||||
| `HunterBolt` | `10` |
|
||||
| `Fist` | `11` |
|
||||
| `Teleporter` | `12` |
|
||||
| `Defender` | `13` |
|
||||
| `YetiClaws` | `14` |
|
||||
| `YetiProjectile` | `15` |
|
||||
| `Crushing` | `16` |
|
||||
| `Lava` | `17` |
|
||||
| `Suffocation` | `18` |
|
||||
| `Goo` | `19` |
|
||||
| `EnergyDrain` | `20` |
|
||||
| `OxygenDrain` | `21` |
|
||||
| `HummerBolt` | `22` |
|
||||
| `ShotgunProjectile` | `23` |
|
||||
|
||||
<!-- EOF -->
|
||||
|
|
|
@ -64,6 +64,7 @@ fn dump_chunk(opt: &Options, cid: Ident, cnk: &[u8], eid: u16) -> ResultS<()>
|
|||
b"plat" => make_yaml(opt, &rd_array(cnk, map::read_plat)?)?,
|
||||
b"term" => make_yaml(opt, &rd_array(cnk, trm::read_term)?)?,
|
||||
b"FXpx" => make_yaml(opt, &rd_array(cnk, phy::read_fxpx)?)?,
|
||||
b"MNpx" => make_yaml(opt, &rd_array(cnk, phy::read_mnpx)?)?,
|
||||
b"PRpx" => make_yaml(opt, &rd_array(cnk, phy::read_prpx)?)?,
|
||||
b"PXpx" => make_yaml(opt, &rd_array(cnk, phy::read_pxpx)?)?,
|
||||
b"WPpx" => make_yaml(opt, &rd_array(cnk, phy::read_wppx)?)?,
|
||||
|
|
|
@ -128,6 +128,86 @@ pub fn read_prpx(b: &[u8]) -> ResultS<(Projectile, usize)>
|
|||
flags, speed, range, snd_pitch, snd_fly, snd_bounce}, 48))
|
||||
}
|
||||
|
||||
pub fn read_mnpx(b: &[u8]) -> ResultS<(Monster, usize)>
|
||||
{
|
||||
read_data! {
|
||||
156, BE in b =>
|
||||
collection = u16[0];
|
||||
vitality = u16[2];
|
||||
dty_immune = u32[4];
|
||||
dty_weak = u32[8];
|
||||
flags = u32[12];
|
||||
cls_self = u32[16];
|
||||
cls_friend = u32[20];
|
||||
cls_enemy = u32[24];
|
||||
snd_pitch = Fixed[28];
|
||||
snd_see_enemy = OptU16[32];
|
||||
snd_see_friend = OptU16[34];
|
||||
snd_seeclear = OptU16[36];
|
||||
snd_kill = OptU16[38];
|
||||
snd_apologize = OptU16[40];
|
||||
snd_amicide = OptU16[42];
|
||||
snd_flaming = OptU16[44];
|
||||
snd_active = OptU16[46];
|
||||
snd_active_mask = u16[48];
|
||||
typ_item = OptU16[50];
|
||||
radius = Unit[52];
|
||||
height = Unit[54];
|
||||
height_hover = Unit[56];
|
||||
ledge_min = Unit[58];
|
||||
ledge_max = Unit[60];
|
||||
ext_vel_scale = Fixed[62];
|
||||
fxt_impact = OptU16[66];
|
||||
fxt_impact_melee = OptU16[68];
|
||||
fxt_trail = OptU16[70];
|
||||
half_fov_horz = u16[72];
|
||||
half_fov_vert = u16[74];
|
||||
view_range = Unit[76];
|
||||
view_range_dark = Unit[78];
|
||||
intelligence = u16[80];
|
||||
speed = u16[82];
|
||||
gravity = u16[84];
|
||||
vel_terminal = u16[86];
|
||||
door_try_mask = u16[88];
|
||||
expl_radius = OptU16[90];
|
||||
expl_damage = read_damage[92..104];
|
||||
seq_hit = OptU16[104];
|
||||
seq_dying_hard = OptU16[106];
|
||||
seq_dying_soft = OptU16[108];
|
||||
seq_dead_hard = OptU16[110];
|
||||
seq_dead_soft = OptU16[112];
|
||||
seq_standing = u16[114];
|
||||
seq_moving = u16[116];
|
||||
seq_tele_in = OptU16[118];
|
||||
seq_tele_out = OptU16[120];
|
||||
atk_frequency = u16[122];
|
||||
atk_melee = read_attack[124..140];
|
||||
atk_range = read_attack[140..156];
|
||||
}
|
||||
|
||||
// friend and enemy fields MUST truncate because the original source code
|
||||
// used `-1` to represent "all classes" which should be invalid normally
|
||||
|
||||
let dty_immune = flag_ok!(DamageTypeFlags, dty_immune)?;
|
||||
let dty_weak = flag_ok!(DamageTypeFlags, dty_weak)?;
|
||||
let flags = flag_ok!(MonsterFlags, flags)?;
|
||||
let cls_self = flag_ok!(MonsterClass, cls_self)?;
|
||||
let cls_friend = MonsterClass::from_bits_truncate(cls_friend);
|
||||
let cls_enemy = MonsterClass::from_bits_truncate(cls_enemy);
|
||||
|
||||
Ok((Monster{collection, vitality, dty_immune, dty_weak, flags, cls_self,
|
||||
cls_friend, cls_enemy, snd_pitch, snd_see_enemy, snd_see_friend,
|
||||
snd_seeclear, snd_kill, snd_apologize, snd_amicide, snd_flaming,
|
||||
snd_active, snd_active_mask, typ_item, radius, height,
|
||||
height_hover, ledge_min, ledge_max, ext_vel_scale, fxt_impact,
|
||||
fxt_impact_melee, fxt_trail, half_fov_horz, half_fov_vert,
|
||||
view_range, view_range_dark, intelligence, speed, gravity,
|
||||
vel_terminal, door_try_mask, expl_radius, expl_damage, seq_hit,
|
||||
seq_dying_hard, seq_dying_soft, seq_dead_hard, seq_dead_soft,
|
||||
seq_standing, seq_moving, seq_tele_in, seq_tele_out,
|
||||
atk_frequency, atk_melee, atk_range}, 156))
|
||||
}
|
||||
|
||||
fn read_trigger(b: &[u8]) -> ResultS<Trigger>
|
||||
{
|
||||
read_data! {
|
||||
|
@ -176,6 +256,23 @@ fn read_damage(b: &[u8]) -> ResultS<Damage>
|
|||
Ok(Damage{dtype, alien, dmg_base, dmg_rand, scale})
|
||||
}
|
||||
|
||||
fn read_attack(b: &[u8]) -> ResultS<Attack>
|
||||
{
|
||||
read_data! {
|
||||
16, BE in b =>
|
||||
ptype = OptU16[0];
|
||||
rep = u16[2];
|
||||
error = Angle[4];
|
||||
range = Unit[6];
|
||||
shape = u16[8];
|
||||
ofs_x = Unit[10];
|
||||
ofs_y = Unit[12];
|
||||
ofs_z = Unit[14];
|
||||
}
|
||||
|
||||
Ok(Attack{ptype, rep, error, range, shape, ofs_x, ofs_y, ofs_z})
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct Physics
|
||||
{
|
||||
|
@ -293,6 +390,62 @@ pub struct Projectile
|
|||
pub snd_bounce: OptU16,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct Monster
|
||||
{
|
||||
pub collection: u16,
|
||||
pub vitality: u16,
|
||||
pub dty_immune: DamageTypeFlags,
|
||||
pub dty_weak: DamageTypeFlags,
|
||||
pub flags: MonsterFlags,
|
||||
pub cls_self: MonsterClass,
|
||||
pub cls_friend: MonsterClass,
|
||||
pub cls_enemy: MonsterClass,
|
||||
pub snd_pitch: Fixed,
|
||||
pub snd_see_enemy: OptU16,
|
||||
pub snd_see_friend: OptU16,
|
||||
pub snd_seeclear: OptU16,
|
||||
pub snd_kill: OptU16,
|
||||
pub snd_apologize: OptU16,
|
||||
pub snd_amicide: OptU16,
|
||||
pub snd_flaming: OptU16,
|
||||
pub snd_active: OptU16,
|
||||
pub snd_active_mask: u16,
|
||||
pub typ_item: OptU16,
|
||||
pub radius: Unit,
|
||||
pub height: Unit,
|
||||
pub height_hover: Unit,
|
||||
pub ledge_min: Unit,
|
||||
pub ledge_max: Unit,
|
||||
pub ext_vel_scale: Fixed,
|
||||
pub fxt_impact: OptU16,
|
||||
pub fxt_impact_melee: OptU16,
|
||||
pub fxt_trail: OptU16,
|
||||
pub half_fov_horz: u16,
|
||||
pub half_fov_vert: u16,
|
||||
pub view_range: Unit,
|
||||
pub view_range_dark: Unit,
|
||||
pub intelligence: u16,
|
||||
pub speed: u16,
|
||||
pub gravity: u16,
|
||||
pub vel_terminal: u16,
|
||||
pub door_try_mask: u16,
|
||||
pub expl_radius: OptU16,
|
||||
pub expl_damage: Damage,
|
||||
pub seq_hit: OptU16,
|
||||
pub seq_dying_hard: OptU16,
|
||||
pub seq_dying_soft: OptU16,
|
||||
pub seq_dead_hard: OptU16,
|
||||
pub seq_dead_soft: OptU16,
|
||||
pub seq_standing: u16,
|
||||
pub seq_moving: u16,
|
||||
pub seq_tele_in: OptU16,
|
||||
pub seq_tele_out: OptU16,
|
||||
pub atk_frequency: u16,
|
||||
pub atk_melee: Attack,
|
||||
pub atk_range: Attack,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct Damage
|
||||
{
|
||||
|
@ -303,6 +456,19 @@ pub struct Damage
|
|||
pub scale: Fixed,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct Attack
|
||||
{
|
||||
pub ptype: OptU16,
|
||||
pub rep: u16,
|
||||
pub error: Angle,
|
||||
pub range: Unit,
|
||||
pub shape: u16,
|
||||
pub ofs_x: Unit,
|
||||
pub ofs_y: Unit,
|
||||
pub ofs_z: Unit,
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[derive(Serialize)]
|
||||
pub struct EffectFlags: u16
|
||||
|
@ -361,6 +527,95 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[derive(Serialize)]
|
||||
pub struct MonsterFlags: u32
|
||||
{
|
||||
const IgnoreLOS = 1;
|
||||
const Flying = 1 << 1;
|
||||
const Alien = 1 << 2;
|
||||
const Major = 1 << 3;
|
||||
const Minor = 1 << 4;
|
||||
const NoOmit = 1 << 5;
|
||||
const Floats = 1 << 6;
|
||||
const NoAttack = 1 << 7;
|
||||
const Snipe = 1 << 8;
|
||||
const Invisible = 1 << 9;
|
||||
const SubtlyInvisible = 1 << 10;
|
||||
const Kamikaze = 1 << 11;
|
||||
const Berserker = 1 << 12;
|
||||
const Enlarged = 1 << 13;
|
||||
const DelayedDeath = 1 << 14;
|
||||
const FireSymmetrical = 1 << 15;
|
||||
const NuclearDeath = 1 << 16;
|
||||
const NoFireBackwards = 1 << 17;
|
||||
const CanDieInFlames = 1 << 18;
|
||||
const WaitForGoodShot = 1 << 19;
|
||||
const Tiny = 1 << 20;
|
||||
const FastAttack = 1 << 21;
|
||||
const LikesWater = 1 << 22;
|
||||
const LikesSewage = 1 << 23;
|
||||
const LikesLava = 1 << 24;
|
||||
const LikesGoo = 1 << 25;
|
||||
const TeleUnderMedia = 1 << 26;
|
||||
const UseRandomWeapon = 1 << 27;
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[derive(Serialize)]
|
||||
pub struct MonsterClass: u32
|
||||
{
|
||||
const Player = 1;
|
||||
const Civilian = 1 << 1;
|
||||
const Madd = 1 << 2;
|
||||
const PossessedHummer = 1 << 3;
|
||||
const Defender = 1 << 4;
|
||||
const Fighter = 1 << 5;
|
||||
const Trooper = 1 << 6;
|
||||
const Hunter = 1 << 7;
|
||||
const Enforcer = 1 << 8;
|
||||
const Juggernaut = 1 << 9;
|
||||
const Hummer = 1 << 10;
|
||||
const Compiler = 1 << 11;
|
||||
const Cyborg = 1 << 12;
|
||||
const Assimilated = 1 << 13;
|
||||
const Tick = 1 << 14;
|
||||
const Yeti = 1 << 15;
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[derive(Serialize)]
|
||||
pub struct DamageTypeFlags: u32
|
||||
{
|
||||
const Explosion = 1;
|
||||
const ElectricalStaff = 1 << 1;
|
||||
const Projectile = 1 << 2;
|
||||
const Absorbed = 1 << 3;
|
||||
const Flame = 1 << 4;
|
||||
const HoundClaws = 1 << 5;
|
||||
const AlienProjectile = 1 << 6;
|
||||
const HulkSlap = 1 << 7;
|
||||
const CompilerBolt = 1 << 8;
|
||||
const FusionBolt = 1 << 9;
|
||||
const HunterBolt = 1 << 10;
|
||||
const Fist = 1 << 11;
|
||||
const Teleporter = 1 << 12;
|
||||
const Defender = 1 << 13;
|
||||
const YetiClaws = 1 << 14;
|
||||
const YetiProjectile = 1 << 15;
|
||||
const Crushing = 1 << 16;
|
||||
const Lava = 1 << 17;
|
||||
const Suffocation = 1 << 18;
|
||||
const Goo = 1 << 19;
|
||||
const EnergyDrain = 1 << 20;
|
||||
const OxygenDrain = 1 << 21;
|
||||
const HummerBolt = 1 << 22;
|
||||
const ShotgunProjectile = 1 << 23;
|
||||
}
|
||||
}
|
||||
|
||||
c_enum! {
|
||||
#[derive(Debug, Serialize)]
|
||||
pub enum CasingType: u16
|
||||
|
|
Loading…
Reference in New Issue