From 6e894abf33a34228c9773d251657edf3458d35a0 Mon Sep 17 00:00:00 2001 From: asasas9500 Date: Tue, 7 Jan 2020 17:33:13 -0300 Subject: [PATCH] Add control functions; Remove duplicated CheckNoColFloorTriangle() --- TR5Main/Game/control.cpp | 529 +++++++++++++++++++++++++++++++--- TR5Main/Game/control.h | 16 +- TR5Main/Game/switch.h | 1 + TR5Main/Game/tomb4fx.h | 6 + TR5Main/Global/vars.h | 4 + TR5Main/Specific/roomload.cpp | 1 + TR5Main/Specific/roomload.h | 4 +- 7 files changed, 515 insertions(+), 46 deletions(-) diff --git a/TR5Main/Game/control.cpp b/TR5Main/Game/control.cpp index fe5aa7c68..5a1bd3e10 100644 --- a/TR5Main/Game/control.cpp +++ b/TR5Main/Game/control.cpp @@ -28,6 +28,8 @@ #include "traps.h" #include "effects.h" #include "sphere.h" +#include "debris.h" +#include "larafire.h" #include "..\Specific\roomload.h" #include "..\Specific\input.h" @@ -41,6 +43,11 @@ int KeyTriggerActive; PENDULUM CurrentPendulum; int number_los_rooms; short los_rooms[20]; +int ClosestItem; +int ClosestDist; +PHD_VECTOR ClosestCoord; +int rand_1 = -747505337; +int rand_2 = -747505337; extern GameFlow* g_GameFlow; extern GameScript* g_GameScript; @@ -1202,45 +1209,6 @@ void TranslateItem(ITEM_INFO* item, int x, int y, int z) item->pos.zPos += (-s * x + c * z) >> W2V_SHIFT; } -int CheckNoColFloorTriangle(FLOOR_INFO* floor, short x, short z) -{ - if (!floor->index) - return 0; - - short func = FloorData[floor->index] & 0x1F; - if (func != NOCOLF1T && func != NOCOLF1B && func != NOCOLF2T && func != NOCOLF2B) - return 0; - - int dx = x & 0x3FF; - int dz = z & 0x3FF; - - switch (func) - { - case NOCOLF1T: - if (dx <= 1024 - dz) - return -1; - break; - - case NOCOLF1B: - if (dx > 1024 - dz) - return -1; - break; - - case NOCOLF2T: - if (dx <= dz) - return -1; - break; - - case NOCOLF2B: - if (dx > dz) - return -1; - break; - - } - - return 1; -} - int GetWaterSurface(int x, int y, int z, short roomNumber) { ROOM_INFO* room = &Rooms[roomNumber]; @@ -2481,10 +2449,493 @@ int ClipTarget(GAME_VECTOR* start, GAME_VECTOR* target) return 1; } +int GetTargetOnLOS(GAME_VECTOR* src, GAME_VECTOR* dest, int DrawTarget, int firing) +{ + GAME_VECTOR target; + int result, flag, itemNumber, count; + MESH_INFO* mesh; + PHD_VECTOR vector; + ITEM_INFO* item; + short angle, room, triggerItems[8]; + + target.x = dest->x; + target.y = dest->y; + target.z = dest->z; + result = LOS(src, &target); + GetFloor(target.x, target.y, target.z, &target.roomNumber); + if (firing && LaserSight) + { + Lara.hasFired = true; + Lara.fired = true; + if (Lara.gunType == WEAPON_REVOLVER) + { + SoundEffect(SFX_REVOLVER, NULL, 0); + } + } + flag = 0; + itemNumber = ObjectOnLOS2(src, dest, &vector, &mesh); + if (itemNumber != 999) + { + target.x = vector.x - (vector.x - src->x >> 5); + target.y = vector.y - (vector.y - src->y >> 5); + target.z = vector.z - (vector.z - src->z >> 5); + GetFloor(target.x, target.y, target.z, &target.roomNumber); + if (itemNumber >= 0) + Lara.target = &Items[itemNumber]; + if (firing) + { + if (Lara.gunType != WEAPON_CROSSBOW) + { + if (itemNumber < 0) + { + if (mesh->staticNumber >= 50 && mesh->staticNumber < 58) + { + ShatterObject(NULL, mesh, 128, target.roomNumber, 0); + SmashedMeshRoom[SmashedMeshCount] = target.roomNumber; + SmashedMesh[SmashedMeshCount] = mesh; + ++SmashedMeshCount; + mesh->Flags &= ~0x1; + SoundEffect(ShatterSounds[CurrentLevel - 5][mesh->staticNumber], (PHD_3DPOS *) mesh, 0); + } + TriggerRicochetSpark(&target, LaraItem->pos.yRot, 3, 0); + TriggerRicochetSpark(&target, LaraItem->pos.yRot, 3, 0); + } + else + { + item = &Items[itemNumber]; + if (item->objectNumber != ID_SHOOT_SWITCH1 && item->objectNumber != ID_SHOOT_SWITCH2) + { + if (Objects[item->objectNumber].explodableMeshbits & TargetMesh && LaserSight) + { + if (!Objects[item->objectNumber].intelligent) + { + ShatterObject(&ShatterItem, 0, 128, target.roomNumber, 0); + item->meshBits &= ~TargetMesh; + TriggerRicochetSpark(&target, LaraItem->pos.yRot, 3, 0); + } + else + { + if (item->objectNumber != ID_TWOGUN) + { + item->hitPoints -= 30; + if (item->hitPoints < 0) + item->hitPoints = 0; + HitTarget(item, &target, WeaponsArray[Lara.gunType].damage, 0); + } + else + { + angle = ATAN(LaraItem->pos.zPos - item->pos.zPos, LaraItem->pos.xPos - item->pos.xPos) - item->pos.yRot; + if (angle > -ANGLE(90) && angle < ANGLE(90)) + { + item->hitPoints = 0; + HitTarget(item, &target, WeaponsArray[Lara.gunType].damage, 0); + } + } + } + } + else + { + if (DrawTarget && (Lara.gunType == WEAPON_REVOLVER || Lara.gunType == WEAPON_HK)) + { + if (Objects[item->objectNumber].intelligent) + { + HitTarget(item, &target, WeaponsArray[Lara.gunType].damage, 0); + } + else + { + if (Objects[item->objectNumber].hitEffect == 3) + TriggerRicochetSpark(&target, LaraItem->pos.yRot, 3, 0); + } + } + else + { + if (item->objectNumber >= ID_SMASH_OBJECT1 && item->objectNumber <= ID_SMASH_OBJECT8) + { + SmashObject(itemNumber); + } + else + { + if (Objects[item->objectNumber].hitEffect == 1) + { + DoBloodSplat(target.x, target.y, target.z, (GetRandomControl() & 3) + 3, item->pos.yRot, item->roomNumber); + } + else if (Objects[item->objectNumber].hitEffect == 2) + { + TriggerRicochetSpark(&target, LaraItem->pos.yRot, 3, -5); + } + else if (Objects[item->objectNumber].hitEffect == 3) + { + TriggerRicochetSpark(&target, LaraItem->pos.yRot, 3, 0); + } + item->hitStatus = true; + if (!Objects[item->objectNumber].undead) + { + item->hitPoints -= WeaponsArray[Lara.gunType].damage; + } + } + } + } + } + else + { + if (TargetMesh == 1 << Objects[item->objectNumber].nmeshes - 1) + { + if (!(item->flags & 0x40)) + { + if (item->objectNumber == ID_SHOOT_SWITCH1) + ExplodeItemNode(item, Objects[item->objectNumber].nmeshes - 1, 0, 64); + if (item->triggerFlags == 444 && item->objectNumber == ID_SHOOT_SWITCH2) + { + ProcessExplodingSwitchType8(item); + } + else + { + if (item->flags & IFLAG_ACTIVATION_MASK && (item->flags & IFLAG_ACTIVATION_MASK) != IFLAG_ACTIVATION_MASK) + { + room = item->roomNumber; + GetFloorHeight(GetFloor(item->pos.xPos, item->pos.yPos - 256, item->pos.zPos, &room), item->pos.xPos, item->pos.yPos - 256, item->pos.zPos); + TestTriggers(TriggerIndex, 1, item->flags & IFLAG_ACTIVATION_MASK); + } + else + { + for (count = GetSwitchTrigger(item, triggerItems, 1); count > 0; --count) + { + AddActiveItem(triggerItems[count]); + Items[triggerItems[count]].status = ITEM_ACTIVE; + Items[triggerItems[count]].flags |= IFLAG_ACTIVATION_MASK; + } + } + } + } + if (item->status != ITEM_DEACTIVATED) + { + AddActiveItem(itemNumber); + item->status = ITEM_ACTIVE; + item->flags |= IFLAG_ACTIVATION_MASK | 0x40; + } + } + TriggerRicochetSpark(&target, LaraItem->pos.yRot, 3, 0); + } + } + } + else + { + if (LaserSight && itemNumber >= 0) + { + item = &Items[itemNumber]; + if (item->objectNumber == ID_ENEMY_JEEP && item->meshBits & 1) + { + /* @FIXME This turns the LaserSight sprite of the Grappling Gun green and calls FireGrapplingBoltFromLasersight() */ + } + } + } + } + else + { + if (itemNumber >= 0) + { + item = &Items[itemNumber]; + if (item->objectNumber == ID_ENEMY_JEEP && Lara.gunType == WEAPON_CROSSBOW && item->meshBits & 1) + { + /* @FIXME This turns the LaserSight sprite of the Grappling Gun green */ + } + } + } + flag = 1; + } + else + { + if (Lara.gunType != WEAPON_CROSSBOW) + { + target.x -= target.x - src->x >> 5; + target.y -= target.y - src->y >> 5; + target.z -= target.z - src->z >> 5; + if (firing && !result) + TriggerRicochetSpark(&target, LaraItem->pos.yRot, 8, 0); + } + else + { + if (firing && LaserSight) + { + /* @FIXME This calls FireGrapplingBoltFromLasersight() */ + } + } + } + if (DrawTarget && (flag || !result)) + { + TriggerDynamicLight(target.x, target.y, target.z, 64, 255, 0, 0); + LaserSightActive = 1; + LaserSightX = target.x; + LaserSightY = target.y; + LaserSightZ = target.z; + } + return flag; +} + +int ObjectOnLOS2(GAME_VECTOR* start, GAME_VECTOR* end, PHD_VECTOR* vec, MESH_INFO** mesh) +{ + int r, m; + ROOM_INFO* room; + short linknum, *box; + ITEM_INFO* item; + PHD_3DPOS pos; + MESH_INFO* meshp; + + ClosestItem = 999; + ClosestDist = SQUARE(end->x - start->x) + SQUARE(end->y - start->y) + SQUARE(end->z - start->z); + for (r = 0; r < number_los_rooms; ++r) + { + room = &Rooms[los_rooms[r]]; + for (linknum = room->itemNumber; linknum != NO_ITEM; linknum = Items[linknum].nextItem) + { + item = &Items[linknum]; + if (item->status != ITEM_DEACTIVATED && item->status != ITEM_INVISIBLE && (item->objectNumber ? (bool) Objects[item->objectNumber].collision : (bool) GetLaraOnLOS)) + { + box = GetBoundsAccurate(item); + pos.xPos = item->pos.xPos; + pos.yPos = item->pos.yPos; + pos.zPos = item->pos.zPos; + pos.yRot = item->pos.yRot; + if (DoRayBox(start, end, box, &pos, vec, linknum)) + { + end->roomNumber = los_rooms[r]; + } + } + } + for (m = room->numMeshes; m > 0; --m) + { + meshp = &room->mesh[m]; + if (meshp->Flags & 1) + { + pos.xPos = meshp->x; + pos.yPos = meshp->y; + pos.zPos = meshp->z; + pos.yRot = meshp->yRot; + if (DoRayBox(start, end, &StaticObjects[meshp->staticNumber].xMinc, &pos, vec, -1 - meshp->staticNumber)) + { + *mesh = meshp; + end->roomNumber = los_rooms[r]; + } + } + } + } + vec->x = ClosestCoord.x; + vec->y = ClosestCoord.y; + vec->z = ClosestCoord.z; + return ClosestItem; +} + +int GetRandomControl() +{ + rand_1 = 1103515245 * rand_1 + 12345; + return rand_1 >> 10 & 0x7FFF; +} + +void SeedRandomControl(int seed) +{ + rand_1 = seed; +} + +int GetRandomDraw() +{ + rand_2 = 1103515245 * rand_2 + 12345; + return rand_2 >> 10 & 0x7FFF; +} + +void SeedRandomDraw(int seed) +{ + rand_2 = seed; +} + +int GetCeiling(FLOOR_INFO* floor, int x, int y, int z) +{ + ROOM_INFO* room; + FLOOR_INFO* floor2; + int ceiling, t0, t1, t2, t3, dx, dz, xOff, yOff; + short type, type2, function, cadj, trigger, *data; + bool end; + ITEM_INFO* item; + + floor2 = floor; + while (floor2->skyRoom != NO_ROOM) + { + if (CheckNoColCeilingTriangle(floor2, x, z) == 1) + break; + room = &Rooms[floor2->skyRoom]; + floor2 = &XZ_GET_SECTOR(room, x - room->x, z - room->z); + } + ceiling = 256 * floor2->ceiling; + if (ceiling != NO_HEIGHT) + { + if (floor2->index) + { + data = &FloorData[floor2->index]; + type = *data; + function = type & DATA_TYPE; + ++data; + end = false; + if (function == TILT_TYPE || function == SPLIT1 || function == SPLIT2 || function == NOCOLF1T || function == NOCOLF1B || function == NOCOLF2T || function == NOCOLF2B) + { + ++data; + if (type & END_BIT) + end = true; + type = *data; + function = type & DATA_TYPE; + ++data; + } + if (!end) + { + xOff = 0; + yOff = 0; + if (function != ROOF_TYPE) + { + if (function == SPLIT3 || function == SPLIT4 || function == NOCOLC1T || function == NOCOLC1B || function == NOCOLC2T || function == NOCOLC2B) + { + dx = x & 0x3FF; + dz = z & 0x3FF; + t0 = -(*data & DATA_TILT); + t1 = -(*data >> 4 & DATA_TILT); + t2 = -(*data >> 8 & DATA_TILT); + t3 = -(*data >> 12 & DATA_TILT); + if (function == SPLIT3 || function == NOCOLC1T || function == NOCOLC1B) + { + if (dx <= 1024 - dz) + { + cadj = type >> 10 & DATA_TYPE; + if (cadj & 0x10) + cadj |= 0xFFF0; + ceiling += 256 * cadj; + xOff = t2 - t1; + yOff = t3 - t2; + } + else + { + cadj = type >> 5 & DATA_TYPE; + if (cadj & 0x10) + cadj |= 0xFFF0; + ceiling += 256 * cadj; + xOff = t3 - t0; + yOff = t0 - t1; + } + } + else + { + if (dx <= dz) + { + cadj = type >> 10 & DATA_TYPE; + if (cadj & 0x10) + cadj |= 0xFFF0; + ceiling += 256 * cadj; + xOff = t2 - t1; + yOff = t0 - t1; + } + else + { + cadj = type >> 5 & DATA_TYPE; + if (cadj & 0x10) + cadj |= 0xFFF0; + ceiling += 256 * cadj; + xOff = t3 - t0; + yOff = t3 - t2; + } + } + } + } + else + { + xOff = *data >> 8; + yOff = *(char *)data; + } + if (xOff < 0) + { + ceiling += (z & 0x3FF) * xOff >> 2; + } + else + { + ceiling -= (-1 - z & 0x3FF) * xOff >> 2; + } + if (yOff < 0) + { + ceiling += (-1 - x & 0x3FF) * yOff >> 2; + } + else + { + ceiling -= (x & 0x3FF) * yOff >> 2; + } + } + } + while (floor->pitRoom != NO_ROOM) + { + if (CheckNoColFloorTriangle(floor, x, z) == 1) + break; + room = &Rooms[floor->pitRoom]; + floor = &XZ_GET_SECTOR(room, x - room->x, z - room->z); + } + if (floor->index) + { + data = &FloorData[floor->index]; + do + { + type = *data; + function = type & DATA_TYPE; + ++data; + switch (function) + { + case DOOR_TYPE: + case TILT_TYPE: + case ROOF_TYPE: + case SPLIT1: + case SPLIT2: + case SPLIT3: + case SPLIT4: + case NOCOLF1T: + case NOCOLF1B: + case NOCOLF2T: + case NOCOLF2B: + case NOCOLC1T: + case NOCOLC1B: + case NOCOLC2T: + case NOCOLC2B: + ++data; + break; + case TRIGGER_TYPE: + ++data; + do + { + type2 = *data; + trigger = TRIG_BITS(type2); + ++data; + if (trigger != TO_OBJECT) + { + if (trigger == TO_CAMERA || trigger == TO_FLYBY) + { + type2 = *data; + ++data; + } + } + else + { + item = &Items[type2 & VALUE_BITS]; + if (Objects[item->objectNumber].ceiling && !(item->flags & 0x8000)) + { + Objects[item->objectNumber].ceiling(item, x, y, z, &ceiling); + } + } + } + while (!(type2 & END_BIT)); + } + } + while (!(type & END_BIT)); + } + } + return ceiling; +} + void Inject_Control() { INJECT(0x00416760, TestTriggers); INJECT(0x004167B0, TestTriggers); INJECT(0x00415960, TranslateItem); INJECT(0x00415B20, GetFloor); + INJECT(0x00417640, GetCeiling); } \ No newline at end of file diff --git a/TR5Main/Game/control.h b/TR5Main/Game/control.h index f39e2718d..de959369d 100644 --- a/TR5Main/Game/control.h +++ b/TR5Main/Game/control.h @@ -2,8 +2,8 @@ #include "..\Global\global.h" -#define GetCeiling ((int (__cdecl*)(FLOOR_INFO*, int, int, int)) 0x00417640) -#define GetRandomControl ((int (__cdecl*)()) 0x004A7C10) +//#define GetCeiling ((int (__cdecl*)(FLOOR_INFO*, int, int, int)) 0x00417640) +//#define GetRandomControl ((int (__cdecl*)()) 0x004A7C10) #define AnimateItem ((void (__cdecl*)(ITEM_INFO*)) 0x00415300) #define GetWaterHeight ((int (__cdecl*)(int, int, int, short)) 0x00415DA0) #define TriggerActive ((int (__cdecl*)(ITEM_INFO*)) 0x004175B0) @@ -34,9 +34,9 @@ #define DoFlipMap ((void (__cdecl*)(short)) 0x00418910) #define PlaySoundTrack ((void (__cdecl*)(short, short)) 0x00418B90) //#define AlterFloorHeight ((void (__cdecl*)(ITEM_INFO*, int)) 0x004159F0) -#define ObjectOnLOS2 ((int (__cdecl*)(GAME_VECTOR*, GAME_VECTOR*, PHD_VECTOR*, BITE_INFO*)) 0x00419110) +//#define ObjectOnLOS2 ((int (__cdecl*)(GAME_VECTOR*, GAME_VECTOR*, PHD_VECTOR*, BITE_INFO*)) 0x00419110) //#define LOS ((int (__cdecl*)(GAME_VECTOR*, GAME_VECTOR*)) 0x00417CF0) -#define GetTargetOnLOS ((int (__cdecl*)(GAME_VECTOR*, GAME_VECTOR*, int, int)) 0x0041A170) +//#define GetTargetOnLOS ((int (__cdecl*)(GAME_VECTOR*, GAME_VECTOR*, int, int)) 0x0041A170) //#define GetFloor ((FLOOR_INFO* (__cdecl*)(int, int, int, short*)) 0x00415B20) //#define GetFloorHeight ((int (__cdecl*)(FLOOR_INFO*, int, int, int)) 0x00415FB0) @@ -54,7 +54,6 @@ void ActivateKey(); short GetDoor(FLOOR_INFO* floor); void TranslateItem(ITEM_INFO* item, int x, int y, int z); void TestTriggers(short* data, int heavy, int HeavyFlags); -int CheckNoColFloorTriangle(FLOOR_INFO* floor, short x, short z); int GetWaterSurface(int x, int y, int z, short roomNumber); void KillMoveItems(); void KillMoveEffects(); @@ -71,6 +70,13 @@ int LOS(GAME_VECTOR* start, GAME_VECTOR* end); int xLOS(GAME_VECTOR* start, GAME_VECTOR* end); int zLOS(GAME_VECTOR* start, GAME_VECTOR* end); int ClipTarget(GAME_VECTOR* start, GAME_VECTOR* target); +int GetTargetOnLOS(GAME_VECTOR* src, GAME_VECTOR* dest, int DrawTarget, int firing); +int ObjectOnLOS2(GAME_VECTOR* start, GAME_VECTOR* end, PHD_VECTOR* vec, MESH_INFO** mesh); +int GetRandomControl(); +void SeedRandomControl(int seed); +int GetRandomDraw(); +void SeedRandomDraw(int seed); +int GetCeiling(FLOOR_INFO* floor, int x, int y, int z); unsigned __stdcall GameMain(void*); void Inject_Control(); diff --git a/TR5Main/Game/switch.h b/TR5Main/Game/switch.h index 54d148fde..d64715474 100644 --- a/TR5Main/Game/switch.h +++ b/TR5Main/Game/switch.h @@ -30,5 +30,6 @@ int SwitchTrigger(short itemNum, short timer); void InitialiseSwitch(short itemNum); void InitialisePulleySwitch(short itemNumber); void InitialiseCrowDoveSwitch(short itemNumber); +void ProcessExplodingSwitchType8(ITEM_INFO* item); void Inject_Switch(); \ No newline at end of file diff --git a/TR5Main/Game/tomb4fx.h b/TR5Main/Game/tomb4fx.h index cd0bd5592..907c660ee 100644 --- a/TR5Main/Game/tomb4fx.h +++ b/TR5Main/Game/tomb4fx.h @@ -21,6 +21,12 @@ extern DRIP_STRUCT Drips[32]; // offset 0xA85FC extern SHOCKWAVE_STRUCT ShockWaves[16]; // 0xA7C3C extern FIRE_LIST Fires[32]; // offset 0xA8D7C +extern int LaserSightX; +extern int LaserSightY; +extern int LaserSightZ; +extern char LaserSightActive; +extern char LaserSightCol; + extern int NextFireSpark; extern int NextSmokeSpark; extern int NextBubble; diff --git a/TR5Main/Global/vars.h b/TR5Main/Global/vars.h index 5128b8721..68b039593 100644 --- a/TR5Main/Global/vars.h +++ b/TR5Main/Global/vars.h @@ -305,6 +305,10 @@ #define LaraNodeUnderwater ARRAY_(0x00E862FE, byte, [15]) #define OnFloor VAR_U_(0x00EEEAC8, int) #define SlowMotion VAR_U_(0x0051CA50, short) +#define ShatterSounds ARRAY_(0x00506BAC, unsigned char, [18][10]) +#define TargetMesh VAR_U_(0x00EEFAF8, int) +#define WeaponsArray ARRAY_(0x005085B0, WEAPON_INFO, [9]) +#define GetLaraOnLOS VAR_U_(0x0051CA64, char) extern bool MonksAttackLara; diff --git a/TR5Main/Specific/roomload.cpp b/TR5Main/Specific/roomload.cpp index 0983d4e1f..f59fbcec9 100644 --- a/TR5Main/Specific/roomload.cpp +++ b/TR5Main/Specific/roomload.cpp @@ -8,6 +8,7 @@ #include "..\Game\savegame.h" #include "..\Game\spotcam.h" #include "..\Scripting\GameFlowScript.h" +#include "..\Game\control.h" #include "IO/ChunkId.h" #include "IO/ChunkReader.h" diff --git a/TR5Main/Specific/roomload.h b/TR5Main/Specific/roomload.h index 3f02fbe80..e0c1b7b20 100644 --- a/TR5Main/Specific/roomload.h +++ b/TR5Main/Specific/roomload.h @@ -37,8 +37,8 @@ struct LEB128; //#define InitialiseLara ((void (__cdecl*)(int)) 0x00473210) #define InitialiseGameStuff ((void (__cdecl*)()) 0x004778F0) #define InitialiseGameFlags ((void (__cdecl*)()) 0x00477880) -#define SeedRandomDraw ((void (__cdecl*)(int)) 0x004A7C90) -#define SeedRandomControl ((void (__cdecl*)(int)) 0x004A7C70) +//#define SeedRandomDraw ((void (__cdecl*)(int)) 0x004A7C90) +//#define SeedRandomControl ((void (__cdecl*)(int)) 0x004A7C70) #define GetAIPickups ((void (__cdecl*)()) 0x00477370) #define GetCarriedItems ((void (__cdecl*)()) 0x004771E0) #define InitialiseLaraMeshes ((void (__cdecl*)()) 0x00455680)