diff --git a/src/game/engine/cargo.cpp b/src/game/engine/cargo.cpp index 08229447..0a27c531 100644 --- a/src/game/engine/cargo.cpp +++ b/src/game/engine/cargo.cpp @@ -83,7 +83,7 @@ FootClass *CargoClass::Detach_Object() void CargoClass::Code_Pointers() { if (m_Object != nullptr) { - m_Object = reinterpret_cast(As_Target(m_Object)); + m_Object = reinterpret_cast(m_Object->As_Target()); } } diff --git a/src/game/engine/cell.cpp b/src/game/engine/cell.cpp index 2244518a..2260ed6d 100644 --- a/src/game/engine/cell.cpp +++ b/src/game/engine/cell.cpp @@ -1044,7 +1044,7 @@ void CellClass::Wall_Update() adjcell.m_OverlayFrame = 0; adjcell.m_Overlay = OVERLAY_NONE; adjcell.m_OwnerHouse = HOUSES_NONE; // C&C DOS sets this, bug fix perhaps? - Detach_This_From_All(As_Target(adjcell.m_CellNumber)); + Detach_This_From_All(As_Target()); } // Frame 16 for SBAG is after the nondamaged set @@ -1052,7 +1052,7 @@ void CellClass::Wall_Update() adjcell.m_OverlayFrame = 0; adjcell.m_Overlay = OVERLAY_NONE; adjcell.m_OwnerHouse = HOUSES_NONE; - Detach_This_From_All(As_Target(adjcell.m_CellNumber)); + Detach_This_From_All(As_Target()); } // Frame 32 for CYCL is after the first damage state set @@ -1060,7 +1060,7 @@ void CellClass::Wall_Update() adjcell.m_OverlayFrame = 0; adjcell.m_Overlay = OVERLAY_NONE; adjcell.m_OwnerHouse = HOUSES_NONE; - Detach_This_From_All(As_Target(adjcell.m_CellNumber)); + Detach_This_From_All(As_Target()); } // Frame 16 for FENC is after the nondamaged set, on a 0 basis frame 32 doesn't exist, some hack for older art? @@ -1068,7 +1068,7 @@ void CellClass::Wall_Update() adjcell.m_OverlayFrame = 0; adjcell.m_Overlay = OVERLAY_NONE; adjcell.m_OwnerHouse = HOUSES_NONE; - Detach_This_From_All(As_Target(adjcell.m_CellNumber)); + Detach_This_From_All(As_Target()); } // Frame 16 for SBAG is after the nondamaged set @@ -1076,7 +1076,7 @@ void CellClass::Wall_Update() adjcell.m_OverlayFrame = 0; adjcell.m_Overlay = OVERLAY_NONE; adjcell.m_OwnerHouse = HOUSES_NONE; - Detach_This_From_All(As_Target(adjcell.m_CellNumber)); + Detach_This_From_All(As_Target()); } adjcell.Recalc_Attributes(); @@ -1163,7 +1163,7 @@ BOOL CellClass::Reduce_Wall(int damage) Adjacent_Cell(FACING_WEST).Wall_Update(); Adjacent_Cell(FACING_SOUTH).Wall_Update(); Adjacent_Cell(FACING_EAST).Wall_Update(); - Detach_This_From_All(As_Target(Cell_Number())); + Detach_This_From_All(As_Target()); if (overlay.Is_Crushable()) { g_Map.Zone_Reset(1 << MZONE_NORMAL); diff --git a/src/game/engine/cell.h b/src/game/engine/cell.h index 1744cc37..d1a7603f 100644 --- a/src/game/engine/cell.h +++ b/src/game/engine/cell.h @@ -131,6 +131,7 @@ class CellClass BOOL Is_Occuppied() const { return m_OccupantBit != OCCUPANT_NONE; } cell_t Cell_Number() const { return m_CellNumber; } + target_t As_Target() const { return ::As_Target(m_CellNumber); } int8_t Get_Zone(MZoneType mzone) const { return m_Zones[mzone]; } void Set_Zone(MZoneType mzone, int8_t zone) { m_Zones[mzone] = zone; } BOOL Get_Placement_Check() const { return m_PlacementCheck; } diff --git a/src/game/engine/display.cpp b/src/game/engine/display.cpp index b93e69b8..e7645903 100644 --- a/src/game/engine/display.cpp +++ b/src/game/engine/display.cpp @@ -1100,7 +1100,7 @@ void DisplayClass::Mouse_Left_Up( m_DisplayBit16 = false; if (object != nullptr) { - target = As_Target(object); + target = object->As_Target(); } else if (cellnum != -1) { target = As_Target(cellnum); } diff --git a/src/game/engine/factory.cpp b/src/game/engine/factory.cpp index 4ff30aa1..c450665b 100644 --- a/src/game/engine/factory.cpp +++ b/src/game/engine/factory.cpp @@ -286,7 +286,7 @@ BOOL FactoryClass::Completed() void FactoryClass::Code_Pointers() { if (m_Object != nullptr) { - m_Object = reinterpret_cast(As_Target(m_Object)); + m_Object = reinterpret_cast(m_Object->As_Target()); } if (m_Owner != nullptr) { m_Owner = (HouseClass *)m_Owner->What_Type(); diff --git a/src/game/engine/foot.cpp b/src/game/engine/foot.cpp index 04745741..772a23c8 100644 --- a/src/game/engine/foot.cpp +++ b/src/game/engine/foot.cpp @@ -1595,3 +1595,43 @@ BOOL FootClass::Is_On_Priority_Mission() { return m_Mission == MISSION_ENTER; } + +/** + * + * + * 0x004C35D0 + */ +void FootClass::Queue_Navigation_List(target_t target) +{ + if (Target_Legal(target)) { + int i; + for (i = 0; i < NAV_LENGTH && Target_Legal(m_NavList[i]); ++i); + + if (target == As_Target() && i > 0) { + m_Bit2_4 = true; + } else { + if (i == 0) { + m_Bit2_4 = false; + } + if (i < NAV_LENGTH) { + m_NavList[i] = target; + } + } + + if (!Target_Legal(m_NavCom) && m_Mission == MISSION_GUARD) { + Enter_Idle_Mode(); + } + } +} + +/** + * + * + * 0x004C3684 + */ +void FootClass::Clear_Navigation_List() +{ + for (int i = 0; i < NAV_LENGTH; ++i) { + m_NavList[i] = 0; + } +} diff --git a/src/game/engine/foot.h b/src/game/engine/foot.h index 560e4bc4..ea229637 100644 --- a/src/game/engine/foot.h +++ b/src/game/engine/foot.h @@ -123,6 +123,12 @@ class FootClass : public TechnoClass FacingType Get_Path_Facing(int index) const { return m_Paths[index]; } target_t Nav_Com() const { return m_NavCom; } + void Set_To_Scatter(BOOL state) { m_ToScatter = state; } + void Set_In_Formation(BOOL state) { m_InFormation = state; } + void Set_Team_Speed(SpeedType speed) { m_TeamSpeed = speed; } + void Set_Team_Max_Speed(MPHType mph) { m_TeamMaxSpeed = mph; } + void Set_Suspended_NavCom(target_t target) { m_SuspendedNavCom = target; } + static int Point_Relative_To_Line(int px, int py, int sx, int sy, int ex, int ey); PathType *Find_Path_Wrapper(cell_t dest, FacingType *buffer, int length, MoveType move); @@ -134,6 +140,9 @@ class FootClass : public TechnoClass const fixed_t &Get_Speed_Multiplier() const { return m_SpeedMult; } const GamePtr &Get_Team() const { return m_Team; } + void Queue_Navigation_List(target_t target); + void Clear_Navigation_List(); + protected: #ifndef CHRONOSHIFT_NO_BITFIELDS BOOL m_LimitedScan : 1; // 1 diff --git a/src/game/engine/gameevent.cpp b/src/game/engine/gameevent.cpp index 4bdfc18d..35c5d1e9 100644 --- a/src/game/engine/gameevent.cpp +++ b/src/game/engine/gameevent.cpp @@ -21,7 +21,7 @@ #include "mission.h" #include -#define EVENT_captainslog_debug(x, ...) \ +#define EVENT_DEBUG_LOG(x, ...) \ /*if ( g_Debug_Print_Events )*/ \ { \ captainslog_debug(x, ##__VA_ARGS__); \ @@ -50,13 +50,13 @@ GameEventClass::EventInfoStruct GameEventClass::s_EventTypeList[EVENT_COUNT] = { { "SELL", sizeof(GameEventClass::WhomEventStruct) }, { "SELLCELL", sizeof(GameEventClass::CellEventStruct) }, { "SPECIAL", sizeof(GameEventClass::SpecialEventStruct) }, - { "FRAME_SYNC", 0 }, // Should be "sizeof(GameEventClass::FrameEventStruct)" + { "FRAME_SYNC", 0 }, // No extra data. { "MESSAGE", 0 }, // No extra data. { "RESPONSE_TIME", sizeof(GameEventClass::TimeEventStruct) }, { "FRAME_INFO", sizeof(GameEventClass::FrameEventStruct) }, { "SAVEGAME", 0 }, // No extra data. { "ARCHIVE", sizeof(GameEventClass::WhomTargetEventStruct) }, - { "ADDPLAYER", 4 }, // TODO + { "ADDPLAYER", 4 }, // original table has it as 4 but the event is actually 8. { "TIMING", sizeof(GameEventClass::TimingEventStruct) }, { "PROCESS_TIME", 2 }, { "PROPOSE_DRAW", 0 }, // No extra data. @@ -70,7 +70,7 @@ GameEventClass::GameEventClass() : m_IsExecuted(false) { // Removed, as this is used at the default constructor, so it will fire a lot of times... - // EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); + // EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); memset(&m_EventData, 0, sizeof(m_EventData)); } @@ -102,7 +102,7 @@ GameEventClass::GameEventClass(GameEventType type) : m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); memset(&m_EventData, 0, sizeof(m_EventData)); } @@ -113,20 +113,20 @@ GameEventClass::GameEventClass(GameEventType type, cell_t cell) : m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); memset(&m_EventData, 0, sizeof(m_EventData)); m_EventData.u_Cell.m_Cell = cell; } -GameEventClass::GameEventClass(GameEventType type, unsigned int gamespeed) : +GameEventClass::GameEventClass(GameEventType type, uint32_t gamespeed) : m_Type(type), m_EventFrame(g_GameFrame), m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); memset(&m_EventData, 0, sizeof(m_EventData)); @@ -139,7 +139,7 @@ GameEventClass::GameEventClass(GameEventType type, HousesType house) : m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); memset(&m_EventData, 0, sizeof(m_EventData)); @@ -152,20 +152,20 @@ GameEventClass::GameEventClass(GameEventType type, RTTIType rtti) : m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); memset(&m_EventData, 0, sizeof(m_EventData)); m_EventData.u_RTTI.m_RTTI = rtti; } -GameEventClass::GameEventClass(GameEventType type, RTTIType rtti, unsigned int heap_id) : +GameEventClass::GameEventClass(GameEventType type, RTTIType rtti, uint32_t heap_id) : m_Type(type), m_EventFrame(g_GameFrame), m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); memset(&m_EventData, 0, sizeof(m_EventData)); @@ -179,7 +179,7 @@ GameEventClass::GameEventClass(GameEventType type, RTTIType rtti, cell_t cell) : m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); memset(&m_EventData, 0, sizeof(m_EventData)); @@ -193,21 +193,21 @@ GameEventClass::GameEventClass(GameEventType type, SpecialWeaponType special, ce m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); memset(&m_EventData, 0, sizeof(m_EventData)); - m_EventData.u_SpecialPlace.m_Special = special; + m_EventData.u_SpecialPlace.m_SpecialWeapon = special; m_EventData.u_SpecialPlace.m_Cell = cell; } -GameEventClass::GameEventClass(GameEventType type, void *a2, unsigned long a3) : +GameEventClass::GameEventClass(GameEventType type, void *a2, uint32_t a3) : m_Type(type), m_EventFrame(g_GameFrame), m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); memset(&m_EventData, 0, sizeof(m_EventData)); @@ -220,7 +220,7 @@ GameEventClass::GameEventClass(GameEventType type, TargetClass whom) : m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); memset(&m_EventData, 0, sizeof(m_EventData)); @@ -233,7 +233,7 @@ GameEventClass::GameEventClass(GameEventType type, TargetClass whom, TargetClass m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); memset(&m_EventData, 0, sizeof(m_EventData)); @@ -247,7 +247,7 @@ GameEventClass::GameEventClass(GameEventType type, AnimType anim, HousesType own m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event. Anim:%s.", + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event. Anim:%s.", Name_From(m_Type), AnimTypeClass::Name_From(anim)); @@ -258,13 +258,13 @@ GameEventClass::GameEventClass(GameEventType type, AnimType anim, HousesType own m_EventData.u_Anim.m_Coord = coord; } -GameEventClass::GameEventClass(GameEventType type, unsigned int crc, unsigned short cmd_count, unsigned char delay) : +GameEventClass::GameEventClass(GameEventType type, uint32_t crc, uint16_t cmd_count, uint8_t delay) : m_Type(type), m_EventFrame(g_GameFrame), m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); memset(&m_EventData, 0, sizeof(m_EventData)); @@ -273,13 +273,13 @@ GameEventClass::GameEventClass(GameEventType type, unsigned int crc, unsigned sh m_EventData.u_Frame.m_Delay = delay; } -GameEventClass::GameEventClass(GameEventType type, unsigned short desired_frame_rate, unsigned short max_ahead) : +GameEventClass::GameEventClass(GameEventType type, uint16_t desired_frame_rate, uint16_t max_ahead) : m_Type(type), m_EventFrame(g_GameFrame), m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); memset(&m_EventData, 0, sizeof(m_EventData)); @@ -293,7 +293,7 @@ GameEventClass::GameEventClass(TargetClass whom, MissionType mission, TargetClas m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating EVENT_MEGAMISSION event."); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating EVENT_MEGAMISSION event."); memset(&m_EventData, 0, sizeof(m_EventData)); @@ -310,7 +310,7 @@ GameEventClass::GameEventClass( m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating EVENT_MEGAMISSION_F event."); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating EVENT_MEGAMISSION_F event."); memset(&m_EventData, 0, sizeof(m_EventData)); @@ -328,7 +328,7 @@ GameEventClass::GameEventClass(SpecialClass special) : m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); + EVENT_DEBUG_LOG("GameEventClass::GameEventClass() - Creating '%s' event.", Name_From(m_Type)); memset(&m_EventData, 0, sizeof(m_EventData)); @@ -341,7 +341,7 @@ GameEventClass::GameEventClass(AnimType anim, HousesType owner, coord_t coord) : m_HouseID(g_PlayerPtr->Get_Heap_ID()), m_IsExecuted(false) { - EVENT_captainslog_debug( + EVENT_DEBUG_LOG( "GameEventClass::GameEventClass() - Creating ANIMATION event. Anim:%s.\n", AnimTypeClass::Name_From(anim)); memset(&m_EventData, 0, sizeof(m_EventData)); @@ -353,7 +353,7 @@ GameEventClass::GameEventClass(AnimType anim, HousesType owner, coord_t coord) : void GameEventClass::Execute() { - EVENT_captainslog_debug("GameEventClass::Execute() - Executing '%s' event (GameFrame:%d, EventFrame:%d, HouseID:%d).", + EVENT_DEBUG_LOG("GameEventClass::Execute() - Executing '%s' event (GameFrame:%d, EventFrame:%d, HouseID:%d).", Name_From(m_Type), g_GameFrame, m_EventFrame, @@ -363,14 +363,14 @@ void GameEventClass::Execute() case EVENT_ALLY: break; case EVENT_MEGAMISSION: - EVENT_captainslog_debug(" MEGAMISSION - Whom:%08X, Mission:%s, Target:%08X, Dest:%08X.", + EVENT_DEBUG_LOG(" MEGAMISSION - Whom:%08X, Mission:%s, Target:%08X, Dest:%08X.", m_EventData.u_MegaMission.m_Whom, MissionClass::Name_From(m_EventData.u_MegaMission.m_Mission), m_EventData.u_MegaMission.m_Target, m_EventData.u_MegaMission.m_Dest); break; case EVENT_MEGAMISSION_F: - EVENT_captainslog_debug( + EVENT_DEBUG_LOG( " MEGAMISSION_F - Whom:%08X, Mission:%s, Target:%08X\n" " Dest:%08X, FormSpeed:%d, FormMaxSpeed:%d.\n", m_EventData.u_MegaMissionF.m_Whom, @@ -381,94 +381,94 @@ void GameEventClass::Execute() m_EventData.u_MegaMissionF.m_FormMaxSpeed); break; case EVENT_IDLE: - EVENT_captainslog_debug(" IDLE."); + EVENT_DEBUG_LOG(" IDLE."); break; case EVENT_SCATTER: - EVENT_captainslog_debug(" SCATTER."); + EVENT_DEBUG_LOG(" SCATTER."); break; case EVENT_DESTRUCT: - EVENT_captainslog_debug(" DESTRUCT."); + EVENT_DEBUG_LOG(" DESTRUCT."); break; case EVENT_DEPLOY: - EVENT_captainslog_debug(" DEPLOY."); + EVENT_DEBUG_LOG(" DEPLOY."); break; case EVENT_PLACE: - EVENT_captainslog_debug(" PLACE."); + EVENT_DEBUG_LOG(" PLACE."); break; case EVENT_OPTIONS: - EVENT_captainslog_debug(" OPTIONS."); + EVENT_DEBUG_LOG(" OPTIONS."); break; case EVENT_GAMESPEED: - EVENT_captainslog_debug(" GAMESPEED - GameSpeed:%d.", m_EventData.u_GameSpeed.m_GameSpeed); + EVENT_DEBUG_LOG(" GAMESPEED - GameSpeed:%d.", m_EventData.u_GameSpeed.m_GameSpeed); break; case EVENT_PRODUCE: - EVENT_captainslog_debug(" PRODUCE."); + EVENT_DEBUG_LOG(" PRODUCE."); break; case EVENT_SUSPEND: - EVENT_captainslog_debug(" SUSPEND."); + EVENT_DEBUG_LOG(" SUSPEND."); break; case EVENT_ABANDON: - EVENT_captainslog_debug(" ABANDON."); + EVENT_DEBUG_LOG(" ABANDON."); break; case EVENT_PRIMARY: - EVENT_captainslog_debug(" PRIMARY."); + EVENT_DEBUG_LOG(" PRIMARY."); break; case EVENT_SPECIAL_PLACE: - EVENT_captainslog_debug(" SPECIAL_PLACE."); + EVENT_DEBUG_LOG(" SPECIAL_PLACE."); break; case EVENT_EXIT: - EVENT_captainslog_debug(" EXIT."); + EVENT_DEBUG_LOG(" EXIT."); break; case EVENT_ANIMATION: - EVENT_captainslog_debug(" ANIMATION - Anim:%s, Coord: X:%d Y:%d.", + EVENT_DEBUG_LOG(" ANIMATION - Anim:%s, Coord: X:%d Y:%d.", AnimTypeClass::Name_From(m_EventData.u_Anim.m_Anim), Coord_Lepton_X(m_EventData.u_Anim.m_Coord), Coord_Lepton_Y(m_EventData.u_Anim.m_Coord)); break; case EVENT_REPAIR: - EVENT_captainslog_debug(" REPAIR."); + EVENT_DEBUG_LOG(" REPAIR."); break; case EVENT_SELL: - EVENT_captainslog_debug(" SELL."); + EVENT_DEBUG_LOG(" SELL."); break; case EVENT_SELL_CELL: - EVENT_captainslog_debug(" SELL_CELL."); + EVENT_DEBUG_LOG(" SELL_CELL."); break; case EVENT_SPECIAL: - EVENT_captainslog_debug(" SPECIAL."); + EVENT_DEBUG_LOG(" SPECIAL."); break; case EVENT_FRAME_SYNC: - EVENT_captainslog_debug(" FRAME_SYNC."); + EVENT_DEBUG_LOG(" FRAME_SYNC."); break; case EVENT_MESSAGE: - EVENT_captainslog_debug(" MESSAGE."); + EVENT_DEBUG_LOG(" MESSAGE."); break; case EVENT_RESPONSE_TIME: - EVENT_captainslog_debug(" RESPONSE_TIME."); + EVENT_DEBUG_LOG(" RESPONSE_TIME."); break; case EVENT_FRAME_INFO: - EVENT_captainslog_debug(" FRAME_INFO."); + EVENT_DEBUG_LOG(" FRAME_INFO."); break; case EVENT_SAVE_GAME: - EVENT_captainslog_debug(" SAVE_GAME."); + EVENT_DEBUG_LOG(" SAVE_GAME."); break; case EVENT_ARCHIVE: - EVENT_captainslog_debug(" ARCHIVE - Whom:%08X, Target:%08X.", m_EventData.u_WhomTarget.m_Whom, m_EventData.u_WhomTarget.m_Target); + EVENT_DEBUG_LOG(" ARCHIVE - Whom:%08X, Target:%08X.", m_EventData.u_WhomTarget.m_Whom, m_EventData.u_WhomTarget.m_Target); break; case EVENT_ADD_PLAYER: - EVENT_captainslog_debug(" ADD_PLAYER."); + EVENT_DEBUG_LOG(" ADD_PLAYER."); break; case EVENT_TIMING: - EVENT_captainslog_debug(" TIMING."); + EVENT_DEBUG_LOG(" TIMING."); break; case EVENT_PROCESS_TIME: - EVENT_captainslog_debug(" PROCESS_TIME."); + EVENT_DEBUG_LOG(" PROCESS_TIME."); break; case EVENT_PROPOSE_DRAW: - EVENT_captainslog_debug(" PROPOSE_DRAW."); + EVENT_DEBUG_LOG(" PROPOSE_DRAW."); break; case EVENT_RETRACT_DRAW: - EVENT_captainslog_debug(" RETRACT_DRAW."); + EVENT_DEBUG_LOG(" RETRACT_DRAW."); break; default: break; diff --git a/src/game/engine/gameevent.h b/src/game/engine/gameevent.h index 4727b83e..6a58e793 100644 --- a/src/game/engine/gameevent.h +++ b/src/game/engine/gameevent.h @@ -78,18 +78,18 @@ class GameEventClass // General constructors. GameEventClass(GameEventType type); // For events: (without special data) - DESTRUCT, SAVEGAME, RETRACT_DRAW, PROPOSE_DRAW, OPTIONS, EXIT GameEventClass(GameEventType type, cell_t cell); // For events: SELLCELL - GameEventClass(GameEventType type, unsigned int gamespeed); // For events: GAMESPEED + GameEventClass(GameEventType type, uint32_t gamespeed); // For events: GAMESPEED GameEventClass(GameEventType type, HousesType house); // For events: ALLY GameEventClass(GameEventType type, RTTIType rtti); // For events: SUSPEND, ABANDON - GameEventClass(GameEventType type, RTTIType rtti, unsigned int heap_id); // For events: PLACE, PRODUCE + GameEventClass(GameEventType type, RTTIType rtti, uint32_t heap_id); // For events: PLACE, PRODUCE GameEventClass(GameEventType type, RTTIType rtti, cell_t cell); // For events: GameEventClass(GameEventType type, SpecialWeaponType special, cell_t cell); // For events: SPECIAL_PLACE - GameEventClass(GameEventType type, void *a2, unsigned long a3); // For events: + GameEventClass(GameEventType type, void *a2, uint32_t a3); // For events: GameEventClass(GameEventType type, TargetClass whom); // For events: PRIMARY, SELL, IDLE, SCATTER, REPAIR GameEventClass(GameEventType type, TargetClass whom, TargetClass target); // For events: ARCHIVE GameEventClass(GameEventType type, AnimType anim, HousesType owner, coord_t coord); // For events: ANIMATION - GameEventClass(GameEventType type, unsigned int crc, unsigned short cmd_count, unsigned char delay); // For events: FRAME_SYNC - GameEventClass(GameEventType type, unsigned short desired_frame_rate, unsigned short max_ahead); // For events: TIMING + GameEventClass(GameEventType type, uint32_t crc, uint16_t cmd_count, uint8_t delay); // For events: FRAME_SYNC + GameEventClass(GameEventType type, uint16_t desired_frame_rate, uint16_t max_ahead); // For events: TIMING // TODO: Once GameEventClass is complete, and code for event below is under control, move // these above and use the constructors above that explicitly take the event type. @@ -104,10 +104,10 @@ class GameEventClass void Execute(); - int Get_Event_Frame() const { return m_EventFrame; } - void Set_Event_Frame(int frame) { m_EventFrame = frame; } - int Get_House_ID() const { return m_HouseID; } - void Set_House_ID(int id) { m_HouseID = id; } + int32_t Get_Event_Frame() const { return m_EventFrame; } + void Set_Event_Frame(int32_t frame) { m_EventFrame = frame; } + int32_t Get_House_ID() const { return m_HouseID; } + void Set_House_ID(int32_t id) { m_HouseID = id; } BOOL Is_Executed() const { return m_IsExecuted; } void Set_Executed(bool state) { m_IsExecuted = state; } @@ -152,7 +152,7 @@ class GameEventClass struct HouseEventStruct { - int /*HousesType*/ m_Whom; + int32_t /*HousesType*/ m_Whom; }; struct AnimEventStruct @@ -181,12 +181,12 @@ class GameEventClass struct RTTIHeapIDEventStruct { RTTIType m_RTTI; - int m_HeapID; + int32_t m_HeapID; }; struct SpecialPlaceEventStruct { - int /*SpecialWeaponType*/ m_Special; + int32_t /*SpecialWeaponType*/ m_SpecialWeapon; cell_t m_Cell; }; @@ -198,37 +198,37 @@ class GameEventClass struct FrameEventStruct { - unsigned int m_CRC; - unsigned short m_CommandCount; - unsigned char m_Delay; + uint32_t m_CRC; + uint16_t m_CommandCount; + uint8_t m_Delay; }; struct TimingEventStruct { - unsigned int m_DesiredFrameRate : 16; // 1 - unsigned int m_MaxAhead : 16; // 16 + uint32_t m_DesiredFrameRate : 16; // 1 + uint32_t m_MaxAhead : 16; // 16 }; struct TimeEventStruct { - unsigned char m_MaxAhead; + uint8_t m_MaxAhead; }; struct GameSpeedEventStruct { - unsigned int m_GameSpeed; + uint32_t m_GameSpeed; }; private: GameEventType m_Type; // The type for this object. #ifndef CHRONOSHIFT_NO_BITFIELDS - unsigned int m_EventFrame : 26; // - unsigned int m_HouseID : 5; // + uint32_t m_EventFrame : 26; // + uint32_t m_HouseID : 5; // BOOL m_IsExecuted : 1; // #else - unsigned int m_EventFrame; // The frame this event was created on. - unsigned int m_HouseID; // The id of the house that triggered this event. + uint32_t m_EventFrame; // The frame this event was created on. + uint32_t m_HouseID; // The id of the house that triggered this event. bool m_IsExecuted; // Has this event been executed? This use to make sure the event is // not executed twice and also used for cleaning up the queue. #endif @@ -257,7 +257,7 @@ class GameEventClass struct EventInfoStruct { char const *Name; - int RawSize; + int32_t RawSize; }; static EventInfoStruct s_EventTypeList[EVENT_COUNT]; diff --git a/src/game/engine/gameloop.cpp b/src/game/engine/gameloop.cpp index 59270385..db984b18 100644 --- a/src/game/engine/gameloop.cpp +++ b/src/game/engine/gameloop.cpp @@ -254,7 +254,7 @@ BOOL Main_Loop() g_FrameTimer = 60 / g_Session.Desired_Frame_Rate(); } } else { - int game_speed = g_Options.Game_Speed(); + int game_speed = g_Options.Get_Game_Speed(); DiffType ai_diff = g_PlayerPtr->Get_AI_Difficulty(); if (game_speed > 0) { g_FrameTimer = game_speed + ((ai_diff == DIFF_EASIEST) - (ai_diff == DIFF_NORMAL)); diff --git a/src/game/engine/house.h b/src/game/engine/house.h index 0e06bf82..4a335be5 100644 --- a/src/game/engine/house.h +++ b/src/game/engine/house.h @@ -215,6 +215,7 @@ class HouseClass RTTIType What_Am_I() const { return m_RTTI; } int Get_Heap_ID() const { return m_HeapID; } + PlayerColorType Get_Color() const { return m_Color; } HousesType What_Type() const { return m_Class->What_Type(); } const char *Get_Name() const { return m_Class->Get_Name(); } diff --git a/src/game/engine/layer.cpp b/src/game/engine/layer.cpp index 7bef45e1..5a3e315e 100644 --- a/src/game/engine/layer.cpp +++ b/src/game/engine/layer.cpp @@ -48,7 +48,7 @@ void LayerClass::Code_Pointers() ObjectClass *obj = (*this)[i]; captainslog_assert(obj != nullptr); - (*this)[i] = reinterpret_cast(As_Target(obj)); + (*this)[i] = reinterpret_cast(obj->As_Target()); } } diff --git a/src/game/engine/options.h b/src/game/engine/options.h index 1113a5a4..d312931e 100644 --- a/src/game/engine/options.h +++ b/src/game/engine/options.h @@ -71,8 +71,9 @@ class OptionsClass void Set_Contrast(fixed_t contrast); void Set_Tint(fixed_t tint); void Set(); + void Set_Game_Speed(int speed) { m_GameSpeed = speed; } - int Game_Speed() const { return m_GameSpeed; } + int Get_Game_Speed() const { return m_GameSpeed; } int Get_Scroll_Rate() const { return m_ScrollRate; } const fixed_t &Get_Sound_Volume() const { return m_Volume; } const fixed_t &Get_Score_Volume() const { return m_ScoreVolume; } diff --git a/src/game/engine/saveload.cpp b/src/game/engine/saveload.cpp index dbf79371..da3ae684 100644 --- a/src/game/engine/saveload.cpp +++ b/src/game/engine/saveload.cpp @@ -33,10 +33,10 @@ void Put_All(Pipe &pipe, int skip_callback) #endif } -int Save_Game(int number, char *savename, int unknown) +BOOL Save_Game(int number, const char *savename, BOOL unknown) { -#ifdef GAME_DLL - int (*func)(int, char *, int) = reinterpret_cast(0x005379FC); +#ifndef CHRONOSHIFT_STANDALONE + BOOL (*func)(int, const char *, BOOL) = reinterpret_cast(0x005379FC); return func(number, savename, unknown); #else return 0; @@ -52,11 +52,11 @@ void Post_Load_Game(int skip_overpass) g_Map.Zone_Reset(15); } -int Load_Game(int unknown) +BOOL Load_Game(int number) { -#ifdef GAME_DLL - int (*func)() = reinterpret_cast(0x00537D10); - return func(); +#ifndef CHRONOSHIFT_STANDALONE + BOOL (*func)(int) = reinterpret_cast(0x00537D10); + return func(number); #else return 0; #endif diff --git a/src/game/engine/saveload.h b/src/game/engine/saveload.h index 25bd674d..2eb55472 100644 --- a/src/game/engine/saveload.h +++ b/src/game/engine/saveload.h @@ -38,8 +38,8 @@ enum }; void Put_All(Pipe &pipe, int skip_callback); -int Save_Game(int number, char *savename, int unknown); -int Load_Game(int unknown); +BOOL Save_Game(int number, const char *savename, BOOL unknown); +BOOL Load_Game(int number); int Save_Misc_Values(Pipe &pipe); int Load_Misc_Values(Straw &straw); int Save_MPlayer_Values(Pipe &pipe); diff --git a/src/game/engine/scenario.h b/src/game/engine/scenario.h index 78099924..b8badbf8 100644 --- a/src/game/engine/scenario.h +++ b/src/game/engine/scenario.h @@ -100,7 +100,9 @@ class ScenarioClass void Set_Bridge_Count(int count) { m_BridgeCount = count; } BOOL Get_Global(int index) const { return m_GlobalVariables[index]; } BOOL Get_field_7CF() const { return m_field_7CF; } + void Set_field_7CF(int state) { m_field_7CF = state; } BOOL Get_field_7D3() const { return m_field_7D3; } + void Set_field_7D3(int state) { m_field_7D3 = state; } BOOL Evacuate_Civilians() const { return m_CivEvac; } #ifdef GAME_DLL diff --git a/src/game/engine/session.h b/src/game/engine/session.h index d7c0d939..32463c4b 100644 --- a/src/game/engine/session.h +++ b/src/game/engine/session.h @@ -99,6 +99,7 @@ struct NodeNameTag HousesType m_House; PlayerColorType m_Color; HousesType m_AltHouse; + int field_19; //set in PROCESS_TIME event }; class SessionClass @@ -112,6 +113,8 @@ class SessionClass GameEnum Game_To_Play() const { return m_GameToPlay; } void Set_Game_To_Play(GameEnum game) { m_GameToPlay = game; } + void Set_MaxAhead(int maxahead) { m_MaxAhead = maxahead; } + int Get_MaxAhead() { return m_MaxAhead; } CommProtocolEnum Packet_Protocol() const { return m_PacketProtocol; } int Frame_Send_Rate() { return m_FrameSendRate; } @@ -169,6 +172,8 @@ class SessionClass DynamicVectorClass &Games_List() { return m_Games; } DynamicVectorClass &Players_List() { return m_Players; } DynamicVectorClass &Network_Players_List() { return m_NetworkPlayers; } + int Player_Count() const { return m_Players.Count(); } + NodeNameTag *Player(int num) { return m_Players[num]; } BOOL Modem_Service() const { return m_ModemService; } diff --git a/src/game/engine/special.h b/src/game/engine/special.h index 1e53bb58..aef2c293 100644 --- a/src/game/engine/special.h +++ b/src/game/engine/special.h @@ -46,6 +46,7 @@ class SpecialClass BOOL Always_Show_Health() { return m_ShowHealth; } uint32_t Pack() const { return m_SpecialFlags; } + void Set(uint32_t special) { m_SpecialFlags = special; } private: union diff --git a/src/game/engine/target.cpp b/src/game/engine/target.cpp index cc97ba3e..3b45dcae 100644 --- a/src/game/engine/target.cpp +++ b/src/game/engine/target.cpp @@ -3,6 +3,7 @@ * * @author OmniBlade * @author CCHyper + * @author tomsons26 * * @brief Functions for converting to and from target values. * @@ -14,43 +15,27 @@ * LICENSE */ #include "target.h" +#include "aircraft.h" +#include "anim.h" +#include "building.h" +#include "bullet.h" #include "cell.h" #include "coord.h" +#include "infantry.h" +#include "iomap.h" #include "object.h" +#include "overlay.h" +#include "smudge.h" #include "techno.h" #include "technotype.h" -//#include "triggertype.h" - -CellClass *TargetClass::As_Cell() const -{ - return nullptr; - //return ::As_Cell(m_Target); -} - -AbstractClass *TargetClass::As_Abstract() const -{ - return ::As_Abstract(m_Target); -} - -AbstractTypeClass *TargetClass::As_TypeClass() const -{ - return nullptr; - //return ::As_TypeClass(m_Target); -} - -TechnoClass *TargetClass::As_Techno() const -{ - return ::As_Techno(m_Target); -} - -ObjectClass *TargetClass::As_Object() const -{ - return ::As_Object(m_Target); -} +#include "terrain.h" +#include "triggertype.h" +#include "unit.h" +#include "vessel.h" TargetClass::TargetClass(AbstractClass *abstract) { - if (abstract != nullptr){ + if (abstract != nullptr) { m_Target = (abstract->What_Am_I() << 24) | (abstract->Get_Heap_ID() & 0xFFFFFF); } else { m_RTTI = RTTI_NONE; @@ -59,7 +44,7 @@ TargetClass::TargetClass(AbstractClass *abstract) TargetClass::TargetClass(AbstractTypeClass *abstractype) { - if (abstractype != nullptr){ + if (abstractype != nullptr) { m_Target = (abstractype->What_Am_I() << 24) | (abstractype->Get_Heap_ID() & 0xFFFFFF); } else { m_RTTI = RTTI_NONE; @@ -68,26 +53,27 @@ TargetClass::TargetClass(AbstractTypeClass *abstractype) TargetClass::TargetClass(CellClass *cell) { - if (cell != nullptr){ + if (cell != nullptr) { m_Target = (RTTI_CELL << 24) | (cell->Cell_Number() & 0xFFFFFF); } else { m_RTTI = RTTI_NONE; } } -TargetClass::TargetClass(cell_t cellnum) +CellClass *TargetClass::As_Cell() const { - m_Target = (RTTI_CELL << 24) | (cellnum & 0xFFFFFF); -} + if (Get_RTTI() == RTTI_CELL) { + return &g_Map[Get_ID()]; + } -BOOL Target_Is_Techno(target_t target) -{ - TechnoClass *ptr = As_Techno(target); - return ptr != nullptr ? ptr->Is_Techno() : false; + return nullptr; } BOOL Target_Legal(target_t target) { + // NOTE: Possible future improvement that could be a bug fix. + // return (Target_Get_RTTI(target) != RTTI_NONE && Target_Get_RTTI(target) < RTTI_COUNT && Target_Get_ID(target) >= 0) && + // As_Object(target)->Is_Active(); return (Target_Get_RTTI(target) != RTTI_NONE && Target_Get_RTTI(target) < RTTI_COUNT && Target_Get_ID(target) >= 0); } @@ -98,248 +84,151 @@ target_t As_Target(cell_t cellnum) target_t As_Target(coord_t coord) { - return Make_Target(RTTI_CELL, (Coord_Lepton_X(coord) >> 4) | ((Coord_Lepton_Y(coord) >> 4) << 12)); -} - -target_t As_Target(CellClass *cell) -{ - return cell != nullptr ? As_Target(cell->Cell_Number()) : 0; -} - -target_t As_Target(AbstractClass *object) -{ - return object != nullptr ? ((object->Get_Heap_ID() & 0xFFFFFF) | ((object->What_Am_I() << 24) & 0xFF000000)) : 0; + return Make_Target(RTTI_CELL, (Coord_Lepton_X(coord) / 16) | ((Coord_Lepton_Y(coord) / 16) << 12)); } TriggerClass *As_Trigger(target_t target) { -#ifdef GAME_DLL - TriggerClass *(*func)(target_t) = reinterpret_cast(0x00554FFC); - return func(target); -#elif 0 - // TODO: Requires TriggerClass implementation. - return Target_Get_RTTI(target) == RTTI_TRIGGER ? &Triggers[Target_Get_ID(target)] : nullptr; -#else - return nullptr; -#endif + return Target_Is_Trigger(target) ? &g_Triggers[Target_Get_ID(target)] : nullptr; } TriggerTypeClass *As_TriggerType(target_t target) { -#ifdef GAME_DLL - TriggerTypeClass *(*func)(target_t) = reinterpret_cast(0x005559CC); - return func(target); -#elif 0 - // TODO: Requires TriggerTypeClass implementation. - return Target_Get_RTTI(target) == RTTI_TRIGGERTYPE ? &TriggerTypes[Target_Get_ID(target)] : nullptr; -#else - return nullptr; -#endif + return Target_Is_TriggerType(target) ? &g_TriggerTypes[Target_Get_ID(target)] : nullptr; } TeamClass *As_Team(target_t target) { -#ifdef GAME_DLL - TeamClass *(*func)(target_t) = reinterpret_cast(0x00555034); - return func(target); -#elif 0 - // TODO: Requires TeamClass implementation. - return Target_Get_RTTI(target) == RTTI_TEAM ? &Teams[Target_Get_ID(target)] : nullptr; -#else - return nullptr; -#endif + return Target_Is_Team(target) ? &g_Teams[Target_Get_ID(target)] : nullptr; } TeamTypeClass *As_TeamType(target_t target) { -#ifdef GAME_DLL - TeamTypeClass *(*func)(target_t) = reinterpret_cast(0x0055506C); - return func(target); -#elif 0 - // TODO: Requires TeamTypeClass implementation. - return Target_Get_RTTI(target) == RTTI_TEAMTYPE ? &TeamTypes[Target_Get_ID(target)] : nullptr; -#else - return nullptr; -#endif -} - -AbstractClass *As_Abstract(target_t target) -{ - return (AbstractClass *)As_Object(target); + return Target_Is_TeamType(target) ? &g_TeamTypes[Target_Get_ID(target)] : nullptr; } ObjectClass *As_Object(target_t target) { -#ifdef GAME_DLL - ObjectClass *(*func)(target_t) = reinterpret_cast(0x00555190); - return func(target); -#elif 0 + int id = Target_Get_ID(target); ObjectClass *objptr = nullptr; + // NOTE: Possible future improvement that could be a bug fix. + // This returns only targetable Objects, in contrast + // xTargetClass::As_Object also returns Smudge and Overlay switch (Target_Get_RTTI(target)) { case RTTI_AIRCRAFT: - objptr = As_Aircraft(target); + objptr = &g_Aircraft[id]; break; case RTTI_ANIM: - objptr = As_Animation(target); + objptr = &g_Anims[id]; break; case RTTI_BUILDING: - objptr = As_Building(target); + objptr = &g_Buildings[id]; break; case RTTI_BULLET: - objptr = As_Bullet(target); + objptr = &g_Bullets[id]; break; case RTTI_INFANTRY: - objptr = As_Infantry(target); + objptr = &g_Infantry[id]; break; case RTTI_TERRAIN: - objptr = As_Terrain(target); + objptr = &g_Terrains[id]; break; case RTTI_UNIT: - objptr = As_Unit(target); + objptr = &g_Units[id]; break; case RTTI_VESSEL: - objptr = As_Vessel(target); + objptr = &g_Vessels[id]; break; default: break; - }; - - // captainslog_assert(objptr != nullptr); + } - if (objptr != nullptr && objptr->m_IsActive) { + if (objptr != nullptr && objptr->Is_Active()) { return objptr; } return nullptr; -#else - return nullptr; -#endif } AnimClass *As_Animation(target_t target) { -#ifdef GAME_DLL - AnimClass *(*func)(target_t) = reinterpret_cast(0x005550A4); - return func(target); -#elif 0 - // TODO: Requires AnimClass implementation. - return Target_Get_RTTI(target) == RTTI_ANIM ? &Anims[Target_Get_ID(target)] : nullptr; -#else - return nullptr; -#endif + return Target_Is_Anim(target) ? &g_Anims[Target_Get_ID(target)] : nullptr; } BulletClass *As_Bullet(target_t target) { -#ifdef GAME_DLL - BulletClass *(*func)(target_t) = reinterpret_cast(0x005550DC); - return func(target); -#elif 0 - // TODO: Requires BulletClass implementation. - return Target_Get_RTTI(target) == RTTI_BULLET ? &Bullets[Target_Get_ID(target)] : nullptr; -#else - return nullptr; -#endif + return Target_Is_Bullet(target) ? &g_Bullets[Target_Get_ID(target)] : nullptr; } TerrainClass *As_Terrain(target_t target) { -#ifdef GAME_DLL - // TODO: Inlined in RA - return nullptr; -#elif 0 - // TODO: Requires TerrainClass implementation. - return Target_Get_RTTI(target) == RTTI_TERRAIN ? &Terrains[Target_Get_ID(target)] : nullptr; -#else - return nullptr; -#endif + return Target_Is_Terrain(target) ? &g_Terrains[Target_Get_ID(target)] : nullptr; } TechnoClass *As_Techno(target_t target) { -#ifdef GAME_DLL - TechnoClass *(*func)(target_t) = reinterpret_cast(0x0055514C); - return func(target); -#else - ObjectClass *objptr = As_Object(target); - captainslog_assert(objptr != nullptr); - return objptr != nullptr && objptr->Is_Techno() ? (TechnoClass *)objptr : nullptr; -#endif + ObjectClass *optr = As_Object(target); + + if (optr != nullptr && optr->Is_Techno()) { + return reinterpret_cast(optr); + } + + return nullptr; } TechnoTypeClass *As_TechnoType(target_t target) { -#ifdef GAME_DLL - TechnoTypeClass *(*func)(target_t) = reinterpret_cast(0x00555964); - return func(target); -#else - // TODO: Requires all derivant TechnoTypeClass's to be implemented. + int id = Target_Get_ID(target); + + switch (Target_Get_RTTI(target)) { + case RTTI_INFANTRYTYPE: + return InfantryTypeClass::As_Pointer(InfantryType(id)); + case RTTI_UNITTYPE: + return UnitTypeClass::As_Pointer(UnitType(id)); + case RTTI_VESSELTYPE: + return VesselTypeClass::As_Pointer(VesselType(id)); + case RTTI_AIRCRAFTTYPE: + return AircraftTypeClass::As_Pointer(AircraftType(id)); + case RTTI_BUILDINGTYPE: + return BuildingTypeClass::As_Pointer(BuildingType(id)); + default: + break; + } return nullptr; -#endif } AircraftClass *As_Aircraft(target_t target) { -#ifdef GAME_DLL - AircraftClass *(*func)(target_t) = reinterpret_cast(0x00555114); - return func(target); -#else - // TODO: Requires AircraftClass implementation. - return 0; -#endif + return Target_Is_Aircraft(target) ? &g_Aircraft[Target_Get_ID(target)] : nullptr; } UnitClass *As_Unit(target_t target) { -#ifdef GAME_DLL - UnitClass *(*func)(target_t) = reinterpret_cast(0x00555290); - return func(target); -#else - // TODO: Requires UnitClass implementation. - return 0; -#endif + return Target_Is_Unit(target) ? &g_Units[Target_Get_ID(target)] : nullptr; } VesselClass *As_Vessel(target_t target) { -#ifdef GAME_DLL - VesselClass *(*func)(target_t) = reinterpret_cast(0x005552C8); - return func(target); -#else - // TODO: Requires VesselClass implementation. - return nullptr; -#endif + return Target_Is_Vessel(target) ? &g_Vessels[Target_Get_ID(target)] : nullptr; } InfantryClass *As_Infantry(target_t target) { -#ifdef GAME_DLL - InfantryClass *(*func)(target_t) = reinterpret_cast(0x00555300); - return func(target); -#else - // TODO: Requires InfantryClass implementation. - return nullptr; -#endif + return Target_Is_Infantry(target) ? &g_Infantry[Target_Get_ID(target)] : nullptr; } BuildingClass *As_Building(target_t target) { -#ifdef GAME_DLL - BuildingClass *(*func)(target_t) = reinterpret_cast(0x00555338); - return func(target); -#else - // TODO: Requires BuildingClass implementation. - return nullptr; -#endif + return Target_Is_Building(target) ? &g_Buildings[Target_Get_ID(target)] : nullptr; } cell_t As_Cell(target_t target) @@ -349,36 +238,217 @@ cell_t As_Cell(target_t target) coord_t As_Coord(target_t target) { -#ifdef GAME_DLL - coord_t (*func)(target_t) = reinterpret_cast(0x00555384); - return func(target); -#else if (!Target_Legal(target)) { return 0; -} - if (!Target_Is_Cell(target)) { - ObjectClass *objptr = As_Object(target); - return (objptr != nullptr ? objptr->Target_Coord() : 0); } - lepton_t lx = 16 * (Target_Get_ID(target) & 0xFFF) + 8; - lepton_t ly = 16 * ((Target_Get_ID(target) >> 12) & 0xFFF) + 8; - return Coord_From_Lepton_XY(lx, ly); -#endif + + if (Target_Is_Cell(target)) { + int id = Target_Get_ID(target); + lepton_t lx = 16 * (id & 0xFFF) + 8; + lepton_t ly = 16 * ((id >> 12) & 0xFFF) + 8; + return Coord_From_Lepton_XY(lx, ly); + } + + ObjectClass *objptr = As_Object(target); + + if (objptr != nullptr) { + captainslog_assert(objptr->Is_Active()); + return objptr->Target_Coord(); + } + return 0; } coord_t As_Movement_Coord(target_t target) { -#ifdef GAME_DLL - coord_t(*func)(target_t) = reinterpret_cast(0x005553F8); - return func(target); -#else if (!Target_Legal(target)) { return 0; } - if (!Target_Is_Cell(target)) { - ObjectClass *objptr = As_Object(target); - return (objptr != nullptr ? objptr->Docking_Coord() : 0); + + if (Target_Is_Cell(target)) { + int id = Target_Get_ID(target); + return Cell_To_Coord(id); + } + + ObjectClass *objptr = As_Object(target); + + if (objptr != nullptr) { + captainslog_assert(objptr->Is_Active()); + return objptr->Docking_Coord(); + } + return 0; +} + +CellClass *xTargetClass::As_Cell() const +{ + if (Get_RTTI() == RTTI_CELL) { + return &g_Map[Get_ID()]; + } + + return nullptr; +} + +AbstractClass *xTargetClass::As_Abstract() const +{ + const int id = Get_ID(); + + switch (Get_RTTI()) { + case RTTI_TEAM: + return &g_Teams[id]; + case RTTI_BULLET: + return &g_Bullets[id]; + case RTTI_OVERLAY: + return &g_Overlays[id]; + case RTTI_SMUDGE: + return &g_Smudges[id]; + case RTTI_UNIT: + return &g_Units[id]; + case RTTI_VESSEL: + return &g_Vessels[id]; + case RTTI_BUILDING: + return &g_Buildings[id]; + case RTTI_INFANTRY: + return &g_Infantry[id]; + case RTTI_AIRCRAFT: + return &g_Aircraft[id]; + case RTTI_TERRAIN: + return &g_Terrains[id]; + case RTTI_ANIM: + return &g_Anims[id]; + default: + break; + } + return nullptr; +} + +AbstractTypeClass *xTargetClass::As_TypeClass() const +{ + const int id = Get_ID(); + + switch (Get_RTTI()) { + // TODO: look into this, i don't think the RTTI checks not checking TYPE are correct... + case RTTI_TEAMTYPE: + return TeamTypeClass::As_Pointer(TeamType(id)); + case RTTI_TRIGGERTYPE: + return TriggerTypeClass::As_Pointer(TriggerType(id)); + case RTTI_BULLETTYPE: + return BulletTypeClass::As_Pointer(BulletType(id)); + case RTTI_OVERLAY: + return OverlayTypeClass::As_Pointer(OverlayType(id)); + case RTTI_SMUDGE: + return SmudgeTypeClass::As_Pointer(SmudgeType(id)); + case RTTI_UNIT: + return UnitTypeClass::As_Pointer(UnitType(id)); + case RTTI_VESSEL: + return VesselTypeClass::As_Pointer(VesselType(id)); + case RTTI_BUILDING: + return BuildingTypeClass::As_Pointer(BuildingType(id)); + case RTTI_INFANTRY: + return InfantryTypeClass::As_Pointer(InfantryType(id)); + case RTTI_AIRCRAFT: + return AircraftTypeClass::As_Pointer(AircraftType(id)); + case RTTI_TERRAIN: + return TerrainTypeClass::As_Pointer(TerrainType(id)); + case RTTI_ANIM: + return AnimTypeClass::As_Pointer(AnimType(id)); + default: + break; + } + return nullptr; +} + +TechnoClass *xTargetClass::As_Techno() const +{ + const int id = Get_ID(); + + switch (Get_RTTI()) { + case RTTI_UNIT: + return &g_Units[id]; + case RTTI_VESSEL: + return &g_Vessels[id]; + case RTTI_BUILDING: + return &g_Buildings[id]; + case RTTI_INFANTRY: + return &g_Infantry[id]; + case RTTI_AIRCRAFT: + return &g_Aircraft[id]; + default: + break; + } + return nullptr; +} + +ObjectClass *xTargetClass::As_Object() const +{ + const int id = Get_ID(); + + switch (Get_RTTI()) { + case RTTI_TERRAIN: + return &g_Terrains[id]; + case RTTI_SMUDGE: + return &g_Smudges[id]; + case RTTI_OVERLAY: + return &g_Overlays[id]; + case RTTI_BULLET: + return &g_Bullets[id]; + case RTTI_ANIM: + return &g_Anims[id]; + case RTTI_UNIT: + return &g_Units[id]; + case RTTI_VESSEL: + return &g_Vessels[id]; + case RTTI_BUILDING: + return &g_Buildings[id]; + case RTTI_INFANTRY: + return &g_Infantry[id]; + case RTTI_AIRCRAFT: + return &g_Aircraft[id]; + default: + break; + } + return nullptr; +} + +AircraftClass *xTargetClass::As_Aircraft() const +{ + if (Get_RTTI() == RTTI_AIRCRAFT) { + return reinterpret_cast(As_Techno()); + } + + return nullptr; +} + +UnitClass *xTargetClass::As_Unit() const +{ + if (Get_RTTI() == RTTI_UNIT) { + return reinterpret_cast(As_Techno()); + } + + return nullptr; +} + +VesselClass *xTargetClass::As_Vessel() const +{ + if (Get_RTTI() == RTTI_VESSEL) { + return reinterpret_cast(As_Techno()); } - return Cell_To_Coord(Target_Get_ID(target)); -#endif + + return nullptr; +} + +InfantryClass *xTargetClass::As_Infantry() const +{ + if (Get_RTTI() == RTTI_UNIT) { + return reinterpret_cast(As_Techno()); + } + + return nullptr; +} + +BuildingClass *xTargetClass::As_Building() const +{ + if (Get_RTTI() == RTTI_BUILDING) { + return reinterpret_cast(As_Techno()); + } + + return nullptr; } diff --git a/src/game/engine/target.h b/src/game/engine/target.h index 790d97b1..770b5e91 100644 --- a/src/game/engine/target.h +++ b/src/game/engine/target.h @@ -3,6 +3,7 @@ * * @author OmniBlade * @author CCHyper + * @author tomsons26 * * @brief Functions for converting to and from target values. * @@ -48,24 +49,26 @@ class TargetClass TargetClass(AbstractClass *abstract); TargetClass(AbstractTypeClass *abstractype); TargetClass(CellClass *cell); - TargetClass(cell_t cellnum); TargetClass(const TargetClass &that) : m_Target(that.m_Target) {} ~TargetClass() {} - operator target_t() { return m_Target; } + operator target_t() const { return m_Target; } + + RTTIType Get_RTTI() const { return RTTIType(m_RTTI); } + + int Get_ID() const { return m_ID; } CellClass *As_Cell() const; - AbstractClass *As_Abstract() const; - AbstractTypeClass *As_TypeClass() const; - TechnoClass *As_Techno() const; - ObjectClass *As_Object() const; private: - union { - struct { + union + { + struct + { unsigned int m_ID : 24; unsigned int m_RTTI : 8; - }; target_t m_Target; + }; + target_t m_Target; }; }; @@ -119,20 +122,51 @@ inline BOOL Target_Is_Cell(target_t target) return Target_Get_RTTI(target) == RTTI_CELL; } -BOOL Target_Is_Techno(target_t target); +inline BOOL Target_Is_TeamType(target_t target) +{ + return Target_Get_RTTI(target) == RTTI_TEAMTYPE; +} -BOOL Target_Legal(target_t target); +inline BOOL Target_Is_TriggerType(target_t target) +{ + return Target_Get_RTTI(target) == RTTI_TRIGGERTYPE; +} +inline BOOL Target_Is_Anim(target_t target) +{ + return Target_Get_RTTI(target) == RTTI_ANIM; +} + +inline BOOL Target_Is_Bullet(target_t target) +{ + return Target_Get_RTTI(target) == RTTI_BULLET; +} + +inline BOOL Target_Is_Team(target_t target) +{ + return Target_Get_RTTI(target) == RTTI_TEAM; +} + +inline BOOL Target_Is_Trigger(target_t target) +{ + return Target_Get_RTTI(target) == RTTI_TRIGGER; +} + +inline BOOL Target_Is_Targetable(target_t target) +{ + RTTIType rtti = Target_Get_RTTI(target); + return rtti == RTTI_TERRAIN || rtti == RTTI_UNIT || rtti == RTTI_VESSEL || rtti == RTTI_INFANTRY || rtti == RTTI_BUILDING + || rtti == RTTI_AIRCRAFT; +} + +BOOL Target_Legal(target_t target); target_t As_Target(cell_t cellnum); target_t As_Target(coord_t coord); -target_t As_Target(CellClass *cell); -target_t As_Target(AbstractClass *object); TriggerClass *As_Trigger(target_t target); TriggerTypeClass *As_TriggerType(target_t target); TeamClass *As_Team(target_t target); TeamTypeClass *As_TeamType(target_t target); -AbstractClass *As_Abstract(target_t target); ObjectClass *As_Object(target_t target); AnimClass *As_Animation(target_t target); BulletClass *As_Bullet(target_t target); @@ -149,4 +183,33 @@ cell_t As_Cell(target_t target); coord_t As_Coord(target_t target); coord_t As_Movement_Coord(target_t target); +// This class is for use with EventClass, as unions can't have constructors. +class xTargetClass +{ +public: + CellClass *As_Cell() const; + AbstractClass *As_Abstract() const; + AbstractTypeClass *As_TypeClass() const; + TechnoClass *As_Techno() const; + ObjectClass *As_Object() const; + AircraftClass *As_Aircraft() const; + UnitClass *As_Unit() const; + VesselClass *As_Vessel() const; + InfantryClass *As_Infantry() const; + BuildingClass *As_Building() const; + + void operator=(const TargetClass &target) { m_Target = target; } + + bool Valid_RTTI() const { return Target_Get_RTTI(m_Target) != RTTI_NONE; } + + RTTIType Get_RTTI() const { return Target_Get_RTTI(m_Target); } + + int Get_ID() const { return Target_Get_ID(m_Target); } + + operator target_t() const { return m_Target; } + +private: + target_t m_Target; +}; + #endif // TARGET_H diff --git a/src/game/engine/teamtype.cpp b/src/game/engine/teamtype.cpp index e091ab29..fccc1baa 100644 --- a/src/game/engine/teamtype.cpp +++ b/src/game/engine/teamtype.cpp @@ -437,6 +437,33 @@ TeamTypeClass *TeamTypeClass::As_Pointer(const char *name) return From_Name(name); } +/** + * Get a TriggerTypeClass pointer from its heap ID. + */ +TeamTypeClass *TeamTypeClass::As_Pointer(TeamType type) +{ + return type != TEAMTYPE_NONE && type < g_TeamTypes.Count() ? &g_TeamTypes[type] : nullptr; +} + +/** + * Get a TeamTypeClass reference from its heap ID. + */ +TeamTypeClass &TeamTypeClass::As_Reference(TeamType type) +{ + captainslog_assert(type != INFANTRY_NONE); + captainslog_assert(type < INFANTRY_COUNT); + + return g_TeamTypes[type]; +} + +/** + * Get a reference to a team type from its name. + */ +TeamTypeClass &TeamTypeClass::As_Reference(const char *name) +{ + return *From_Name(name); +} + /** * Get a pointer to a team type from its name. */ diff --git a/src/game/engine/teamtype.h b/src/game/engine/teamtype.h index dd72a3d5..bc676541 100644 --- a/src/game/engine/teamtype.h +++ b/src/game/engine/teamtype.h @@ -32,6 +32,13 @@ class ObjectTypeClass; class TriggerTypeClass; class GameINIClass; +// This enum is just for casting the TeamType heap indexes. +enum TeamType +{ + TEAMTYPE_NONE = -1, + TEAMTYPE_FORCESIZE = 0x80000000 +}; + enum TeamMissionType { TMISSION_ATTACK, // "Attack..." @@ -121,6 +128,9 @@ class TeamTypeClass : public AbstractTypeClass static TeamMissionType Mission_From_Name(const char *name); static const char *Name_From_Mission(TeamMissionType tmission); static TeamTypeClass *As_Pointer(const char *name); + static TeamTypeClass *As_Pointer(TeamType type); + static TeamTypeClass &As_Reference(TeamType type); + static TeamTypeClass &As_Reference(const char *name); static TeamTypeClass *From_Name(const char *name); static TeamTypeClass *Suggested_New_Team(HouseClass *house, int32_t avail_air, int32_t avail_unit, int32_t avail_inf, int32_t avail_vessel, BOOL allow_autocreate); diff --git a/src/game/engine/techno.h b/src/game/engine/techno.h index f1d04f25..836e1c14 100644 --- a/src/game/engine/techno.h +++ b/src/game/engine/techno.h @@ -176,6 +176,7 @@ class TechnoClass : public RadioClass int Get_Price() const { return m_Price; } void Set_Price(int price) { m_Price = price; } void Set_Archive(target_t archive) { m_Archive = archive; } + void Set_Suspended_TarCom(target_t target) { m_SuspendedTarCom = target; } target_t Get_TarCom() const { return m_TarCom; } BOOL Can_Teleport_Here(cell_t cell) const; diff --git a/src/game/engine/triggertype.h b/src/game/engine/triggertype.h index 1656b069..97a674fc 100644 --- a/src/game/engine/triggertype.h +++ b/src/game/engine/triggertype.h @@ -33,6 +33,7 @@ class TriggerClass; enum TriggerType { TRIGGER_NONE = -1, + TRIGGER_FORCESIZE = 0x80000000 }; DEFINE_ENUMERATION_OPERATORS(TriggerType); diff --git a/src/game/engine/vessel.h b/src/game/engine/vessel.h index f5cd8841..8518558d 100644 --- a/src/game/engine/vessel.h +++ b/src/game/engine/vessel.h @@ -89,6 +89,9 @@ class VesselClass : public DriveClass VesselType What_Type() const { return m_Class->What_Type(); } + void Set_Self_Repair(BOOL state) { m_ToSelfRepair = state; } + void Set_Repairing(BOOL state) { m_Repairing = state; } + static void Init(); #ifdef GAME_DLL diff --git a/src/hooker/setuphooks.cpp b/src/hooker/setuphooks.cpp index 0347fe7a..bdf9ebdd 100644 --- a/src/hooker/setuphooks.cpp +++ b/src/hooker/setuphooks.cpp @@ -833,6 +833,8 @@ void Setup_Hooks() Hook_Function(0x004C2BFC, *FootClass::Receive_Message); Hook_Function(0x004C14C8, *FootClass::Start_Driver); Hook_Function(0x004C3174, *FootClass::Greatest_Threat); + Hook_Function(0x004C35D0, *FootClass::Queue_Navigation_List); + Hook_Function(0x004C3684, *FootClass::Clear_Navigation_List); // abstract.h Hook_Function(0x004CD8E0, *AbstractClass::Hook_Ctor_NoInit);