diff --git a/TR5Main/Game/control.cpp b/TR5Main/Game/control.cpp index 49ce2bdab..32f555923 100644 --- a/TR5Main/Game/control.cpp +++ b/TR5Main/Game/control.cpp @@ -1735,129 +1735,6 @@ int GetFloorHeight(FLOOR_INFO* floor, int x, int y, int z) return height; } -void UpdateBats() -{ - if (!Objects[ID_BATS].loaded) - return; - - short* bounds = GetBoundsAccurate(LaraItem); - - int x1 = LaraItem->pos.xPos + bounds[0] - (bounds[0] >> 2); - int x2 = LaraItem->pos.xPos + bounds[1] - (bounds[1] >> 2); - - int y1 = LaraItem->pos.yPos + bounds[2] - (bounds[2] >> 2); - int y2 = LaraItem->pos.yPos + bounds[3] - (bounds[3] >> 2); - - int z1 = LaraItem->pos.zPos + bounds[4] - (bounds[4] >> 2); - int z2 = LaraItem->pos.zPos + bounds[5] - (bounds[5] >> 2); - - int minDistance = 0xFFFFFFF; // v40 - int minIndex = -1; - - for (int i = 0; i < NUM_BATS; i++) - { - BAT_STRUCT* bat = &Bats[i]; - - if (!bat->on) - continue; - - if ((Lara.burn || LaraItem->hitPoints <= 0) - && bat->counter > 90 - && !(GetRandomControl() & 7)) - bat->counter = 90; - - if (!(--bat->counter)) - { - bat->on = 0; - continue; - } - - if (!(GetRandomControl() & 7)) - { - bat->laraTarget = GetRandomControl() % 640 + 128; - bat->xTarget = (GetRandomControl() & 0x7F) - 64; - bat->zTarget = (GetRandomControl() & 0x7F) - 64; - } - - short angles[2]; - phd_GetVectorAngles( - LaraItem->pos.xPos + 8 * bat->xTarget - bat->pos.xPos, - LaraItem->pos.yPos - bat->laraTarget - bat->pos.yPos, - LaraItem->pos.zPos + 8 * bat->zTarget - bat->pos.zPos, - angles); - - int distance = SQUARE(LaraItem->pos.zPos - bat->pos.zPos) + SQUARE(LaraItem->pos.xPos - bat->pos.xPos); - if (distance < minDistance) - { - minDistance = distance; - minIndex = i; - } - - distance = SQRT_ASM(distance) / 8; - if (distance <= 128) - { - if (distance < 48) - distance = 48; - } - else - { - distance = 128; - } - - if (bat->speed < distance) - bat->speed++; - else if (bat->speed > distance) - bat->speed--; - - if (bat->counter > 90) - { - int speed = bat->speed * 128; - - short xAngle = abs(angles[1] - bat->pos.yRot) >> 3; - short yAngle = abs(angles[0] - bat->pos.yRot) >> 3; - - if (xAngle <= -speed) - xAngle = -speed; - else if (xAngle >= speed) - xAngle = speed; - - if (yAngle <= -speed) - yAngle = -speed; - else if (yAngle >= speed) - yAngle = speed; - - bat->pos.yRot += yAngle; - bat->pos.xRot += xAngle; - } - - int sp = bat->speed * SIN(bat->pos.xRot) >> W2V_SHIFT; - - bat->pos.xPos += sp * SIN(bat->pos.yRot) >> W2V_SHIFT; - bat->pos.yPos += bat->speed * SIN(-bat->pos.xRot) >> W2V_SHIFT; - bat->pos.zPos += sp * COS(bat->pos.yRot) >> W2V_SHIFT; - - if ((i % 2 == 0) - && bat->pos.xPos > x1 - && bat->pos.xPos < x2 - && bat->pos.yPos > y1 - && bat->pos.yPos < y2 - && bat->pos.zPos > z1 - && bat->pos.zPos < z2) - { - TriggerBlood(bat->pos.xPos, bat->pos.yPos, bat->pos.zPos, 2 * GetRandomControl(), 2); - if (LaraItem->hitPoints > 0) - LaraItem->hitPoints -= 2; - } - } - - if (minIndex != -1) - { - BAT_STRUCT* bat = &Bats[minIndex]; - if (!(GetRandomControl() & 4)) - SoundEffect(SFX_BATS_1, &bat->pos, 0); - } -} - void UpdateDebris() { for (int i = 0; i < 256; i++) @@ -1896,305 +1773,6 @@ void UpdateDebris() } } -void UpdateRats() -{ - if (Objects[ID_RATS].loaded) - { - for (int i = 0; i < 32; i++) - { - RAT_STRUCT* rat = &Rats[i]; - - if (rat->on) - { - int oldX = rat->pos.xPos; - int oldY = rat->pos.yPos; - int oldZ = rat->pos.zPos; - - rat->pos.xPos += rat->speed * SIN(rat->pos.yRot) >> W2V_SHIFT; - rat->pos.yPos += rat->fallspeed; - rat->pos.zPos += rat->speed * COS(rat->pos.yRot) >> W2V_SHIFT; - - rat->fallspeed += 6; - - int dx = LaraItem->pos.xPos - rat->pos.xPos; - int dy = LaraItem->pos.yPos - rat->pos.yPos; - int dz = LaraItem->pos.zPos - rat->pos.zPos; - - short angle; - if (rat->flags >= 170) - angle = rat->pos.yRot - ATAN(dz, dx); - else - angle = ATAN(dz, dx) - rat->pos.yRot; - - if (abs(dx) < 85 && abs(dy) < 85 && abs(dz) < 85) - { - LaraItem->hitPoints--; - LaraItem->hitStatus = true; - } - - if (rat->flags & 1) - { - if (abs(dz) + abs(dx) <= 1024) - { - if (rat->speed & 1) - rat->pos.yRot += 512; - else - rat->pos.yRot -= 512; - rat->speed = 48 - (abs(angle) >> 10); - } - else - { - if (rat->speed < (i & 0x1F) + 24) - rat->speed++; - - if (abs(angle) >= 2048) - { - if (angle >= 0) - rat->pos.yRot += 1024; - else - rat->pos.yRot -= 1024; - } - else - { - rat->pos.yRot += 8 * (Wibble - i); - } - } - } - - __int16 oldRoomNumber = rat->roomNumber; - - FLOOR_INFO* floor = GetFloor(rat->pos.xPos, rat->pos.yPos, rat->pos.zPos, &rat->roomNumber); - int height = GetFloorHeight(floor, rat->pos.xPos, rat->pos.yPos, rat->pos.zPos); - if (height < rat->pos.yPos - 1280 || height == NO_HEIGHT) - { - if (rat->flags > 170) - { - rat->on = false; - NextRat = 0; - } - if (angle <= 0) - rat->pos.yRot -= ANGLE(90); - else - rat->pos.yRot += ANGLE(90); - - rat->pos.xPos = oldX; - rat->pos.yPos = oldY; - rat->pos.zPos = oldZ; - - rat->fallspeed = 0; - } - else - { - if (height >= rat->pos.yPos - 64) - { - if (rat->pos.yPos <= height) - { - if (rat->fallspeed >= 500 || rat->flags >= 200) - { - rat->on = 0; - NextRat = 0; - } - else - { - rat->pos.xRot = -128 * rat->fallspeed; - } - } - else - { - rat->pos.yPos = height; - rat->fallspeed = 0; - rat->flags |= 1; - } - } - else - { - rat->pos.xRot = 14336; - rat->pos.xPos = oldX; - rat->pos.yPos = oldY - 24; - rat->pos.zPos = oldZ; - rat->fallspeed = 0; - } - } - - if (!(Wibble & 0x3C)) - rat->flags += 2; - - ROOM_INFO* r = &Rooms[rat->roomNumber]; - if (r->flags & ENV_FLAG_WATER) - { - rat->fallspeed = 0; - rat->speed = 16; - rat->pos.yPos = r->maxceiling + 50; - - if (Rooms[oldRoomNumber].flags & ENV_FLAG_WATER) - { - if (!(GetRandomControl() & 0xF)) - { - SetupRipple(rat->pos.xPos, r->maxceiling, rat->pos.zPos, (GetRandomControl() & 3) + 48, 2); - } - } - else - { - AddWaterSparks(rat->pos.xPos, r->maxceiling, rat->pos.zPos, 16); - SetupRipple(rat->pos.xPos, r->maxceiling, rat->pos.zPos, (GetRandomControl() & 3) + 48, 2); - SoundEffect(SFX_RATSPLASH, &rat->pos, 0); - } - } - - if (!i && !(GetRandomControl() & 4)) - SoundEffect(SFX_RATS_1, &rat->pos, 0); - } - } - } -} - -/*char __usercall UpdateSpiders@ (signed int a1@ ) -{ - if (Objects[ID_SPIDER].loaded) - { - for (int i = 0; i < 64; i++) - { - SPIDER_STRUCT* spider = &Spiders[i]; - if (spider->on) - { - - } - } - } - - LOBYTE(a1) = *(&objects[95] + 50); - if (*(&objects[95] + 50) & 1) - { - v1 = Spiders; - v23 = 0; - do - { - if (BYTE2(v1[1].yPos)) - { - LOWORD(a1) = v1->yRot; - v2 = SHIWORD(v1[1].xPos); - v3 = v1->yPos; - v4 = (a1 >> 3) & 0x1FFE; - v25 = v1->xPos; - v5 = v1->zPos; - v6 = v1[1].yPos; - v1->xPos += v2 * 4 * rcossin_tbl[v4] >> 14; - v26 = v3; - v1->yPos = v3 + v6; - v27 = v5; - v7 = v5 + (v2 * 4 * rcossin_tbl[v4 + 1] >> 14); - LOWORD(v1[1].yPos) = v6 + 6; - v1->zPos = v7; - v8 = v3 + v6; - v9 = LaraItem->pos.zPos - v1->zPos; - v10 = LaraItem->pos.xPos - v1->xPos; - v11 = LaraItem->pos.yPos - v8; - v12 = phd_atan(v9, v10) - v1->yRot; - v24 = v12; - v13 = abs(v9); - if (v13 < 85 && abs(v11) < 85 && abs(v10) < 85) - { - LaraItem->hit_points -= 3; - LaraItem->_bf15ea |= 0x10u; - TriggerBlood(v1->xPos, v1->yPos, v1->zPos, v1->yRot, 1); - v12 = v24; - } - if (HIBYTE(v1[1].yPos)) - { - if (v13 + abs(v10) <= 768) - { - if (v1[1].xPos & 0x10000) - v1->yRot += 512; - else - v1->yRot -= 512; - HIWORD(v1[1].xPos) = 48 - (abs(v12) >> 10); - } - else - { - v14 = HIWORD(v1[1].xPos); - if (v14 < (v23 & 0x1F) + 24) - HIWORD(v1[1].xPos) = v14 + 1; - if (abs(v12) >= 2048) - { - if (v12 >= 0) - v1->yRot += 1024; - else - v1->yRot -= 1024; - } - else - { - v1->yRot += 8 * (wibble - v23); - } - } - } - v15 = v1 + 1; - v16 = GetFloor(v1->xPos, v1->yPos, v1->zPos, &v1[1]); - v17 = GetHeight(v16, v1->xPos, v1->yPos, v1->zPos); - v18 = v1->yPos; - if (v17 >= v18 - 1280 || v17 == -32512) - { - if (v17 >= v18 - 64) - { - if (v18 <= v17) - { - if (SLOWORD(v1[1].yPos) >= 500) - { - BYTE2(v1[1].yPos) = 0; - NextSpider = 0; - } - else - { - v1->xRot = -128 * LOWORD(v1[1].yPos); - } - } - else - { - v1->yPos = v17; - LOWORD(v1[1].yPos) = 0; - HIBYTE(v1[1].yPos) = 1; - } - } - else - { - v1->xRot = 14336; - v1->xPos = v25; - v1->yPos = v26 - 8; - if (!(GetRandomControl() & 0x1F)) - v1->yRot += -32768; - LOWORD(v1[1].yPos) = 0; - v1->zPos = v27; - } - } - else - { - if (v24 <= 0) - v1->yRot -= 0x4000; - else - v1->yRot += 0x4000; - v1->xPos = v25; - v1->yPos = v26; - v1->zPos = v27; - LOWORD(v1[1].yPos) = 0; - } - if (v1->yPos < room[SLOWORD(v15->xPos)].maxceiling + 50) - { - v19 = room[SLOWORD(v15->xPos)].maxceiling; - LOWORD(v1[1].yPos) = 1; - v1->yRot += -32768; - v1->yPos = v19 + 50; - } - if (!v23 && !(GetRandomControl() & 4)) - SoundEffect(276, v1, 0); - } - v1 = (v1 + 26); - a1 = v23 + 1; - v21 = __OFSUB__(v23 + 1, 64); - v20 = v23++ - 63 < 0; - } while (v20 ^ v21); - } - return a1; -}*/ - int LOS(GAME_VECTOR* start, GAME_VECTOR* end) { int result1, result2; diff --git a/TR5Main/Game/control.h b/TR5Main/Game/control.h index 494da637f..451cd0cd0 100644 --- a/TR5Main/Game/control.h +++ b/TR5Main/Game/control.h @@ -2,7 +2,7 @@ #include "..\Global\global.h" -#define UpdateSpiders ((void (__cdecl*)()) 0x0047A340) +//#define UpdateSpiders ((void (__cdecl*)()) 0x0047A340) #define UpdateLightning ((void (__cdecl*)()) 0x00484CB0) #define UpdatePulseColor ((void (__cdecl*)()) 0x00480830) #define DoRayBox_sub_401523 ((int (__cdecl*)(PHD_VECTOR*, PHD_VECTOR*, PHD_VECTOR*, PHD_VECTOR*, PHD_VECTOR*)) 0x00401523) @@ -40,9 +40,7 @@ int CheckNoColCeilingTriangle(FLOOR_INFO* floor, int x, int z); int CheckNoColFloorTriangle(FLOOR_INFO* floor, int x, int z); int GetFloorHeight(FLOOR_INFO* floor, int x, int y, int z); FLOOR_INFO* GetFloor(int x, int y, int z, short* roomNumber); -void UpdateRats(); void UpdateDebris(); -void UpdateBats(); int LOS(GAME_VECTOR* start, GAME_VECTOR* end); int xLOS(GAME_VECTOR* start, GAME_VECTOR* end); int zLOS(GAME_VECTOR* start, GAME_VECTOR* end); diff --git a/TR5Main/Game/effects.cpp b/TR5Main/Game/effects.cpp index 1b6434746..fd1dcdc53 100644 --- a/TR5Main/Game/effects.cpp +++ b/TR5Main/Game/effects.cpp @@ -9,6 +9,8 @@ #include "draw.h" #include "sphere.h" #include "footprint.h" +#include "..\Objects\oldobjects.h" + int wf = 256; extern std::deque footprints; @@ -244,21 +246,6 @@ void invisibility_on(ITEM_INFO* item) item->status = ITEM_INVISIBLE; } -void ClearSpiders()// (F) -{ - /*if (Objects[ID_SPIDER].loaded) - { - memset((char*)&Spiders, 0, 64 * sizeof(SPIDER_STRUCT)); - NextSpider = 0; - FlipEffect = -1; - }*/ -} - -void ClearSpidersPatch(ITEM_INFO* item)//39AA4(<), 39FA4(<) (F) -{ - ClearSpiders(); -} - /*void SetFog() { FlipEffect = -1; diff --git a/TR5Main/Game/effects.h b/TR5Main/Game/effects.h index 5c966bec2..fa74e91a0 100644 --- a/TR5Main/Game/effects.h +++ b/TR5Main/Game/effects.h @@ -31,8 +31,6 @@ void lara_hands_free(ITEM_INFO* item); void shoot_right_gun(ITEM_INFO* item); void shoot_left_gun(ITEM_INFO* item); void SetFog(ITEM_INFO* item); -void ClearSpidersPatch(ITEM_INFO* item); -void ClearSpiders(); void invisibility_on(ITEM_INFO* item); void invisibility_off(ITEM_INFO* item); void reset_hair(ITEM_INFO* item); diff --git a/TR5Main/Game/rat.h b/TR5Main/Game/rat.h index c356858a9..c45d1d232 100644 --- a/TR5Main/Game/rat.h +++ b/TR5Main/Game/rat.h @@ -2,5 +2,5 @@ #include "..\Global\global.h" -#define InitialiseLittleRats ((void (__cdecl*)(short)) 0x0046B220) +//#define InitialiseLittleRats ((void (__cdecl*)(short)) 0x0046B220) //#define ControlLittleRats ((void (__cdecl*)(short)) 0x0046AB30) \ No newline at end of file diff --git a/TR5Main/Game/tomb4fx.cpp b/TR5Main/Game/tomb4fx.cpp index 8194ff8fc..0652608f4 100644 --- a/TR5Main/Game/tomb4fx.cpp +++ b/TR5Main/Game/tomb4fx.cpp @@ -31,7 +31,6 @@ int NextSmokeSpark = 0; int NextBubble = 0; int NextDrip = 0; int NextBlood = 0; -int NextSpider = 0; int NextGunShell = 0; GUNFLASH_STRUCT Gunflashes[MAX_GUNFLASH]; @@ -1813,40 +1812,12 @@ void TriggerFenceSparks(int x, int y, int z, int kill, int crane)//(F) spark->friction = 4; } - //loc_365C4 spark->flags = 0; spark->gravity = (GetRandomControl() & 0xF) + ((crane << 4) + 16); spark->maxYvel = 0; } -int GetFreeSpider()// (F) -{ - SPIDER_STRUCT* peter = &Spiders[NextSpider]; - int peter_num = NextSpider; - int count = 0; - - while (peter->on) - { - if (peter_num == 63) - { - peter = &Spiders[0]; - peter_num = 0; - } - else - { - peter++; - peter_num++; - } - - if (++count >= 64) - return -1; - } - - NextSpider = (peter_num + 1) & 63; - return peter_num; -} - -void TriggerSmallSplash(int x, int y, int z, int num)// (F) +void TriggerSmallSplash(int x, int y, int z, int num) { int i; int angle; diff --git a/TR5Main/Game/tomb4fx.h b/TR5Main/Game/tomb4fx.h index 76c286b53..e346e1c5f 100644 --- a/TR5Main/Game/tomb4fx.h +++ b/TR5Main/Game/tomb4fx.h @@ -71,7 +71,6 @@ void TriggerShockwave(PHD_3DPOS* pos, short innerRad, short outerRad, int speed, void TriggerShockwaveHitEffect(int x, int y, int z, int color, short rot, int vel); void UpdateShockwaves(); void TriggerSmallSplash(int x, int y, int z, int num); -int GetFreeSpider(); void SetFadeClip(short height, short speed); void TriggerLightningGlow(int x, int y, int z, int rgb); diff --git a/TR5Main/Global/vars.h b/TR5Main/Global/vars.h index 012dba0ca..0fa43e60a 100644 --- a/TR5Main/Global/vars.h +++ b/TR5Main/Global/vars.h @@ -213,8 +213,8 @@ #define PhdHeight VAR_U_(0x0055D164, int) #define PhdPerspective VAR_U_(0x0055D208, int) //#define Bats VAR_U_(0x00EEEFE8, BAT_STRUCT*) -#define Rats VAR_U_(0x00EEEFEC, RAT_STRUCT*) -#define Spiders VAR_U_(0x00EEF45C, SPIDER_STRUCT*) +//#define Rats VAR_U_(0x00EEEFEC, RAT_STRUCT*) +//#define Spiders VAR_U_(0x00EEF45C, SPIDER_STRUCT*) #define PoisonFlags VAR_U_(0x00E5BF3E, byte) #define SmashedMeshCount VAR_U_(0x0051CA5C, short) #define SmashedMesh ARRAY_(0x00EEF8C0, MESH_INFO*, [16]) @@ -307,7 +307,7 @@ #define KillEverythingFlag VAR_U_(0x0051CDF4, int) #define SmokeWindX VAR_U_(0x00E6C9E0, int) #define SmokeWindZ VAR_U_(0x00E6C9E4, int) -#define NextRat VAR_U_(0x0051CF94, int) +//#define NextRat VAR_U_(0x0051CF94, int) //#define NextFireSpark VAR_U_(0x0050A17C, int) #define LaraNodeUnderwater ARRAY_(0x00E862FE, byte, [15]) #define OnFloor VAR_U_(0x00EEEAC8, int) diff --git a/TR5Main/Objects/TR5/tr5_particle_enemies.cpp b/TR5Main/Objects/TR5/tr5_particle_enemies.cpp index 83b03da45..5966887d4 100644 --- a/TR5Main/Objects/TR5/tr5_particle_enemies.cpp +++ b/TR5Main/Objects/TR5/tr5_particle_enemies.cpp @@ -10,9 +10,15 @@ #include "../../Game/control.h" #include "../../Game/effects.h" -int NumBats; +int NextBat; BAT_STRUCT* Bats; +int NextSpider; +SPIDER_STRUCT* Spiders; + +int NextRat; +RAT_STRUCT* Rats; + void InitialiseLittleBats(short itemNumber) { ITEM_INFO* item = &Items[itemNumber]; @@ -58,11 +64,11 @@ void ControlLittleBats(short itemNumber) } } -short GetFreeBat() +short GetNextBat() { - short batNumber = NumBats; + short batNumber = NextBat; int index = 0; - BAT_STRUCT* bat = &Bats[NumBats]; + BAT_STRUCT* bat = &Bats[NextBat]; while (bat->on) { @@ -83,14 +89,14 @@ short GetFreeBat() return NO_ITEM; } - NumBats = (batNumber + 1) & (NUM_BATS - 1); + NextBat = (batNumber + 1) & (NUM_BATS - 1); return batNumber; } void TriggerLittleBat(ITEM_INFO* item) { - short batNumber = GetFreeBat(); + short batNumber = GetNextBat(); if (batNumber != NO_ITEM) { @@ -108,4 +114,651 @@ void TriggerLittleBat(ITEM_INFO* item) bat->laraTarget = GetRandomControl() & 0x1FF; bat->counter = 20 * ((GetRandomControl() & 7) + 15); } +} + +short GetNextSpider() +{ + short spiderNum = NextSpider; + int i = 0; + SPIDER_STRUCT* spider = &Spiders[NextSpider]; + + while (spider->on) + { + if (spiderNum == NUM_SPIDERS - 1) + { + spider = &Spiders[0]; + spiderNum = 0; + } + else + { + ++spiderNum; + ++spider; + } + + if (++i >= NUM_SPIDERS) + return -1; + } + + NextSpider = (spiderNum + 1) & 0x3F; + + return spiderNum; +} + +void ClearSpiders() +{ + if (Objects[ID_SPIDER].loaded) + { + ZeroMemory(Spiders, NUM_SPIDERS * sizeof(SPIDER_STRUCT)); + NextSpider = 0; + FlipEffect = -1; + } +} + +void ClearSpidersPatch(ITEM_INFO* item) +{ + ClearSpiders(); +} + +void InitialiseSpiders(short itemNumber) +{ + ITEM_INFO* item = &Items[itemNumber]; + + short flags = item->triggerFlags / -24; + + item->pos.xRot = ANGLE(45); + item->itemFlags[1] = flags & 2; + item->itemFlags[2] = flags & 4; + item->itemFlags[0] = flags & 1; + item->triggerFlags = flags % 1000; + + if (flags & 1) + { + ClearSpiders(); + return; + } + + if (item->pos.yRot > -28672 && item->pos.yRot < -4096) + { + item->pos.xPos += 512; + } + else if(item->pos.yRot > 4096 && item->pos.yRot < 28672) + { + item->pos.xPos -= 512; + } + + if (item->pos.yRot > -8192 && item->pos.yRot < 8192) + { + item->pos.zPos -= 512; + } + else if (item->pos.yRot < -20480 || item->pos.yRot > 20480) + { + item->pos.zPos += 512; + } + + ClearSpiders(); +} + +void ControlSpiders(short itemNumber) +{ + ITEM_INFO* item = &Items[itemNumber]; + + if (item->triggerFlags) + { + if (!item->itemFlags[2] || !(GetRandomControl() & 0xF)) + { + item->triggerFlags--; + + if (item->itemFlags[2] && GetRandomControl() & 1) + item->itemFlags[2]--; + + short spiderNum = GetNextSpider(); + if (spiderNum != -1) + { + SPIDER_STRUCT* spider = &Spiders[spiderNum]; + + spider->pos.xPos = item->pos.xPos; + spider->pos.yPos = item->pos.yPos; + spider->pos.zPos = item->pos.zPos; + spider->roomNumber = item->roomNumber; + + if (item->itemFlags[0]) + { + spider->pos.yRot = 2 * GetRandomControl(); + spider->fallspeed = -16 - (GetRandomControl() & 0x1F); + } + else + { + spider->fallspeed = 0; + spider->pos.yRot = item->pos.yRot + (GetRandomControl() & 0x3FFF) - ANGLE(45); + } + + spider->pos.xRot = 0; + spider->pos.zRot = 0; + spider->on = true; + spider->flags = 0; + spider->speed = (GetRandomControl() & 0x1F) + 1; + } + } + } +} + +short GetNextRat() +{ + short ratNum = NextRat; + int i = 0; + RAT_STRUCT* rat = &Rats[NextRat]; + + while (rat->on) + { + if (ratNum == NUM_RATS - 1) + { + rat = &Rats[0]; + ratNum = 0; + } + else + { + ratNum++; + rat++; + } + + i++; + + if (i >= NUM_RATS) + return NO_ITEM; + } + + NextRat = (ratNum + 1) & 0x1F; + return ratNum; +} + +void ControlLittleRats(short itemNumber) +{ + ITEM_INFO* item = &Items[itemNumber]; + + if (item->triggerFlags) + { + if (!item->itemFlags[2] || !(GetRandomControl() & 0xF)) + { + item->triggerFlags--; + + if (item->itemFlags[2] && GetRandomControl() & 1) + item->itemFlags[2]--; + + short ratNum = GetNextRat(); + if (ratNum != -1) + { + RAT_STRUCT* rat = &Rats[ratNum]; + + rat->pos.xPos = item->pos.xPos; + rat->pos.yPos = item->pos.yPos; + rat->pos.zPos = item->pos.zPos; + rat->roomNumber = item->roomNumber; + + if (item->itemFlags[0]) + { + rat->pos.yRot = 2 * GetRandomControl(); + rat->fallspeed = -16 - (GetRandomControl() & 0x1F); + } + else + { + rat->fallspeed = 0; + rat->pos.yRot = item->pos.yRot + (GetRandomControl() & 0x3FFF) - ANGLE(45); + } + + rat->pos.xRot = 0; + rat->pos.zRot = 0; + rat->on = 1; + rat->flags = GetRandomControl() & 0x1E; + rat->speed = (GetRandomControl() & 0x1F) + 1; + } + } + } +} + +void ClearRats() +{ + if (Objects[ID_RATS].loaded) + { + ZeroMemory(Rats, NUM_RATS * sizeof(RAT_STRUCT)); + NextRat = 0; + FlipEffect = -1; + } +} + +void InitialiseLittleRats(short itemNumber) +{ + ITEM_INFO* item = &Items[itemNumber]; + + short flags = item->triggerFlags / -24; + + item->pos.xRot = ANGLE(45); + item->itemFlags[1] = flags & 2; + item->itemFlags[2] = flags & 4; + item->itemFlags[0] = flags & 1; + item->triggerFlags = flags % 1000; + + if (flags & 1) + { + ClearRats(); + return; + } + + if (item->pos.yRot > -28672 && item->pos.yRot < -4096) + { + item->pos.xPos += 512; + } + else if (item->pos.yRot > 4096 && item->pos.yRot < 28672) + { + item->pos.xPos -= 512; + } + + if (item->pos.yRot > -8192 && item->pos.yRot < 8192) + { + item->pos.zPos -= 512; + } + else if (item->pos.yRot < -20480 || item->pos.yRot > 20480) + { + item->pos.zPos += 512; + } + + ClearRats(); +} + +void UpdateBats() +{ + if (!Objects[ID_BATS].loaded) + return; + + short* bounds = GetBoundsAccurate(LaraItem); + + int x1 = LaraItem->pos.xPos + bounds[0] - (bounds[0] >> 2); + int x2 = LaraItem->pos.xPos + bounds[1] - (bounds[1] >> 2); + + int y1 = LaraItem->pos.yPos + bounds[2] - (bounds[2] >> 2); + int y2 = LaraItem->pos.yPos + bounds[3] - (bounds[3] >> 2); + + int z1 = LaraItem->pos.zPos + bounds[4] - (bounds[4] >> 2); + int z2 = LaraItem->pos.zPos + bounds[5] - (bounds[5] >> 2); + + int minDistance = 0xFFFFFFF; // v40 + int minIndex = -1; + + for (int i = 0; i < NUM_BATS; i++) + { + BAT_STRUCT* bat = &Bats[i]; + + if (!bat->on) + continue; + + if ((Lara.burn || LaraItem->hitPoints <= 0) + && bat->counter > 90 + && !(GetRandomControl() & 7)) + bat->counter = 90; + + if (!(--bat->counter)) + { + bat->on = 0; + continue; + } + + if (!(GetRandomControl() & 7)) + { + bat->laraTarget = GetRandomControl() % 640 + 128; + bat->xTarget = (GetRandomControl() & 0x7F) - 64; + bat->zTarget = (GetRandomControl() & 0x7F) - 64; + } + + short angles[2]; + phd_GetVectorAngles( + LaraItem->pos.xPos + 8 * bat->xTarget - bat->pos.xPos, + LaraItem->pos.yPos - bat->laraTarget - bat->pos.yPos, + LaraItem->pos.zPos + 8 * bat->zTarget - bat->pos.zPos, + angles); + + int distance = SQUARE(LaraItem->pos.zPos - bat->pos.zPos) + SQUARE(LaraItem->pos.xPos - bat->pos.xPos); + if (distance < minDistance) + { + minDistance = distance; + minIndex = i; + } + + distance = SQRT_ASM(distance) / 8; + if (distance <= 128) + { + if (distance < 48) + distance = 48; + } + else + { + distance = 128; + } + + if (bat->speed < distance) + bat->speed++; + else if (bat->speed > distance) + bat->speed--; + + if (bat->counter > 90) + { + int speed = bat->speed * 128; + + short xAngle = abs(angles[1] - bat->pos.yRot) >> 3; + short yAngle = abs(angles[0] - bat->pos.yRot) >> 3; + + if (xAngle <= -speed) + xAngle = -speed; + else if (xAngle >= speed) + xAngle = speed; + + if (yAngle <= -speed) + yAngle = -speed; + else if (yAngle >= speed) + yAngle = speed; + + bat->pos.yRot += yAngle; + bat->pos.xRot += xAngle; + } + + int sp = bat->speed * SIN(bat->pos.xRot) >> W2V_SHIFT; + + bat->pos.xPos += sp * SIN(bat->pos.yRot) >> W2V_SHIFT; + bat->pos.yPos += bat->speed * SIN(-bat->pos.xRot) >> W2V_SHIFT; + bat->pos.zPos += sp * COS(bat->pos.yRot) >> W2V_SHIFT; + + if ((i % 2 == 0) + && bat->pos.xPos > x1 + && bat->pos.xPos < x2 + && bat->pos.yPos > y1 + && bat->pos.yPos < y2 + && bat->pos.zPos > z1 + && bat->pos.zPos < z2) + { + TriggerBlood(bat->pos.xPos, bat->pos.yPos, bat->pos.zPos, 2 * GetRandomControl(), 2); + if (LaraItem->hitPoints > 0) + LaraItem->hitPoints -= 2; + } + } + + if (minIndex != -1) + { + BAT_STRUCT* bat = &Bats[minIndex]; + if (!(GetRandomControl() & 4)) + SoundEffect(SFX_BATS_1, &bat->pos, 0); + } +} + + +void UpdateRats() +{ + if (Objects[ID_RATS].loaded) + { + for (int i = 0; i < NUM_RATS; i++) + { + RAT_STRUCT* rat = &Rats[i]; + + if (rat->on) + { + int oldX = rat->pos.xPos; + int oldY = rat->pos.yPos; + int oldZ = rat->pos.zPos; + + rat->pos.xPos += rat->speed * SIN(rat->pos.yRot) >> W2V_SHIFT; + rat->pos.yPos += rat->fallspeed; + rat->pos.zPos += rat->speed * COS(rat->pos.yRot) >> W2V_SHIFT; + + rat->fallspeed += 6; + + int dx = LaraItem->pos.xPos - rat->pos.xPos; + int dy = LaraItem->pos.yPos - rat->pos.yPos; + int dz = LaraItem->pos.zPos - rat->pos.zPos; + + short angle; + if (rat->flags >= 170) + angle = rat->pos.yRot - ATAN(dz, dx); + else + angle = ATAN(dz, dx) - rat->pos.yRot; + + if (abs(dx) < 85 && abs(dy) < 85 && abs(dz) < 85) + { + LaraItem->hitPoints--; + LaraItem->hitStatus = true; + } + + if (rat->flags & 1) + { + if (abs(dz) + abs(dx) <= 1024) + { + if (rat->speed & 1) + rat->pos.yRot += 512; + else + rat->pos.yRot -= 512; + rat->speed = 48 - (abs(angle) >> 10); + } + else + { + if (rat->speed < (i & 0x1F) + 24) + rat->speed++; + + if (abs(angle) >= 2048) + { + if (angle >= 0) + rat->pos.yRot += 1024; + else + rat->pos.yRot -= 1024; + } + else + { + rat->pos.yRot += 8 * (Wibble - i); + } + } + } + + __int16 oldRoomNumber = rat->roomNumber; + + FLOOR_INFO* floor = GetFloor(rat->pos.xPos, rat->pos.yPos, rat->pos.zPos, &rat->roomNumber); + int height = GetFloorHeight(floor, rat->pos.xPos, rat->pos.yPos, rat->pos.zPos); + if (height < rat->pos.yPos - 1280 || height == NO_HEIGHT) + { + if (rat->flags > 170) + { + rat->on = false; + NextRat = 0; + } + if (angle <= 0) + rat->pos.yRot -= ANGLE(90); + else + rat->pos.yRot += ANGLE(90); + + rat->pos.xPos = oldX; + rat->pos.yPos = oldY; + rat->pos.zPos = oldZ; + + rat->fallspeed = 0; + } + else + { + if (height >= rat->pos.yPos - 64) + { + if (rat->pos.yPos <= height) + { + if (rat->fallspeed >= 500 || rat->flags >= 200) + { + rat->on = 0; + NextRat = 0; + } + else + { + rat->pos.xRot = -128 * rat->fallspeed; + } + } + else + { + rat->pos.yPos = height; + rat->fallspeed = 0; + rat->flags |= 1; + } + } + else + { + rat->pos.xRot = 14336; + rat->pos.xPos = oldX; + rat->pos.yPos = oldY - 24; + rat->pos.zPos = oldZ; + rat->fallspeed = 0; + } + } + + if (!(Wibble & 0x3C)) + rat->flags += 2; + + ROOM_INFO* r = &Rooms[rat->roomNumber]; + if (r->flags & ENV_FLAG_WATER) + { + rat->fallspeed = 0; + rat->speed = 16; + rat->pos.yPos = r->maxceiling + 50; + + if (Rooms[oldRoomNumber].flags & ENV_FLAG_WATER) + { + if (!(GetRandomControl() & 0xF)) + { + SetupRipple(rat->pos.xPos, r->maxceiling, rat->pos.zPos, (GetRandomControl() & 3) + 48, 2); + } + } + else + { + AddWaterSparks(rat->pos.xPos, r->maxceiling, rat->pos.zPos, 16); + SetupRipple(rat->pos.xPos, r->maxceiling, rat->pos.zPos, (GetRandomControl() & 3) + 48, 2); + SoundEffect(SFX_RATSPLASH, &rat->pos, 0); + } + } + + if (!i && !(GetRandomControl() & 4)) + SoundEffect(SFX_RATS_1, &rat->pos, 0); + } + } + } +} + +void UpdateSpiders() +{ + if (Objects[ID_SPIDER].loaded) + { + for (int i = 0; i < NUM_SPIDERS; i++) + { + SPIDER_STRUCT* spider = &Spiders[i]; + if (spider->on) + { + int x = spider->pos.xPos; + int y = spider->pos.yPos; + int z = spider->pos.zPos; + + spider->pos.xPos += spider->speed * SIN(spider->pos.yRot) >> W2V_SHIFT; + spider->pos.yPos += spider->fallspeed; + spider->pos.zPos += spider->speed * COS(spider->pos.yRot) >> W2V_SHIFT; + spider->fallspeed += GRAVITY; + + int dx = LaraItem->pos.xPos - spider->pos.xPos; + int dy = LaraItem->pos.yPos - spider->pos.yPos; + int dz = LaraItem->pos.zPos - spider->pos.zPos; + + short angle = ATAN(dz, dx) - spider->pos.yRot; + + if (abs(dx) < 85 && abs(dy) < 85 && abs(dz) < 85) + { + LaraItem->hitPoints -= 3; + LaraItem->hitStatus = true; + TriggerBlood(spider->pos.xPos, spider->pos.yPos, spider->pos.zPos, spider->pos.yRot, 1); + } + + if (spider->flags) + { + if (abs(dx) + abs(dz) <= 768) + { + if (spider->speed & 1) + spider->pos.yRot += 512; + else + spider->pos.yRot -= 512; + spider->speed = 48 - (abs(angle) >> 10); + } + else + { + if (spider->speed < (i & 0x1F) + 24) + spider->speed++; + + if (abs(angle) >= 2048) + { + if (angle >= 0) + spider->pos.yRot += 1024; + else + spider->pos.yRot -= 1024; + } + else + { + spider->pos.yRot += 8 * (Wibble - i); + } + } + } + + FLOOR_INFO* floor = GetFloor(spider->pos.xPos, spider->pos.yPos, spider->pos.zPos, &spider->roomNumber); + int height = GetFloorHeight(floor, spider->pos.xPos, spider->pos.yPos, spider->pos.zPos); + + if (height >= spider->pos.yPos - 1280 || height == -32512) + { + if (height >= spider->pos.yPos - 64) + { + if (spider->pos.yPos <= height) + { + if (spider->fallspeed >= 500) + { + spider->on = false; + NextSpider = 0; + } + else + { + spider->pos.xRot = -128 * spider->fallspeed; + } + } + else + { + spider->pos.yPos = height; + spider->fallspeed = 0; + spider->flags = 1; + } + } + else + { + spider->pos.xRot = 14336; + spider->pos.xPos = x; + spider->pos.yPos = y - 8; + spider->pos.zPos = z; + spider->fallspeed = 0; + if (!(GetRandomControl() & 0x1F)) + spider->pos.yRot += -ANGLE(180); + } + } + else + { + if (angle <= 0) + spider->pos.yRot -= ANGLE(90); + else + spider->pos.yRot += ANGLE(90); + spider->pos.xPos = x; + spider->pos.yPos = y; + spider->pos.zPos = z; + spider->fallspeed = 0; + } + + if (spider->pos.yPos < Rooms[spider->roomNumber].maxceiling + 50) + { + spider->fallspeed = 1; + spider->pos.yRot += -32768; + spider->pos.yPos = Rooms[spider->roomNumber].maxceiling + 50; + } + + if (!i && !(GetRandomControl() & 4)) + SoundEffect(SFX_BEETLES, &spider->pos, 0); + } + } + } } \ No newline at end of file diff --git a/TR5Main/Objects/TR5/tr5_rats.cpp b/TR5Main/Objects/TR5/tr5_rats.cpp index 68c8c1090..78069f4cc 100644 --- a/TR5Main/Objects/TR5/tr5_rats.cpp +++ b/TR5Main/Objects/TR5/tr5_rats.cpp @@ -1,74 +1,2 @@ #include "..\newobjects.h" -short GetNextRat() -{ - short ratNum = NextRat; - int i = 0; - RAT_STRUCT* rat = &Rats[NextRat]; - - while (rat->on) - { - if (ratNum == 31) - { - rat = &Rats[0]; - ratNum = 0; - } - else - { - ratNum++; - rat++; - } - - i++; - - if (i >= 32) - return NO_ITEM; - } - - NextRat = (ratNum + 1) & 0x1F; - return ratNum; -} - -void ControlLittleRats(short itemNumber) -{ - ITEM_INFO* item = &Items[itemNumber]; - - if (item->triggerFlags) - { - if (!item->itemFlags[2] || !(GetRandomControl() & 0xF)) - { - item->triggerFlags--; - - if (item->itemFlags[2] && GetRandomControl() & 1) - item->itemFlags[2]--; - - short ratNum = GetNextRat(); - if (ratNum != -1) - { - RAT_STRUCT* rat = &Rats[ratNum]; - - rat->pos.xPos = item->pos.xPos; - rat->pos.yPos = item->pos.yPos; - rat->pos.zPos = item->pos.zPos; - rat->roomNumber = item->roomNumber; - - if (item->itemFlags[0]) - { - rat->pos.yRot = 2 * GetRandomControl(); - rat->fallspeed = -16 - (GetRandomControl() & 0x1F); - } - else - { - rat->fallspeed = 0; - rat->pos.yRot = item->pos.yRot + (GetRandomControl() & 0x3FFF) - ANGLE(45); - } - - rat->pos.xRot = 0; - rat->pos.zRot = 0; - rat->on = 1; - rat->flags = GetRandomControl() & 0x1E; - rat->speed = (GetRandomControl() & 0x1F) + 1; - } - } - } -} \ No newline at end of file diff --git a/TR5Main/Objects/oldobjects.h b/TR5Main/Objects/oldobjects.h index bacb635f2..986053388 100644 --- a/TR5Main/Objects/oldobjects.h +++ b/TR5Main/Objects/oldobjects.h @@ -21,8 +21,8 @@ //#define ControlInvisibleGhost ((void (__cdecl*)(short)) 0x00477AB0) //#define InitialiseLittleBats ((void (__cdecl*)(short)) 0x00407EC0) //#define ControlLittleBats ((void (__cdecl*)(short)) 0x00407F50) -#define InitialiseSpiders ((void (__cdecl*)(short)) 0x0043F2B0) -#define ControlSpiders ((void (__cdecl*)(short)) 0x0047A200) +//#define InitialiseSpiders ((void (__cdecl*)(short)) 0x0043F2B0) +//#define ControlSpiders ((void (__cdecl*)(short)) 0x0047A200) //#define ControlGladiator ((void (__cdecl*)(short)) 0x00436700) //#define ControlRomanStatue ((void (__cdecl*)(short)) 0x0046BC10) //#define ControlAutoGuns ((void (__cdecl*)(short)) 0x004078A0) @@ -30,9 +30,15 @@ //#define InitialiseRomanStatue ((void (__cdecl*)(short)) 0x0046BB00) // need to check a dword_ variable before decompiling -extern int NumBats; +extern int NextBat; extern BAT_STRUCT* Bats; +extern int NextSpider; +extern SPIDER_STRUCT* Spiders; + +extern int NextRat; +extern RAT_STRUCT* Rats; + void InitialiseGuard(short itemNum); void InitialiseGuardM16(short itemNum); void InitialiseGuardLaser(short itemNum); @@ -130,7 +136,7 @@ void ChaffFlareControl(short itemNumber); void TorpedoControl(short itemNumber); void InitialiseLittleBats(short itemNumber); void ControlLittleBats(short itemNumber); -short GetFreeBat(); +short GetNextBat(); void TriggerLittleBat(ITEM_INFO* item); void TriggerCyborgSparks(int x, int y, int z, short xv, short yv, short zv); void ControlCyborg(short itemNumber); @@ -141,4 +147,14 @@ void HydraBubblesAttack(PHD_3DPOS* pos, short roomNumber, int count); void TriggerAutoGunSmoke(PHD_VECTOR* pos, char shade); void ControlAutoGuns(short itemNumber); void TriggerLaserHeadSparks1(PHD_VECTOR* pos, int count, CVECTOR* color, int unk); -void LaserHeadCharge(ITEM_INFO* item); \ No newline at end of file +void LaserHeadCharge(ITEM_INFO* item); +short GetNextSpider(); +void ControlSpiders(short itemNumber); +void InitialiseSpiders(short itemNumber); +void ClearSpidersPatch(ITEM_INFO* item); +void ClearSpiders(); +void InitialiseLittleRats(short itemNumber); +void ClearRats(); +void UpdateSpiders(); +void UpdateRats(); +void UpdateBats(); \ No newline at end of file