//============================================================================// // File: missile.hpp // // Project: BattleTech // // Contents: A guided self-propelled projectile entity that hosts a Seeker // // and a MissileThruster subsystem. // //----------------------------------------------------------------------------// // Date Who Modification // // -------- --- ------------------------------------------------------------// // 04/13/95 JM Initial coding. // //----------------------------------------------------------------------------// // Copyright (C) 1995, Virtual World Entertainment, Inc. All Rights reserved // // PROPRIETARY AND CONFIDENTIAL // //============================================================================// // // RECONSTRUCTED from the shipped binary (Ghidra pseudo-C, module cluster // @004bef4c-@004bf8bc in part_013.c). NO surviving header exists for this // class -- only the test fragments MISSILE.TCP and PROJTILE.TCP. The // declaration below is therefore INFERRED from: // * the decompiled ctor @004bf5b4 and integrator @004bef78 // * MISSILE.TCP (Missile::TestClass: GetSubsystem(MissileThrusterSubsystem / // SeekerSubsystem), MoveAndCollide, gun->currentProjectile) // * the surviving SEEKER.HPP / MISTHRST.HPP that name its two subsystems // * the sibling Projectile base (PROJTILE.TCP: Projectile::TestClass) // Member names past the Projectile base are best-effort and flagged. // // Inheritance chain established from the decomp: // Entity -> Projectile (ctor @004be1bc, vtable @00512a5c, sizeof 0x340) // -> Missile (ctor @004bf5b4, vtable @00512f2c, sizeof 0x368) // The Missile ctor chains Projectile::Projectile (@004be1bc) and then builds a // 2-entry subsystem roster: slot 0 = Seeker ("Seeker"), slot 1 = // MissileThruster ("MissleThruster", spelled as in the shipped string table // @00512e25). Spawned by the launcher as streamed-entity ClassID 0xBD0. // #if !defined (MISSILE_HPP) # define MISSILE_HPP # if !defined(PROJTILE_HPP) # include // Projectile : Entity base # endif //######################### Forward Class Declarations ######################## class Mech; class Seeker; class MissileThruster; //########################################################################### //######################### CLASS -- Missile ######################### //########################################################################### // // (vtable @00512f2c, ctor @004bf5b4, dtor @004bf890, allocator @004bf8bc.) // class Missile: public Projectile { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Shared Data Support // public: static Derivation ClassDerivations; static Receiver::MessageHandlerSet MessageHandlers; static AttributeIndexSet AttributeIndex; static SharedData DefaultData; // Entity factory hook (Entity::SharedData requires a MakeHandler). static Entity *Make(MakeMessage *creation_message); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Subsystem roster // // The two hosted subsystem IDs, used by GetSubsystem() in MISSILE.TCP. // Build order in the ctor (@004bf5b4): Seeker first, MissileThruster // second. // public: enum { SeekerSubsystem = 0, MissileThrusterSubsystem = 1, SubsystemCount = 2 // this[0x49] == 2 (@0x124) }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Model Support // public: typedef void (Missile::*Performance)(Scalar time_slice); // @004bef78 -- the per-frame integrate-guidance-and-collide pass. // Ages the missile (this+0x35c), asks the Seeker for the lead point, // applies the MissileThruster acceleration toward it, integrates // position/velocity, runs the world collision query (FUN_0042291c) and, // on impact, spawns the explosion/Damage entity (FUN_004be078) before // retiring itself. void MoveAndCollide(Scalar time_slice); void SetPerformance(Performance performance) { Check(this); activePerformance = (Simulation::Performance)performance; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Update record (network) // protected: void WriteUpdateRecord( // vtable slot 7, @004bef4c UpdateRecord *message, int update_model); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // TestClass Support (MISSILE.TCP) // public: static Logical TestClass(Mech &); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Construction and Destruction // public: Missile( // @004bf5b4 int owner, // spawning launcher / streamed-entity ctx const char *spawn_descriptor // &DAT_00512d48 default record ); ~Missile(); // @004bf890 // @004bf8bc -- allocate (0x368 bytes) and construct. static Missile * New(int spawn_context); Logical TestInstance() const; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Local data appended past the Projectile base (offsets best-effort). // protected: Scalar lifetime; // @0x340 this[0xd0] max time-of-flight (model +0x44) Scalar ageFraction; // @0x344 this[0xd1] age/lifetime, clamped to 1.0 Scalar thrustScale; // @0x348 this[0xd2] sqrt(model+0x48 / mass) void *targetConnection; // @0x34c this[0xd3] resolved target/launcher link Vector3D targetOffset; // @0x350 this[0xd4..0xd6] aim offset handed to the Seeker Scalar age; // @0x35c this[0xd7] accumulated time-of-flight void *explosionModel; // @0x360 this[0xd8] detonation model (model +?) int detonationFlag; // @0x364 this[0xd9] proximity/contact detonation mode // --- Entity-motion working fields (reconstruction; the shipped binary // keeps these in the Entity transform/motion block). --- Scalar mass; // missile mass (model) Vector3D velocity; // @0x1dc linear velocity Vector3D thrustVelocity; // @0x1e8 thrust-contributed velocity Scalar thrustImpulse; // @0x1d0 thrust impulse scale Vector3D thrusterAxis; // @0x234 thruster acceleration axis // --- small proxy types for the recovered model/thruster reads --- struct ModelRecord { Scalar maxTimeOfFlight; // model +0x44 Scalar thrust; // model +0x48 int detonationMode; // model +0x50 }; struct ThrusterState { Scalar acceleration; }; // --- recovered helpers (engine/model plumbing rendered as artifacts) --- void GetForward(Vector3D &out); // FUN_0040d150 void *ResolveTargetConnection(int owner); // resolved target/launcher link Vector3D LaunchAimOffset(int owner); // launch aim offset const ModelRecord *ResolveModel(); // FUN_00407064 chain void SpawnDetonation(Entity *hit); // FUN_004be078 (ClassID 0x5C) // subsystem roster (Projectile base fields, shown for clarity) // int subsystemCount; // @0x124 this[0x49] == 2 // Subsystem **subsystems; // @0x128 this[0x4a] -> {Seeker, MissileThruster} }; #endif