2019-11-09 09:55:56 +01:00
|
|
|
#include "switch.h"
|
|
|
|
#include "door.h"
|
|
|
|
#include "items.h"
|
|
|
|
#include "lot.h"
|
|
|
|
#include "objects.h"
|
|
|
|
#include "collide.h"
|
|
|
|
#include "Lara.h"
|
|
|
|
#include "inventory.h"
|
|
|
|
#include "draw.h"
|
|
|
|
#include "sphere.h"
|
|
|
|
|
|
|
|
byte SequenceUsed[6];
|
|
|
|
byte SequenceResults[3][3][3];
|
|
|
|
byte Sequences[3];
|
|
|
|
byte CurrentSequence;
|
2019-11-18 07:48:35 +01:00
|
|
|
|
2019-11-15 07:40:22 +01:00
|
|
|
extern PHD_VECTOR OldPickupPos;
|
2019-11-18 07:48:35 +01:00
|
|
|
extern Inventory* g_Inventory;
|
2019-11-09 09:55:56 +01:00
|
|
|
|
2019-11-27 15:12:35 +01:00
|
|
|
short Switch2Bounds[12] =
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
0xFC00, 0x0400, 0xFC00, 0x0400, 0xFC00, 0x0200, 0xC720, 0x38E0, 0xC720, 0x38E0,
|
|
|
|
0xC720, 0x38E0
|
|
|
|
};
|
|
|
|
PHD_VECTOR Switch2Position = { 0, 0, 108 };
|
2019-11-27 15:12:35 +01:00
|
|
|
short TurnSwitchBoundsA[12] = // offset 0xA14D8
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
0x0200, 0x0380, 0x0000, 0x0000, 0xFE00, 0x0000, 0xF8E4, 0x071C, 0xEAAC, 0x1554,
|
|
|
|
0xF8E4, 0x071C
|
|
|
|
};
|
|
|
|
PHD_VECTOR TurnSwitchPos = { 650, 0, 138 }; // offset 0xA14F0
|
2019-11-27 15:12:35 +01:00
|
|
|
short TurnSwitchBoundsC[12] = // offset 0xA14FC
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
0x0200, 0x0380, 0x0000, 0x0000, 0x0000, 0x0200, 0xF8E4, 0x071C, 0xEAAC, 0x1554,
|
|
|
|
0xF8E4, 0x071C
|
|
|
|
};
|
|
|
|
PHD_VECTOR TurnSwitchPosA = { 650, 0, -138 }; // offset 0xA1514
|
|
|
|
PHD_VECTOR CogSwitchPos = { 0, 0, -856 }; // offset 0xA1520
|
2019-11-27 15:12:35 +01:00
|
|
|
short CogSwitchBounds[12] = // offset 0xA152C
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
0xFE00, 0x0200, 0x0000, 0x0000, 0xFA00, 0xFE00, 0xF8E4, 0x071C, 0xEAAC, 0x1554,
|
|
|
|
0xF8E4, 0x071C
|
|
|
|
};
|
|
|
|
PHD_VECTOR RailSwitchPos = { 0, 0, -550 }; // offset 0xA1544
|
2019-11-27 15:12:35 +01:00
|
|
|
short RailSwitchBounds[12] = // offset 0xA1550
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
0xFF00, 0x0100, 0x0000, 0x0000, 0xFD00, 0xFE00, 0xF8E4, 0x071C, 0xEAAC, 0x1554,
|
|
|
|
0xF8E4, 0x071C
|
|
|
|
};
|
|
|
|
PHD_VECTOR RailSwitchPos2 = { 0, 0, 550 }; // offset 0xA1568
|
2019-11-27 15:12:35 +01:00
|
|
|
short RailSwitchBounds2[12] = // offset 0xA1574
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
0xFF00, 0x0100, 0x0000, 0x0000, 0x0200, 0x0300, 0xF8E4, 0x071C, 0xEAAC, 0x1554,
|
|
|
|
0xF8E4, 0x071C
|
|
|
|
};
|
2019-11-27 15:12:35 +01:00
|
|
|
short JumpSwitchBounds[12] = // offset 0xA158C
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
0xFF80, 0x0080, 0xFF00, 0x0100, 0x0180, 0x0200, 0xF8E4, 0x071C, 0xEAAC, 0x1554,
|
|
|
|
0xF8E4, 0x071C
|
|
|
|
};
|
|
|
|
PHD_VECTOR JumpSwitchPos = { 0, -208, 256 }; // offset 0xA15A4
|
|
|
|
PHD_VECTOR CrowbarPos = { -89, 0, -328 }; // offset 0xA15B0
|
2019-11-27 15:12:35 +01:00
|
|
|
short CrowbarBounds[12] = // offset 0xA15BC
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
0xFF00, 0x0100, 0x0000, 0x0000, 0xFE00, 0xFF00, 0xF8E4, 0x071C, 0xEAAC, 0x1554,
|
|
|
|
0xF8E4, 0x071C
|
|
|
|
};
|
|
|
|
PHD_VECTOR CrowbarPos2 = { 89, 0, 328 }; // offset 0xA15D4
|
2019-11-27 15:12:35 +01:00
|
|
|
short CrowbarBounds2[12] = // offset 0xA15E0
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
0xFF00, 0x0100, 0x0000, 0x0000, 0x0100, 0x0200, 0xF8E4, 0x071C, 0xEAAC, 0x1554,
|
|
|
|
0xF8E4, 0x071C
|
|
|
|
};
|
2019-11-27 15:12:35 +01:00
|
|
|
short FullBlockSwitchBounds[12] = // offset 0xA15F8
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
0xFE80, 0x0180, 0x0000, 0x0100, 0x0000, 0x0200, 0xF8E4, 0x071C, 0xEAAC, 0x1554,
|
|
|
|
0xF8E4, 0x071C
|
|
|
|
};
|
|
|
|
PHD_VECTOR FullBlockSwitchPos = { 0, 0, 0 }; // offset 0xA1610
|
2019-11-27 15:12:35 +01:00
|
|
|
short PulleyBounds[12] = // offset 0xA161C
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
0xFF00, 0x0100, 0x0000, 0x0000, 0xFE00, 0x0200, 0xF8E4, 0x071C, 0xEAAC, 0x1554,
|
|
|
|
0xF8E4, 0x071C
|
|
|
|
};
|
|
|
|
PHD_VECTOR PulleyPos = { 0, 0, -148 }; // offset 0xA1634
|
|
|
|
PHD_VECTOR CrowDovePos = { 0, 0, -400 }; // offset 0xA1640
|
2019-11-27 15:12:35 +01:00
|
|
|
short UnderwaterSwitchBounds[12] = // offset 0xA164C
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
0xFF00, 0x0100, 0xFB00, 0xFE00, 0xFE00, 0x0000, 0xC720, 0x38E0, 0xC720, 0x38E0,
|
|
|
|
0xC720, 0x38E0
|
|
|
|
};
|
2019-11-27 15:12:35 +01:00
|
|
|
short UnderwaterSwitchBounds2[12] = // offset 0xA1664
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
0xFF00, 0x0100, 0xFB00, 0xFE00, 0x0000, 0x0200, 0xC720, 0x38E0, 0xC720, 0x38E0,
|
|
|
|
0xC720, 0x38E0
|
|
|
|
};
|
|
|
|
PHD_VECTOR UnderwaterSwitchPos = { 0, -736, -416 }; // offset 0xA167C
|
|
|
|
PHD_VECTOR UnderwaterSwitchPos2 = { 0, -736, 416 }; // offset 0xA1688
|
2019-11-27 15:12:35 +01:00
|
|
|
short SwitchBounds[12] = // offset 0xA1694
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF8E4, 0x071C, 0xEAAC, 0x1554,
|
|
|
|
0xF8E4, 0x071C
|
|
|
|
};
|
|
|
|
PHD_VECTOR SwitchPos = { 0, 0, 0 }; // offset 0xA16AC
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void ProcessExplodingSwitchType8(ITEM_INFO* item)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
PHD_VECTOR pos;
|
|
|
|
pos.x = 0;
|
|
|
|
pos.y = 0;
|
|
|
|
pos.z = 0;
|
|
|
|
GetJointAbsPosition(item, &pos, 0);
|
|
|
|
TestTriggersAtXYZ(pos.x, pos.y, pos.z, item->roomNumber, 1, 0);
|
|
|
|
ExplodeItemNode(item, Objects[item->objectNumber].nmeshes - 1, 0, 64);
|
|
|
|
item->meshBits |= 1 << ((Objects[item->objectNumber].nmeshes & 0xFF) - 2);
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void CrowDoveSwitchCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (item->flags & 0x100
|
|
|
|
|| !(item->meshBits & 4)
|
2019-11-17 08:21:25 +01:00
|
|
|
|| (!(TrInput & IN_ACTION)
|
|
|
|
|| Lara.gunStatus
|
|
|
|
|| l->currentAnimState != STATE_LARA_STOP
|
|
|
|
|| l->animNumber != ANIMATION_LARA_STAY_IDLE
|
|
|
|
|| l->gravityStatus)
|
2019-11-09 09:55:56 +01:00
|
|
|
&& (!Lara.isMoving || Lara.generalPtr != (void*)itemNum))
|
|
|
|
{
|
|
|
|
if (l->currentAnimState != STATE_LARA_DOVESWITCH)
|
|
|
|
ObjectCollision(itemNum, l, coll);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
int oldYrot = item->pos.yRot;
|
2019-11-09 09:55:56 +01:00
|
|
|
item->pos.yRot = l->pos.yRot;
|
|
|
|
if (TestLaraPosition(PulleyBounds, item, l))
|
|
|
|
{
|
|
|
|
if (MoveLaraPosition(&CrowDovePos, item, l))
|
|
|
|
{
|
|
|
|
l->animNumber = ANIMATION_LARA_DOVESWITCH_TURN;
|
|
|
|
l->currentAnimState = STATE_LARA_DOVESWITCH;
|
|
|
|
l->frameNumber = Anims[l->animNumber].frameBase;
|
|
|
|
|
|
|
|
AddActiveItem(itemNum);
|
|
|
|
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
item->pos.yRot = oldYrot;
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.headYrot = 0;
|
|
|
|
Lara.headXrot = 0;
|
|
|
|
Lara.torsoYrot = 0;
|
|
|
|
Lara.torsoXrot = 0;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
Lara.generalPtr = (void*)item;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Lara.generalPtr = (void*)itemNum;
|
|
|
|
}
|
|
|
|
item->pos.yRot = oldYrot;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (Lara.isMoving && Lara.generalPtr == (void*)itemNum)
|
|
|
|
{
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
|
|
}
|
|
|
|
item->pos.yRot = oldYrot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void CrowDoveSwitchControl(short itemNumber)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
|
|
|
|
if ((item->meshBits & 2))
|
|
|
|
{
|
|
|
|
ExplodeItemNode(item, 1, 0, 0x100);
|
|
|
|
SoundEffect(SFX_RAVENSWITCH_EXP, &item->pos, 0);
|
|
|
|
item->meshBits = 5;
|
|
|
|
RemoveActiveItem(itemNumber);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (item->currentAnimState == 0)
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
|
|
|
|
AnimateItem(item);
|
|
|
|
|
|
|
|
if (item->currentAnimState == 0)
|
|
|
|
item->pos.yRot += ANGLE(90);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void CogSwitchCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
2019-11-17 08:21:25 +01:00
|
|
|
|
2019-11-09 09:55:56 +01:00
|
|
|
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &item->roomNumber);
|
|
|
|
GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
2019-11-27 15:12:35 +01:00
|
|
|
short* trigger = TriggerIndex;
|
|
|
|
for (int i = *TriggerIndex; (i & 0x1F) != 4; trigger++)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
if (i < 0)
|
|
|
|
break;
|
2019-11-17 08:21:25 +01:00
|
|
|
i = trigger[1];
|
2019-11-09 09:55:56 +01:00
|
|
|
}
|
|
|
|
|
2019-11-17 08:21:25 +01:00
|
|
|
ITEM_INFO* target = &Items[trigger[3] & 0x3FF];
|
|
|
|
DOOR_DATA* door = (DOOR_DATA*)target->data;
|
2019-11-09 09:55:56 +01:00
|
|
|
|
|
|
|
if (item->status == ITEM_INACTIVE)
|
|
|
|
{
|
|
|
|
if (!(item->flags & 0x100)
|
2019-11-17 08:21:25 +01:00
|
|
|
&& (TrInput & IN_ACTION
|
|
|
|
&& !Lara.gunStatus
|
|
|
|
&& !(item->status && item->gravityStatus)
|
|
|
|
&& l->currentAnimState == STATE_LARA_STOP
|
|
|
|
&& l->animNumber == ANIMATION_LARA_STAY_IDLE
|
2019-11-09 09:55:56 +01:00
|
|
|
|| Lara.isMoving && Lara.generalPtr == (void*)itemNum))
|
|
|
|
{
|
|
|
|
if (TestLaraPosition(CogSwitchBounds, item, l))
|
|
|
|
{
|
|
|
|
if (MoveLaraPosition(&CogSwitchPos, item, l))
|
|
|
|
{
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.headYrot = 0;
|
|
|
|
Lara.headXrot = 0;
|
|
|
|
Lara.torsoYrot = 0;
|
|
|
|
Lara.torsoXrot = 0;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
Lara.generalPtr = target;
|
|
|
|
l->animNumber = ANIMATION_LARA_COGWHEEL_GRAB;
|
|
|
|
l->goalAnimState = STATE_LARA_COGWHEEL;
|
|
|
|
l->currentAnimState = STATE_LARA_COGWHEEL;
|
|
|
|
l->frameNumber = Anims[l->animNumber].frameBase;
|
|
|
|
|
|
|
|
AddActiveItem(itemNum);
|
|
|
|
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
if (!door->opened)
|
|
|
|
{
|
2019-11-17 08:21:25 +01:00
|
|
|
AddActiveItem((target - Items) / sizeof(ITEM_INFO));
|
2019-11-09 09:55:56 +01:00
|
|
|
target->itemFlags[2] = target->pos.yPos;
|
|
|
|
target->status = ITEM_ACTIVE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Lara.generalPtr = (void*)itemNum;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (Lara.isMoving && Lara.generalPtr == (void*)itemNum)
|
|
|
|
{
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjectCollision(itemNum, l, coll);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void CogSwitchControl(short itemNum)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
AnimateItem(item);
|
|
|
|
|
|
|
|
if (item->currentAnimState == 1)
|
|
|
|
{
|
|
|
|
if (item->goalAnimState == 1 && !(TrInput & IN_ACTION))
|
|
|
|
{
|
2019-11-17 08:21:25 +01:00
|
|
|
LaraItem->goalAnimState = STATE_LARA_STOP;
|
2019-11-09 09:55:56 +01:00
|
|
|
item->goalAnimState = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LaraItem->animNumber == ANIMATION_LARA_COGWHEEL_PULL)
|
|
|
|
{
|
|
|
|
if (LaraItem->frameNumber == (Anims[ANIMATION_LARA_COGWHEEL_PULL].frameBase + 10))
|
|
|
|
{
|
|
|
|
ITEM_INFO* it = (ITEM_INFO*)Lara.generalPtr;
|
|
|
|
it->itemFlags[0] = 40;
|
|
|
|
Lara.generalPtr = it;
|
|
|
|
SoundEffect(SFX_STONE_SCRAPE_FAST, &it->pos, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (item->frameNumber == Anims[item->animNumber].frameEnd)
|
|
|
|
{
|
|
|
|
item->currentAnimState = 0;
|
|
|
|
item->status = ITEM_INACTIVE;
|
|
|
|
RemoveActiveItem(itemNum);
|
|
|
|
LaraItem->animNumber = ANIMATION_LARA_STAY_SOLID;
|
|
|
|
LaraItem->frameNumber = Anims[LaraItem->animNumber].frameBase;
|
|
|
|
LaraItem->goalAnimState = STATE_LARA_STOP;
|
|
|
|
LaraItem->currentAnimState = STATE_LARA_STOP;
|
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void FullBlockSwitchCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if ((!(TrInput & IN_ACTION)
|
|
|
|
|| item->status
|
|
|
|
|| item->flags & 0x100
|
|
|
|
|| CurrentSequence >= 3u
|
|
|
|
|| Lara.gunStatus
|
|
|
|
|| l->currentAnimState != STATE_LARA_STOP
|
|
|
|
|| l->animNumber != ANIMATION_LARA_STAY_IDLE)
|
|
|
|
&& (!Lara.isMoving || Lara.generalPtr != (void*)itemNum))
|
|
|
|
{
|
|
|
|
ObjectCollision(itemNum, l, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TestLaraPosition(FullBlockSwitchBounds, item, l))
|
|
|
|
{
|
|
|
|
if (MoveLaraPosition(&FullBlockSwitchPos, item, l))
|
|
|
|
{
|
|
|
|
if (item->currentAnimState == 1)
|
|
|
|
{
|
|
|
|
l->currentAnimState = STATE_LARA_SWITCH_DOWN;
|
|
|
|
l->animNumber = ANIMATION_LARA_GIANT_BUTTON_PUSH;
|
|
|
|
item->goalAnimState = 0;
|
|
|
|
}
|
|
|
|
l->goalAnimState = STATE_LARA_STOP;
|
|
|
|
l->frameNumber = Anims[l->animNumber].frameBase;
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
|
|
|
|
AddActiveItem(itemNum);
|
|
|
|
AnimateItem(item);
|
|
|
|
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.headYrot = 0;
|
|
|
|
Lara.headXrot = 0;
|
|
|
|
Lara.torsoYrot = 0;
|
|
|
|
Lara.torsoXrot = 0;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Lara.generalPtr = (void*)itemNum;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (Lara.isMoving && Lara.generalPtr == (void*)itemNum)
|
|
|
|
{
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void FullBlockSwitchControl(short itemNumber)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
|
|
|
|
if (item->animNumber != Objects[item->objectNumber].animIndex + 2
|
|
|
|
|| CurrentSequence >= 3u
|
|
|
|
|| item->itemFlags[0])
|
|
|
|
{
|
|
|
|
if (CurrentSequence >= 4u)
|
|
|
|
{
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
item->status = ITEM_INACTIVE;
|
|
|
|
if (++CurrentSequence >= 7u)
|
|
|
|
CurrentSequence = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->itemFlags[0] = 1;
|
|
|
|
Sequences[CurrentSequence++] = item->triggerFlags;
|
|
|
|
}
|
|
|
|
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void CrowbarSwitchCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
int doSwitch = 0;
|
2019-11-09 09:55:56 +01:00
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
2019-11-18 07:48:35 +01:00
|
|
|
if ((!(TrInput & IN_ACTION) && g_Inventory->GetSelectedObject() != ID_CROWBAR_ITEM
|
2019-11-09 09:55:56 +01:00
|
|
|
|| l->currentAnimState != STATE_LARA_STOP
|
|
|
|
|| l->animNumber != ANIMATION_LARA_STAY_IDLE
|
|
|
|
|| Lara.gunStatus
|
|
|
|
|| item->itemFlags[0])
|
|
|
|
&& (!Lara.isMoving|| Lara.generalPtr != (void*)itemNum))
|
|
|
|
{
|
|
|
|
ObjectCollision(itemNum, l, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->currentAnimState)
|
|
|
|
{
|
|
|
|
if (item->currentAnimState != 1)
|
|
|
|
{
|
|
|
|
ObjectCollision(itemNum, l, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-11-27 15:12:35 +01:00
|
|
|
l->pos.yRot ^= (short)ANGLE(180);
|
2019-11-09 09:55:56 +01:00
|
|
|
if (TestLaraPosition(CrowbarBounds2, item, l))
|
|
|
|
{
|
2019-11-18 07:48:35 +01:00
|
|
|
if (Lara.isMoving || g_Inventory->GetSelectedObject() == ID_CROWBAR_ITEM)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
if (MoveLaraPosition(&CrowbarPos2, item, l))
|
|
|
|
{
|
|
|
|
l->animNumber = ANIMATION_LARA_CROWBAR_USE_ON_FLOOR;
|
|
|
|
doSwitch = 1;
|
|
|
|
l->frameNumber = Anims[l->animNumber].frameBase;
|
|
|
|
item->goalAnimState = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Lara.generalPtr = (void*)itemNum;
|
|
|
|
}
|
2019-11-18 07:48:35 +01:00
|
|
|
g_Inventory->SetSelectedObject(NO_ITEM);
|
2019-11-09 09:55:56 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
doSwitch = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (Lara.isMoving && Lara.generalPtr == (void*)itemNum)
|
|
|
|
{
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
|
|
}
|
2019-11-27 15:12:35 +01:00
|
|
|
l->pos.yRot ^= (short)ANGLE(180);
|
2019-11-09 09:55:56 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!TestLaraPosition(CrowbarBounds, item, l))
|
|
|
|
{
|
|
|
|
if (Lara.isMoving && Lara.generalPtr == (void*)itemNum)
|
|
|
|
{
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
|
|
}
|
|
|
|
ObjectCollision(itemNum, l, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-11-18 07:48:35 +01:00
|
|
|
if (!(Lara.isMoving && g_Inventory->GetSelectedObject() != ID_CROWBAR_ITEM))
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
if (Lara.crowbar)
|
2019-11-18 07:48:35 +01:00
|
|
|
g_Inventory->SetEnterObject(ID_CROWBAR_ITEM);
|
2019-11-09 09:55:56 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (OldPickupPos.x != l->pos.xPos || OldPickupPos.y != l->pos.yPos || OldPickupPos.z != l->pos.zPos)
|
|
|
|
{
|
|
|
|
OldPickupPos.x = l->pos.xPos;
|
|
|
|
OldPickupPos.y = l->pos.yPos;
|
|
|
|
OldPickupPos.z = l->pos.zPos;
|
|
|
|
SayNo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (MoveLaraPosition(&CrowbarPos, item, l))
|
|
|
|
{
|
|
|
|
l->animNumber = ANIMATION_LARA_CROWBAR_USE_ON_FLOOR;
|
|
|
|
doSwitch = 1;
|
|
|
|
l->frameNumber = Anims[l->animNumber].frameBase;
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Lara.generalPtr = (void*)itemNum;
|
|
|
|
}
|
|
|
|
|
2019-11-18 07:48:35 +01:00
|
|
|
g_Inventory->SetSelectedObject(NO_ITEM);
|
2019-11-09 09:55:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!doSwitch)
|
|
|
|
{
|
|
|
|
ObjectCollision(itemNum, l, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (doSwitch != -1)
|
|
|
|
{
|
|
|
|
l->goalAnimState = STATE_LARA_SWITCH_DOWN;
|
|
|
|
l->currentAnimState = STATE_LARA_SWITCH_DOWN;
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.headYrot = 0;
|
|
|
|
Lara.headXrot = 0;
|
|
|
|
Lara.torsoYrot = 0;
|
|
|
|
Lara.torsoXrot = 0;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
|
|
|
|
AddActiveItem(itemNum);
|
|
|
|
AnimateItem(item);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Lara.crowbar)
|
2019-11-18 07:48:35 +01:00
|
|
|
g_Inventory->SetEnterObject(ID_CROWBAR_ITEM);
|
2019-11-09 09:55:56 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (OldPickupPos.x != l->pos.xPos || OldPickupPos.y != l->pos.yPos || OldPickupPos.z != l->pos.zPos)
|
|
|
|
{
|
|
|
|
OldPickupPos.x = l->pos.xPos;
|
|
|
|
OldPickupPos.y = l->pos.yPos;
|
|
|
|
OldPickupPos.z = l->pos.zPos;
|
|
|
|
SayNo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void JumpSwitchCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (TrInput & IN_ACTION)
|
|
|
|
{
|
|
|
|
if (!Lara.gunStatus)
|
|
|
|
{
|
|
|
|
if (l->currentAnimState == STATE_LARA_REACH || l->currentAnimState == STATE_LARA_JUMP_UP)
|
|
|
|
{
|
|
|
|
if (l->status || l->gravityStatus)
|
|
|
|
{
|
|
|
|
if (l->fallspeed > 0 && !item->currentAnimState)
|
|
|
|
{
|
|
|
|
if (TestLaraPosition(JumpSwitchBounds, item, l))
|
|
|
|
{
|
|
|
|
AlignLaraPosition(&JumpSwitchPos, item, l);
|
|
|
|
|
|
|
|
l->currentAnimState = STATE_LARA_SWITCH_DOWN;
|
|
|
|
l->animNumber = ANIMATION_LARA_JUMPSWITCH;
|
|
|
|
l->fallspeed = 0;
|
|
|
|
l->frameNumber = Anims[l->animNumber].frameBase;
|
|
|
|
l->gravityStatus = false;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
|
|
|
|
AddActiveItem(itemNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void RailSwitchCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
int flag = 0;
|
2019-11-09 09:55:56 +01:00
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if ((!(TrInput & IN_ACTION) || l->currentAnimState != STATE_LARA_STOP || l->animNumber != ANIMATION_LARA_STAY_IDLE || Lara.gunStatus)
|
|
|
|
&& (!Lara.isMoving || Lara.generalPtr != (void*)itemNum))
|
|
|
|
{
|
|
|
|
ObjectCollision(itemNum, l, coll);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->currentAnimState)
|
|
|
|
{
|
|
|
|
if (item->currentAnimState == 1)
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
l->pos.yRot ^= (short)ANGLE(180);
|
2019-11-09 09:55:56 +01:00
|
|
|
if (TestLaraPosition(RailSwitchBounds2, item, l))
|
|
|
|
{
|
|
|
|
if (MoveLaraPosition(&RailSwitchPos2, item, l))
|
|
|
|
{
|
|
|
|
item->goalAnimState = 0;
|
|
|
|
flag = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Lara.generalPtr = (void*)itemNum;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (Lara.isMoving && Lara.generalPtr == (void*)itemNum)
|
|
|
|
{
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
|
|
}
|
2019-11-27 15:12:35 +01:00
|
|
|
l->pos.yRot ^= (short)ANGLE(180);
|
2019-11-09 09:55:56 +01:00
|
|
|
if (flag)
|
|
|
|
{
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
l->animNumber = ANIMATION_LARA_LEVERSWITCH_PUSH;
|
|
|
|
l->frameNumber = Anims[l->animNumber].frameBase;
|
|
|
|
l->goalAnimState = STATE_LARA_LEVERSWITCH_PUSH;
|
|
|
|
l->currentAnimState = STATE_LARA_LEVERSWITCH_PUSH;
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.headYrot = 0;
|
|
|
|
Lara.headXrot = 0;
|
|
|
|
Lara.torsoYrot = 0;
|
|
|
|
Lara.torsoXrot = 0;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
AddActiveItem(itemNum);
|
|
|
|
AnimateItem(item);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjectCollision(itemNum, l, coll);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!TestLaraPosition(RailSwitchBounds, item, l))
|
|
|
|
{
|
|
|
|
if (Lara.isMoving)
|
|
|
|
{
|
|
|
|
if (Lara.generalPtr == (void*)itemNum)
|
|
|
|
{
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjectCollision(itemNum, l, coll);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!MoveLaraPosition(&RailSwitchPos, item, l))
|
|
|
|
{
|
|
|
|
Lara.generalPtr = (void*)itemNum;
|
|
|
|
ObjectCollision(itemNum, l, coll);
|
|
|
|
}
|
|
|
|
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
l->animNumber = ANIMATION_LARA_LEVERSWITCH_PUSH;
|
|
|
|
l->frameNumber = Anims[l->animNumber].frameBase;
|
|
|
|
l->goalAnimState = STATE_LARA_LEVERSWITCH_PUSH;
|
|
|
|
l->currentAnimState = STATE_LARA_LEVERSWITCH_PUSH;
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.headYrot = 0;
|
|
|
|
Lara.headXrot = 0;
|
|
|
|
Lara.torsoYrot = 0;
|
|
|
|
Lara.torsoXrot = 0;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
AddActiveItem(itemNum);
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void TurnSwitchCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
2019-11-27 15:12:35 +01:00
|
|
|
int flag = 0;
|
2019-11-09 09:55:56 +01:00
|
|
|
|
|
|
|
if (item->currentAnimState
|
|
|
|
&& TrInput & IN_ACTION
|
|
|
|
&& l->currentAnimState == STATE_LARA_STOP
|
|
|
|
&& l->animNumber == ANIMATION_LARA_STAY_IDLE
|
|
|
|
&& !l->gravityStatus
|
|
|
|
&& Lara.gunStatus == LG_NO_ARMS
|
|
|
|
|| Lara.isMoving && Lara.generalPtr == (void*)itemNum)
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
short ItemNos[8];
|
2019-11-09 09:55:56 +01:00
|
|
|
if (TestLaraPosition(TurnSwitchBoundsA, item, l))
|
|
|
|
{
|
|
|
|
if (MoveLaraPosition(&TurnSwitchPosA, item, l))
|
|
|
|
{
|
|
|
|
l->animNumber = ANIMATION_LARA_ROUND_HANDLE_GRAB_COUNTERCLOCKWISE;
|
|
|
|
l->frameNumber = Anims[ANIMATION_LARA_ROUND_HANDLE_GRAB_COUNTERCLOCKWISE].frameBase;
|
|
|
|
item->animNumber = Objects[item->objectNumber].animIndex + 4;
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
item->itemFlags[0] = 1;
|
|
|
|
ForcedFixedCamera.x = item->pos.xPos - (1024 * SIN(item->pos.yRot) >> W2V_SHIFT);
|
|
|
|
ForcedFixedCamera.z = item->pos.zPos - (1024 * COS(item->pos.yRot) >> W2V_SHIFT);
|
|
|
|
Lara.isMoving = 0;
|
|
|
|
Lara.headYrot = 0;
|
|
|
|
Lara.headXrot = 0;
|
|
|
|
Lara.torsoYrot = 0;
|
|
|
|
Lara.torsoXrot = 0;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
l->currentAnimState = ANIMATION_LARA_TRY_HANG_SOLID;
|
|
|
|
|
|
|
|
UseForcedFixedCamera = true;
|
|
|
|
ForcedFixedCamera.y = item->pos.yPos - 2048;
|
|
|
|
ForcedFixedCamera.roomNumber = item->roomNumber;
|
|
|
|
|
|
|
|
AddActiveItem(itemNum);
|
|
|
|
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
item->itemFlags[1] = 0;
|
|
|
|
|
|
|
|
if (GetSwitchTrigger(item, ItemNos, 0))
|
|
|
|
{
|
|
|
|
if (!TriggerActive(&Items[ItemNos[0]]))
|
|
|
|
{
|
|
|
|
Items[ItemNos[0]].animNumber = Objects[Items[ItemNos[0]].objectNumber].animIndex;
|
|
|
|
Items[ItemNos[0]].frameNumber = Anims[Items[ItemNos[0]].animNumber].frameBase;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Lara.generalPtr = (void*)itemNum;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
l->pos.yRot ^= (short)ANGLE(180);
|
2019-11-09 09:55:56 +01:00
|
|
|
if (TestLaraPosition(TurnSwitchBoundsC, item, l))
|
|
|
|
{
|
|
|
|
if (MoveLaraPosition(&TurnSwitchPos, item, l))
|
|
|
|
{
|
|
|
|
l->animNumber = 319;
|
|
|
|
flag = 1;
|
|
|
|
l->frameNumber = Anims[319].frameBase;
|
|
|
|
item->itemFlags[0] = 2;
|
|
|
|
ForcedFixedCamera.x = item->pos.xPos + (1024 * SIN(item->pos.yRot) >> W2V_SHIFT);
|
|
|
|
ForcedFixedCamera.z = item->pos.zPos + (1024 * COS(item->pos.yRot) >> W2V_SHIFT);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Lara.generalPtr = (void*)itemNum;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (Lara.isMoving && Lara.generalPtr == (void*)itemNum)
|
|
|
|
{
|
2019-11-21 07:43:34 +01:00
|
|
|
Lara.isMoving = false;
|
2019-11-09 09:55:56 +01:00
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
|
|
}
|
2019-11-27 15:12:35 +01:00
|
|
|
l->pos.yRot ^= (short)ANGLE(180);
|
2019-11-09 09:55:56 +01:00
|
|
|
if (flag)
|
|
|
|
{
|
|
|
|
Lara.isMoving = 0;
|
|
|
|
Lara.headYrot = 0;
|
|
|
|
Lara.headXrot = 0;
|
|
|
|
Lara.torsoYrot = 0;
|
|
|
|
Lara.torsoXrot = 0;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
l->currentAnimState = ANIMATION_LARA_TRY_HANG_SOLID;
|
|
|
|
UseForcedFixedCamera = TRUE;
|
|
|
|
ForcedFixedCamera.y = item->pos.yPos - 2048;
|
|
|
|
ForcedFixedCamera.roomNumber = item->roomNumber;
|
|
|
|
AddActiveItem(itemNum);
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
item->itemFlags[1] = 0;
|
|
|
|
if (GetSwitchTrigger(item, ItemNos, 0))
|
|
|
|
{
|
|
|
|
if (!TriggerActive(&Items[ItemNos[0]]))
|
|
|
|
{
|
|
|
|
Items[ItemNos[0]].animNumber = Objects[Items[ItemNos[0]].objectNumber].animIndex + 4;
|
|
|
|
Items[ItemNos[0]].frameNumber = Anims[Items[ItemNos[0]].animNumber].frameBase;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (coll->enableBaddiePush && TestBoundsCollide(item, l, coll->radius))
|
|
|
|
{
|
|
|
|
GlobalCollisionBounds.X1 = -512;
|
|
|
|
GlobalCollisionBounds.X2 = 512;
|
|
|
|
GlobalCollisionBounds.Y1 = -512;
|
|
|
|
GlobalCollisionBounds.Y2 = 0;
|
|
|
|
GlobalCollisionBounds.Z1 = -512;
|
|
|
|
GlobalCollisionBounds.Z2 = 512;
|
|
|
|
|
|
|
|
ItemPushLara(item, l, coll, 0, 2);
|
|
|
|
|
|
|
|
GlobalCollisionBounds.X1 = 256;
|
|
|
|
GlobalCollisionBounds.X2 = 1024;
|
|
|
|
GlobalCollisionBounds.Z1 = -128;
|
|
|
|
GlobalCollisionBounds.Z2 = 128;
|
|
|
|
|
|
|
|
ItemPushLara(item, l, coll, 0, 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void TurnSwitchControl(short itemNum)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* l = LaraItem;
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (Items[itemNum].itemFlags[0] == 2)
|
|
|
|
{
|
|
|
|
if (item->animNumber == Objects[ID_TURN_SWITCH].animIndex + 2)
|
|
|
|
{
|
|
|
|
item->pos.yRot += ANGLE(90);
|
|
|
|
if (TrInput & IN_ACTION)
|
|
|
|
{
|
|
|
|
l->animNumber = ANIMATION_LARA_ROUND_HANDLE_PUSH_RIGHT_BEGIN;
|
|
|
|
l->frameNumber = Anims[l->animNumber].frameBase;
|
|
|
|
item->animNumber = Objects[item->objectNumber].animIndex + 1;
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (l->animNumber == ANIMATION_LARA_ROUND_HANDLE_PUSH_RIGHT_END && l->frameNumber == Anims[l->animNumber].frameEnd && !item->itemFlags[1])
|
|
|
|
item->itemFlags[1] = 1;
|
|
|
|
|
|
|
|
if (l->frameNumber >= Anims[ANIMATION_LARA_ROUND_HANDLE_PUSH_RIGHT_BEGIN].frameBase &&
|
|
|
|
l->frameNumber <= Anims[ANIMATION_LARA_ROUND_HANDLE_PUSH_RIGHT_BEGIN].frameBase + 43
|
|
|
|
||
|
|
|
|
l->frameNumber >= Anims[ANIMATION_LARA_ROUND_HANDLE_PUSH_RIGHT_BEGIN].frameBase + 58 &&
|
|
|
|
l->frameNumber <= Anims[ANIMATION_LARA_ROUND_HANDLE_PUSH_RIGHT_BEGIN].frameBase + 115)
|
|
|
|
{
|
|
|
|
SoundEffect(SFX_PUSHABLE_SOUND, &item->pos, 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (item->animNumber == Objects[ID_TURN_SWITCH].animIndex + 6)
|
|
|
|
{
|
|
|
|
item->pos.yRot -= ANGLE(90);
|
|
|
|
if (TrInput & IN_ACTION)
|
|
|
|
{
|
|
|
|
l->animNumber = ANIMATION_LARA_ROUND_HANDLE_PUSH_LEFT_BEGIN;
|
|
|
|
l->frameNumber = Anims[l->animNumber].frameBase;
|
|
|
|
item->animNumber = Objects[item->objectNumber].animIndex + 5;
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (l->animNumber == ANIMATION_LARA_ROUND_HANDLE_PUSH_LEFT_END && l->frameNumber == Anims[ANIMATION_LARA_ROUND_HANDLE_PUSH_LEFT_END].frameEnd &&
|
|
|
|
!item->itemFlags[1])
|
|
|
|
item->itemFlags[1] = 1;
|
|
|
|
|
|
|
|
if (l->frameNumber >= Anims[ANIMATION_LARA_ROUND_HANDLE_PUSH_LEFT_BEGIN].frameBase &&
|
|
|
|
l->frameNumber <= Anims[ANIMATION_LARA_ROUND_HANDLE_PUSH_LEFT_BEGIN].frameBase + 43
|
|
|
|
||
|
|
|
|
l->frameNumber >= Anims[ANIMATION_LARA_ROUND_HANDLE_PUSH_LEFT_BEGIN].frameBase + 58 &&
|
|
|
|
l->frameNumber <= Anims[ANIMATION_LARA_ROUND_HANDLE_PUSH_LEFT_BEGIN].frameBase + 115)
|
|
|
|
{
|
|
|
|
SoundEffect(SFX_PUSHABLE_SOUND, &item->pos, 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AnimateItem(item);
|
|
|
|
|
|
|
|
if (item->itemFlags[1] == 1)
|
|
|
|
{
|
|
|
|
l->animNumber = ANIMATION_LARA_STAY_IDLE;
|
|
|
|
l->currentAnimState = STATE_LARA_STOP;
|
|
|
|
l->frameNumber = Anims[l->animNumber].frameBase;
|
|
|
|
item->animNumber = Objects[item->objectNumber].animIndex;
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
item->status = ITEM_INACTIVE;
|
|
|
|
|
|
|
|
RemoveActiveItem(itemNum);
|
|
|
|
|
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
|
|
UseForcedFixedCamera = 0;
|
|
|
|
item->itemFlags[1] = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void PulleyCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (item->flags & 0x100
|
|
|
|
|| (!(TrInput & IN_ACTION) || Lara.gunStatus || l->currentAnimState != STATE_LARA_STOP || l->animNumber != ANIMATION_LARA_STAY_IDLE ||
|
|
|
|
item->status || item->gravityStatus)
|
|
|
|
&& (!Lara.isMoving || Lara.generalPtr != (void*)itemNum))
|
|
|
|
{
|
|
|
|
if (l->currentAnimState != STATE_LARA_PULLEY)
|
|
|
|
ObjectCollision(itemNum, l, coll);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
short oldYrot = item->pos.yRot;
|
2019-11-09 09:55:56 +01:00
|
|
|
item->pos.yRot = l->pos.yRot;
|
|
|
|
if (TestLaraPosition(PulleyBounds, item, l))
|
|
|
|
{
|
|
|
|
if (MoveLaraPosition(&PulleyPos, item, l))
|
|
|
|
{
|
|
|
|
l->animNumber = ANIMATION_LARA_PULLEY_GRAB;
|
|
|
|
l->currentAnimState = STATE_LARA_PULLEY;
|
|
|
|
l->frameNumber = Anims[l->animNumber].frameBase;
|
|
|
|
|
|
|
|
AddActiveItem(itemNum);
|
|
|
|
|
|
|
|
item->pos.yRot = oldYrot;
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.headYrot = 0;
|
|
|
|
Lara.headXrot = 0;
|
|
|
|
Lara.torsoYrot = 0;
|
|
|
|
Lara.torsoXrot = 0;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
Lara.generalPtr = item;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Lara.generalPtr = (void*)itemNum;
|
|
|
|
}
|
|
|
|
item->pos.yRot = oldYrot;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (Lara.isMoving && Lara.generalPtr == (void*)itemNum)
|
|
|
|
{
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
|
|
}
|
|
|
|
item->pos.yRot = oldYrot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void UnderwaterSwitchCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
2019-11-27 15:12:35 +01:00
|
|
|
int flag = 0;
|
2019-11-09 09:55:56 +01:00
|
|
|
|
|
|
|
if (TrInput & IN_ACTION
|
|
|
|
&& Lara.waterStatus == LW_UNDERWATER
|
|
|
|
&& l->currentAnimState == STATE_LARA_UNDERWATER_STOP
|
|
|
|
&& l->animNumber == ANIMATION_LARA_UNDERWATER_IDLE
|
|
|
|
&& !Lara.gunStatus
|
|
|
|
&& !item->currentAnimState
|
|
|
|
|| Lara.isMoving && Lara.generalPtr == (void*)itemNum)
|
|
|
|
{
|
|
|
|
flag = 0;
|
|
|
|
if (TestLaraPosition(UnderwaterSwitchBounds, item, l))
|
|
|
|
{
|
|
|
|
if (!MoveLaraPosition(&UnderwaterSwitchPos, item, l))
|
|
|
|
{
|
|
|
|
Lara.generalPtr = (void*)itemNum;
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
LABEL_17:
|
|
|
|
l->currentAnimState = STATE_LARA_SWITCH_DOWN;
|
|
|
|
l->animNumber = ANIMATION_LARA_UNDERWATER_PULLEY;
|
|
|
|
l->frameNumber = Anims[l->animNumber].frameBase;
|
|
|
|
l->fallspeed = 0;
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
|
|
|
|
AddActiveItem(itemNum);
|
|
|
|
|
|
|
|
ForcedFixedCamera.x = item->pos.xPos - 1024 * SIN(item->pos.yRot + ANGLE(90)) >> W2V_SHIFT;
|
|
|
|
ForcedFixedCamera.y = item->pos.yPos - 1024;
|
|
|
|
ForcedFixedCamera.z = item->pos.zPos - 1024 * COS(item->pos.yRot + ANGLE(90)) >> W2V_SHIFT;
|
|
|
|
ForcedFixedCamera.roomNumber = item->roomNumber;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-11-27 15:12:35 +01:00
|
|
|
l->pos.yRot ^= (short)ANGLE(180);
|
2019-11-09 09:55:56 +01:00
|
|
|
if (TestLaraPosition(UnderwaterSwitchBounds2, item, l))
|
|
|
|
{
|
|
|
|
if (MoveLaraPosition(&UnderwaterSwitchPos2, item, l))
|
|
|
|
flag = 1;
|
|
|
|
else
|
|
|
|
Lara.generalPtr = (void*)itemNum;
|
|
|
|
}
|
2019-11-27 15:12:35 +01:00
|
|
|
l->pos.yRot ^= (short)ANGLE(180);
|
2019-11-09 09:55:56 +01:00
|
|
|
|
|
|
|
if (flag)
|
|
|
|
{
|
|
|
|
l->currentAnimState = STATE_LARA_SWITCH_DOWN;
|
|
|
|
l->animNumber = ANIMATION_LARA_UNDERWATER_PULLEY;
|
|
|
|
l->frameNumber = Anims[l->animNumber].frameBase;
|
|
|
|
l->fallspeed = 0;
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
|
|
|
|
AddActiveItem(itemNum);
|
|
|
|
|
|
|
|
ForcedFixedCamera.x = item->pos.xPos - 1024 * SIN(item->pos.yRot + ANGLE(90)) >> W2V_SHIFT;
|
|
|
|
ForcedFixedCamera.y = item->pos.yPos - 1024;
|
|
|
|
ForcedFixedCamera.z = item->pos.zPos - 1024 * COS(item->pos.yRot + ANGLE(90)) >> W2V_SHIFT;
|
|
|
|
ForcedFixedCamera.roomNumber = item->roomNumber;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void SwitchCollision2(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (TrInput & IN_ACTION)
|
|
|
|
{
|
|
|
|
if (item->status == ITEM_INACTIVE && Lara.waterStatus == LW_UNDERWATER && !Lara.gunStatus && l->currentAnimState == STATE_LARA_UNDERWATER_STOP)
|
|
|
|
{
|
|
|
|
if (TestLaraPosition(Switch2Bounds, item, l))
|
|
|
|
{
|
|
|
|
if (item->currentAnimState == 1 || !item->currentAnimState)
|
|
|
|
{
|
|
|
|
if (MoveLaraPosition(&Switch2Position, item, l))
|
|
|
|
{
|
|
|
|
l->fallspeed = 0;
|
|
|
|
l->goalAnimState = STATE_LARA_SWITCH_DOWN;
|
|
|
|
|
|
|
|
do
|
|
|
|
AnimateLara(l);
|
|
|
|
while (l->goalAnimState != STATE_LARA_SWITCH_DOWN);
|
|
|
|
|
|
|
|
l->goalAnimState = STATE_LARA_UNDERWATER_STOP;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
item->goalAnimState = item->currentAnimState != 1;
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
AddActiveItem(itemNum);
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void SwitchCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
if (TrInput & IN_ACTION
|
|
|
|
&& l->currentAnimState == STATE_LARA_STOP
|
|
|
|
&& l->animNumber == ANIMATION_LARA_STAY_IDLE
|
|
|
|
&& !Lara.gunStatus
|
|
|
|
&& item->status == ITEM_INACTIVE
|
|
|
|
&& !(item->flags & 0x100)
|
|
|
|
&& item->triggerFlags >= 0
|
|
|
|
|| Lara.isMoving && Lara.generalPtr == (void*)itemNum)
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
short* bounds = GetBoundsAccurate(item);
|
2019-11-09 09:55:56 +01:00
|
|
|
|
|
|
|
if (item->triggerFlags == 3 && item->currentAnimState == 1 || item->triggerFlags >= 5 && item->triggerFlags <= 7 && !item->currentAnimState)
|
|
|
|
return;
|
|
|
|
|
2019-11-17 08:21:25 +01:00
|
|
|
SwitchBounds[0] = bounds[0] - 256;
|
2019-11-09 09:55:56 +01:00
|
|
|
SwitchBounds[1] = bounds[1] + 256;
|
|
|
|
if (item->triggerFlags)
|
|
|
|
{
|
|
|
|
SwitchBounds[4] = bounds[4] - 512;
|
|
|
|
SwitchBounds[5] = bounds[5] + 512;
|
|
|
|
|
|
|
|
if (item->triggerFlags == 3)
|
|
|
|
{
|
|
|
|
SwitchPos.z = bounds[4] - 256;
|
|
|
|
}
|
|
|
|
else if (item->triggerFlags == 4)
|
|
|
|
{
|
|
|
|
SwitchPos.z = bounds[4] - 88;
|
|
|
|
}
|
|
|
|
else if (item->triggerFlags < 5 || item->triggerFlags > 7)
|
|
|
|
{
|
|
|
|
if (item->triggerFlags < 8)
|
|
|
|
SwitchPos.z = bounds[4] - 128;
|
|
|
|
else
|
|
|
|
SwitchPos.z = bounds[4] - 96;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SwitchPos.z = bounds[4] - 160;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SwitchBounds[4] = bounds[4] - 200;
|
|
|
|
SwitchBounds[5] = bounds[5] + 200;
|
|
|
|
SwitchPos.z = bounds[4] - 64;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TestLaraPosition(SwitchBounds, item, l))
|
|
|
|
{
|
|
|
|
if (MoveLaraPosition(&SwitchPos, item, l))
|
|
|
|
{
|
2019-11-18 07:48:35 +01:00
|
|
|
if (item->currentAnimState == 1) /* Switch down */
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
if (item->triggerFlags)
|
|
|
|
{
|
|
|
|
if (item->triggerFlags >= 3)
|
|
|
|
{
|
|
|
|
if (item->triggerFlags == 4)
|
|
|
|
{
|
|
|
|
l->currentAnimState = STATE_LARA_SWITCH_UP;
|
|
|
|
l->animNumber = ANIMATION_LARA_SWITCH_SMALL_DOWN;
|
|
|
|
item->goalAnimState = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (item->triggerFlags >= 5 && item->triggerFlags <= 7)
|
|
|
|
{
|
|
|
|
if (item->triggerFlags == 6)
|
|
|
|
DisableLaraControl = true;
|
|
|
|
l->currentAnimState = STATE_LARA_SWITCH_DOWN;
|
|
|
|
l->animNumber = ANIMATION_LARA_BUTTON_PUSH;
|
|
|
|
}
|
|
|
|
item->goalAnimState = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
l->animNumber = ANIMATION_LARA_HOLE_GRAB;
|
|
|
|
l->currentAnimState = STATE_LARA_HOLE;
|
|
|
|
item->goalAnimState = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
l->currentAnimState = STATE_LARA_SWITCH_UP;
|
|
|
|
l->animNumber = ANIMATION_LARA_PULL_SWITCH_DOWN;
|
|
|
|
item->goalAnimState = 0;
|
|
|
|
}
|
|
|
|
}
|
2019-11-18 07:48:35 +01:00
|
|
|
else /* Switch up */
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
2019-11-18 07:48:35 +01:00
|
|
|
if (item->triggerFlags)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
if (item->triggerFlags == 3)
|
|
|
|
{
|
|
|
|
l->currentAnimState = STATE_LARA_SWITCH_DOWN;
|
|
|
|
l->animNumber = ANIMATION_LARA_BIG_BUTTON_PUSH;
|
|
|
|
}
|
|
|
|
else if (item->triggerFlags == 4)
|
|
|
|
{
|
|
|
|
l->currentAnimState = STATE_LARA_SWITCH_DOWN;
|
|
|
|
l->animNumber = ANIMATION_LARA_SWITCH_SMALL_UP;
|
|
|
|
}
|
|
|
|
else if (item->triggerFlags < 8)
|
|
|
|
{
|
|
|
|
l->currentAnimState = STATE_LARA_HOLE;
|
|
|
|
l->animNumber = ANIMATION_LARA_HOLE_GRAB;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
l->currentAnimState = STATE_LARA_SWITCH_DOWN;
|
|
|
|
l->animNumber = ANIMATION_LARA_VALVE_TURN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
l->currentAnimState = STATE_LARA_SWITCH_DOWN;
|
|
|
|
l->animNumber = ANIMATION_LARA_PULL_SWITCH_UP;
|
|
|
|
}
|
|
|
|
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
}
|
|
|
|
l->frameNumber = Anims[l->animNumber].frameBase;
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
Lara.headYrot = 0;
|
|
|
|
Lara.headXrot = 0;
|
|
|
|
Lara.torsoYrot = 0;
|
|
|
|
Lara.torsoXrot = 0;
|
|
|
|
|
|
|
|
AddActiveItem(itemNum);
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Lara.generalPtr = (void*)itemNum;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (Lara.isMoving && Lara.generalPtr == (void*)itemNum)
|
|
|
|
{
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (l->currentAnimState != STATE_LARA_SWITCH_DOWN && l->currentAnimState != STATE_LARA_SWITCH_UP)
|
|
|
|
ObjectCollision(itemNum, l, coll);
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void SwitchControl(short itemNumber)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
if (item->objectNumber != ID_AIRLOCK_SWITCH || item->triggerFlags < 8)
|
|
|
|
{
|
|
|
|
item->flags |= 0x3E00;
|
|
|
|
if (!TriggerActive(item) && !(item->flags & 0x100))
|
|
|
|
{
|
|
|
|
if (item->objectNumber == ID_JUMP_SWITCH)
|
|
|
|
{
|
|
|
|
item->goalAnimState = 0;
|
|
|
|
item->timer = 0;
|
|
|
|
AnimateItem(item);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
item->timer = 0;
|
|
|
|
}
|
|
|
|
}
|
2019-11-17 08:21:25 +01:00
|
|
|
else
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
2019-11-17 08:21:25 +01:00
|
|
|
/*if (item->animNumber == Objects[ID_AIRLOCK_SWITCH].animIndex + 1 && item->frameNumber == Anims[item->animNumber].frameEnd - 1)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
if (GetSwitchTrigger(&item, &ItemNos, 1) > 0)
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
v4 = (short*)((char*)& v15 + 2 * v3 + 2);
|
2019-11-09 09:55:56 +01:00
|
|
|
v11 = v3;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
v5 = *v4;
|
|
|
|
v6 = items;
|
|
|
|
v6[v5].flags ^= 0x3E00u;
|
|
|
|
v7 = & v6[v5];
|
|
|
|
if ((v6[v5].flags & 0x3E00) == 15872 && (*(_BYTE*)(v7 + 5610) & 6) != 2)
|
|
|
|
{
|
|
|
|
AddActiveItem(*v4);
|
|
|
|
v8 = *(_DWORD*)(v7 + 5610);
|
|
|
|
LOBYTE(v8) = v8 & 0xFB | 2;
|
|
|
|
*(_DWORD*)(v7 + 5610) = v8;
|
|
|
|
}
|
|
|
|
--v4;
|
|
|
|
--v11;
|
|
|
|
} while (v11);
|
|
|
|
}
|
2019-11-17 08:21:25 +01:00
|
|
|
}*/
|
|
|
|
|
2019-11-09 09:55:56 +01:00
|
|
|
if (item->triggerFlags == 8)
|
|
|
|
{
|
2019-11-17 08:21:25 +01:00
|
|
|
PHD_VECTOR pos;
|
|
|
|
pos.x = 0;
|
|
|
|
pos.y = 0;
|
|
|
|
pos.z = 0;
|
|
|
|
|
|
|
|
GetJointAbsPosition(item, &pos, 0);
|
|
|
|
|
2019-11-27 15:12:35 +01:00
|
|
|
short roomNumber = item->roomNumber;
|
2019-11-17 08:21:25 +01:00
|
|
|
GetFloor(pos.x, pos.y, pos.z, &roomNumber);
|
|
|
|
if (roomNumber != item->roomNumber)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
2019-11-17 08:21:25 +01:00
|
|
|
ItemNewRoom(itemNumber, roomNumber);
|
|
|
|
AnimateItem(item);
|
2019-11-09 09:55:56 +01:00
|
|
|
}
|
|
|
|
}
|
2019-11-17 08:21:25 +01:00
|
|
|
}
|
2019-11-09 09:55:56 +01:00
|
|
|
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void TestTriggersAtXYZ(int x, int y, int z, short roomNumber, int heavy, int flags)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
GetFloorHeight(GetFloor(x, y, z, &roomNumber), x, y, z);
|
|
|
|
TestTriggers(TriggerIndex, heavy, flags);
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
int GetKeyTrigger(ITEM_INFO* item)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &item->roomNumber);
|
|
|
|
GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
|
|
|
|
|
|
|
if (TriggerIndex)
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
short* trigger = TriggerIndex;
|
|
|
|
for (short i = *TriggerIndex; (i & 0x1F) != 4; trigger++)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
if (i < 0)
|
|
|
|
break;
|
2019-11-18 07:48:35 +01:00
|
|
|
i = trigger[1];
|
2019-11-09 09:55:56 +01:00
|
|
|
}
|
|
|
|
if (*trigger & 4)
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
for (short* j = &trigger[2]; (*j >> 8) & 0x3C || item != &Items[*j & 0x3FF]; j++)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
if (*j & 0x8000)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
int GetSwitchTrigger(ITEM_INFO* item, short* itemNos, int AttatchedToSwitch)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &item->roomNumber);
|
|
|
|
GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
|
|
|
|
|
|
|
if (TriggerIndex)
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
short* trigger = TriggerIndex;
|
|
|
|
for (int i = *TriggerIndex; (i & 0x1F) != 4; trigger++)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
if (i < 0)
|
|
|
|
break;
|
2019-11-18 07:48:35 +01:00
|
|
|
i = trigger[1];
|
2019-11-09 09:55:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (*trigger & 4)
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
short* current = itemNos;
|
|
|
|
for (short* j = &trigger[2]; (*j >> 8) & 0x3C || item != &Items[*j & 0x3FF]; j++, current++)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
*current = *j & 0x3FF;
|
|
|
|
if (*j & 0x8000)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
int SwitchTrigger(short itemNum, short timer)
|
2019-11-09 09:55:56 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
if (item->status == ITEM_DEACTIVATED)
|
|
|
|
{
|
|
|
|
if ((!item->currentAnimState && item->objectNumber != ID_JUMP_SWITCH || item->currentAnimState == 1 && item->objectNumber == ID_JUMP_SWITCH) && timer > 0)
|
|
|
|
{
|
|
|
|
item->timer = timer;
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
if (timer != 1)
|
|
|
|
item->timer = 30 * timer;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (item->triggerFlags != 6 || item->currentAnimState)
|
|
|
|
{
|
|
|
|
RemoveActiveItem(itemNum);
|
|
|
|
|
|
|
|
item->status = ITEM_INACTIVE;
|
|
|
|
if (!item->itemFlags[0] == 0)
|
|
|
|
item->flags |= 0x100;
|
|
|
|
if (item->currentAnimState != 1)
|
|
|
|
return 1;
|
|
|
|
if (item->triggerFlags != 5 && item->triggerFlags != 6)
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (item->status)
|
|
|
|
{
|
|
|
|
return (item->flags & 0x100u) >> 8;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void InitialiseSwitch(short itemNumber)
|
2019-11-18 07:48:35 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
if (item->triggerFlags >= 1000)
|
|
|
|
{
|
|
|
|
item->itemFlags[3] = ((item->triggerFlags - 1000) % 10) | 16 * ((item->triggerFlags - 1000) / 10);
|
|
|
|
item->triggerFlags = 6;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void InitialisePulleySwitch(short itemNumber)
|
2019-11-18 07:48:35 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
item->itemFlags[3] = item->triggerFlags;
|
|
|
|
item->triggerFlags = abs(item->triggerFlags);
|
|
|
|
//if (itemNumber == word_E5BF24)
|
|
|
|
// item->itemFlags[1] = 1;
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void InitialiseCrowDoveSwitch(short itemNumber)
|
2019-11-18 07:48:35 +01:00
|
|
|
{
|
|
|
|
Items[itemNumber].meshBits = 3;
|
|
|
|
}
|
|
|
|
|
2019-11-09 09:55:56 +01:00
|
|
|
void Inject_Switch()
|
|
|
|
{
|
|
|
|
INJECT(0x0047FD20, CrowDoveSwitchCollision);
|
|
|
|
INJECT(0x0047FC80, CrowDoveSwitchControl);
|
|
|
|
INJECT(0x0047F990, CogSwitchCollision);
|
|
|
|
INJECT(0x0047F810, CogSwitchControl);
|
|
|
|
INJECT(0x0047F610, FullBlockSwitchCollision);
|
|
|
|
INJECT(0x0047F520, FullBlockSwitchControl);
|
|
|
|
INJECT(0x0047F190, CrowbarSwitchCollision);
|
|
|
|
INJECT(0x0047F050, JumpSwitchCollision);
|
|
|
|
INJECT(0x0047EE00, RailSwitchCollision);
|
|
|
|
INJECT(0x0047E950, TurnSwitchCollision);
|
|
|
|
INJECT(0x0047E650, TurnSwitchControl);
|
|
|
|
INJECT(0x0047E450, PulleyCollision);
|
|
|
|
INJECT(0x0047E220, UnderwaterSwitchCollision);
|
|
|
|
INJECT(0x0047E0C0, SwitchCollision2);
|
|
|
|
INJECT(0x0047DC70, SwitchCollision);
|
|
|
|
INJECT(0x0047D9D0, TestTriggersAtXYZ);
|
|
|
|
INJECT(0x0047D8C0, GetKeyTrigger);
|
|
|
|
INJECT(0x0047D7B0, GetSwitchTrigger);
|
|
|
|
INJECT(0x0047D670, SwitchTrigger);
|
|
|
|
}
|