//===========================================================================// // File: DamageObject.hpp // // Project: Adept Brick: DamageObject // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 03/08/99 DPB Initial coding. // //---------------------------------------------------------------------------// // Copyright (C) 1998-1999, Virtual World Entertainment, Inc. // // PROPRIETARY AND CONFIDENTIAL // //===========================================================================// #pragma once #include "Adept.hpp" #include "Receiver.hpp" #include "Entity.hpp" namespace Adept { void __cdecl AdeptDamageSecurityCheckStart(void); void __cdecl AdeptDamageSecurityCheckStop(void); extern HGOSHEAP g_DamageObjectHeap; // MSL 5.03 Lava enum { BeamDamageType = 0, MissileDamageType, ProjectileDamageType, SplashDamageType, HeatDamageType, RammingDamageFromAboveType, RammingDamageFromBelowType, RammingDamageFromLeftType, RammingDamageFromRightType, RammingDamageFromAheadType, RammingDamageFromBehindType, HighExplosiveDamageType, LavaDamageType, AmmoFireDamageType }; class Effect; class InternalDamageObject; class Site; class DamageEffectObject { public: Adept::ResourceID resourceID; Stuff::Scalar armorPercent; }; typedef Receiver__ClassData InternalDamageObject__ClassData; typedef Receiver__Message InternalDamageObject__Message; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Internal Damage Object class // class InternalDamageObject: public Receiver { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Inheritance Support // public: typedef InternalDamageObject__ClassData ClassData; typedef InternalDamageObject__Message Message; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Construction, Destruction, Testing // public: static void InitializeClass(); static void TerminateClass(); static void ConstructInternalDamageObjectStream( Stuff::MemoryStream *stream, Stuff::Page *instance_page, Stuff::RegisteredClass::ClassID class_id = DefaultData->GetClassID() ); virtual void Save(MemoryStream *stream, Stuff::RegisteredClass::ClassID class_id = DefaultData->GetClassID()); InternalDamageObject( ClassData *class_data, Stuff::MemoryStream *stream ); ~InternalDamageObject(); void Reuse(); void TestInstance(); void* operator new(size_t); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class Data support // public: static ClassData *DefaultData; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Simulation support // public: virtual Scalar TakeDamage(Stuff::Scalar damage_taken, Entity__TakeDamageMessage *message); virtual void InflictCriticalHit() {} ResourceID GetDamageEffectID(); void PlayDamageEffects(Entity__TakeDamageMessage *message); Stuff::Scalar baseInternalDamage, currentInternalDamage; Scalar *m_HitPointPointer; void SetHitPointPointer (Scalar *m_HitPoints) { m_HitPointPointer = m_HitPoints; } Stuff::DynamicArrayOf damageEffects; ResourceID currentDamageEffectResourceID; Effect *currentDamageEffect; // visual damage types.. // currently we only use // normal and destroyed // normal = regular geometry // damaged = darkened // destroyed = destroyed geometry // desimated = no geometry // this is for network support enum { NoDamage = 0, Damaged, Destroyed, Desimated }; int GetCurrentDamageLevel(); void SetCurrentDamageLevel(int level); Scalar GetHighResDamageLevel(); void SetHighResDamageLevel(Scalar damage_percentage); void SilentDestruction(); bool CanRepair() {Check_Object(this); return GetCurrentDamageLevel() == Damaged;} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Entity Interaction Support // public: enum { GeneralDamageMode = 0, GimpLeftDamageMode, GimpRightDamageMode, DestructionDamageMode, DetachableDamageMode, EngineDamageMode, NextDamageMode, // MSL 5.02 headshot HeadShotDamageMode, // MSL 5.03 Gyro Hit GyroHitDamageMode, // MSL 5.05 Torso TorsoLeftDamageMode, TorsoRightDamageMode, ArmLeftDamageMode, ArmRightDamageMode, }; enum { NullZone=-1, LeftLegZone = 0, //Mech pieces must follow default zone RightLegZone, LeftArmZone, RightArmZone, RightTorsoZone, LeftTorsoZone, CenterTorsoZone, HeadZone, SpecialZone1, SpecialZone2, VehicleHullZone, //All Vehicle and non-mech zones must be after the specials VehicleWeaponZone, VehicleSpecialZone, DefaultZone, NextDamageZone }; enum{ StandardInternal = 0, EndoSteelInternal, TypeCount }; enum{ DefaultInternalType = StandardInternal }; void Initialize(Entity *entity); static int DamageModeTextToAscii(const char *mode_name); static const char * DamageModeAsciiToText(int damage_mode); static int InternalZoneTextToAscii(const char *mode_name); static const char * InternalZoneAsciiToText(int internal_zone); void SetType(int new_type); Entity *parentEntity; InternalDamageObject *damagePropagationObject; int damagePropagationZoneID; int damageMode; int damageZone; MString parentEntityName; Stuff::Time m_firstHitTime; // MSL 5.02 headshot bool m_headShotFlag; //damage mode is really head shot damage mode when true. // MSL 5.03 Gyro Hit bool m_gyrohitFlag; //damage mode is really head shot damage mode when true. int m_internalType; //Used only if we are a special zone. int m_specialConnectedTo; Site* GetNextWeaponSite(); Site* GetNextEjectSite(); Stuff::SortedChainOf m_sites; // The same sites were being returned for each call. The iterators // are now seperated into a weapon port iterator and and eject port // iterator. Added this change to Vengeance, too --CBT 1/10/2002 Stuff::SortedChainIteratorOf m_weaponSiteIterator; Stuff::SortedChainIteratorOf m_ejectionSiteIterator; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // The following helper classes must always be typedef'd or overriden by an // inheritor // typedef Receiver__ClassData DamageObject__ClassData; typedef Receiver__Message DamageObject__Message; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class DamageObject: public Receiver { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Inheritance Support // public: typedef DamageObject__ClassData ClassData; typedef DamageObject__Message Message; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Construction, Destruction, Testing // public: static void InitializeClass(); static void TerminateClass(); static void ConstructDamageObjectStream( Stuff::MemoryStream *stream, Stuff::Page *instance_page ); virtual void Save(MemoryStream *stream); DamageObject( ClassData *class_data, Stuff::MemoryStream *stream ); ~DamageObject(); void Reuse(); void TestInstance(); void* operator new(size_t); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class Data support // public: static ClassData *DefaultData; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Simulation support // public: virtual void TakeDamage(Entity__TakeDamageMessage *message, Entity *entity_hit); Stuff::Scalar baseArmorValue, currentArmorValue, scaleSplashDamage, maxArmorValue; enum { NullArmorZone=-1, LeftLegArmorZone = 0, RightLegArmorZone, LeftArmArmorZone, RightArmArmorZone, RightTorsoArmorZone, LeftTorsoArmorZone, CenterTorsoArmorZone, CenterRearTorsoArmorZone, HeadArmorZone, SpecialArmorZone1, SpecialArmorZone2, DefaultArmorZone }; static int ArmorZoneTextToAscii(const char *armor_name); static const char * ArmorZoneAsciiToText(int armor_zone); enum { NoArmorDamage = 0, PartialArmorDamage, MediumArmorDamage, BadArmorDamage, ArmorDestroyedDamage, InternalDestroyedDamage }; enum{ StandardArmor = 0, FerroFiberusArmor, ReactiveArmor, ReflectiveArmor, SolarianArmor, TypeCount }; enum{ DefaultArmorType = StandardArmor }; // visual damage types.. // currently we only use // normal and destroyed // normal = regular geometry // damaged = darkened // destroyed = destroyed geometry // desimated = no geometry // this is for network support enum { NoDamage = 0, Damaged, Destroyed, Desimated }; int GetCurrentDamageLevel(); void SetCurrentDamageLevel(int level); // Fix Bug #3100 // Damage Object are now refreshed when a mech sustains internal damage void RefreshCurrentDamageLevel(); Scalar GetHighResDamageLevel(); void SetHighResDamageLevel(Scalar damage_percentage); void SilentDestruction(); bool CanRepair(); public: enum { DmgModifier_Default = 0, DmgModifier_Splash, DmgModifier_Count, }; protected: // from here by jcem Stuff::Scalar m_aDamageModifier[DmgModifier_Count * 2]; // (Modifier & Safety)* // to here by jcem //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Entity Interaction Support // public: // from here by jcem Stuff::Scalar GetDamageModifier (int nIdx) const; void SetDamageModifier (int nIdx, Stuff::Scalar newvalue); // to here by jcem void Initialize(Entity *entity); void SetDamageArrayEntry(int *array_entry) {Check_Object(this); damageArrayEntry = array_entry;} void SetArmorArrayEntry(Scalar *array_entry) {Check_Object(this); armorArrayEntry = array_entry;} int DetermineDamageLevel(); void SetType(int new_type); void AppendArmor(Stuff::Scalar additive_armor); Entity *parentEntity; InternalDamageObject *internalDamageObject; int internalDamageObjectID; MString damageObjectName; int armorZone; int *damageArrayEntry; Scalar *armorArrayEntry; Scalar *m_HitPointPointer; void SetHitPointPointer (Scalar *m_HitPoints) { m_HitPointPointer = m_HitPoints; } int damageLevel; Scalar armorLevel; int m_armorType; int m_specialConnectedToZone; // // There is a problem when splash damage hits multiple entities that share a single damage zone. // bool m_fTakenDamageFromThisEvent; void SetTakenDamageFromThisEvent() {m_fTakenDamageFromThisEvent = true;} void ClearTakenDamageFromThisEvent() {m_fTakenDamageFromThisEvent = false;} bool GetTakenDamageFromThisEvent() {return m_fTakenDamageFromThisEvent;} public: void RefrehDamageState(); // jcem void RepairDamage(Scalar fRepair); }; }