diff --git a/TR5Main/Game/laramisc.h b/TR5Main/Game/laramisc.h
index 836ed635c..db58819c4 100644
--- a/TR5Main/Game/laramisc.h
+++ b/TR5Main/Game/laramisc.h
@@ -4,6 +4,8 @@
extern COLL_INFO coll;
#define GetLaraDeadlyBounds ((void (__cdecl*)()) 0x004569C0)
+#define phd_SetTrans ((void (__cdecl*)(int, int, int)) 0x0048FA40)
+#define phd_RotBoundingBoxNoPersp ((void (__cdecl*)(short*, short*)) 0x0042E240)
//void GetLaraDeadlyBounds();
void DelAlignLaraToRope(ITEM_INFO* item);
diff --git a/TR5Main/Game/tomb4fx.h b/TR5Main/Game/tomb4fx.h
index 69621a950..73c36dea8 100644
--- a/TR5Main/Game/tomb4fx.h
+++ b/TR5Main/Game/tomb4fx.h
@@ -2,6 +2,24 @@
#include "..\Global\types.h"
#include "..\Global\constants.h"
+struct ENERGY_ARC
+{
+ PHD_VECTOR pos1; // 0
+ PHD_VECTOR pos2; // 12
+ PHD_VECTOR pos3; // 24
+ PHD_VECTOR pos4; // 36
+ byte r; // 48
+ byte g; // 49
+ byte b; // 50
+ byte on; // 51
+ byte byte34; // 52
+ byte gap35[8]; // 53
+ byte byte3D; // 61
+ byte flags; // 62
+ byte byte3F; // 63
+ byte byte40; // 64
+};
+
extern int LaserSightX;
extern int LaserSightY;
extern int LaserSightZ;
diff --git a/TR5Main/Game/traps.cpp b/TR5Main/Game/traps.cpp
index 43b5be906..c941ef975 100644
--- a/TR5Main/Game/traps.cpp
+++ b/TR5Main/Game/traps.cpp
@@ -6,6 +6,7 @@
#include "effects.h"
#include "lara.h"
#include "collide.h"
+#include "switch.h"
static short CeilingTrapDoorBounds[12] = {-256, 256, 0, 900, -768, -256, -1820, 1820, -5460, 5460, -1820, 1820};
static PHD_VECTOR CeilingTrapDoorPos = {0, 1056, -480};
@@ -659,3 +660,218 @@ void _WreckingBallControl(short itemNumber)
}
}
+
+void FlameEmitterCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
+{
+ ITEM_INFO* item = &Items[itemNumber];
+
+ if (Lara.gunType != WEAPON_TORCH
+ || Lara.gunStatus != LG_READY
+ || Lara.leftArm.lock
+ || Lara.litTorch == (item->status & 1)
+ || item->timer == -1
+ || !(TrInput & IN_ACTION)
+ || l->currentAnimState != STATE_LARA_STOP
+ || l->animNumber != ANIMATION_LARA_STAY_IDLE
+ || l->gravityStatus)
+ {
+ if (item->objectNumber == ID_BURNING_ROOTS)
+ ObjectCollision(itemNumber, l, coll);
+ }
+ else
+ {
+ short bounds[6];
+
+ switch (item->objectNumber)
+ {
+ case ID_FLAME_EMITTER:
+ bounds[0] = -256;
+ bounds[1] = 256;
+ bounds[2] = 0;
+ bounds[3] = 1024;
+ bounds[4] = -800;
+ bounds[5] = 800;
+ break;
+
+ case ID_FLAME_EMITTER2:
+ bounds[0] = -256;
+ bounds[1] = 256;
+ bounds[2] = 0;
+ bounds[3] = 1024;
+ bounds[4] = -600;
+ bounds[5] = 600;
+ break;
+
+ case ID_BURNING_ROOTS:
+ bounds[0] = -384;
+ bounds[1] = 384;
+ bounds[2] = 0;
+ bounds[3] = 2048;
+ bounds[4] = -384;
+ bounds[5] = 384;
+ break;
+
+ }
+
+ short oldYrot = item->pos.yRot;
+ item->pos.yRot = l->pos.yRot;
+
+ if (TestLaraPosition(bounds, item, l))
+ {
+ if (item->objectNumber == ID_BURNING_ROOTS)
+ {
+ l->animNumber = ANIMATION_LARA_TORCH_LIGHT_5;
+ }
+ else
+ {
+ int dy = abs(l->pos.yPos - item->pos.yPos);
+ l->itemFlags[3] = 1;
+ l->animNumber = (dy >> 8) + ANIMATION_LARA_TORCH_LIGHT_1;
+ }
+
+ l->currentAnimState = STATE_LARA_MISC_CONTROL;
+ l->frameNumber = Anims[l->animNumber].frameBase;
+ Lara.flareControlLeft = false;
+ Lara.leftArm.lock = 3;
+ Lara.generalPtr = (void*)itemNumber;
+ }
+
+ item->pos.yRot = oldYrot;
+ }
+
+ if (Lara.generalPtr == (void*)itemNumber
+ && item->status != ITEM_ACTIVE
+ && l->currentAnimState == STATE_LARA_MISC_CONTROL)
+ {
+ if (l->animNumber >= ANIMATION_LARA_TORCH_LIGHT_1 && l->animNumber <= ANIMATION_LARA_TORCH_LIGHT_5)
+ {
+ if (l->frameNumber - Anims[l->animNumber].frameBase == 40)
+ {
+ TestTriggersAtXYZ(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 1, item->flags & 0x3E00);
+
+ item->flags |= 0x3E00;
+ item->itemFlags[3] = 0;
+ item->status = ITEM_ACTIVE;
+
+ AddActiveItem(itemNumber);
+ }
+ }
+ }
+}
+
+void InitialiseFlameEmitter2(short itemNumber)
+{
+ ITEM_INFO* item = &Items[itemNumber];
+
+ item->pos.yPos -= 64;
+
+ if (item->triggerFlags != 123)
+ {
+ if (item->pos.yRot > 0)
+ {
+ if (item->pos.yRot == ANGLE(90))
+ {
+ if (item->triggerFlags == 2)
+ item->pos.xPos += 80;
+ else
+ item->pos.xPos += 256;
+ }
+ }
+ else if (item->pos.yRot < 0)
+ {
+ if (item->pos.yRot == -ANGLE(180))
+ {
+ if (item->triggerFlags == 2)
+ item->pos.zPos -= 80;
+ else
+ item->pos.zPos -= 256;
+ }
+ else if (item->pos.yRot == -ANGLE(90))
+ {
+ if (item->triggerFlags == 2)
+ item->pos.xPos -= 80;
+ else
+ item->pos.xPos -= 256;
+ }
+ }
+ else
+ {
+ if (item->triggerFlags == 2)
+ item->pos.zPos += 80;
+ else
+ item->pos.zPos += 256;
+ }
+ }
+}
+
+void InitialiseFlameEmitter(short itemNumber)
+{
+ ITEM_INFO* item = &Items[itemNumber];
+
+ if (item->triggerFlags > 0)
+ {
+ if (item->triggerFlags == 33)
+ {
+ if (item->pos.yRot > 0)
+ {
+ if (item->pos.yRot == ANGLE(90))
+ item->pos.xPos += 144;
+ }
+ else
+ {
+ if (item->pos.yRot == 0)
+ {
+ item->pos.zPos += 144;
+ item->pos.yPos += 32;
+ return;
+ }
+ else if (item->pos.yRot == -ANGLE(180))
+ {
+ item->pos.zPos -= 144;
+ item->pos.yPos += 32;
+ return;
+ }
+ else if (item->pos.yRot == -ANGLE(90))
+ {
+ item->pos.xPos -= 144;
+ item->pos.yPos += 32;
+ return;
+ }
+ }
+
+ item->pos.yPos += 32;
+ return;
+ }
+ }
+ else
+ {
+ item->itemFlags[0] = (GetRandomControl() & 0x3F) + 90;
+ item->itemFlags[2] = 256;
+
+ if (((-item->triggerFlags) & 7) == 7)
+ {
+ if (item->pos.yRot > 0)
+ {
+ if (item->pos.yRot == ANGLE(90))
+ {
+ item->pos.xPos += 512;
+ }
+ }
+ else if (item->pos.yRot < 0)
+ {
+ if (item->pos.yRot == -ANGLE(180))
+ {
+ item->pos.zPos -= 512;
+ }
+ else if (item->pos.yRot == -ANGLE(90))
+ {
+ item->pos.xPos -= 512;
+ }
+ }
+ else
+ {
+ item->pos.zPos += 512;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/TR5Main/Game/traps.h b/TR5Main/Game/traps.h
index 905a81a19..2dfb9ef85 100644
--- a/TR5Main/Game/traps.h
+++ b/TR5Main/Game/traps.h
@@ -13,9 +13,9 @@
//#define TwoBlocksPlatformControl ((void (__cdecl*)(short)) 0x0048BBB0)
//#define TwoBlocksPlatformFloor ((void (__cdecl*)(ITEM_INFO*,int,int,int,int*)) 0x0048B9E0)
//#define TwoBlocksPlatformCeiling ((void (__cdecl*)(ITEM_INFO*,int,int,int,int*)) 0x0048BA50)
-#define KillAllTriggersControl ((void (__cdecl*)(short)) 0x00431030)
-#define FallingCeilingCollision ((void (__cdecl*)(short,ITEM_INFO*,COLL_INFO*)) 0x004127C0)
-#define FallingCeilingControl ((void (__cdecl*)(short)) 0x004899D0)
+//#define KillAllTriggersControl ((void (__cdecl*)(short)) 0x00431030)
+//#define FallingCeilingCollision ((void (__cdecl*)(short,ITEM_INFO*,COLL_INFO*)) 0x004127C0)
+//#define FallingCeilingControl ((void (__cdecl*)(short)) 0x004899D0)
//#define InitialiseFallingBlock ((void (__cdecl*)(short)) 0x0043D330)
//#define FallingBlockCollision ((void (__cdecl*)(short,ITEM_INFO*,COLL_INFO*)) 0x00489750)
//#define FallingBlockControl ((void (__cdecl*)(short)) 0x00489820)
@@ -24,23 +24,23 @@
//#define InitialisePushableBlock ((void (__cdecl*)(short)) 0x0045E720)
//#define PushableBlockControl ((void (__cdecl*)(short)) 0x0045EA30)
//#define PushableBlockCollision ((void (__cdecl*)(short,ITEM_INFO*,COLL_INFO*)) 0x0045F570)
-#define DartEmitterControl ((void (__cdecl*)(short)) 0x00489B30)
+//#define DartEmitterControl ((void (__cdecl*)(short)) 0x00489B30)
#define DrawDart ((void (__cdecl*)(ITEM_INFO*)) 0x004CBB10)
-#define DartControl ((void (__cdecl*)(short)) 0x00489D60)
-#define InitialiseFlameEmitter ((void (__cdecl*)(short)) 0x0043D370)
-#define FlameEmitterCollision ((void (__cdecl*)(short,ITEM_INFO*,COLL_INFO*)) 0x00433B40)
+//#define DartControl ((void (__cdecl*)(short)) 0x00489D60)
+//#define InitialiseFlameEmitter ((void (__cdecl*)(short)) 0x0043D370)
+//#define FlameEmitterCollision ((void (__cdecl*)(short,ITEM_INFO*,COLL_INFO*)) 0x00433B40)
//#define FlameEmitterControl ((void (__cdecl*)(short)) 0x00489F70)
-#define InitialiseFlameEmitter2 ((void (__cdecl*)(short)) 0x0043D4E0)
+//#define InitialiseFlameEmitter2 ((void (__cdecl*)(short)) 0x0043D4E0)
//#define FlameEmitter2Control ((void (__cdecl*)(short)) 0x0048A3B0)
#define FlameEmitter3Control ((void (__cdecl*)(short)) 0x0048A570)
//#define FlameControl ((void (__cdecl*)(short)) 0x0048AB80)
#define InitialiseRopeTrap ((void (__cdecl*)()) 0x0046EE40)
-#define GenSlot1Control ((void (__cdecl*)(short)) 0x00406580)
+//#define GenSlot1Control ((void (__cdecl*)(short)) 0x00406580)
#define InitialiseGenSlot2 ((void (__cdecl*)(short)) 0x0043FD70)
#define GenSlot2Control ((void (__cdecl*)(short)) 0x00488710)
#define DrawGenSlot2 ((void (__cdecl*)(ITEM_INFO*)) 0x004CFF80)
-#define InitialiseGenSlot3 ((void (__cdecl*)(short)) 0x004402E0)
-#define InitialiseGenSlot4 ((void (__cdecl*)(short)) 0x00440440)
+//#define InitialiseGenSlot3 ((void (__cdecl*)(short)) 0x004402E0)
+//#define InitialiseGenSlot4 ((void (__cdecl*)(short)) 0x00440440)
#define GenSlot4Control ((void (__cdecl*)(short)) 0x00486450)
//#define InitialiseHighObject1 ((void (__cdecl*)(short)) 0x0043FC30)
//#define HighObject1Control ((void (__cdecl*)(short)) 0x004067E0)
@@ -51,8 +51,8 @@
//#define WreckingBallCollision ((void (__cdecl*)(short,ITEM_INFO*,COLL_INFO*)) 0x00441D50)
#define WreckingBallControl ((void (__cdecl*)(short)) 0x00441410)
#define DrawWreckingBall ((void (__cdecl*)(ITEM_INFO*)) 0x00441F50)
-#define InitialiseVentilator ((void (__cdecl*)(short)) 0x0043F3D0)
-#define VentilatorControl ((void (__cdecl*)(short)) 0x00405610)
+//#define InitialiseVentilator ((void (__cdecl*)(short)) 0x0043F3D0)
+//#define VentilatorControl ((void (__cdecl*)(short)) 0x00405610)
//#define InitialiseTeethSpike ((void (__cdecl*)(short)) 0x0043FBC0)
//#define TeethSpikeControl ((void (__cdecl*)(short)) 0x0043FBC0)
//#define DrawScaledSpike ((void (__cdecl*)(ITEM_INFO*)) 0x0043FBC0)
@@ -77,3 +77,6 @@ void FallingBlockCeiling(ITEM_INFO* item, int x, int y, int z, int* height);
void InitialiseWreckingBall(short itemNumber);
void WreckingBallCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll);
void _WreckingBallControl(short itemNumber);
+void FlameEmitterCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll);
+void InitialiseFlameEmitter2(short itemNumber);
+void InitialiseFlameEmitter(short itemNumber);
\ No newline at end of file
diff --git a/TR5Main/Objects/TR5/tr5_misc_objects.cpp b/TR5Main/Objects/TR5/tr5_misc_objects.cpp
index 5c3e0bc9e..06bf4c833 100644
--- a/TR5Main/Objects/TR5/tr5_misc_objects.cpp
+++ b/TR5Main/Objects/TR5/tr5_misc_objects.cpp
@@ -1213,4 +1213,99 @@ void ControlHighObject1(short itemNumber)
targetItem->flags |= 0x20;
targetItem->pos.yPos = item->pos.yPos - 560;
}
+}
+
+void GenSlot1Control(short itemNumber)
+{
+ ITEM_INFO* item = &Items[itemNumber];
+
+ if (TriggerActive(item) && !item->triggerFlags)
+ {
+ int df = item->frameNumber - Anims[item->animNumber].frameBase;
+
+ if (df == 10 || df == 11)
+ {
+ GetLaraDeadlyBounds();
+
+ DeadlyBounds[0] -= 350;
+ DeadlyBounds[1] += 350;
+ DeadlyBounds[4] -= 350;
+ DeadlyBounds[5] += 350;
+
+ bool found = false;
+ for (int i = 0; i < 6; i++)
+ {
+ PHD_VECTOR pos;
+ pos.x = 0;
+ pos.y = -350;
+ pos.z = 0;
+
+ GetJointAbsPosition(item, &pos, i + 1);
+
+ if (pos.x > DeadlyBounds[0]
+ && pos.x < DeadlyBounds[1]
+ && pos.y > DeadlyBounds[2]
+ && pos.y < DeadlyBounds[3]
+ && pos.z > DeadlyBounds[4]
+ && pos.z < DeadlyBounds[5])
+ {
+ found = true;
+ }
+ }
+
+ if (found)
+ {
+ for (int i = 0; i < 8; i++)
+ {
+ PHD_VECTOR pos;
+ pos.x = 0;
+ pos.y = 0;
+ pos.z = 0;
+
+ GetLaraJointPosition(&pos, i + 7);
+
+ int x = pos.x + (GetRandomControl() & 0xFF) - 128;
+ int y = pos.y + (GetRandomControl() & 0xFF) - 128;
+ int z = pos.z + (GetRandomControl() & 0xFF) - 128;
+
+ DoBloodSplat(x, y, z, 1, -1, LaraItem->roomNumber);
+ }
+
+ LaraItem->hitPoints = 0;
+ }
+ }
+
+ AnimateItem(item);
+ }
+}
+
+void InitialiseGenSlot3(short itemNumber)
+{
+ ITEM_INFO* item = &Items[itemNumber];
+ if (CurrentLevel != 7)
+ item->meshBits = item->triggerFlags;
+}
+
+void InitialiseGenSlot4(short itemNumber)
+{
+ /*ITEM_INFO* item = &Items[itemNumber];
+
+ HIWORD(v1) = HIWORD(items);
+ item = &items[itemNumber];
+ LOWORD(v1) = item->pos.y_rot;
+ v3 = item->pos.x_pos;
+ v4 = 2 * ((v1 >> 3) & 0x1FFE);
+ v5 = 5 * *(__int16*)((char*)rcossin_tbl + v4);
+ v6 = item->pos.z_pos;
+ v7 = v6 + (10240 * *(__int16*)((char*)& rcossin_tbl[1] + v4) >> 14);
+ item->item_flags[2] = 1;
+ BYTE1(v4) = v6 >> 9;
+ LOBYTE(v4) = v3 >> 9;
+ item->item_flags[0] = v4;
+ LOBYTE(v6) = (item->pos.xPos + (v5 << 11 >> 14)) >> 9;
+ BYTE1(v6) = v7 >> 9;
+
+ item->itemFlags[1] = item->pos.xPos + 2560 * SIN(item->pos.yRot) >> W2V_SHIFT;
+ item->itemFlags[3] = 0;
+ item->triggerFlags = 0;*/
}
\ No newline at end of file
diff --git a/TR5Main/Objects/TR5/tr5_romanstatue.cpp b/TR5Main/Objects/TR5/tr5_romanstatue.cpp
index 6d6181fbe..507fad3da 100644
--- a/TR5Main/Objects/TR5/tr5_romanstatue.cpp
+++ b/TR5Main/Objects/TR5/tr5_romanstatue.cpp
@@ -26,24 +26,6 @@
#define ANIMATION_ROMAN_STATUE_DEATH 14
#define ANIMATION_ROMAN_STATUE_START_JUMP_DOWN 16
-struct ENERGY_ARC
-{
- PHD_VECTOR pos1; // 0
- PHD_VECTOR pos2; // 12
- PHD_VECTOR pos3; // 24
- PHD_VECTOR pos4; // 36
- byte r; // 48
- byte g; // 49
- byte b; // 50
- byte on; // 51
- byte byte34; // 52
- byte gap35[8]; // 53
- byte byte3D; // 61
- byte flags; // 62
- byte byte3F; // 63
- byte byte40; // 64
-};
-
struct ROMAN_STATUE_STRUCT
{
PHD_VECTOR pos;
diff --git a/TR5Main/Objects/TR5/tr5_traps.cpp b/TR5Main/Objects/TR5/tr5_traps.cpp
index 7daae23b4..f34efb048 100644
--- a/TR5Main/Objects/TR5/tr5_traps.cpp
+++ b/TR5Main/Objects/TR5/tr5_traps.cpp
@@ -655,4 +655,489 @@ void InitialiseRomeHammer(short itemNumber)
item->itemFlags[0] = 2;
item->itemFlags[3] = 250;
+}
+
+void VentilatorEffect(short* bounds, int intensity, short rot, int speed)
+{
+ int x, y, z;
+
+ if (abs(intensity) == 1)
+ {
+ x = (bounds[0]+bounds[1]) >> 1;
+ if (intensity >= 0)
+ y = bounds[3];
+ else
+ y = bounds[2];
+ z = (bounds[4] + bounds[5]) >> 1;
+ }
+ else
+ {
+ y = (bounds[2]+bounds[3]) >> 1;
+ if (rot & 0x7FFF)
+ {
+ if (intensity >= 0)
+ z = bounds[5];
+ else
+ z = bounds[4];
+ x = (bounds[0]+bounds[1]) >> 1;
+ }
+ else
+ {
+ if (intensity >= 0)
+ x = bounds[1];
+ else
+ x = bounds[0];
+ z = (bounds[4] + bounds[5]) >> 1;
+ }
+ }
+
+ if (abs(Camera.pos.x-x) <= 7168)
+ {
+ if (abs(Camera.pos.y-y) <= 7168)
+ {
+ if (abs(Camera.pos.z-z) <= 7168)
+ {
+ SPARKS* spark = &Sparks[GetFreeSpark()];
+
+ spark->on = 1;
+ spark->sR = 0;
+ spark->sG = 0;
+ spark->sB = 0;
+ spark->dR = spark->dG = 48 * speed >> 7;
+ spark->colFadeSpeed = 4;
+ spark->fadeToBlack = 8;
+ spark->dB = speed * ((GetRandomControl() & 8) + 48) >> 7;
+ spark->transType = COLADD;
+ spark->life = spark->sLife = (GetRandomControl() & 3) + 20;
+
+ if (abs(intensity) == 1)
+ {
+ int factor = 3 * (bounds[1]-bounds[0]) >> 3;
+ short angle = 2 * GetRandomControl();
+
+ spark->x = ((bounds[0] + bounds[1]) >> 1) + ((GetRandomControl() % factor) * SIN(angle) >> W2V_SHIFT);
+ spark->z = ((bounds[4] + bounds[5]) >> 1) + ((GetRandomControl() % factor) * COS(angle) >> W2V_SHIFT);
+
+ if (intensity >= 0)
+ spark->y = bounds[3];
+ else
+ spark->y = bounds[2];
+
+ spark->zVel = 0;
+ spark->xVel = 0;
+ spark->yVel = 32 * intensity * ((GetRandomControl() & 0x1F) + 224);
+ }
+ else
+ {
+ int factor = 3 * (bounds[3] - bounds[2]) >> 3;
+ short angle = 2 * GetRandomControl();
+
+ spark->y = (bounds[2] + bounds[3]) >> 1;
+
+ if (rot & 0x7FFF)
+ {
+ if (intensity >= 0)
+ spark->z = bounds[5];
+ else
+ spark->z = bounds[4];
+
+ spark->x = ((bounds[0] + bounds[1]) >> 1) + ((GetRandomControl() % factor) * COS(angle) >> W2V_SHIFT);
+ spark->y += (GetRandomControl() % factor) * SIN(angle) >> W2V_SHIFT;
+ spark->xVel = 0;
+ spark->zVel = 16 * intensity * ((GetRandomControl() & 0x1F) + 224);
+ }
+ else
+ {
+ if (intensity >= 0)
+ spark->x = bounds[1];
+ else
+ spark->x = bounds[0];
+
+ spark->y += (GetRandomControl() % factor) * SIN(angle) >> W2V_SHIFT;
+ spark->z = ((bounds[4] + bounds[5]) >> 1) + ((GetRandomControl() % factor) * COS(angle) >> W2V_SHIFT);
+ spark->zVel = 0;
+ spark->xVel = 16 * intensity * ((GetRandomControl() & 0x1F) + 224);
+ }
+
+ spark->yVel = 0;
+ }
+
+ spark->friction = 85;
+ spark->xVel = speed * spark->xVel >> 7;
+ spark->yVel = speed * spark->yVel >> 7;
+ spark->zVel = speed * spark->zVel >> 7;
+ spark->maxYvel = 0;
+ spark->gravity = 0;
+ spark->flags = 0;
+ }
+ }
+ }
+}
+
+void InitialiseVentilator(short itemNumber)
+{
+ ITEM_INFO* item = &Items[itemNumber];
+
+ item->itemFlags[0] = item->triggerFlags << WALL_SHIFT;
+ if (item->itemFlags[0] < 2048)
+ item->itemFlags[0] = 3072;
+}
+
+void VentilatorControl(short itemNumber)
+{
+ ITEM_INFO* item = &Items[itemNumber];
+
+ AnimateItem(item);
+
+ int xChange = 0;
+ int zChange = 0;
+
+ if (TriggerActive(item))
+ {
+ xChange = 1;
+ }
+ else
+ {
+ xChange = 1;
+ TestTriggersAtXYZ(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 1, 0);
+ if (item->currentAnimState == 1)
+ {
+ //result = 5 * item->animNumber;
+ if (item->frameNumber == Anims[item->animNumber].frameEnd)
+ return;
+ }
+ else
+ {
+ item->goalAnimState = 1;
+ }
+ }
+
+ int speed = 0;
+ if (item->currentAnimState == 1)
+ {
+ speed = Anims[item->animNumber].frameEnd - item->frameNumber;
+ }
+ else
+ {
+ speed = 128;
+ }
+
+ short* bounds = GetBoundsAccurate(item);
+ short effectBounds[6];
+
+ effectBounds[2] = item->pos.yPos + bounds[2];
+ effectBounds[3] = item->pos.yPos + bounds[3];
+
+ if (item->objectNumber != ID_PROPELLER_V) // TODO: check this ID
+ {
+ if (item->pos.yRot != -ANGLE(180))
+ {
+ if (item->pos.yRot == -ANGLE(90))
+ {
+ effectBounds[0] = item->pos.xPos - bounds[5];
+ effectBounds[1] = item->pos.xPos - bounds[4];
+ effectBounds[4] = item->pos.zPos + bounds[0];
+ effectBounds[5] = item->pos.zPos + bounds[1];
+ xChange = 0;
+ zChange = 1;
+ }
+ else
+ {
+ if (item->pos.yRot != ANGLE(90))
+ {
+ effectBounds[0] = item->pos.xPos + bounds[0];
+ effectBounds[1] = item->pos.xPos + bounds[1];
+ effectBounds[4] = item->pos.zPos + bounds[4];
+ effectBounds[5] = item->pos.zPos + bounds[5];
+ zChange = 0;
+ }
+ else
+ {
+ effectBounds[0] = item->pos.xPos + bounds[4];
+ effectBounds[1] = item->pos.xPos + bounds[5];
+ effectBounds[4] = item->pos.zPos - bounds[1];
+ effectBounds[5] = item->pos.zPos - bounds[0];
+ xChange = 0;
+ zChange = 1;
+ }
+ }
+ }
+ else
+ {
+ effectBounds[0] = item->pos.xPos - bounds[1];
+ effectBounds[1] = item->pos.xPos - bounds[0];
+ effectBounds[4] = item->pos.zPos - bounds[5];
+ effectBounds[5] = item->pos.zPos - bounds[4];
+ zChange = 0;
+ }
+
+ VentilatorEffect(effectBounds, 2, item->pos.yRot, speed);
+ VentilatorEffect(effectBounds, -2, item->pos.yRot, speed);
+
+ if (LaraItem->pos.yPos >= effectBounds[2] && LaraItem->pos.yPos <= effectBounds[3])
+ {
+ if (zChange)
+ {
+ if (LaraItem->pos.xPos >= effectBounds[0] && LaraItem->pos.xPos <= effectBounds[1])
+ {
+ int z1 = abs(LaraItem->pos.zPos - effectBounds[4]);
+ int z2 = abs(LaraItem->pos.zPos - effectBounds[5]);
+
+ if (z2 >= z1)
+ zChange = -zChange;
+ else
+ z1 = z2;
+
+ if (z1 < item->itemFlags[0])
+ {
+ int dz = 96 * zChange * (item->itemFlags[0] - z1) / item->itemFlags[0];
+ if (item->currentAnimState == 1)
+ dz = speed * dz / 120;
+ LaraItem->pos.zPos += dz;
+ }
+ }
+ }
+ else
+ {
+ if (LaraItem->pos.zPos >= effectBounds[4] && LaraItem->pos.zPos <= effectBounds[5])
+ {
+ int x1 = abs(LaraItem->pos.xPos - effectBounds[0]);
+ int x2 = abs(LaraItem->pos.xPos - effectBounds[0]);
+
+ if (x2 >= x1)
+ xChange = -xChange;
+ else
+ x1 = x2;
+
+ if (x1 < item->itemFlags[0])
+ {
+ int dx = 96 * xChange * (item->itemFlags[0] - x1) / item->itemFlags[0];
+ if (item->currentAnimState == 1)
+ dx = speed * dx / 120;
+ LaraItem->pos.xPos += dx;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ phd_PushUnitMatrix();
+ phd_RotYXZ(item->pos.yRot, item->pos.xRot, item->pos.zRot);
+ phd_SetTrans(0, 0, 0);
+ short tbounds[6];
+ phd_RotBoundingBoxNoPersp(bounds, tbounds);
+ phd_PopMatrix();
+
+ effectBounds[0] = item->pos.xPos + tbounds[0];
+ effectBounds[1] = item->pos.xPos + tbounds[1];
+ effectBounds[4] = item->pos.zPos + tbounds[4];
+ effectBounds[5] = item->pos.zPos + tbounds[5];
+
+ VentilatorEffect(effectBounds, 1, 0, speed);
+ VentilatorEffect(effectBounds, -1, 0, speed);
+
+ if (LaraItem->pos.xPos >= effectBounds[0] && LaraItem->pos.xPos <= effectBounds[1])
+ {
+ if (LaraItem->pos.zPos >= effectBounds[4] && LaraItem->pos.zPos <= effectBounds[5])
+ {
+ int y = effectBounds[3];
+
+ if (LaraItem->pos.yPos <= effectBounds[3])
+ {
+ if (effectBounds[2] - LaraItem->pos.yPos >= item->itemFlags[0])
+ return;
+ y = 96 * (effectBounds[3] - item->itemFlags[0]) / item->itemFlags[0];
+ }
+ else
+ {
+ if (LaraItem->pos.yPos - effectBounds[3] >= item->itemFlags[0])
+ return;
+ y = 96 * (item->itemFlags[0] - (LaraItem->pos.yPos - effectBounds[3])) / item->itemFlags[0];
+ }
+ if (item->currentAnimState == 1)
+ y = speed * y / 120;
+ LaraItem->pos.yPos += y;
+ }
+ }
+ }
+}
+
+void DartControl(short itemNumber)
+{
+ ITEM_INFO* item = &Items[itemNumber];
+
+ if (item->touchBits)
+ {
+ LaraItem->hitPoints -= 25;
+ LaraItem->hitStatus = true;
+ Lara.poisoned += 160;
+ DoBloodSplat(item->pos.xPos, item->pos.yPos, item->pos.zPos, (GetRandomControl() & 3) + 4, LaraItem->pos.yRot, LaraItem->roomNumber);
+ KillItem(itemNumber);
+ }
+ else
+ {
+ item->pos.xPos += item->speed * SIN(item->pos.yRot) >> W2V_SHIFT;
+ item->pos.yPos -= item->speed * SIN(item->pos.xRot) >> W2V_SHIFT;
+ item->pos.xPos += item->speed * COS(item->pos.yRot) >> W2V_SHIFT;
+
+ short roomNumber = item->roomNumber;
+ FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
+
+ if (item->roomNumber != roomNumber)
+ ItemNewRoom(itemNumber, roomNumber);
+
+ int height = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
+ item->floor = height;
+
+ if (item->pos.yPos >= height)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ TriggerDartSmoke(item->pos.xPos, item->pos.yPos, item->pos.zPos, 0, 0, 1);
+ }
+
+ KillItem(itemNumber);
+ }
+ }
+}
+
+void DartEmitterControl(short itemNumber)
+{
+ ITEM_INFO* item = &Items[itemNumber];
+
+ if (item->active)
+ {
+ if (item->timer > 0)
+ {
+ item->timer--;
+ return;
+ }
+ else
+ {
+ item->timer = 24;
+ }
+ }
+
+ short dartItemNumber = CreateItem();
+
+ if (dartItemNumber != NO_ITEM)
+ {
+ ITEM_INFO* dartItem = &Items[dartItemNumber];
+
+ dartItem->objectNumber = ID_DARTS;
+ dartItem->roomNumber = item->roomNumber;
+
+ int x = 0;
+ int z = 0;
+
+ if (item->pos.yRot > 0)
+ {
+ if (item->pos.yRot == ANGLE(90))
+ x = 512;
+ }
+ else if (item->pos.yRot < 0)
+ {
+ if (item->pos.yRot == -ANGLE(180))
+ {
+ z = -512;
+ }
+ else if (item->pos.yRot == -ANGLE(90))
+ {
+ x = -512;
+ }
+ }
+ else
+ {
+ z = 512;
+ }
+
+ dartItem->pos.xPos = x + item->pos.xPos;
+ dartItem->pos.yPos = item->pos.yPos - 512;
+ dartItem->pos.zPos = z + item->pos.zPos;
+
+ InitialiseItem(dartItemNumber);
+
+ dartItem->pos.xRot = 0;
+ dartItem->pos.yRot = item->pos.yRot + -ANGLE(180);
+ dartItem->speed = 256;
+
+ int xf = 0;
+ int zf = 0;
+
+ if (x)
+ xf = abs(2 * x) - 1;
+ else
+ zf = abs(2 * z) - 1;
+
+ for (int i = 0; i < 5; i++)
+ {
+ int random = -GetRandomControl();
+
+ int xv = 0;
+ int zv = 0;
+
+ if (z >= 0)
+ zv = zf & random;
+ else
+ zv = -(zf & random);
+
+ if (x >= 0)
+ xv = xf & random;
+ else
+ xv = -(xf & random);
+
+ TriggerDartSmoke(dartItem->pos.xPos, dartItem->pos.yPos, dartItem->pos.zPos, xv, zv, 0);
+ }
+
+ AddActiveItem(dartItemNumber);
+ dartItem->status = ITEM_ACTIVE;
+ SoundEffect(SFX_LIFT_DOORS, &dartItem->pos, 0);
+ }
+}
+
+void FallingCeilingControl(short itemNumber)
+{
+ ITEM_INFO* item = &Items[itemNumber];
+
+ if (item->currentAnimState)
+ {
+ if (item->currentAnimState == 1 && item->touchBits)
+ {
+ LaraItem->hitPoints -= 300;
+ LaraItem->hitStatus = true;
+ }
+ }
+ else
+ {
+ item->goalAnimState = 1;
+ item->gravityStatus = true;;
+ }
+
+ AnimateItem(item);
+
+ if (item->status == ITEM_DEACTIVATED)
+ {
+ RemoveActiveItem(itemNumber);
+ }
+ else
+ {
+ short roomNumber = item->roomNumber;
+ FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
+ item->floor = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
+
+ if (roomNumber != item->roomNumber)
+ ItemNewRoom(itemNumber, roomNumber);
+
+ if (item->currentAnimState == 1)
+ {
+ if (item->pos.yPos >= item->floor)
+ {
+ item->pos.yPos = item->floor;
+ item->gravityStatus = false;
+ item->goalAnimState = 2;
+ item->fallspeed = 0;
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/TR5Main/Objects/oldobjects.h b/TR5Main/Objects/oldobjects.h
index 8f161b101..ac2598f5f 100644
--- a/TR5Main/Objects/oldobjects.h
+++ b/TR5Main/Objects/oldobjects.h
@@ -105,3 +105,11 @@ void InitialiseTeleporter(short itemNumber);
void ControlTeleporter(short itemNumber);
void InitialiseHighObject1(short itemNumber);
void ControlHighObject1(short itemNumber);
+void VentilatorEffect(short* bounds, int intensity, short rot, int speed);
+void InitialiseVentilator(short itemNumber);
+void VentilatorControl(short itemNumber);
+void GenSlot1Control(short itemNumber);
+void InitialiseGenSlot3(short itemNumber);
+void DartControl(short itemNumber);
+void DartEmitterControl(short itemNumber);
+void FallingCeilingControl(short itemNumber);
diff --git a/TR5Main/Specific/setup.cpp b/TR5Main/Specific/setup.cpp
index 909243c68..79b0c5608 100644
--- a/TR5Main/Specific/setup.cpp
+++ b/TR5Main/Specific/setup.cpp
@@ -3049,7 +3049,7 @@ void TrapObjects()
obj = &Objects[ID_KILL_ALL_TRIGGERS];
if (obj->loaded)
{
- obj->control = KillAllTriggersControl;
+ obj->control = KillAllCurrentItems;
obj->drawRoutine = NULL;
obj->hitPoints = 0;
obj->saveFlags = true;
@@ -3059,7 +3059,7 @@ void TrapObjects()
obj = &Objects[ID_FALLING_CEILING];
if (obj->loaded)
{
- obj->collision = FallingCeilingCollision;
+ obj->collision = TrapCollision;
obj->control = FallingCeilingControl;
obj->saveAnim = true;
obj->saveFlags = true;
@@ -3189,7 +3189,7 @@ void TrapObjects()
obj = &Objects[ID_GEN_SLOT4];
if (obj->loaded)
{
- obj->initialise = InitialiseGenSlot4;
+ //obj->initialise = InitialiseGenSlot4;
obj->control = GenSlot4Control;
obj->saveAnim = true;
obj->saveFlags = true;
diff --git a/TR5Main/TR5Main.vcxproj b/TR5Main/TR5Main.vcxproj
index 1ebacddb1..0a9d94887 100644
--- a/TR5Main/TR5Main.vcxproj
+++ b/TR5Main/TR5Main.vcxproj
@@ -244,6 +244,7 @@ xcopy /Y "$(ProjectDir)Scripting\Scripts\*.lua" "$(TargetDir)\Scripts"
+
diff --git a/TR5Main/TR5Main.vcxproj.filters b/TR5Main/TR5Main.vcxproj.filters
index c62f1023e..9882ebe32 100644
--- a/TR5Main/TR5Main.vcxproj.filters
+++ b/TR5Main/TR5Main.vcxproj.filters
@@ -836,6 +836,9 @@
File di origine
+
+ File di origine
+