diff --git a/AircraftClass.h b/AircraftClass.h index 905857cf..6c5aa4ef 100644 --- a/AircraftClass.h +++ b/AircraftClass.h @@ -61,14 +61,14 @@ class NOVTABLE AircraftClass : public FootClass, public IFlyControl public: AircraftTypeClass* Type; - bool unknown_bool_6C8; + bool LoseAmmo; // flag for Mission_Attack mission_statue == 1 == AIR_ATT_PICK_ATTACK_LOCATION bool HasPassengers; //parachutes bool IsKamikaze; // when crashing down, duh BuildingClass* DockNowHeadingTo; bool unknown_bool_6D0; bool unknown_bool_6D1; - bool unknown_bool_6D2; - char unknown_char_6D3; - bool unknown_bool_6D4; + bool IsLocked; + bool ParadropsLeft; + bool IsCarrayall; bool unknown_bool_6D5; }; diff --git a/AircraftTrackerClass.h b/AircraftTrackerClass.h new file mode 100644 index 00000000..102fafb9 --- /dev/null +++ b/AircraftTrackerClass.h @@ -0,0 +1,49 @@ +/* + AircraftTrackerClass +*/ + +#pragma once + +#include +#include +#include +#include + +/** + * The game use this array when searching for and damaging air techno, + * when warhead explosion or greatest threat. + * JumpjetLoco, RocketLoco and FlyLoco will Add or Remove or Update this list. + * + */ +class AircraftTrackerClass +{ +public: + static constexpr constant_ptr const Instance{}; + + //Destructor + ~AircraftTrackerClass() RX; + + void Add_Entry(TechnoClass* pAircraft) + { JMP_THIS(0x4134A0); } + + void Remove_Entry(TechnoClass* pAircraft) + { JMP_THIS(0x4135D0); } + + void Update_Entry(TechnoClass* pAircraft, CellStruct lastCell, CellStruct curretCell) + { JMP_THIS(0x4138C0); } + + int Search_Entry(CellClass* pCell, int cellSpread) + { JMP_THIS(0x412B40); } + +protected: + //Constructor + AircraftTrackerClass() {} //don't need this + + //=========================================================================== + //===== Properties ========================================================== + //=========================================================================== + +public: + DECLARE_PROPERTY(DynamicVectorClass, Technos); // All Techno in air + DECLARE_PROPERTY(DynamicVectorClass, Current); // Searching for +}; diff --git a/BasicStructures.h b/BasicStructures.h index b103559d..7487ecb9 100644 --- a/BasicStructures.h +++ b/BasicStructures.h @@ -41,9 +41,26 @@ struct ColorStruct inline explicit operator WORD() const; + operator bool() + { + return R != 0 || G != 0 || B != 0; + } + BYTE R, G, B; }; +// Helper +namespace Colors +{ + static ColorStruct Empty{ 0, 0, 0 }; + static ColorStruct Red{ 252, 0, 0 }; + static ColorStruct Green{ 0, 252, 0 }; + static ColorStruct Blue{ 0, 0, 252 }; + static ColorStruct Yellow{ 252, 212, 0 }; + static ColorStruct White{ 252, 252, 252 }; + static ColorStruct Black{ 3, 3, 3 }; +} + struct BytePalette { ColorStruct Entries[256]; @@ -155,6 +172,11 @@ struct RandomStruct struct RectangleStruct { int X, Y, Width, Height; + + bool IsEmpty() + { + return X == 0 && Y == 0 && Width == 0 && Height == 0; + } }; struct LTRBStruct @@ -163,4 +185,4 @@ struct LTRBStruct int Top; int Right; int Bottom; -}; \ No newline at end of file +}; diff --git a/BombListClass.h b/BombListClass.h index 0dcd6214..86609e44 100644 --- a/BombListClass.h +++ b/BombListClass.h @@ -31,7 +31,7 @@ class BombListClass void RemoveDetector(TechnoClass *Detector) { JMP_THIS(0x4390D0); } - void PointerGotInvalid(AbstractClass* pInvalid) + void Detach(TechnoClass* pOwner) { JMP_THIS(0x439150); } protected: diff --git a/BuildingClass.h b/BuildingClass.h index 59a2bcbe..4f961037 100644 --- a/BuildingClass.h +++ b/BuildingClass.h @@ -255,8 +255,8 @@ class NOVTABLE BuildingClass : public TechnoClass BuildingTypeClass* Type; FactoryClass* Factory; CDTimerClass C4Timer; - int BState; - int QueueBState; + BStateType BState; + BStateType QueueBState; DWORD OwnerCountryIndex; InfantryClass* C4AppliedBy; DWORD unknown_544; diff --git a/BulletClass.h b/BulletClass.h index c095e4fe..72dbb546 100644 --- a/BulletClass.h +++ b/BulletClass.h @@ -127,14 +127,14 @@ class NOVTABLE BulletClass : public ObjectClass BulletTypeClass* Type; TechnoClass* Owner; - bool unknown_B4; + bool IsInaccurate; BulletData Data; bool Bright; DWORD unknown_E4; BulletVelocity Velocity; DWORD unknown_100; - bool unknown_104; - DWORD unknown_108; + bool CourseLocked; + int CourseLockedDuration; AbstractClass* Target; int Speed; int InheritedColor; diff --git a/CCINIClass.h b/CCINIClass.h index c2b53cd8..a8e61c65 100644 --- a/CCINIClass.h +++ b/CCINIClass.h @@ -338,6 +338,11 @@ class CCINIClass : public INIClass static constexpr reference const INI_UIMD{}; static constexpr reference const INI_RA2MD{}; + // get the fileName + static constexpr reference const INI_Rules_FileName{}; + static constexpr reference const INI_AI_FileName{}; + static constexpr reference const INI_Art_FileName{}; + //non-static CCINIClass() : INIClass(false) { diff --git a/CellClass.h b/CellClass.h index 952573e6..d530c489 100644 --- a/CellClass.h +++ b/CellClass.h @@ -24,6 +24,31 @@ class TagClass; class TiberiumClass; class PixelFXClass; +enum class TileType : unsigned int +{ + Unknown = 0, + Tunnel = 0x484AB0, + Water = 0x485060, + Blank = 0x486380, + Ramp = 0x4863A0, + Cliff = 0x4863D0, + Shore = 0x4865B0, + Wet = 0x4865D0, + MiscPave = 0x486650, + Pave = 0x486670, + DirtRoad = 0x486690, + PavedRoad = 0x4866D0, + PavedRoadEnd = 0x4866F0, + PavedRoadSlope = 0x486710, + Median = 0x486730, + Bridge = 0x486750, + WoodBridge = 0x486770, + ClearToSandLAT = 0x486790, + Green = 0x4867B0, + NotWater = 0x4867E0, + DestroyableCliff = 0x486900 +}; + class NOVTABLE CellClass : public AbstractClass { public: @@ -178,6 +203,9 @@ class NOVTABLE CellClass : public AbstractClass void SetMapCoords(const CoordStruct& coords) { JMP_THIS(0x485240); } + int GetFloorHeightAdjust() const + { JMP_THIS(0x485080); } + int GetFloorHeight(Point2D const& subcoords) const { JMP_THIS(0x47B3A0); } @@ -192,6 +220,15 @@ class NOVTABLE CellClass : public AbstractClass return buffer; } + // pass + bool IsClearToMove(SpeedType speedType, bool ignoreInfantry, bool ignoreVehicles, ZoneType zone, MovementZone movementZone, int level, bool alt) + { JMP_THIS(0x4834A0); } + + bool IsClearToMove(SpeedType speedType, MovementZone movementZone, bool ignoreInfantry = false, bool ignoreVehicles = false, int level = -1) + { + return IsClearToMove(speedType, ignoreInfantry, ignoreInfantry, ZoneType::None, movementZone, level, (bool)(this->Flags & CellFlags::CenterRevealed)); + } + void ActivateVeins() { JMP_THIS(0x486920); } @@ -250,8 +287,8 @@ class NOVTABLE CellClass : public AbstractClass // helper bool ContainsBridge() const - { - return static_cast(this->Flags & CellFlags::BridgeHead); + { + return static_cast(this->Flags & CellFlags::BridgeHead); } bool ContainsBridgeEx() const { @@ -291,6 +328,31 @@ class NOVTABLE CellClass : public AbstractClass ISTILE(NotWater, 0x4867E0); ISTILE(DestroyableCliff, 0x486900); + TileType GetTileType() + { + if (Tile_Is_Tunnel()) return TileType::Tunnel; + if (Tile_Is_Water()) return TileType::Water; + if (Tile_Is_Blank()) return TileType::Blank; + if (Tile_Is_Ramp()) return TileType::Ramp; + if (Tile_Is_Cliff()) return TileType::Cliff; + if (Tile_Is_Shore()) return TileType::Shore; + if (Tile_Is_Wet()) return TileType::Wet; + if (Tile_Is_MiscPave()) return TileType::MiscPave; + if (Tile_Is_Pave()) return TileType::Pave; + if (Tile_Is_DirtRoad()) return TileType::DirtRoad; + if (Tile_Is_PavedRoad()) return TileType::PavedRoad; + if (Tile_Is_PavedRoadEnd()) return TileType::PavedRoadEnd; + if (Tile_Is_PavedRoadSlope()) return TileType::PavedRoadSlope; + if (Tile_Is_Median()) return TileType::Median; + if (Tile_Is_Bridge()) return TileType::Bridge; + if (Tile_Is_WoodBridge()) return TileType::WoodBridge; + if (Tile_Is_ClearToSandLAT()) return TileType::ClearToSandLAT; + if (Tile_Is_Green()) return TileType::Green; + if (Tile_Is_NotWater()) return TileType::NotWater; + if (Tile_Is_DestroyableCliff()) return TileType::DestroyableCliff; + return TileType::Unknown; + } + static CoordStruct Cell2Coord(const CellStruct &cell, int z = 0) { CoordStruct ret; diff --git a/Dir.h b/Dir.h index 23dd66ee..99eb1296 100644 --- a/Dir.h +++ b/Dir.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include @@ -11,8 +11,8 @@ enum class DirType : unsigned char; struct DirStruct { public: - explicit DirStruct() noexcept : Raw { 0 } { } - explicit DirStruct(int raw) noexcept : Raw { static_cast(raw) } { } + explicit DirStruct() noexcept : Raw{ 0 } { } + explicit DirStruct(int raw) noexcept : Raw{ static_cast(raw) } { } explicit DirStruct(double rad) noexcept { SetRadian<65536>(rad); } explicit DirStruct(const DirType dir) noexcept { SetDir(dir); } explicit DirStruct(const noinit_t&) noexcept { } @@ -52,6 +52,25 @@ struct DirStruct Raw = static_cast(TranslateFixedPoint(value, offset)); } + // untemplate + short GetValue(const size_t Bits = 16) + { + if (Bits > 0 && Bits <= 16) + { + return (short)(TranslateFixedPoint(16, Bits, (size_t)(this->Raw), 0)); + } + return 0; + } + + // untemplate + void SetValue(short value, size_t Bits = 16, size_t offset = 0) + { + if (Bits > 0 && Bits <= 16) + { + Raw = static_cast(TranslateFixedPoint(16, Bits, (size_t)value, offset)); + } + } + template constexpr size_t GetFacing(size_t offset = 0) const { @@ -95,6 +114,31 @@ struct DirStruct SetValue(value & Max); } + // untemplate + double GetRadian(size_t Bits = 16) + { + if (Bits > 0 && Bits <= 16) + { + int Max = (1 << (int)Bits) - 1; + + int value = Max / 4 - this->GetValue(Bits); + return -value * -(Math::TwoPi / Max); + } + return 0; + } + + // untemplate + void SetRadian(double rad, size_t Bits = 16) + { + if (Bits > 0 && Bits <= 16) + { + int Max = (1 << (int)Bits) - 1; + + int value = (int)(rad * (Max / Math::TwoPi)); + this->SetValue((short)(Max / 4 - value), Bits); + } + } + private: template constexpr static size_t TranslateFixedPoint(size_t value, size_t offset = 0) @@ -110,6 +154,27 @@ struct DirStruct return value & MaskOut; } + // untemplate + constexpr static size_t TranslateFixedPoint(size_t bitsFrom, size_t bitsTo, size_t value, size_t offset = 0) + { + size_t MaskIn = (1u << (int)bitsFrom) - 1; + size_t MaskOut = (1u << (int)bitsTo) - 1; + + if (bitsFrom > bitsTo) + { + // converting down + return (((((value & MaskIn) >> (int)(bitsFrom - bitsTo - 1)) + 1) >> 1) + offset) & MaskOut; + } + else if (bitsFrom < bitsTo) + { + // converting up + return (((value - offset) & MaskIn) << (int)(bitsTo - bitsFrom)) & MaskOut; + } + else + { + return value & MaskOut; + } + } public: unsigned short Raw; private: diff --git a/DiskLaserClass.h b/DiskLaserClass.h index 880fa27c..302aa5d8 100644 --- a/DiskLaserClass.h +++ b/DiskLaserClass.h @@ -39,7 +39,7 @@ class NOVTABLE DiskLaserClass : public AbstractClass void Fire(TechnoClass* pOwner, TechnoClass* pTarget, WeaponTypeClass* pWeapon, int nDamage) { JMP_THIS(0x4A71A0); } - void PointerGotInvalid(AbstractClass* pInvalid) + void Detach(TechnoClass* pTecno) { JMP_THIS(0x4A7900); } //Constructor diff --git a/DisplayClass.h b/DisplayClass.h index 6a97fa8f..3a9c1494 100644 --- a/DisplayClass.h +++ b/DisplayClass.h @@ -4,6 +4,7 @@ class CCINIClass; class ObjectTypeClass; +class BuildingTypeClass; class NOVTABLE DisplayClass : public MapClass { @@ -11,6 +12,13 @@ class NOVTABLE DisplayClass : public MapClass //Static static constexpr constant_ptr const Instance{}; + static constexpr reference const Display_ZoneCell{}; + static constexpr reference const Display_ZoneOffset{}; + static constexpr reference const Display_CurrentFoundation_Data{}; + static constexpr reference const Display_PassedProximityCheck{}; + static constexpr reference const Display_PendingObject{}; + static constexpr reference const Display_PendingHouse{}; + //WIP: DisplayClass::TacticalClass goes HERE bool ProcessClickCoords(Point2D *src, CellStruct *XYdst, CoordStruct *XYZdst, ObjectClass **Target, BYTE *a5, BYTE *a6) @@ -65,6 +73,17 @@ class NOVTABLE DisplayClass : public MapClass return outBuffer; } + bool Passes_Proximity_Check(BuildingTypeClass* pPendingObject, int houseIndex, CellStruct* foundation, CellStruct* center) + { JMP_THIS(0x4A8EB0); } + + bool Passes_Proximity_Check() + { + CellStruct zoneCell = Display_ZoneCell.get(); + CellStruct zoneOffset = Display_ZoneOffset.get(); + CellStruct center = zoneCell + zoneOffset; + return Passes_Proximity_Check(Display_PendingObject.get(), Display_PendingHouse.get(), Display_CurrentFoundation_Data.get(), ¢er); + } + /* marks or unmarks the cells pointed to by CurrentFoundationData as containing a building */ void MarkFoundation(CellStruct * BaseCell, bool Mark) { JMP_THIS(0x4A95A0); } diff --git a/EBolt.h b/EBolt.h index 5293611e..e0171e29 100644 --- a/EBolt.h +++ b/EBolt.h @@ -5,7 +5,9 @@ #pragma once #include +#include +class TechnoClass; class UnitClass; class EBolt diff --git a/Facing.h b/Facing.h index 4b0d7687..b8893e7e 100644 --- a/Facing.h +++ b/Facing.h @@ -25,7 +25,7 @@ class FacingClass DesiredFacing.SetDir(dir); } - explicit FacingClass(const FacingClass& another) noexcept + FacingClass(const FacingClass& another) noexcept : DesiredFacing { another.DesiredFacing } , StartFacing { another.StartFacing } , RotationTimer { another.RotationTimer } @@ -132,8 +132,8 @@ class FacingClass public: - DirStruct DesiredFacing; + DirStruct DesiredFacing; // target facing DirStruct StartFacing; // The starting direction from which to calcuate the rotation. - CDTimerClass RotationTimer; - DirStruct ROT; + CDTimerClass RotationTimer; // counts rotation steps + DirStruct ROT; // Rate of Turn. INI Value * 256 }; diff --git a/FootClass.h b/FootClass.h index a576f574..379bb03e 100644 --- a/FootClass.h +++ b/FootClass.h @@ -68,7 +68,7 @@ class NOVTABLE FootClass : public TechnoClass virtual DWORD vt_entry_53C(DWORD dwUnk) R0; virtual void vt_entry_540(DWORD dwUnk) RX; virtual void SetSpeedPercentage(double percentage) RX; - virtual void vt_entry_548() RX; + virtual void vt_entry_548() RX; // StopMoving? virtual void vt_entry_54C() RX; virtual bool vt_entry_550(DWORD dwUnk) R0; @@ -151,8 +151,8 @@ class NOVTABLE FootClass : public TechnoClass DWORD unknown_530; DWORD unknown_534; int WalkedFramesSoFar; - bool unknown_bool_53C; - DWORD unknown_540; + bool PlayingMovingSound; + DWORD MovingSoundDelay; DECLARE_PROPERTY(AudioController, Audio7); diff --git a/Helpers/Cast.h b/Helpers/Cast.h index 5a7f24ef..9193b8fe 100644 --- a/Helpers/Cast.h +++ b/Helpers/Cast.h @@ -13,14 +13,14 @@ class FootClass; // either we use abstract_cast everywhere or remove abstract_cast and only use specific_cast and generic_cast. // what do you think? -template +template __forceinline T specific_cast(AbstractClass* pAbstract) { using Base = std::remove_pointer_t; - return const_cast(specific_cast(static_cast(pAbstract))); + return const_cast(specific_cast(static_cast(pAbstract))); }; -template +template __forceinline T specific_cast(const AbstractClass* pAbstract) { using Base = std::remove_const_t>; @@ -33,20 +33,23 @@ __forceinline T specific_cast(const AbstractClass* pAbstract) { static_assert(!std::is_abstract::value, "specific_cast: Abstract types (not fully implemented classes) are not supported."); - if(pAbstract && pAbstract->WhatAmI() == Base::AbsID) { - return static_cast(pAbstract); + if constexpr (!SkipNullCheck) + { + if (!pAbstract) + return nullptr; } - return nullptr; + + return pAbstract->WhatAmI() == Base::AbsID ? static_cast(pAbstract) : nullptr; }; -template +template __forceinline T generic_cast(AbstractClass* pAbstract) { using Base = std::remove_pointer_t; - return const_cast(generic_cast(static_cast(pAbstract))); + return const_cast(generic_cast(static_cast(pAbstract))); }; -template +template __forceinline T generic_cast(const AbstractClass* pAbstract) { using Base = std::remove_const_t>; @@ -57,20 +60,23 @@ __forceinline T generic_cast(const AbstractClass* pAbstract) { && std::is_abstract::value, "generic_cast: T is required to be an abstract type derived from ObjectClass."); - if(pAbstract && (pAbstract->AbstractFlags & Base::AbsDerivateID) != AbstractFlags::None) { - return static_cast(pAbstract); + if constexpr (!SkipNullCheck) + { + if (!pAbstract) + return nullptr; } - return nullptr; + + return (pAbstract->AbstractFlags & Base::AbsDerivateID) != AbstractFlags::None ? static_cast(pAbstract) : nullptr; }; -template +template __forceinline T abstract_cast(AbstractClass* pAbstract) { using Base = std::remove_pointer_t; - return const_cast(abstract_cast(static_cast(pAbstract))); + return const_cast(abstract_cast(static_cast(pAbstract))); }; -template +template __forceinline T abstract_cast(const AbstractClass* pAbstract) { using Base = std::remove_const_t>; @@ -84,69 +90,45 @@ __forceinline T abstract_cast(const AbstractClass* pAbstract) { || !std::is_abstract::value, "abstract_cast: Abstract types (not fully implemented classes) derived from AbstractTypeClass are not suppored."); - return specific_cast(pAbstract); -}; - -// non-const versions - -template <> -__forceinline AbstractClass* abstract_cast(AbstractClass* pAbstract) { - return pAbstract; -}; - -template <> -__forceinline ObjectClass* abstract_cast(AbstractClass* pAbstract) { - return generic_cast(pAbstract); -}; - -template <> -__forceinline MissionClass* abstract_cast(AbstractClass* pAbstract) { - return reinterpret_cast(generic_cast(pAbstract)); -}; - -template <> -__forceinline RadioClass* abstract_cast(AbstractClass* pAbstract) { - return reinterpret_cast(generic_cast(pAbstract)); -}; - -template <> -__forceinline TechnoClass* abstract_cast(AbstractClass* pAbstract) { - return generic_cast(pAbstract); -}; - -template <> -__forceinline FootClass* abstract_cast(AbstractClass* pAbstract) { - return generic_cast(pAbstract); -}; - -// const versions - -template <> -__forceinline const AbstractClass* abstract_cast(const AbstractClass* pAbstract) { - return pAbstract; -}; - -template <> -__forceinline const ObjectClass* abstract_cast(const AbstractClass* pAbstract) { - return generic_cast(pAbstract); -}; - -template <> -__forceinline const MissionClass* abstract_cast(const AbstractClass* pAbstract) { - return reinterpret_cast(generic_cast(pAbstract)); -}; - -template <> -__forceinline const RadioClass* abstract_cast(const AbstractClass* pAbstract) { - return reinterpret_cast(generic_cast(pAbstract)); -}; - -template <> -__forceinline const TechnoClass* abstract_cast(const AbstractClass* pAbstract) { - return generic_cast(pAbstract); -}; - -template <> -__forceinline const FootClass* abstract_cast(const AbstractClass* pAbstract) { - return generic_cast(pAbstract); -}; + return specific_cast(pAbstract); +}; + +#define ABSTRACT_PARAM pAbstract +#define GENERIC_CAST(TypePointer, ConstQual, SkipNullCheck) \ + generic_cast(ABSTRACT_PARAM) +#define RT_GENERIC_CAST(TypePointer, ConstQual, SkipNullCheck) \ + reinterpret_cast(GENERIC_CAST(TechnoClass*, ConstQual, SkipNullCheck)) +#define ABSTRACT_CAST(TypePointer, ConstQual, SkipNullCheck, Code) \ + template <> \ + __forceinline ConstQual TypePointer abstract_cast(ConstQual AbstractClass* ABSTRACT_PARAM) \ + { return Code; } +#define APPLY_ABSTRACT_CAST(TypePointer) \ + ABSTRACT_CAST(TypePointer, , true, ABSTRACT_PARAM) \ + ABSTRACT_CAST(TypePointer, , false, ABSTRACT_PARAM) \ + ABSTRACT_CAST(TypePointer, const, true, ABSTRACT_PARAM) \ + ABSTRACT_CAST(TypePointer, const, false, ABSTRACT_PARAM) +#define APPLY_GC_ABSTRACT_CAST(TypePointer) \ + ABSTRACT_CAST(TypePointer, , true, GENERIC_CAST(TypePointer, , true)) \ + ABSTRACT_CAST(TypePointer, , false, GENERIC_CAST(TypePointer, , false)) \ + ABSTRACT_CAST(TypePointer, const, true, GENERIC_CAST(TypePointer, const, true)) \ + ABSTRACT_CAST(TypePointer, const, false, GENERIC_CAST(TypePointer, const, false)) +#define APPLY_RT_ABSTRACT_CAST(TypePointer) \ + ABSTRACT_CAST(TypePointer, , true, RT_GENERIC_CAST(TypePointer, , true)) \ + ABSTRACT_CAST(TypePointer, , false, RT_GENERIC_CAST(TypePointer, , false)) \ + ABSTRACT_CAST(TypePointer, const, true, RT_GENERIC_CAST(TypePointer, const, true)) \ + ABSTRACT_CAST(TypePointer, const, false, RT_GENERIC_CAST(TypePointer, const, false)) + +APPLY_ABSTRACT_CAST(AbstractClass*); +APPLY_GC_ABSTRACT_CAST(ObjectClass*); +APPLY_RT_ABSTRACT_CAST(MissionClass*); +APPLY_RT_ABSTRACT_CAST(RadioClass*); +APPLY_GC_ABSTRACT_CAST(TechnoClass*); +APPLY_GC_ABSTRACT_CAST(FootClass*); + +#undef APPLY_RT_ABSTRACT_CAST +#undef APPLY_GC_ABSTRACT_CAST +#undef APPLY_ABSTRACT_CAST +#undef ABSTRACT_CAST +#undef RT_GENERIC_CAST +#undef GENERIC_CAST +#undef ABSTRACT_PARAM diff --git a/HouseClass.h b/HouseClass.h index c454881e..643f0036 100644 --- a/HouseClass.h +++ b/HouseClass.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -504,6 +505,8 @@ class NOVTABLE HouseClass : public AbstractClass, public IHouse, public IPublicH SuperClass* FindSuperWeapon(SuperWeaponType type) const; + SuperClass* FindSuperWeapon(SuperWeaponTypeClass* type) const; + // I don't want to talk about these // read the code <_< @@ -1011,5 +1014,5 @@ class NOVTABLE HouseClass : public AbstractClass, public IHouse, public IPublicH int TotalOwnedInfantryCost; int TotalOwnedVehicleCost; int TotalOwnedAircraftCost; - DWORD unknown_power_160B4; + int PowerSurplus; }; diff --git a/InfantryClass.h b/InfantryClass.h index 41fc9d48..854f5c02 100644 --- a/InfantryClass.h +++ b/InfantryClass.h @@ -35,6 +35,8 @@ class NOVTABLE InfantryClass : public FootClass : InfantryClass(noinit_t()) { JMP_THIS(0x517A50); } + int UpdateDeplory() + { JMP_THIS(0x521320); } protected: explicit __forceinline InfantryClass(noinit_t) noexcept : FootClass(noinit_t()) diff --git a/JumpjetLocomotionClass.h b/JumpjetLocomotionClass.h index 5bc8e39b..c8ba86f4 100644 --- a/JumpjetLocomotionClass.h +++ b/JumpjetLocomotionClass.h @@ -59,6 +59,9 @@ class NOVTABLE JumpjetLocomotionClass : public LocomotionClass, public IPiggybac //JumpjetLocomotionClass + int GetZBalloonHover() + { JMP_THIS(0x54D820); } + //Constructor JumpjetLocomotionClass() : LocomotionClass(noinit_t()) diff --git a/MapClass.h b/MapClass.h index 59a63520..e00fe374 100644 --- a/MapClass.h +++ b/MapClass.h @@ -154,7 +154,7 @@ class LogicClass : public LayerClass virtual bool AddObject(ObjectClass* pObject, bool sorted) override { JMP_THIS(0x55BAA0); } - virtual void PointerGotInvalid(AbstractClass* pInvalid, bool removed) + virtual void Detach(AbstractClass* pItem, bool all) { JMP_THIS(0x55B880); } void RemoveObject(ObjectClass* pObject) @@ -196,7 +196,7 @@ class NOVTABLE MapClass : public GScreenClass virtual void AllocateCells() RX; virtual void DestructCells() RX; virtual void ConstructCells() RX; - virtual void PointerGotInvalid(AbstractClass* ptr, bool bUnk) RX; + virtual void Detach(AbstractClass* pItem, bool all) RX; virtual bool DraggingInProgress() R0; virtual void UpdateCrates() RX; virtual void CreateEmptyMap(const RectangleStruct& mapRect, bool reuse, char nLevel, bool bUnk2) RX; @@ -443,7 +443,7 @@ class NOVTABLE MapClass : public GScreenClass * BuildingClass::Place - RevealToAll * Foot/Infantry Class::Update/UpdatePosition * MapClass::RevealArea0 calls this to do the work - * ParasiteClass::Infect/PointerGotInvalid + * ParasiteClass::Infect/Detach * TechnoClass::Unlimbo * TechnoClass::Fire uses this (r = 4) right after using RevealArea0, wtfcock */ diff --git a/MechLocomotionClass.h b/MechLocomotionClass.h new file mode 100644 index 00000000..9a8d3c20 --- /dev/null +++ b/MechLocomotionClass.h @@ -0,0 +1,37 @@ +//Locomotor = {55D141B8-DB94-11d1-AC98-006008055BB5} + +#pragma once + +#include + +class NOVTABLE MechLocomotionClass : public LocomotionClass, public IPiggyback +{ +public: + static constexpr reference const ClassGUID {}; + + // TODO stub virtuals implementations + + //Destructor + virtual ~MechLocomotionClass() RX; + + //Constructor + MechLocomotionClass() + : MechLocomotionClass(noinit_t()) + { JMP_THIS(0x5AFEF0); } + +protected: + explicit __forceinline MechLocomotionClass(noinit_t) + : LocomotionClass(noinit_t()) + { } + + //=========================================================================== + //===== Properties ========================================================== + //=========================================================================== + +public: + + CoordStruct Destination; + CoordStruct HeadToCoord; + bool IsMoving; +}; + diff --git a/MessageListClass.h b/MessageListClass.h index 983734e1..5a3444c2 100644 --- a/MessageListClass.h +++ b/MessageListClass.h @@ -83,10 +83,12 @@ class MessageListClass void PrintMessage(const wchar_t* pMessage, int durationFrames = 0x96, int nColorSchemeIndex = ColorScheme::White, bool bSilent = false) { this->AddMessage(nullptr, 0, pMessage, nColorSchemeIndex, static_cast(0x4046), durationFrames, bSilent); } + void PrintMessage(const wchar_t* pLabel, const wchar_t* pMessage, int durationFrames = 0x96, int nColorSchemeIndex = ColorScheme::White, bool bSilent = false) + { this->AddMessage(pLabel, 0, pMessage, nColorSchemeIndex, static_cast(0x4046), static_cast(durationFrames), bSilent); } + void PrintMessage(const wchar_t* pMessage, double durationMinutes, int nColorSchemeIndex = ColorScheme::White, bool bSilent = false) { this->AddMessage(nullptr, 0, pMessage, nColorSchemeIndex, static_cast(0x4046), static_cast(durationMinutes * 900), bSilent); } - TextLabelClass* MessageList; Point2D MessagePos; int MaxMessageCount; diff --git a/MissionClass.h b/MissionClass.h index 2c16961c..68f9715b 100644 --- a/MissionClass.h +++ b/MissionClass.h @@ -89,6 +89,9 @@ class NOVTABLE MissionClass : public ObjectClass virtual int Mission_SpyPlaneApproach() R0; virtual int Mission_SpyPlaneOverfly() R0; + int Mission_Move_Carryall() // only use for AircraftClass + { JMP_THIS(0x416D50); } + //Constructor MissionClass() noexcept : MissionClass(noinit_t()) diff --git a/ObjectClass.h b/ObjectClass.h index 09028557..f22a0bc9 100644 --- a/ObjectClass.h +++ b/ObjectClass.h @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -196,9 +197,11 @@ class NOVTABLE ObjectClass : public AbstractClass { PUSH_VAR32(color); PUSH_VAR32(dst_Z); PUSH_VAR32(dst_Y); PUSH_VAR32(dst_X); PUSH_VAR32(src_Z); PUSH_VAR32(src_Y); PUSH_VAR32(src_X); CALL(0x704E40); } - int DistanceFrom(AbstractClass *that) const - { JMP_THIS(0x5F6440); } + DirStruct Direction(AbstractClass* pTarget) + { JMP_THIS(0x5F3DB0); } + int DistanceFrom(AbstractClass* that) const + { JMP_THIS(0x5F6440); } double GetHealthPercentage() const { return static_cast(this->Health) / this->GetType()->Strength; } @@ -265,6 +268,16 @@ class NOVTABLE ObjectClass : public AbstractClass return ret; } + DamageState TakeDamage(int damage, WarheadTypeClass* pWH, bool crewed, bool ignoreDefenses = true, ObjectClass* pAttacker = nullptr, HouseClass* pAttackingHouse = nullptr) + { + return ReceiveDamage(&damage, 0, pWH, pAttacker, ignoreDefenses, !crewed, pAttackingHouse); + } + + DamageState TakeDamage(int damage, bool crewed, bool ignoreDefenses = true, ObjectClass* pAttacker = nullptr, HouseClass* pAttackingHouse = nullptr) + { + return TakeDamage(damage, RulesClass::Instance->C4Warhead, crewed, ignoreDefenses, pAttacker, pAttackingHouse); + } + //Constructor NEVER CALL IT DIRECTLY /*ObjectClass() noexcept { JMP_THIS(0x5F3900); }*/ diff --git a/ObjectTypeClass.h b/ObjectTypeClass.h index fe726e0d..eb037ad7 100644 --- a/ObjectTypeClass.h +++ b/ObjectTypeClass.h @@ -51,6 +51,9 @@ class NOVTABLE ObjectTypeClass : public AbstractTypeClass void LoadVoxel() { JMP_STD(0x5F8110); } + void DestroyVoxelShadowCache() + { JMP_STD(0x5F99E0); } + //Constructor ObjectTypeClass(const char* pID) noexcept : ObjectTypeClass(noinit_t()) diff --git a/RulesClass.h b/RulesClass.h index 3f3a6a7f..8b38e2cb 100644 --- a/RulesClass.h +++ b/RulesClass.h @@ -206,7 +206,7 @@ class RulesClass void Read_AdvancedCommandBar(CCINIClass *pINI) { JMP_THIS(0x674650); } - void PointerGotInvalid(AbstractClass* pInvalid, bool removed) + void Detach(AbstractClass* pItem, bool all) { JMP_THIS(0x678850); } @@ -946,4 +946,4 @@ class RulesClass float DirectRockingCoefficient; float FallBackCoefficient; }; -#pragma pack(pop) \ No newline at end of file +#pragma pack(pop) diff --git a/ShipLocomotionClass.h b/ShipLocomotionClass.h index e14049ac..3506b158 100644 --- a/ShipLocomotionClass.h +++ b/ShipLocomotionClass.h @@ -28,8 +28,8 @@ class __declspec(align(4)) NOVTABLE ShipLocomotionClass : public LocomotionClass public: - DWORD Ramp1; - DWORD Ramp2; + DWORD PreviousRamp; + DWORD CurrentRamp; RateTimer SlopeTimer; CoordStruct Destination; CoordStruct HeadToCoord; diff --git a/SpawnManagerClass.h b/SpawnManagerClass.h index b4f7efc0..4c3d37b2 100644 --- a/SpawnManagerClass.h +++ b/SpawnManagerClass.h @@ -102,7 +102,7 @@ class NOVTABLE SpawnManagerClass : public AbstractClass DynamicVectorClass SpawnedNodes; CDTimerClass UpdateTimer; CDTimerClass SpawnTimer; - AbstractClass* Target; - AbstractClass* NewTarget; + AbstractClass* Destination; // SpawnMissile's destination + AbstractClass* Target; // Spwan plane's target SpawnManagerStatus Status; }; diff --git a/StaticInits.cpp b/StaticInits.cpp index 3c977bad..dfdcdab9 100644 --- a/StaticInits.cpp +++ b/StaticInits.cpp @@ -116,6 +116,16 @@ SuperClass* HouseClass::FindSuperWeapon(SuperWeaponType const type) const { return this->Supers.GetItemOrDefault(index); } +SuperClass* HouseClass::FindSuperWeapon(SuperWeaponTypeClass* const type) const { + for (int i = 0; i < this->Supers.Count; ++i) { + auto pItem = this->Supers.Items[i]; + if (this->Supers.Items[i]->Type == type) { + return pItem; + } + } + return nullptr; +} + bool HouseClass::IsIonCannonEligibleTarget(const TechnoClass* const pTechno) const { if(pTechno->InWhichLayer() == Layer::Ground && pTechno->IsAlive && !pTechno->InLimbo) { return true; diff --git a/Surface.h b/Surface.h index 6623f8a3..4cccc492 100644 --- a/Surface.h +++ b/Surface.h @@ -12,6 +12,8 @@ struct SHPStruct; class NOVTABLE Surface { public: + static constexpr reference const Pattern{}; + Surface() = default; virtual ~Surface() RX; @@ -108,14 +110,22 @@ class NOVTABLE Surface virtual bool IsDSurface() R0; // guessed - secsome + static bool __fastcall ClipLine(Point2D& point1, Point2D& point2, RectangleStruct& Bounds) + { JMP_STD(0x7BC2B0); } + // Helper RectangleStruct GetRect() { - RectangleStruct ret; + RectangleStruct ret{ 0, 0, 0, 0 }; this->GetRect(&ret); return ret; } + bool DrawDashedLine(Point2D* pStart, Point2D* pEnd, int nColor, int nOffset) + { + return DrawDashedLine(pStart, pEnd, nColor, Pattern.get(), nOffset); + } + // Properties @@ -139,9 +149,9 @@ class NOVTABLE XSurface : public Surface class NOVTABLE BSurface : public XSurface { public: - static constexpr constant_ptr VoxelSurface {}; + static constexpr constant_ptr VoxelSurface{}; - BSurface() : XSurface(), Buffer { this->Width * this->Height * 2 } { BytesPerPixel = 2; ((int*)this)[0] = 0x7E2070; } + BSurface() : XSurface(), Buffer{ this->Width * this->Height * 2 } { BytesPerPixel = 2; ((int*)this)[0] = 0x7E2070; } MemoryBuffer Buffer; }; @@ -186,23 +196,27 @@ static Point2D* Fancy_Text_Print_Wide(const Point2D& retBuffer, const wchar_t* T class NOVTABLE DSurface : public XSurface { public: - static constexpr reference const Tile {}; - static constexpr reference const Sidebar {}; - static constexpr reference const Primary {}; - static constexpr reference const Hidden {}; - static constexpr reference const Alternate {}; - static constexpr reference const Temp {}; - static constexpr reference const Composite {}; - - static constexpr reference const SidebarBounds {}; - static constexpr reference const ViewBounds {}; - static constexpr reference const WindowBounds {}; + static constexpr reference const Tile{}; + static constexpr reference const Sidebar{}; + static constexpr reference const Primary{}; + static constexpr reference const Hidden{}; + static constexpr reference const Alternate{}; + static constexpr reference const Temp{}; + static constexpr reference const Composite{}; + + static constexpr reference const SidebarBounds{}; + static constexpr reference const ViewBounds{}; + static constexpr reference const WindowBounds{}; virtual bool DrawGradientLine(RectangleStruct* pRect, Point2D* pStart, Point2D* pEnd, ColorStruct* pStartColor, ColorStruct* pEndColor, float fStep, int nColor) R0; virtual bool CanBlit() R0; + void DrawLineBlit(RectangleStruct* pRect, Point2D* pStart, Point2D* pEnd, + ColorStruct* pStartColor, int mult, int start_z, int end_z) + { JMP_THIS(0x4BEAC0); } + // Comments from thomassneddon void DrawSHP(ConvertClass* Palette, SHPStruct* SHP, int FrameIndex, const Point2D* const Position, const RectangleStruct* const Bounds, BlitterFlags Flags, int Remap, @@ -215,8 +229,29 @@ class NOVTABLE DSurface : public XSurface ZGradientDescIndex, Brightness, TintColor, ZShape, ZShapeFrame, XOffset, YOffset); } + void DrawSHP(ConvertClass* Palette, SHPStruct* SHP, int FrameIndex, + const Point2D* const Position, const RectangleStruct* const Bounds, + BlitterFlags Flags = (BlitterFlags)0x600, + int Brightness = 1000, + int TintColor = 0) + { + DrawSHP(Palette, SHP, FrameIndex, Position, Bounds, Flags, 0, + 0, + ZGradient::Ground, + Brightness, + TintColor, nullptr, 0, 0, 0 + ); + } + + void DrawSHP(ConvertClass* Palette, SHPStruct* SHP, int FrameIndex, + const Point2D* const Position, BlitterFlags Flags = (BlitterFlags)0x600) + { + RectangleStruct bound = this->GetRect(); + DrawSHP(Palette, SHP, FrameIndex, Position, &bound, Flags); + } + void DrawText(const wchar_t* pText, RectangleStruct* pBounds, Point2D* pLocation, - COLORREF ForeColor, COLORREF BackColor, TextPrintType Flag) + COLORREF ForeColor, COLORREF BackColor = 0, TextPrintType Flag = TextPrintType::NoShadow) { Point2D tmp = { 0, 0 }; @@ -228,7 +263,7 @@ class NOVTABLE DSurface : public XSurface RectangleStruct rect = { 0, 0, 0, 0 }; this->GetRect(&rect); - Point2D tmp { 0,0 }; + Point2D tmp{ 0, 0 }; Fancy_Text_Print_Wide(tmp, pText, this, rect, *pLoction, Color, 0, TextPrintType::NoShadow); } @@ -238,6 +273,30 @@ class NOVTABLE DSurface : public XSurface DrawText(pText, &P, Color); } + /* + void DrawText(const wchar_t* pText, RectangleStruct* pBounds, Point2D* pLocation, + ColorStruct ForeColor, ColorStruct BackColor = Colors::Empty, TextPrintType Flag = TextPrintType::NoShadow) + { + DrawText(pText, pBounds, pLocation, Drawing::RGB_To_Int(ForeColor), Drawing::RGB_To_Int(BackColor), Flag); + } + + void DrawText(const wchar_t* pText, Point2D* pPos, ColorStruct color, TextPrintType flag = TextPrintType::NoShadow) + { + RectangleStruct bound = this->GetRect(); + DrawText(pText, &bound, pPos, Drawing::RGB_To_Int(color), 0, flag); + } + + void DrawText(const wchar_t* pText, CoordStruct location, ColorStruct color, TextPrintType flag = TextPrintType::NoShadow) + { + Point2D pos{ 0, 0 }; + if (TacticalClass::Instance->CoordsToClient(location, &pos)) + { + RectangleStruct bound = this->GetRect(); + DrawText(pText, &bound, &pos, Drawing::RGB_To_Int(color), 0, flag); + } + } + */ + void* Buffer; bool IsAllocated; bool IsInVideoRam; diff --git a/TacticalClass.h b/TacticalClass.h index e3804ae0..d640fc86 100644 --- a/TacticalClass.h +++ b/TacticalClass.h @@ -33,6 +33,12 @@ class NOVTABLE TacticalClass : public AbstractClass bool CoordsToClient(CoordStruct const& coords, Point2D* pOutClient) const { JMP_THIS(0x6D2140); } + Point2D CoordsToClient(CoordStruct const& coords) const { + Point2D buffer; + this->CoordsToClient(coords, &buffer); + return buffer; + } + Point2D* CoordsToScreen(Point2D* pDest, CoordStruct* pSource) { JMP_THIS(0x6D1F10); } diff --git a/TechnoClass.h b/TechnoClass.h index a71fcc94..d3828d5c 100644 --- a/TechnoClass.h +++ b/TechnoClass.h @@ -23,6 +23,7 @@ class AnimClass; class BulletClass; class BuildingClass; class CellClass; +class EBolt; class HouseClass; class FootClass; class HouseClass; @@ -190,7 +191,7 @@ class NOVTABLE TechnoClass : public RadioClass virtual bool vt_entry_29C() R0; virtual bool IsReadyToCloak() const JMP_THIS(0x6FBDC0); virtual bool ShouldNotBeCloaked() const JMP_THIS(0x6FBC90); - virtual DirStruct* TurretFacing(DirStruct* pBuffer) const R0; + virtual FacingClass* TurretFacing(FacingClass* pBuffer) const R0; virtual bool IsArmed() const R0; // GetWeapon(primary) && GetWeapon(primary)->WeaponType virtual bool vt_entry_2B0() const R0; virtual double GetStoragePercentage() const R0; @@ -214,7 +215,7 @@ class NOVTABLE TechnoClass : public RadioClass virtual CellStruct* vt_entry_2FC(CellStruct* Buffer, DWORD dwUnk2, DWORD dwUnk3) const R0; virtual CoordStruct * vt_entry_300(CoordStruct * Buffer, DWORD dwUnk2) const R0; virtual DWORD vt_entry_304(DWORD dwUnk, DWORD dwUnk2) const R0; - virtual DirStruct* GetRealFacing(DirStruct* pBuffer) const R0; + virtual FacingClass* GetRealFacing(FacingClass* pBuffer) const R0; virtual InfantryTypeClass* GetCrew() const R0; virtual bool vt_entry_310() const R0; virtual bool CanDeploySlashUnload() const R0; @@ -350,6 +351,13 @@ class NOVTABLE TechnoClass : public RadioClass return pType ? pType->get_ID() : nullptr; } + bool InRange(CoordStruct* pLocation, AbstractClass* pTarget, WeaponTypeClass* pWeapon) + { JMP_THIS(0x6F7220); } + + // Unit and Infantry fire logic is diffrent, this function for help to fire custom weapon, force use Unit's fire logic + BulletClass* Fire_IgnoreType(AbstractClass* pTarget, int idxWeapon) + { JMP_THIS(0x6FDD50); } + int TimeToBuild() const { JMP_THIS(0x6F47A0); } @@ -359,9 +367,15 @@ class NOVTABLE TechnoClass : public RadioClass bool CanBePermaMindControlled() const { JMP_THIS(0x53C450); } - LaserDrawClass* CreateLaser(ObjectClass *pTarget, int idxWeapon, WeaponTypeClass *pWeapon, const CoordStruct &Coords) + LaserDrawClass* CreateLaser(AbstractClass *pTarget, int idxWeapon, WeaponTypeClass *pWeapon, const CoordStruct &Coords) { JMP_THIS(0x6FD210); } + EBolt* Electric_Zap(AbstractClass* pTarget, WeaponTypeClass* pWeapon, const CoordStruct& Coords) + { JMP_THIS(0x6FD460); } + + void DrawALinkTo(CoordStruct from, CoordStruct to, ColorStruct color) + { JMP_THIS(0x704E40); } + /* * Cell->AddThreat(this->Owner, -this->ThreatPosed); * this->ThreatPosed = 0; @@ -438,6 +452,9 @@ class NOVTABLE TechnoClass : public RadioClass int __fastcall ClearPlanningTokens(NetworkEvent* pEvent) { JMP_STD(0x6386E0); } + int GetElevationBonusDistance(AbstractClass* pTarget) + { JMP_THIS(0x6F6F60); } + void SetTargetForPassengers(AbstractClass* pTarget) { JMP_THIS(0x710550); } @@ -475,6 +492,9 @@ class NOVTABLE TechnoClass : public RadioClass WeaponStruct* GetPrimaryWeapon() const { JMP_THIS(0x70E1A0); } + bool TryNextPlanningTokenNode() + { JMP_THIS(0x6385C0); } + int GetIonCannonValue(AIDifficulty difficulty) const; int GetIonCannonValue(AIDifficulty difficulty, int maxHealth) const { @@ -486,14 +506,15 @@ class NOVTABLE TechnoClass : public RadioClass return this->GetIonCannonValue(difficulty); } - DirStruct TurretFacing() const { - DirStruct ret; + FacingClass TurretFacing() const { + FacingClass ret; this->TurretFacing(&ret); return ret; } - DirStruct GetRealFacing() const { - DirStruct ret; + // return bodyFacing or turretFacing if it has turret + FacingClass GetRealFacing() const { + FacingClass ret; this->GetRealFacing(&ret); return ret; } @@ -614,8 +635,8 @@ class NOVTABLE TechnoClass : public RadioClass TechnoClass* BunkerLinkedItem; float PitchAngle; // not exactly, and it doesn't affect the drawing, only internal state of a dropship - DECLARE_PROPERTY(CDTimerClass, DiskLaserTimer); - int ROF; + DECLARE_PROPERTY(CDTimerClass, ROFTimer);// ROF + int ROF; int Ammo; int Value; // set to actual cost when this gets queued in factory, updated only in building's 42C @@ -688,7 +709,7 @@ class NOVTABLE TechnoClass : public RadioClass HouseClass* ChronoWarpedByHouse; bool unknown_bool_430; bool IsMouseHovering; - bool unknown_bool_432; + bool WasSelected; TeamClass* OldTeam; bool CountedAsOwnedSpecial; // for absorbers, infantry uses this to manually control OwnedInfantry count bool Absorbed; // in UnitAbsorb/InfantryAbsorb or smth, lousy memory diff --git a/TechnoTypeClass.h b/TechnoTypeClass.h index bd9e4856..cb64cbf2 100644 --- a/TechnoTypeClass.h +++ b/TechnoTypeClass.h @@ -277,8 +277,8 @@ class NOVTABLE TechnoTypeClass : public ObjectTypeClass int MindClearedSound; MovementZone MovementZone; int GuardRange; - int MinDebris; int MaxDebris; + int MinDebris; TypeList DebrisAnims; int Passengers; bool OpenTopped; diff --git a/WalkLocomotionClass.h b/WalkLocomotionClass.h new file mode 100644 index 00000000..6308c19c --- /dev/null +++ b/WalkLocomotionClass.h @@ -0,0 +1,39 @@ +//Locomotor = {4A582744-9839-11d1-B709-00A024DDAFD1} + +#pragma once + +#include + +class NOVTABLE WalkLocomotionClass : public LocomotionClass, public IPiggyback +{ +public: + static constexpr reference const ClassGUID {}; + + // TODO stub virtuals implementations + + //Destructor + virtual ~WalkLocomotionClass() RX; + + //Constructor + WalkLocomotionClass() + : WalkLocomotionClass(noinit_t()) + { JMP_THIS(0x75AA90); } + +protected: + explicit __forceinline WalkLocomotionClass(noinit_t) + : LocomotionClass(noinit_t()) + { } + + //=========================================================================== + //===== Properties ========================================================== + //=========================================================================== + +public: + + CoordStruct Destination; + CoordStruct HeadToCoord; + bool IsMoving; + bool Bool_35; + bool IsReallyMoving; +}; + diff --git a/WeaponTypeClass.h b/WeaponTypeClass.h index 41c3da3b..1040ea43 100644 --- a/WeaponTypeClass.h +++ b/WeaponTypeClass.h @@ -35,10 +35,23 @@ class NOVTABLE WeaponTypeClass : public AbstractTypeClass virtual int Size() const R0; //AbstractTypeClass - void CalculateSpeed() { JMP_THIS(0x7729F0); } + int GetSpeed(int range) + { JMP_THIS(0x773070); } + + //Helper + int GetSpeed(CoordStruct source, CoordStruct target) + { + return GetSpeed((int)source.DistanceFrom(target)); + } + + static int __fastcall GetSpeed(double range, int gravity) + { JMP_STD(0x48AB90); } + + + //Constructor WeaponTypeClass(const char* pID = nullptr) : WeaponTypeClass(noinit_t()) diff --git a/YRMathVector.h b/YRMathVector.h index f4cd369b..61683cda 100644 --- a/YRMathVector.h +++ b/YRMathVector.h @@ -13,9 +13,15 @@ template class Vector2D static const Vector2D Empty; //no constructor, so this class stays aggregate and can be initialized using the curly braces {} - T X,Y; + T X, Y; //operator overloads + template + void operator=(const Vector2D& a) + { + this->X = static_cast(a.X); + this->Y = static_cast(a.Y); + } //addition Vector2D operator+(const Vector2D& a) const { @@ -72,6 +78,11 @@ template class Vector2D { return static_cast(X) * a.X + static_cast(Y) * a.Y; } + // for map key + bool operator<(const Vector2D& other) const + { + return other.X >= X || (other.X < X && other.Y >= Y); + } //magnitude double Magnitude() const { @@ -102,18 +113,24 @@ template class Vector2D double FindScalar(const Vector2D& a) const { double r = static_cast(a.X) / static_cast(X); - if(static_cast(r * Y) == a.Y) { + if (static_cast(r * Y) == a.Y) { return r; - } else { + } + else { //the vectors are not collinear, return NaN! - unsigned long NaN[2] = {0xFFFFFFFF,0x7FFFFFFF}; + unsigned long NaN[2] = { 0xFFFFFFFF,0x7FFFFFFF }; return *reinterpret_cast(NaN); } } + //is empty + bool IsEmpty() + { + return X == Empty.X && Y == Empty.Y; + } }; template -const Vector2D Vector2D::Empty = {T(), T()}; +const Vector2D Vector2D::Empty = { T(), T() }; /*========================================== ============ 3D Vector ===================== @@ -125,9 +142,16 @@ template class Vector3D static const Vector3D Empty; //no constructor, so this class stays aggregate and can be initialized using the curly braces {} - T X,Y,Z; + T X, Y, Z; //operator overloads + template + void operator=(const Vector3D& a) + { + this->X = static_cast(a.X); + this->Y = static_cast(a.Y); + this->Z = static_cast(a.Z); + } //addition Vector3D operator+(const Vector3D& a) const { @@ -192,6 +216,11 @@ template class Vector3D + static_cast(Y) * a.Y + static_cast(Z) * a.Z; } + // for map key + bool operator<(const Vector3D& other) const + { + return other.X >= X || (other.X < X && other.Y >= Y) || (other.X < X && other.Y < Y && other.Z >= Z); + } //magnitude double Magnitude() const { @@ -221,11 +250,12 @@ template class Vector3D double FindScalar(const Vector3D& a) const { double r = static_cast(a.X) / static_cast(X); - if((static_cast(r * Y) == a.Y) && (static_cast(r * Z) == a.Z)) { + if ((static_cast(r * Y) == a.Y) && (static_cast(r * Z) == a.Z)) { return r; - } else { + } + else { //the vectors are not collinear, return NaN! - unsigned long NaN[2] = {0xFFFFFFFF,0x7FFFFFFF}; + unsigned long NaN[2] = { 0xFFFFFFFF,0x7FFFFFFF }; return *reinterpret_cast(NaN); } } @@ -237,7 +267,12 @@ template class Vector3D Z * a.X - X * a.Z, X * a.Y - Y * a.X }; } + //is empty + bool IsEmpty() + { + return X == Empty.X && Y == Empty.Y && Z == Empty.Z; + } }; template -const Vector3D Vector3D::Empty = {T(), T(), T()}; +const Vector3D Vector3D::Empty = { T(), T(), T() };