Merge branch 'DiagonalCollisions' into NoShifts

This commit is contained in:
asasas9500 2020-08-07 16:43:29 -03:00
commit 671d59e1c8
304 changed files with 15655 additions and 17021 deletions

View file

@ -1,3 +1,4 @@
#include "./../VertexInput.hlsli"
cbuffer HUDBarBuffer : register(b0)
{
float Percent;

View file

@ -1,18 +1,10 @@
#include "./../VertexInput.hlsli"
cbuffer HUDBuffer : register(b0)
{
float4x4 View;
float4x4 Projection;
};
struct VertexShaderInput
{
float3 Position: POSITION;
float3 Normal: NORMAL;
float2 UV: TEXCOORD;
float4 Color: COLOR;
float Bone : BLENDINDICES;
};
struct PixelShaderInput
{
float4 Position: SV_POSITION;

View file

@ -36,14 +36,14 @@ typedef enum ZoneType
ZONE_APE, // only 2 click climb
};
typedef struct OBJECT_BONES
typedef struct OBJECT_Bones
{
short bone0;
short bone1;
short bone2;
short bone3;
OBJECT_BONES()
OBJECT_Bones()
{
this->bone0 = 0;
this->bone1 = 0;
@ -51,7 +51,7 @@ typedef struct OBJECT_BONES
this->bone3 = 0;
}
OBJECT_BONES(short all)
OBJECT_Bones(short all)
{
this->bone0 = all;
this->bone1 = all;
@ -59,7 +59,7 @@ typedef struct OBJECT_BONES
this->bone3 = all;
}
OBJECT_BONES(short angleY, short angleX)
OBJECT_Bones(short angleY, short angleX)
{
this->bone0 = angleY;
this->bone1 = angleX;
@ -67,7 +67,7 @@ typedef struct OBJECT_BONES
this->bone3 = angleX;
}
OBJECT_BONES(short angleY, short angleX, bool total)
OBJECT_Bones(short angleY, short angleX, bool total)
{
this->bone0 = angleY;
this->bone1 = angleX;
@ -84,28 +84,18 @@ typedef struct OBJECT_BONES
}
};
typedef struct BOX_NODE
struct BOX_NODE
{
short exitBox;
unsigned short searchNumber;
short nextExpansion;
short boxNumber;
int exitBox;
int searchNumber;
int nextExpansion;
int boxNumber;
};
typedef struct BOX_INFO
struct AI_INFO
{
unsigned char left;
unsigned char right;
unsigned char top;
unsigned char bottom;
short height;
short overlapIndex;
};
typedef struct AI_INFO
{
short zoneNumber;
short enemyZone;
int zoneNumber;
int enemyZone;
int distance;
int ahead;
int bite;
@ -114,7 +104,24 @@ typedef struct AI_INFO
short enemyFacing;
};
typedef struct BITE_INFO
struct BOX_INFO
{
unsigned int left;
unsigned int right;
unsigned int top;
unsigned int bottom;
int height;
int overlapIndex;
int flags;
};
struct OVERLAP
{
int box;
int flags;
};
struct BITE_INFO
{
int x;
int y;
@ -138,18 +145,18 @@ typedef struct BITE_INFO
}
};
typedef struct LOT_INFO
struct LOT_INFO
{
BOX_NODE* node;
short head;
short tail;
unsigned short searchNumber;
unsigned short blockMask;
std::vector<BOX_NODE> node;
int head;
int tail;
int searchNumber;
int blockMask;
short step;
short drop;
short zoneCount;
short targetBox;
short requiredBox;
int targetBox;
int requiredBox;
short fly;
bool canJump;
bool canMonkey;
@ -160,7 +167,7 @@ typedef struct LOT_INFO
ZoneType zone;
};
typedef struct CREATURE_INFO
struct CREATURE_INFO
{
short jointRotation[4];
short maximumTurn;
@ -249,7 +256,7 @@ constexpr auto BLOCKED = 0x4000;
constexpr auto OVERLAP_INDEX = 0x3FFF;
constexpr auto SEARCH_NUMBER = 0x7FFF;
constexpr auto BLOCKED_SEARCH = 0x8000;
constexpr auto NO_BOX = 0x7FF;
constexpr auto NO_BOX = -1;
constexpr auto BOX_JUMP = 0x800;
constexpr auto BOX_MONKEY = 0x2000;
constexpr auto BOX_NUMBER = 0x7FF;
@ -268,12 +275,6 @@ constexpr auto SECONDARY_CLIP = 0x10;
constexpr auto ALL_CLIP = (CLIP_LEFT | CLIP_RIGHT | CLIP_TOP | CLIP_BOTTOM);
constexpr auto SLOPE_DIF = 60;
extern int NumberBoxes;
extern BOX_INFO* Boxes;
extern int NumberOverlaps;
extern short* Overlaps;
extern short* Zones[ZONE_MAX][2];
void GetCreatureMood(ITEM_INFO* item, AI_INFO* info, int violent);
void CreatureMood(ITEM_INFO* item, AI_INFO* info, int violent);
void FindAITargetObject(CREATURE_INFO* creature, short objectNumber);
@ -299,13 +300,13 @@ void CreatureDie(short itemNumber, int explode);
int BadFloor(int x, int y, int z, int boxHeight, int nextHeight, short roomNumber, LOT_INFO* LOT);
int CreatureCreature(short itemNumber);
int ValidBox(ITEM_INFO* item, short zoneNumber, short boxNumber);
int EscapeBox(ITEM_INFO* item, ITEM_INFO* enemy, short boxNumber);
void TargetBox(LOT_INFO* LOT, short boxNumber);
int EscapeBox(ITEM_INFO* item, ITEM_INFO* enemy, int boxNumber);
void TargetBox(LOT_INFO* LOT, int boxNumber);
int UpdateLOT(LOT_INFO* LOT, int expansion);
int SearchLOT(LOT_INFO* LOT, int expansion);
int CreatureActive(short itemNumber);
void InitialiseCreature(short itemNumber);
int StalkBox(ITEM_INFO* item, ITEM_INFO* enemy, short boxNumber);
int StalkBox(ITEM_INFO* item, ITEM_INFO* enemy, int boxNumber);
void CreatureAIInfo(ITEM_INFO* item, AI_INFO* info);
TARGET_TYPE CalculateTarget(PHD_VECTOR* target, ITEM_INFO* item, LOT_INFO* LOT);
int CreatureAnimation(short itemNumber, short angle, short tilt);

View file

@ -12,12 +12,6 @@
#include "trmath.h"
#include "objectslist.h"
int NumberBoxes;
BOX_INFO* Boxes;
int NumberOverlaps;
short* Overlaps;
short* Zones[ZONE_MAX][2];
#define CHECK_CLICK(x) CLICK(x) / 2
#define ESCAPE_DIST SECTOR(5)
#define STALK_DIST SECTOR(3)
@ -34,11 +28,11 @@ void DropBaddyPickups(ITEM_INFO* item)
ITEM_INFO* pickup = NULL;
FLOOR_INFO* floor;
short roomNumber;
short* bounds;
BOUNDING_BOX* bounds;
for (short pickupNumber = item->carriedItem; pickupNumber != NO_ITEM; pickupNumber = pickup->carriedItem)
{
pickup = &Items[pickupNumber];
pickup = &g_Level.Items[pickupNumber];
pickup->pos.xPos = (item->pos.xPos & -CLICK(2)) | CLICK(2);
pickup->pos.zPos = (item->pos.zPos & -CLICK(2)) | CLICK(2);
@ -46,7 +40,7 @@ void DropBaddyPickups(ITEM_INFO* item)
floor = GetFloor(pickup->pos.xPos, item->pos.yPos, pickup->pos.zPos, &roomNumber);
pickup->pos.yPos = GetFloorHeight(floor, pickup->pos.xPos, item->pos.yPos, pickup->pos.zPos);
bounds = GetBoundsAccurate(pickup);
pickup->pos.yPos -= bounds[3];
pickup->pos.yPos -= bounds->Y2;
ItemNewRoom(pickupNumber, item->roomNumber);
pickup->flags |= 32;
@ -112,17 +106,17 @@ void CreatureYRot2(PHD_3DPOS* srcpos, short angle, short angadd)
short SameZone(CREATURE_INFO* creature, ITEM_INFO* targetItem)
{
ITEM_INFO* item = &Items[creature->itemNum];
ITEM_INFO* item = &g_Level.Items[creature->itemNum];
ROOM_INFO* r;
short* zone;
int* zone;
r = &Rooms[item->roomNumber];
r = &g_Level.Rooms[item->roomNumber];
item->boxNumber = XZ_GET_SECTOR(r, item->pos.xPos - r->x, item->pos.zPos - r->z).box;
r = &Rooms[targetItem->roomNumber];
r = &g_Level.Rooms[targetItem->roomNumber];
targetItem->boxNumber = XZ_GET_SECTOR(r, targetItem->pos.xPos - r->x, targetItem->pos.zPos - r->z).box;
zone = Zones[creature->LOT.zone][FlipStatus];
zone = g_Level.Zones[creature->LOT.zone][FlipStatus].data();
return zone[item->boxNumber] == zone[targetItem->boxNumber];
}
@ -131,7 +125,7 @@ short AIGuard(CREATURE_INFO* creature)
ITEM_INFO* item;
int random;
item = &Items[creature->itemNum];
item = &g_Level.Items[creature->itemNum];
if (item->aiBits & (GUARD | PATROL1))
return 0;
@ -175,7 +169,7 @@ void AlertNearbyGuards(ITEM_INFO* item)
if (creature->itemNum == NO_ITEM)
continue;
target = &Items[creature->itemNum + i];
target = &g_Level.Items[creature->itemNum + i];
if (item->roomNumber == target->roomNumber)
{
creature->alerted = true;
@ -204,8 +198,8 @@ void AlertAllGuards(short itemNumber)
if (creature->itemNum == NO_ITEM)
continue;
target = &Items[creature->itemNum];
objNumber = Items[itemNumber].objectNumber;
target = &g_Level.Items[creature->itemNum];
objNumber = g_Level.Items[itemNumber].objectNumber;
if (objNumber == target->objectNumber)
{
if (target->status == ITEM_ACTIVE)
@ -217,11 +211,11 @@ void AlertAllGuards(short itemNumber)
void CreatureKill(ITEM_INFO* item, int killAnim, int killState, short laraKillState)
{
item->animNumber = Objects[item->objectNumber].animIndex + killAnim;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = killState;
LaraItem->animNumber = Objects[ID_LARA_EXTRA_ANIMS].animIndex;
LaraItem->frameNumber = Anims[LaraItem->animNumber].frameBase;
LaraItem->frameNumber = g_Level.Anims[LaraItem->animNumber].frameBase;
LaraItem->currentAnimState = 0;
LaraItem->goalAnimState = laraKillState;
@ -330,7 +324,7 @@ void CreatureFloat(short itemNumber)
int y;
short roomNumber;
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
item->hitPoints = NOT_TARGETABLE;
item->pos.xRot = 0;
@ -353,7 +347,7 @@ void CreatureFloat(short itemNumber)
if (item->pos.yPos <= waterLevel)
{
if (item->frameNumber == Anims[item->animNumber].frameBase)
if (item->frameNumber == g_Level.Anims[item->animNumber].frameBase)
{
item->pos.yPos = waterLevel;
item->collidable = false;
@ -432,72 +426,6 @@ short CreatureTurn(ITEM_INFO* item, short maximumTurn)
item->pos.yRot += angle;
/*
ROOM_INFO* r;
CREATURE_INFO* creature;
int range, distance;
short angle;
short xAngle1, zAngle1;
short xAngle2, zAngle2;
short xAngle3, zAngle3;
int xDist, zDist;
unsigned short floorIndex1, floorIndex2, floorIndex3;
r = &Rooms[item->roomNumber];
creature = (CREATURE_INFO*)item->data;
// "<< 11" is really needed ? it can cause problem i think since it TR3 code the "<< 11" is not there !
xAngle1 = item->pos.xPos + phd_sin(item->pos.yRot + ANGLE(45)) << 11 >> W2V_SHIFT;
zAngle1 = item->pos.zPos + phd_cos(item->pos.yRot + ANGLE(45)) << 11 >> W2V_SHIFT;
floorIndex1 = XZ_GET_SECTOR(r, xAngle1 - r->x, zAngle1 - r->z).index;
xAngle2 = item->pos.xPos + phd_sin(item->pos.yRot - ANGLE(45)) << 11 >> W2V_SHIFT;
zAngle2 = item->pos.zPos + phd_cos(item->pos.yRot - ANGLE(45)) << 11 >> W2V_SHIFT;
floorIndex2 = XZ_GET_SECTOR(r, xAngle2 - r->x, zAngle2 - r->z).index;
xAngle3 = item->pos.xPos + phd_sin(item->pos.yRot) << 11 >> W2V_SHIFT;
zAngle3 = item->pos.zPos + phd_cos(item->pos.yRot) << 11 >> W2V_SHIFT;
floorIndex3 = XZ_GET_SECTOR(r, xAngle3 - r->x, zAngle3 - r->z).index;
if (floorIndex1 && !floorIndex2 && !floorIndex3)
{
creature = (CREATURE_INFO*)item->data;
creature->target.x = xAngle1;
creature->target.z = zAngle1;
}
else if (floorIndex2 && !floorIndex1 && !floorIndex3)
{
creature = (CREATURE_INFO*)item->data;
creature->target.x = xAngle2;
creature->target.z = zAngle2;
}
else if (floorIndex3 && !floorIndex1 && !floorIndex2)
{
creature = (CREATURE_INFO*)item->data;
creature->target.x = xAngle3;
creature->target.z = zAngle3;
}
xDist = creature->target.x - item->pos.xPos;
zDist = creature->target.z - item->pos.zPos;
angle = phd_atan(zDist, xDist) - item->pos.yRot;
if (angle > FRONT_ARC || angle < -FRONT_ARC)
{
range = (item->speed << W2V_SHIFT) / maximumTurn;
distance = SQUARE(zDist) + SQUARE(xDist);
if (distance < SQUARE(range))
maximumTurn >>= 1;
}
if (angle > maximumTurn)
angle = maximumTurn;
else if (angle < -maximumTurn)
angle = -maximumTurn;
item->pos.yRot += (angle + maximumTurn);
*/
return angle;
}
@ -509,17 +437,19 @@ int CreatureAnimation(short itemNumber, short angle, short tilt)
FLOOR_INFO* floor;
PHD_VECTOR old;
int xPos, zPos, x, y, z, ceiling, shiftX, shiftZ, dy;
short* zone, *bounds;
short roomNumber, boxHeight, height, nextHeight, nextBox, radius, biffAngle, top;
BOUNDING_BOX* bounds;
int* zone;
short roomNumber, radius, biffAngle, top;
int boxHeight, height, nextHeight, nextBox;
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
if (item->data == NULL)
return FALSE;
return false;
creature = (CREATURE_INFO*)item->data;
LOT = &creature->LOT;
zone = Zones[LOT->zone][FlipStatus];
boxHeight = Boxes[item->boxNumber].height;
zone = g_Level.Zones[LOT->zone][FlipStatus].data();
boxHeight = g_Level.Boxes[item->boxNumber].height;
old.x = item->pos.xPos;
old.y = item->pos.yPos;
old.z = item->pos.zPos;
@ -536,16 +466,16 @@ int CreatureAnimation(short itemNumber, short angle, short tilt)
if (item->status == ITEM_DEACTIVATED)
{
CreatureDie(itemNumber, FALSE);
return FALSE;
return false;
}
bounds = GetBoundsAccurate(item);
y = item->pos.yPos + bounds[2];
y = item->pos.yPos + bounds->Y1;
roomNumber = item->roomNumber;
GetFloor(old.x, y, old.z, &roomNumber);
floor = GetFloor(item->pos.xPos, y, item->pos.zPos, &roomNumber);
height = Boxes[floor->box].height;
height = g_Level.Boxes[floor->box].height;
nextHeight = 0;
if (!Objects[item->objectNumber].nonLot)
@ -555,14 +485,14 @@ int CreatureAnimation(short itemNumber, short angle, short tilt)
else
{
floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
height = Boxes[floor->box].height;
height = g_Level.Boxes[floor->box].height;
nextBox = floor->box;
}
if (nextBox == NO_BOX)
nextHeight = height;
else
nextHeight = Boxes[nextBox].height;
nextHeight = g_Level.Boxes[nextBox].height;
if (floor->box == NO_BOX || !LOT->isJumping && (LOT->fly == NO_FLYING && zone[item->boxNumber] != zone[floor->box] || boxHeight - height > LOT->step || boxHeight - height < LOT->drop))
{
@ -582,7 +512,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt)
item->pos.zPos = old.z | (WALL_SIZE - 1);
floor = GetFloor(item->pos.xPos, y, item->pos.zPos, &roomNumber);
height = Boxes[floor->box].height;
height = g_Level.Boxes[floor->box].height;
if (!Objects[item->objectNumber].nonLot)
{
nextHeight = LOT->node[floor->box].exitBox;
@ -590,14 +520,14 @@ int CreatureAnimation(short itemNumber, short angle, short tilt)
else
{
floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
height = Boxes[floor->box].height;
height = g_Level.Boxes[floor->box].height;
nextBox = floor->box;
}
if (nextBox == NO_BOX)
nextHeight = height;
else
nextHeight = Boxes[nextBox].height;
nextHeight = g_Level.Boxes[nextBox].height;
}
x = item->pos.xPos;
@ -714,7 +644,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt)
item->pos.yRot -= BIFF_AVOID_TURN;
else
item->pos.yRot += BIFF_AVOID_TURN;
return TRUE;
return true;
}
if (LOT->fly != NO_FLYING && item->hitPoints > 0)
@ -735,7 +665,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt)
if (item->objectNumber == ID_WHALE)
top = STEP_SIZE / 2;
else
top = bounds[2];
top = bounds->Y1;
if (item->pos.yPos + top + dy < ceiling)
{
@ -752,7 +682,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt)
else
{
floor = GetFloor(item->pos.xPos, y + STEP_SIZE, item->pos.zPos, &roomNumber);
if (Rooms[roomNumber].flags & (ENV_FLAG_WATER | ENV_FLAG_SWAMP))
if (g_Level.Rooms[roomNumber].flags & (ENV_FLAG_WATER | ENV_FLAG_SWAMP))
{
dy = -LOT->fly;
}
@ -796,7 +726,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt)
if (LOT->isMonkeying)
{
ceiling = GetCeiling(floor, item->pos.xPos, y, item->pos.zPos);
item->pos.yPos = ceiling - bounds[2];
item->pos.yPos = ceiling - bounds->Y1;
}
else
{
@ -823,7 +753,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt)
if (item->objectNumber == ID_TYRANNOSAUR || item->objectNumber == ID_SHIVA || item->objectNumber == ID_MUTANT2)
top = STEP_SIZE*3;
else
top = bounds[2];
top = bounds->Y1; // TODO: check if Y1 or Y2
if (item->pos.yPos + top < ceiling)
{
@ -850,19 +780,19 @@ int CreatureAnimation(short itemNumber, short angle, short tilt)
{
GetFloor(item->pos.xPos, item->pos.yPos - STEP_SIZE*2, item->pos.zPos, &roomNumber);
if (Rooms[roomNumber].flags & ENV_FLAG_WATER)
if (g_Level.Rooms[roomNumber].flags & ENV_FLAG_WATER)
item->hitPoints = 0;
}
if (item->roomNumber != roomNumber)
ItemNewRoom(itemNumber, roomNumber);
return TRUE;
return true;
}
void CreatureDie(short itemNumber, int explode)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->hitPoints = -16384;
item->collidable = false;
@ -897,10 +827,10 @@ int BadFloor(int x, int y, int z, int boxHeight, int nextHeight, short roomNumbe
if (LOT->isJumping)
return false;
if (Boxes[floor->box].overlapIndex & LOT->blockMask)
if (g_Level.Boxes[floor->box].flags & LOT->blockMask)
return true;
height = Boxes[floor->box].height;
height = g_Level.Boxes[floor->box].height;
if (boxHeight - height > LOT->step || boxHeight - height < LOT->drop)
return true;
@ -916,22 +846,22 @@ int BadFloor(int x, int y, int z, int boxHeight, int nextHeight, short roomNumbe
int CreatureCreature(short itemNumber)
{
ITEM_INFO* item, *linked;
ObjectInfo* obj;
OBJECT_INFO* obj;
ROOM_INFO* r;
int x, z, xDistance, zDistance, distance = 0;
short link, radius;
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
obj = &Objects[item->objectNumber];
x = item->pos.xPos;
z = item->pos.zPos;
radius = obj->radius;
r = &Rooms[item->roomNumber];
r = &g_Level.Rooms[item->roomNumber];
link = r->itemNumber;
do
{
linked = &Items[link];
linked = &g_Level.Items[link];
if (link != itemNumber && linked != LaraItem && linked->status == ITEM_ACTIVE && linked->hitPoints > 0)
{
@ -957,15 +887,15 @@ int ValidBox(ITEM_INFO* item, short zoneNumber, short boxNumber)
{
CREATURE_INFO* creature;
BOX_INFO* box;
short* zone;
int* zone;
creature = (CREATURE_INFO*)item->data;
zone = Zones[creature->LOT.zone][FlipStatus];
zone = g_Level.Zones[creature->LOT.zone][FlipStatus].data();
if (creature->LOT.fly == NO_FLYING && zone[boxNumber] != zoneNumber)
return false;
box = &Boxes[boxNumber];
if (box->overlapIndex & creature->LOT.blockMask)
box = &g_Level.Boxes[boxNumber];
if (box->flags & creature->LOT.blockMask)
return false;
if ((item->pos.zPos > (box->left << WALL_SHIFT)) && item->pos.zPos < ((box->right << WALL_SHIFT)) &&
@ -975,9 +905,9 @@ int ValidBox(ITEM_INFO* item, short zoneNumber, short boxNumber)
return true;
}
int EscapeBox(ITEM_INFO* item, ITEM_INFO* enemy, short boxNumber)
int EscapeBox(ITEM_INFO* item, ITEM_INFO* enemy, int boxNumber)
{
BOX_INFO* box = &Boxes[boxNumber];
BOX_INFO* box = &g_Level.Boxes[boxNumber];
int x, z;
x = (int(box->top + box->bottom) << (WALL_SHIFT - 1)) - enemy->pos.xPos;
@ -992,15 +922,13 @@ int EscapeBox(ITEM_INFO* item, ITEM_INFO* enemy, short boxNumber)
return true;
}
void TargetBox(LOT_INFO* LOT, short boxNumber)
void TargetBox(LOT_INFO* LOT, int boxNumber)
{
BOX_INFO* box;
boxNumber &= NO_BOX;
box = &Boxes[boxNumber];
box = &g_Level.Boxes[boxNumber];
//LOT->target.x = (((((box->bottom - box->top) - 1) * GetRandomControl()) / 32) + (box->top * 1024)) + 512;
//LOT->target.z = (((((box->right - box->left) - 1) * GetRandomControl()) / 32) + (box->left * 1024)) + 512;
LOT->target.x = ((box->top << WALL_SHIFT) + GetRandomControl() * ((box->bottom - box->top) - 1) >> 5) + WALL_SIZE / 2;
LOT->target.z = ((box->left << WALL_SHIFT) + GetRandomControl() * ((box->right - box->left) - 1) >> 5) + WALL_SIZE / 2;
LOT->requiredBox = boxNumber;
@ -1015,6 +943,8 @@ int UpdateLOT(LOT_INFO* LOT, int depth)
{
BOX_NODE* node;
//printf("LOT->head: %d, LOT->tail: %d\n", LOT->head, LOT->tail);
if (LOT->requiredBox != NO_BOX && LOT->requiredBox != LOT->targetBox)
{
LOT->targetBox = LOT->requiredBox;
@ -1041,97 +971,102 @@ int SearchLOT(LOT_INFO* LOT, int depth)
{
BOX_NODE* node, *expand;
BOX_INFO* box;
short* zone, index, searchZone, boxNumber, delta;
int* zone, index, searchZone, boxNumber, delta, flags;
bool done;
zone = Zones[LOT->zone][FlipStatus];
zone = g_Level.Zones[LOT->zone][FlipStatus].data();
searchZone = zone[LOT->head];
if (depth <= 0)
return 1;
return true;
for (int i = 0; i < depth; i++)
{
if (LOT->head == NO_BOX)
{
LOT->tail = NO_BOX;
return FALSE;
return false;
}
node = &LOT->node[LOT->head];
box = &Boxes[LOT->head];
box = &g_Level.Boxes[LOT->head];
index = box->overlapIndex & OVERLAP_INDEX;
index = box->overlapIndex;
done = false;
do
if (index >= 0)
{
boxNumber = Overlaps[index++];
if (boxNumber & BOX_END_BIT)
do
{
done = TRUE;
boxNumber &= BOX_NUMBER;
}
boxNumber = g_Level.Overlaps[index].box;
flags = g_Level.Overlaps[index++].flags;
if (LOT->fly == NO_FLYING && searchZone != zone[boxNumber])
continue;
delta = Boxes[boxNumber].height - box->height;
if (delta > LOT->step || delta < LOT->drop)
continue;
expand = &LOT->node[boxNumber];
if ((node->searchNumber & SEARCH_NUMBER) < (expand->searchNumber & SEARCH_NUMBER))
continue;
if (node->searchNumber & BLOCKED_SEARCH)
{
if ((node->searchNumber & SEARCH_NUMBER) == (expand->searchNumber & SEARCH_NUMBER))
continue;
expand->searchNumber = node->searchNumber;
}
else
{
if ((node->searchNumber & SEARCH_NUMBER) == (expand->searchNumber & SEARCH_NUMBER) && !(expand->searchNumber & BLOCKED_SEARCH))
continue;
if (Boxes[boxNumber].overlapIndex & LOT->blockMask)
if (flags & BOX_END_BIT)
{
expand->searchNumber = node->searchNumber | BLOCKED_SEARCH;
done = true;
}
if (LOT->fly == NO_FLYING && searchZone != zone[boxNumber])
continue;
delta = g_Level.Boxes[boxNumber].height - box->height;
if (delta > LOT->step || delta < LOT->drop)
continue;
expand = &LOT->node[boxNumber];
if ((node->searchNumber & SEARCH_NUMBER) < (expand->searchNumber & SEARCH_NUMBER))
continue;
if (node->searchNumber & BLOCKED_SEARCH)
{
if ((node->searchNumber & SEARCH_NUMBER) == (expand->searchNumber & SEARCH_NUMBER))
continue;
expand->searchNumber = node->searchNumber;
}
else
{
expand->searchNumber = node->searchNumber;
expand->exitBox = LOT->head;
}
}
if ((node->searchNumber & SEARCH_NUMBER) == (expand->searchNumber & SEARCH_NUMBER) && !(expand->searchNumber & BLOCKED_SEARCH))
continue;
if (expand->nextExpansion == NO_BOX && boxNumber != LOT->tail)
{
LOT->node[LOT->tail].nextExpansion = boxNumber;
LOT->tail = boxNumber;
}
} while (!done);
if (g_Level.Boxes[boxNumber].flags & LOT->blockMask)
{
expand->searchNumber = node->searchNumber | BLOCKED_SEARCH;
}
else
{
expand->searchNumber = node->searchNumber;
expand->exitBox = LOT->head;
}
}
if (expand->nextExpansion == NO_BOX && boxNumber != LOT->tail)
{
LOT->node[LOT->tail].nextExpansion = boxNumber;
LOT->tail = boxNumber;
}
} while (!done);
}
LOT->head = node->nextExpansion;
node->nextExpansion = NO_BOX;
}
return TRUE;
return true;
}
int CreatureActive(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (!(item->flags & IFLAG_KILLED) && item->status & ITEM_INVISIBLE)
if (!(item->flags & IFLAG_KILLED)
&& item->status & ITEM_INVISIBLE)
{
if (!EnableBaddieAI(itemNumber, FALSE))
return FALSE;
if (!EnableBaddieAI(itemNumber, false))
return false;
item->status = ITEM_ACTIVE;
}
return TRUE;
return true;
}
void InitialiseCreature(short itemNumber)
@ -1139,16 +1074,16 @@ void InitialiseCreature(short itemNumber)
ClearItem(itemNumber);
}
int StalkBox(ITEM_INFO* item, ITEM_INFO* enemy, short boxNumber)
int StalkBox(ITEM_INFO* item, ITEM_INFO* enemy, int boxNumber)
{
if (enemy == NULL)
return FALSE;
return false;
BOX_INFO* box;
int x, z, xrange, zrange;
int enemyQuad, boxQuad, baddieQuad;
box = &Boxes[boxNumber];
box = &g_Level.Boxes[boxNumber];
xrange = STALK_DIST + ((box->bottom - box->top + 3) << WALL_SHIFT);
zrange = STALK_DIST + ((box->right - box->left + 3) << WALL_SHIFT);
@ -1156,7 +1091,7 @@ int StalkBox(ITEM_INFO* item, ITEM_INFO* enemy, short boxNumber)
z = ((box->left + box->right) << (WALL_SHIFT - 1)) - enemy->pos.zPos;
if (x > xrange || x < -xrange || z > zrange || z < -zrange)
return FALSE;
return false;
enemyQuad = (enemy->pos.yRot >> W2V_SHIFT) + 2;
@ -1167,7 +1102,7 @@ int StalkBox(ITEM_INFO* item, ITEM_INFO* enemy, short boxNumber)
boxQuad = (x > 0) ? 3 : 0;
if (enemyQuad == boxQuad)
return FALSE;
return false;
baddieQuad = 0;
if (item->pos.zPos > enemy->pos.zPos)
@ -1176,14 +1111,14 @@ int StalkBox(ITEM_INFO* item, ITEM_INFO* enemy, short boxNumber)
baddieQuad = (item->pos.xPos > enemy->pos.xPos) ? 3 : 0;
if (enemyQuad == baddieQuad && abs(enemyQuad - boxQuad) == 2)
return FALSE;
return false;
return TRUE;
return true;
}
int CreatureVault(short itemNum, short angle, int vault, int shift)
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
int xBlock, zBlock, y, newXblock, newZblock;
short roomNumber;
@ -1269,7 +1204,7 @@ void GetAITarget(CREATURE_INFO* creature)
else
enemyObjectNumber = NO_ITEM;
item = &Items[creature->itemNum];
item = &g_Level.Items[creature->itemNum];
if (item->aiBits & GUARD)
{
@ -1381,11 +1316,11 @@ void GetAITarget(CREATURE_INFO* creature)
// tr3 old way..
void FindAITarget(CREATURE_INFO* creature, short objectNumber)
{
ITEM_INFO* item = &Items[creature->itemNum];
ITEM_INFO* item = &g_Level.Items[creature->itemNum];
ITEM_INFO* targetItem;
int i;
for (i = 0, targetItem = &Items[0]; i < LevelItems; i++, targetItem++)
for (i = 0, targetItem = &g_Level.Items[0]; i < g_Level.NumItems; i++, targetItem++)
{
if (targetItem->objectNumber == objectNumber && targetItem->roomNumber != NO_ROOM)
{
@ -1400,25 +1335,25 @@ void FindAITarget(CREATURE_INFO* creature, short objectNumber)
void FindAITargetObject(CREATURE_INFO* creature, short objectNumber)
{
ITEM_INFO* item = &Items[creature->itemNum];
ITEM_INFO* item = &g_Level.Items[creature->itemNum];
if (nAIObjects > 0)
if (g_Level.AIObjects.size() > 0)
{
AIOBJECT* foundObject = NULL;
for (int i = 0; i < nAIObjects; i++)
for (int i = 0; i < g_Level.AIObjects.size(); i++)
{
AIOBJECT* aiObject = &AIObjects[i];
AIOBJECT* aiObject = &g_Level.AIObjects[i];
if (aiObject->objectNumber == objectNumber && aiObject->triggerFlags == item->itemFlags[3] && aiObject->roomNumber != 255)
if (aiObject->objectNumber == objectNumber && aiObject->triggerFlags == item->itemFlags[3] && aiObject->roomNumber != NO_ROOM)
{
short* zone = Zones[creature->LOT.zone][FlipStatus];
int* zone = g_Level.Zones[creature->LOT.zone][FlipStatus].data();
ROOM_INFO* r = &Rooms[item->roomNumber];
item->boxNumber = XZ_GET_SECTOR(r, item->pos.xPos - r->x, item->pos.zPos - r->z).box & 0x7FF;
ROOM_INFO* r = &g_Level.Rooms[item->roomNumber];
item->boxNumber = XZ_GET_SECTOR(r, item->pos.xPos - r->x, item->pos.zPos - r->z).box;
r = &Rooms[aiObject->roomNumber];
aiObject->boxNumber = XZ_GET_SECTOR(r, aiObject->x - r->x, aiObject->z - r->z).box & 0x7FF;
r = &g_Level.Rooms[aiObject->roomNumber];
aiObject->boxNumber = XZ_GET_SECTOR(r, aiObject->x - r->x, aiObject->z - r->z).box;
if (zone[item->boxNumber] == zone[aiObject->boxNumber])
{
@ -1458,36 +1393,37 @@ void CreatureAIInfo(ITEM_INFO* item, AI_INFO* info)
if (item->data == NULL)
return;
CREATURE_INFO* creature;
ITEM_INFO* enemy;
ObjectInfo* obj;
ROOM_INFO* r;
short* zone, angle;
CREATURE_INFO * creature;
ITEM_INFO * enemy;
OBJECT_INFO * obj;
ROOM_INFO * r;
short angle;
int* zone;
int x, y, z;
creature = (CREATURE_INFO*)item->data;
obj = &Objects[item->objectNumber];
enemy = creature->enemy;
if (!enemy)
{
enemy = LaraItem;
enemy = LaraItem;
creature->enemy = LaraItem;
}
zone = Zones[creature->LOT.zone][FlipStatus];
zone = g_Level.Zones[creature->LOT.zone][FlipStatus].data();
r = &Rooms[item->roomNumber];
item->boxNumber = XZ_GET_SECTOR(r, item->pos.xPos - r->x, item->pos.zPos - r->z).box & BOX_NUMBER;
r = &g_Level.Rooms[item->roomNumber];
item->boxNumber = XZ_GET_SECTOR(r, item->pos.xPos - r->x, item->pos.zPos - r->z).box;
info->zoneNumber = zone[item->boxNumber];
r = &Rooms[enemy->roomNumber];
enemy->boxNumber = XZ_GET_SECTOR(r, enemy->pos.xPos - r->x, enemy->pos.zPos - r->z).box & BOX_NUMBER;
r = &g_Level.Rooms[enemy->roomNumber];
enemy->boxNumber = XZ_GET_SECTOR(r, enemy->pos.xPos - r->x, enemy->pos.zPos - r->z).box;
info->enemyZone = zone[enemy->boxNumber];
if (!obj->nonLot)
{
if (Boxes[enemy->boxNumber].overlapIndex & creature->LOT.blockMask)
if (g_Level.Boxes[enemy->boxNumber].flags & creature->LOT.blockMask)
info->enemyZone |= BLOCKED;
else if (creature->LOT.node[item->boxNumber].searchNumber == (creature->LOT.searchNumber | BLOCKED_SEARCH))
info->enemyZone |= BLOCKED;
@ -1520,20 +1456,20 @@ void CreatureAIInfo(ITEM_INFO* item, AI_INFO* info)
}
info->angle = angle - item->pos.yRot;
info->enemyFacing = ANGLE(180) + angle - enemy->pos.yRot;
info->enemyFacing = -ANGLE(180) + angle - enemy->pos.yRot;
x = abs(x);
z = abs(z);
if (enemy == LaraItem)
{
short laraState = LaraItem->currentAnimState;
if (laraState == STATE_LARA_CROUCH_IDLE ||
laraState == STATE_LARA_CROUCH_TURN_LEFT ||
laraState == STATE_LARA_CROUCH_TURN_RIGHT ||
laraState == STATE_LARA_CROUCH_ROLL ||
laraState <= STATE_LARA_MONKEYSWING_TURNAROUND ||
laraState >= STATE_LARA_CLIMB_TO_CRAWL)
if (laraState == LS_CROUCH_IDLE ||
laraState == LS_CROUCH_TURN_LEFT ||
laraState == LS_CROUCH_TURN_RIGHT ||
laraState == LS_CROUCH_ROLL ||
laraState <= LS_MONKEYSWING_TURN_180 ||
laraState >= LS_HANG_TO_CRAWL)
{
y -= STEPUP_HEIGHT;
}
@ -1545,7 +1481,7 @@ void CreatureAIInfo(ITEM_INFO* item, AI_INFO* info)
info->xAngle = phd_atan(z + (x >> 1), y);
info->ahead = (info->angle > -FRONT_ARC && info->angle < FRONT_ARC);
info->bite = (info->ahead && enemy->hitPoints > 0 && abs(enemy->pos.yPos - item->pos.yPos) <= (STEP_SIZE*2));
info->bite = (info->ahead && enemy->hitPoints > 0 && abs(enemy->pos.yPos - item->pos.yPos) <= (STEP_SIZE * 2));
}
void CreatureMood(ITEM_INFO* item, AI_INFO* info, int violent)
@ -1556,8 +1492,8 @@ void CreatureMood(ITEM_INFO* item, AI_INFO* info, int violent)
CREATURE_INFO* creature;
ITEM_INFO* enemy;
LOT_INFO* LOT;
short boxNumber, startBox, overlapIndex, nextBox;
short* bounds;
int boxNumber, startBox, overlapIndex, nextBox, flags;
BOUNDING_BOX* bounds;
creature = (CREATURE_INFO*)item->data;
enemy = creature->enemy;
@ -1567,7 +1503,8 @@ void CreatureMood(ITEM_INFO* item, AI_INFO* info, int violent)
{
case BORED_MOOD:
boxNumber = LOT->node[GetRandomControl() * LOT->zoneCount >> NODE_SHIFT].boxNumber;
if (ValidBox(item, info->zoneNumber, boxNumber))
if (ValidBox(item, info->zoneNumber, boxNumber)
&& !(GetRandomControl() & 0x0F))
{
if (StalkBox(item, enemy, boxNumber) && enemy->hitPoints > 0 && creature->enemy)
{
@ -1589,14 +1526,14 @@ void CreatureMood(ITEM_INFO* item, AI_INFO* info, int violent)
if (LOT->fly != NO_FLYING && Lara.waterStatus == LW_ABOVE_WATER)
{
bounds = GetBestFrame(enemy);
LOT->target.y += bounds[2];
bounds = (BOUNDING_BOX*)GetBestFrame(enemy);
LOT->target.y += bounds->Y1;
}
break;
case ESCAPE_MOOD:
boxNumber = LOT->node[GetRandomControl() * LOT->zoneCount >> NODE_SHIFT].boxNumber;
if (ValidBox(item, info->zoneNumber, boxNumber))
if (ValidBox(item, info->zoneNumber, boxNumber) && LOT->requiredBox == NO_BOX)
{
if (EscapeBox(item, enemy, boxNumber))
{
@ -1634,30 +1571,35 @@ void CreatureMood(ITEM_INFO* item, AI_INFO* info, int violent)
if (LOT->targetBox == NO_BOX)
TargetBox(LOT, item->boxNumber);
CalculateTarget(&creature->target, item, &creature->LOT);
creature->jumpAhead = false;
creature->monkeyAhead = false;
startBox = LOT->node[item->boxNumber].exitBox;
if (startBox != NO_BOX)
{
overlapIndex = Boxes[startBox].overlapIndex & OVERLAP_INDEX;
overlapIndex = g_Level.Boxes[startBox].overlapIndex;
nextBox = 0;
do
flags = 0;
if (overlapIndex >= 0)
{
overlapIndex++;
nextBox = Overlaps[overlapIndex];
} while (nextBox != NO_BOX && ((nextBox & BOX_END_BIT) == FALSE) && ((nextBox & BOX_NUMBER) != startBox));
do
{
overlapIndex++;
nextBox = g_Level.Overlaps[overlapIndex].box;
flags = g_Level.Overlaps[overlapIndex].flags;
} while (nextBox != NO_BOX && ((flags & BOX_END_BIT) == FALSE) && (nextBox != startBox));
}
if ((nextBox & BOX_NUMBER) == startBox)
if (nextBox == startBox)
{
if (nextBox & BOX_JUMP)
if (flags & BOX_JUMP)
creature->jumpAhead = true;
if (nextBox & BOX_MONKEY)
if (flags & BOX_MONKEY)
creature->monkeyAhead = true;
}
}
/*Unk_00EEFB6C =*/ CalculateTarget(&creature->target, item, &creature->LOT);
}
void GetCreatureMood(ITEM_INFO* item, AI_INFO* info, int isViolent)
@ -1677,7 +1619,8 @@ void GetCreatureMood(ITEM_INFO* item, AI_INFO* info, int isViolent)
if (creature->LOT.node[item->boxNumber].searchNumber == (creature->LOT.searchNumber | BLOCKED_SEARCH))
creature->LOT.requiredBox = NO_BOX;
if (creature->mood != ATTACK_MOOD && creature->LOT.requiredBox != NO_BOX)
if (creature->mood != ATTACK_MOOD
&& creature->LOT.requiredBox != NO_BOX)
{
if (!ValidBox(item, info->zoneNumber, creature->LOT.targetBox))
{
@ -1720,13 +1663,14 @@ void GetCreatureMood(ITEM_INFO* item, AI_INFO* info, int isViolent)
break;
}
}
else if (!isViolent)
else
{
switch (creature->mood)
{
case BORED_MOOD:
case STALK_MOOD:
if (creature->alerted && info->zoneNumber != info->enemyZone)
if (creature->alerted
&& info->zoneNumber != info->enemyZone)
{
if (info->distance > 3072)
creature->mood = STALK_MOOD;
@ -1735,7 +1679,9 @@ void GetCreatureMood(ITEM_INFO* item, AI_INFO* info, int isViolent)
}
else if (info->zoneNumber == info->enemyZone)
{
if (info->distance < ATTACK_RANGE || (creature->mood == STALK_MOOD && LOT->requiredBox == NO_BOX))
if (info->distance < ATTACK_RANGE
|| (creature->mood == STALK_MOOD
&& LOT->requiredBox == NO_BOX))
creature->mood = ATTACK_MOOD;
else
creature->mood = STALK_MOOD;
@ -1743,14 +1689,17 @@ void GetCreatureMood(ITEM_INFO* item, AI_INFO* info, int isViolent)
break;
case ATTACK_MOOD:
if (item->hitStatus && (GetRandomControl() < ESCAPE_CHANCE || info->zoneNumber != info->enemyZone))
if (item->hitStatus
&& (GetRandomControl() < ESCAPE_CHANCE
|| info->zoneNumber != info->enemyZone))
creature->mood = STALK_MOOD;
else if (info->zoneNumber != info->enemyZone && info->distance > (WALL_SIZE*6))
creature->mood = BORED_MOOD;
break;
case ESCAPE_MOOD:
if (info->zoneNumber == info->enemyZone && GetRandomControl() < RECOVER_CHANCE)
if (info->zoneNumber == info->enemyZone
&& GetRandomControl() < RECOVER_CHANCE)
creature->mood = STALK_MOOD;
break;
}
@ -1770,7 +1719,7 @@ TARGET_TYPE CalculateTarget(PHD_VECTOR* target, ITEM_INFO* item, LOT_INFO* LOT)
int boxLeft, boxRight, boxTop, boxBottom;
int left, top, right, bottom;
int direction;
short boxNumber;
int boxNumber;
UpdateLOT(LOT, 5);
@ -1782,7 +1731,7 @@ TARGET_TYPE CalculateTarget(PHD_VECTOR* target, ITEM_INFO* item, LOT_INFO* LOT)
if (boxNumber == NO_BOX)
return TARGET_TYPE::NO_TARGET;
box = &Boxes[boxNumber];
box = &g_Level.Boxes[boxNumber];
boxLeft = ((int)box->left << WALL_SHIFT);
boxRight = ((int)box->right << WALL_SHIFT) - 1;
boxTop = ((int)box->top << WALL_SHIFT);
@ -1795,7 +1744,7 @@ TARGET_TYPE CalculateTarget(PHD_VECTOR* target, ITEM_INFO* item, LOT_INFO* LOT)
do
{
box = &Boxes[boxNumber];
box = &g_Level.Boxes[boxNumber];
if (LOT->fly == NO_FLYING)
{
@ -1958,7 +1907,7 @@ TARGET_TYPE CalculateTarget(PHD_VECTOR* target, ITEM_INFO* item, LOT_INFO* LOT)
}
boxNumber = LOT->node[boxNumber].exitBox;
if (boxNumber != NO_BOX && (Boxes[boxNumber].overlapIndex & LOT->blockMask))
if (boxNumber != NO_BOX && (g_Level.Boxes[boxNumber].flags & LOT->blockMask))
break;
} while (boxNumber != NO_BOX);
@ -1999,7 +1948,7 @@ void AdjustStopperFlag(ITEM_INFO* item, int dir, int set)
int x = item->pos.xPos;
int z = item->pos.zPos;
ROOM_INFO* r = &Rooms[item->roomNumber];
ROOM_INFO* r = &g_Level.Rooms[item->roomNumber];
FLOOR_INFO* floor = &XZ_GET_SECTOR(r, x - r->x, z - r->z);
floor->stopper = set;
@ -2009,7 +1958,7 @@ void AdjustStopperFlag(ITEM_INFO* item, int dir, int set)
short roomNumber = item->roomNumber;
GetFloor(x, item->pos.yPos, z, &roomNumber);
r = &Rooms[roomNumber];
r = &g_Level.Rooms[roomNumber];
floor = &XZ_GET_SECTOR(r, x - r->x, z - r->z);
floor->stopper = set;

View file

@ -21,7 +21,7 @@ void UpdateBubbles()
bubble->size = lerp(0, bubble->destinationSize, alpha);
bubble->color = Vector4::Lerp(bubble->sourceColor, bubble->destinationColor, alpha);
int ceilingHeight = Rooms[bubble->roomNumber].maxceiling;
int ceilingHeight = g_Level.Rooms[bubble->roomNumber].maxceiling;
short roomNumber = bubble->roomNumber;
@ -34,9 +34,9 @@ void UpdateBubbles()
continue;
}
if (!(Rooms[roomNumber].flags & ENV_FLAG_WATER))
if (!(g_Level.Rooms[roomNumber].flags & ENV_FLAG_WATER))
{
SetupRipple(bubble->worldPosition.x, Rooms[bubble->roomNumber].maxceiling, bubble->worldPosition.z, (GetRandomControl() & 0xF) + 48, RIPPLE_FLAG_SHORT_LIFE + RIPPLE_FLAG_RAND_ROT);
SetupRipple(bubble->worldPosition.x, g_Level.Rooms[bubble->roomNumber].maxceiling, bubble->worldPosition.z, (GetRandomControl() & 0xF) + 48, RIPPLE_FLAG_SHORT_LIFE + RIPPLE_FLAG_RAND_ROT);
bubble->active = false;
continue;
}
@ -77,7 +77,7 @@ int GetFreeBubble() //8BEAC(<), 8DEF0(<) (F)
void CreateBubble(PHD_VECTOR* pos, short roomNum, int unk1, int unk2, int flags, int xv, int yv, int zv) //8BF14(<), 8DF58(<) (F)
{
if (Rooms[roomNum].flags & ENV_FLAG_WATER)
if (g_Level.Rooms[roomNum].flags & ENV_FLAG_WATER)
{
BUBBLE_STRUCT* bubble = &Bubbles[GetFreeBubble()];
bubble->active = true;

View file

@ -14,7 +14,7 @@
#include "sound.h"
#include "savegame.h"
#include "input.h"
using T5M::Renderer::g_Renderer;
struct OLD_CAMERA
{
short currentAnimState;
@ -63,26 +63,23 @@ int PhdPerspective;
short CurrentFOV;
int GetLaraOnLOS;
int SniperOverlay;
std::vector<OBJECT_VECTOR> FixedCameras;
void LookAt(int posX, int posY, int posZ, int targetX, int targetY, int targetZ, short roll)
void LookAt(CAMERA_INFO* cam, short roll)
{
Vector3 position = Vector3(posX, posY, posZ);
Vector3 target = Vector3(targetX, targetY, targetZ);
Vector3 position = Vector3(cam->pos.x, cam->pos.y, cam->pos.z);
Vector3 target = Vector3(cam->target.x, cam->target.y, cam->target.z);
Vector3 up = Vector3(0.0f, -1.0f, 0.0f);
float fov = TO_RAD(CurrentFOV / 1.333333f);
float r = TO_RAD(roll);
float r = 0; TO_RAD(roll);
// This should not be needed but it seems to solve our issues
if (posX == targetX && posY == targetY && posZ == targetZ)
return;
g_Renderer->UpdateCameraMatrices(posX, posY, posZ, targetX, targetY, targetZ, r, fov);
g_Renderer.UpdateCameraMatrices(cam, r, fov);
}
void AlterFOV(int value)
{
CurrentFOV = value;
PhdPerspective = g_Renderer->ScreenWidth / 2 * phd_cos(CurrentFOV / 2) / phd_sin(CurrentFOV / 2);
PhdPerspective = g_Renderer.ScreenWidth / 2 * phd_cos(CurrentFOV / 2) / phd_sin(CurrentFOV / 2);
}
int mgLOS(GAME_VECTOR* start, GAME_VECTOR* target, int push)
@ -331,7 +328,7 @@ void MoveCamera(GAME_VECTOR* ideal, int speed)
}
GetFloor(Camera.pos.x, Camera.pos.y, Camera.pos.z, &Camera.pos.roomNumber);
LookAt(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.target.x, Camera.target.y, Camera.target.z, 0);
LookAt(&Camera, 0);
if (Camera.mikeAtLara)
{
@ -369,8 +366,8 @@ void ChaseCamera(ITEM_INFO* item)
int distance = Camera.targetDistance * phd_cos(Camera.actualElevation) >> W2V_SHIFT;
GetFloor(Camera.target.x, Camera.target.y, Camera.target.z, &Camera.target.roomNumber);
if (Rooms[Camera.target.roomNumber].flags & ENV_FLAG_SWAMP)
Camera.target.y = Rooms[Camera.target.roomNumber].y - 256;
if (g_Level.Rooms[Camera.target.roomNumber].flags & ENV_FLAG_SWAMP)
Camera.target.y = g_Level.Rooms[Camera.target.roomNumber].y - 256;
int x = Camera.target.x;
int y = Camera.target.y;
@ -779,7 +776,7 @@ void FixedCamera(ITEM_INFO* item)
}
else
{
OBJECT_VECTOR* camera = &Camera.fixed[Camera.number];
OBJECT_VECTOR* camera = &FixedCameras[Camera.number];
from.x = camera->x;
from.y = camera->y;
@ -814,7 +811,7 @@ void FixedCamera(ITEM_INFO* item)
PHD_VECTOR pos;
int objLos = ObjectOnLOS2(&from, &to, &pos, &CollidedMeshes[0]);
objLos = (objLos != 999 && objLos >= 0 && Items[objLos].objectNumber != ID_LARA);
objLos = (objLos != 999 && objLos >= 0 && g_Level.Items[objLos].objectNumber != ID_LARA);
if (!(GetRandomControl() & 0x3F)
|| !(GlobalCounter & 0x3F)
@ -920,9 +917,9 @@ void LookCamera(ITEM_INFO* item)
roomNumber = LaraItem->roomNumber;
floor = GetFloor(pos.x, pos.y + 256, pos.z, &roomNumber);
if (Rooms[roomNumber].flags & ENV_FLAG_SWAMP)
if (g_Level.Rooms[roomNumber].flags & ENV_FLAG_SWAMP)
{
pos.y = Rooms[roomNumber].y - 256;
pos.y = g_Level.Rooms[roomNumber].y - 256;
floor = GetFloor(pos.x, pos.y, pos.z, &roomNumber);
}
else
@ -964,9 +961,9 @@ void LookCamera(ITEM_INFO* item)
{
roomNumber = roomNumber2;
floor = GetFloor(x, y + 256, z, &roomNumber2);
if (Rooms[roomNumber2].flags & ENV_FLAG_SWAMP)
if (g_Level.Rooms[roomNumber2].flags & ENV_FLAG_SWAMP)
{
y = Rooms[roomNumber2].y - 256;
y = g_Level.Rooms[roomNumber2].y - 256;
break;
}
else
@ -1090,8 +1087,8 @@ void LookCamera(ITEM_INFO* item)
floor = GetFloor(x, y, z, &roomNumber);
h = GetFloorHeight(floor, x, y, z);
c = GetCeiling(floor, x, y, z);
if ((Rooms[roomNumber].flags & ENV_FLAG_SWAMP))
Camera.pos.y = Rooms[roomNumber].y - 256;
if ((g_Level.Rooms[roomNumber].flags & ENV_FLAG_SWAMP))
Camera.pos.y = g_Level.Rooms[roomNumber].y - 256;
else if (y < c || y > h || c >= h || h == NO_HEIGHT || c == NO_HEIGHT)
mgLOS(&Camera.target, &Camera.pos, 0);
@ -1102,7 +1099,7 @@ void LookCamera(ITEM_INFO* item)
floor = GetFloor(x, y, z, &roomNumber);
h = GetFloorHeight(floor, x, y, z);
c = GetCeiling(floor, x, y, z);
if (y < c || y > h || c >= h || h == NO_HEIGHT || c == NO_HEIGHT || (Rooms[roomNumber].flags & ENV_FLAG_SWAMP))
if (y < c || y > h || c >= h || h == NO_HEIGHT || c == NO_HEIGHT || (g_Level.Rooms[roomNumber].flags & ENV_FLAG_SWAMP))
{
Camera.pos.x = pos.x;
Camera.pos.y = pos.y;
@ -1111,7 +1108,7 @@ void LookCamera(ITEM_INFO* item)
}
GetFloor(Camera.pos.x, Camera.pos.y, Camera.pos.z, &Camera.pos.roomNumber);
LookAt(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.target.x, Camera.target.y, Camera.target.z, 0);
LookAt(&Camera, 0);
if (Camera.mikeAtLara)
{
@ -1180,7 +1177,6 @@ void BinocularCamera(ITEM_INFO* item)
Lara.headXrot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
//dword_87B0F8 = 0;
Camera.type = BinocularOldCamera;
return;
}
@ -1257,7 +1253,7 @@ void BinocularCamera(ITEM_INFO* item)
}
GetFloor(Camera.pos.x, Camera.pos.y, Camera.pos.z, &Camera.pos.roomNumber);
LookAt(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.target.x, Camera.target.y, Camera.target.z, 0);
LookAt(&Camera, 0);
if (Camera.mikeAtLara)
{
@ -1444,7 +1440,6 @@ void BinocularCamera(ITEM_INFO* item)
if (!(InputBusy & IN_ACTION) || Infrared)
{
//dword_87B0F8 = 0;
}
else
{
@ -1559,20 +1554,12 @@ void CalculateCamera()
Camera.underwater = 0;
}
TLFlag = 0;
//if (gfCurrentLevel != LVL5_DEEPSEA_DIVE)
//{
//Camera is in a water room, play water sound effect.
if ((Rooms[Camera.pos.roomNumber].flags & ENV_FLAG_WATER))
if ((g_Level.Rooms[Camera.pos.roomNumber].flags & ENV_FLAG_WATER))
{
SoundEffect(SFX_UNDERWATER, NULL, SFX_ALWAYS);
if (Camera.underwater == 0)
{
/*if (GLOBAL_playing_cutseq == 0 && TLFlag == 0)
{
CDDA_SetMasterVolume(savegame.VolumeCD >> 2);
}*/
Camera.underwater = 1;
}
}
@ -1580,15 +1567,9 @@ void CalculateCamera()
{
if (Camera.underwater != 0)
{
/*if (GLOBAL_playing_cutseq == 0 && TLFlag == 0 && savegame.VolumeCD > 0)
{
CDDA_SetMasterVolume(savegame.VolumeCD);
}*/
Camera.underwater = 0;
}
}
//}
if (Camera.type == CINEMATIC_CAMERA)
{
@ -1609,10 +1590,10 @@ void CalculateCamera()
fixedCamera = 0;
}
short* bounds = GetBoundsAccurate(item);
BOUNDING_BOX* bounds = GetBoundsAccurate(item);
int x;
int y = ((bounds[2] + bounds[3]) >> 1) + item->pos.yPos - 256;
int y = ((bounds->Y1 + bounds->Y2) / 2) + item->pos.yPos - 256;
int z;
if (Camera.item)
@ -1623,7 +1604,7 @@ void CalculateCamera()
int dz = Camera.item->pos.zPos - item->pos.zPos;
int shift = sqrt(SQUARE(dx) + SQUARE(dz));
short angle = phd_atan(dz, dx) - item->pos.yRot;
short tilt = phd_atan(shift, y - (bounds[2] + bounds[3]) / 2 - Camera.item->pos.yPos);
short tilt = phd_atan(shift, y - (bounds->Y1 + bounds->Y2) / 2 - Camera.item->pos.yPos);
bounds = GetBoundsAccurate(Camera.item);
angle >>= 1;
tilt >>= 1;
@ -1695,7 +1676,7 @@ void CalculateCamera()
if (Camera.type
&& Camera.flags != CF_CHASE_OBJECT
&& (Camera.number != -1 &&(SniperCamActive = Camera.fixed[Camera.number].flags & 3, Camera.fixed[Camera.number].flags & 2)))
&& (Camera.number != -1 &&(SniperCamActive = FixedCameras[Camera.number].flags & 3, FixedCameras[Camera.number].flags & 2)))
{
PHD_VECTOR pos;
pos.x = 0;
@ -1713,7 +1694,7 @@ void CalculateCamera()
}
else
{
int shift = (bounds[0] + bounds[1] + bounds[4] + bounds[5]) >> 2;
int shift = (bounds->X1 + bounds->X2 + bounds->Z1 + bounds->Z2) / 4;
x = item->pos.xPos + (shift * phd_sin(item->pos.yRot) >> W2V_SHIFT);
z = item->pos.zPos + (shift * phd_cos(item->pos.yRot) >> W2V_SHIFT);

View file

@ -1,6 +1,7 @@
#pragma once
#include "phd_global.h"
#include "items.h"
#include <Specific\setup.h>
typedef enum CAMERA_TYPE
{
@ -38,7 +39,6 @@ typedef struct CAMERA_INFO
short targetspeed; // size=0, offset=88
ITEM_INFO* item; // size=144, offset=92
ITEM_INFO* lastItem; // size=144, offset=96
OBJECT_VECTOR* fixed; // size=16, offset=100
int mikeAtLara; // size=0, offset=104
PHD_VECTOR mikePos; // size=12, offset=108
};
@ -69,8 +69,9 @@ extern int PhdPerspective;
extern short CurrentFOV;
extern int GetLaraOnLOS;
extern int SniperOverlay;
extern std::vector<OBJECT_VECTOR> FixedCameras;
void LookAt(int posX, int posY, int posZ, int targetX, int targetY, int targetZ, short roll);
void LookAt(CAMERA_INFO* cam, short roll);
void AlterFOV(int value);
int mgLOS(GAME_VECTOR* start, GAME_VECTOR* target, int push);
void InitialiseCamera();

View file

@ -33,7 +33,7 @@ void TriggerChaffEffects(int flareAge)
vel.y = vect.y - pos.y;
vel.z = vect.z - pos.z;
TriggerChaffEffects(LaraItem, &pos, &vel, LaraItem->speed, (bool)(Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WATER),flareAge);
TriggerChaffEffects(LaraItem, &pos, &vel, LaraItem->speed, (bool)(g_Level.Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WATER),flareAge);
}
void TriggerChaffEffects(ITEM_INFO* Item,int age)
@ -57,7 +57,7 @@ void TriggerChaffEffects(ITEM_INFO* Item,int age)
vel.y = world.Translation().y;
vel.z = world.Translation().z;
TriggerChaffEffects(Item, &pos, &vel, Item->speed, (bool)(Rooms[Item->roomNumber].flags & ENV_FLAG_WATER),age);
TriggerChaffEffects(Item, &pos, &vel, Item->speed, (bool)(g_Level.Rooms[Item->roomNumber].flags & ENV_FLAG_WATER),age);
}
void TriggerChaffEffects(ITEM_INFO* item, PHD_VECTOR* pos, PHD_VECTOR* vel, int speed, bool isUnderwater,int age)

View file

@ -31,6 +31,7 @@ char LM[] =
};
extern int SplitFloor, SplitCeiling;
int hitSoundTimer;
int XFront, ZFront;
BOUNDING_BOX GlobalCollisionBounds;
ITEM_INFO* CollidedItems[1024];
@ -58,17 +59,18 @@ int CollideStaticObjects(COLL_INFO* coll, int x, int y, int z, short roomNumber,
for (int i = 0; i < numRooms; i++)
{
room = &Rooms[roomList[i]];
room = &g_Level.Rooms[roomList[i]];
for (int j = room->mesh.size(); j > 0; j--, mesh++)
{
mesh = &room->mesh[j];
StaticInfo* sInfo = &StaticObjects[mesh->staticNumber];
STATIC_INFO* sInfo = &StaticObjects[mesh->staticNumber];
if ((sInfo->flags & 1)) // No collision
continue;
int yMin = mesh->y + sInfo->xMinc;
int yMax = mesh->y + sInfo->yMaxc;
short yRot = mesh->yRot;
std::array<float, 4> box{sInfo->xMinc, sInfo->zMinc, sInfo->xMaxc, sInfo->zMaxc};
RotateBoundingBox(box, mesh->yRot);
@ -77,6 +79,37 @@ int CollideStaticObjects(COLL_INFO* coll, int x, int y, int z, short roomNumber,
zMin = box[1];
xMax = box[2];
zMax = box[3];
if (yRot == ANGLE(180))
{
xMin = mesh->x - sInfo->collisionBox.X2;
xMax = mesh->x - sInfo->collisionBox.X1;
zMin = mesh->z - sInfo->collisionBox.Z2;
zMax = mesh->z - sInfo->collisionBox.Z1;
}
else if (yRot == -ANGLE(90))
{
xMin = mesh->x - sInfo->collisionBox.Z2;
xMax = mesh->x - sInfo->collisionBox.Z1;
zMin = mesh->z + sInfo->collisionBox.X1;
zMax = mesh->z + sInfo->collisionBox.X2;
}
else if (yRot == ANGLE(90))
{
xMin = mesh->x + sInfo->collisionBox.Z1;
xMax = mesh->x + sInfo->collisionBox.Z2;
zMin = mesh->z - sInfo->collisionBox.X2;
zMax = mesh->z - sInfo->collisionBox.X1;
}
else
{
xMin = mesh->x + sInfo->collisionBox.X1;
xMax = mesh->x + sInfo->collisionBox.X2;
zMin = mesh->z + sInfo->collisionBox.Z1;
zMax = mesh->z + sInfo->collisionBox.Z2;
}
if (inXmax <= xMin
|| inXmin >= xMax
@ -110,27 +143,27 @@ int GetCollidedObjects(ITEM_INFO* collidingItem, int radius, int onlyVisible, IT
{
for (int i = 0; i < numRooms; i++)
{
room = &Rooms[roomsArray[i]];
room = &g_Level.Rooms[roomsArray[i]];
for (int j = 0; j < room->mesh.size(); j++)
{
MESH_INFO* mesh = &room->mesh[j];
StaticInfo* staticMesh = &StaticObjects[mesh->staticNumber];
STATIC_INFO* staticMesh = &StaticObjects[mesh->staticNumber];
if (mesh->flags & 1)
{
if (collidingItem->pos.yPos + radius + STEP_SIZE/2 >= mesh->y + staticMesh->yMinc)
if (collidingItem->pos.yPos + radius + STEP_SIZE/2 >= mesh->y + staticMesh->collisionBox.Y1)
{
if (collidingItem->pos.yPos <= mesh->y + staticMesh->yMaxc)
if (collidingItem->pos.yPos <= mesh->y + staticMesh->collisionBox.Y2)
{
s = phd_sin(mesh->yRot);
c = phd_cos(mesh->yRot);
rx = ((collidingItem->pos.xPos - mesh->x) * c - s * (collidingItem->pos.zPos - mesh->z)) >> W2V_SHIFT;
rz = ((collidingItem->pos.zPos - mesh->z) * c + s * (collidingItem->pos.xPos - mesh->x)) >> W2V_SHIFT;
if (radius + rx + STEP_SIZE/2 >= staticMesh->xMinc && rx - radius - STEP_SIZE/2 <= staticMesh->xMaxc)
if (radius + rx + STEP_SIZE/2 >= staticMesh->collisionBox.X1 && rx - radius - STEP_SIZE/2 <= staticMesh->collisionBox.X2)
{
if (radius + rz + STEP_SIZE/2 >= staticMesh->zMinc && rz - radius - STEP_SIZE/2 <= staticMesh->zMaxc)
if (radius + rz + STEP_SIZE/2 >= staticMesh->collisionBox.Z1 && rz - radius - STEP_SIZE/2 <= staticMesh->collisionBox.Z2)
{
collidedMeshes[numMeshes++] = mesh;
if (!radius)
@ -153,14 +186,14 @@ int GetCollidedObjects(ITEM_INFO* collidingItem, int radius, int onlyVisible, IT
{
for (int i = 0; i < numRooms; i++)
{
ROOM_INFO* room = &Rooms[roomsArray[i]];
ROOM_INFO* room = &g_Level.Rooms[roomsArray[i]];
int itemNumber = room->itemNumber;
if (itemNumber != NO_ITEM)
{
do
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (item == collidingItem || !ignoreLara && item == LaraItem)
{
@ -184,7 +217,7 @@ int GetCollidedObjects(ITEM_INFO* collidingItem, int radius, int onlyVisible, IT
int dy = collidingItem->pos.yPos - item->pos.yPos;
int dz = collidingItem->pos.zPos - item->pos.zPos;
short* framePtr = GetBestFrame(item);
ANIM_FRAME* framePtr = GetBestFrame(item);
if (Objects[item->objectNumber].drawRoutine
&& item->meshBits
@ -195,8 +228,8 @@ int GetCollidedObjects(ITEM_INFO* collidingItem, int radius, int onlyVisible, IT
&& dy <= 2048
&& dz >= -2048
&& dz <= 2048
&& collidingItem->pos.yPos + radius + 128 >= item->pos.yPos + framePtr[2]
&& collidingItem->pos.yPos - radius - 128 <= item->pos.yPos + framePtr[3])
&& collidingItem->pos.yPos + radius + 128 >= item->pos.yPos + framePtr->boundingBox.Y1
&& collidingItem->pos.yPos - radius - 128 <= item->pos.yPos + framePtr->boundingBox.Y2)
{
int s = phd_sin(item->pos.yRot);
int c = phd_cos(item->pos.yRot);
@ -214,9 +247,9 @@ int GetCollidedObjects(ITEM_INFO* collidingItem, int radius, int onlyVisible, IT
bounds = &v57;*/
}
if (radius + rx + 128 >= framePtr[0] && rx - radius - 128 <= framePtr[1])
if (radius + rx + 128 >= framePtr->boundingBox.X1 && rx - radius - 128 <= framePtr->boundingBox.X2)
{
if (radius + rz + 128 >= framePtr[4] && rz - radius - 128 <= framePtr[5])
if (radius + rz + 128 >= framePtr->boundingBox.Z1 && rz - radius - 128 <= framePtr->boundingBox.Z2)
{
collidedItems[numItems++] = item;
if (!radius)
@ -234,17 +267,17 @@ int GetCollidedObjects(ITEM_INFO* collidingItem, int radius, int onlyVisible, IT
collidedItems[numItems] = NULL;
}
return (numItems | numMeshes);
return (numItems || numMeshes);
}
int TestWithGlobalCollisionBounds(ITEM_INFO* item, ITEM_INFO* lara, COLL_INFO* coll)
{
short* framePtr = GetBestFrame(lara);
ANIM_FRAME* framePtr = GetBestFrame(lara);
if (item->pos.yPos + GlobalCollisionBounds.Y2 <= lara->pos.yPos + framePtr[3])
if (item->pos.yPos + GlobalCollisionBounds.Y2 <= lara->pos.yPos + framePtr->boundingBox.Y1)
return false;
if (item->pos.yPos + GlobalCollisionBounds.Y1 >= framePtr[4])
if (item->pos.yPos + GlobalCollisionBounds.Y1 >= framePtr->boundingBox.Y2)
return false;
int s = phd_sin(item->pos.yRot);
@ -267,7 +300,7 @@ int TestWithGlobalCollisionBounds(ITEM_INFO* item, ITEM_INFO* lara, COLL_INFO* c
void TrapCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* c)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (item->status == ITEM_ACTIVE)
{
@ -275,9 +308,6 @@ void TrapCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* c)
return;
TestCollision(item, LaraItem);
/*if (item->object_number == FAN && item->currentAnimState == 1) // Is the fan moving slow ?
ObjectCollision(item_num, laraitem, coll);*/
}
else if (item->status != ITEM_INVISIBLE)
ObjectCollision(itemNumber, l, c);
@ -349,7 +379,7 @@ short GetTiltType(FLOOR_INFO* floor, int x, int y, int z)
{
if (CheckNoColFloorTriangle(floor, x, z) == TRUE)
break;
r = &Rooms[floor->pitRoom];
r = &g_Level.Rooms[floor->pitRoom];
floor = &XZ_GET_SECTOR(r, x - r->x, z - r->z);
}
@ -359,7 +389,7 @@ short GetTiltType(FLOOR_INFO* floor, int x, int y, int z)
if (!floor->index)
return FLOOR_TYPE;
data = &FloorData[floor->index];
data = &g_Level.FloorData[floor->index];
func = *data & DATA_TYPE;
if (func == TILT_TYPE)
@ -423,17 +453,17 @@ int FindGridShift(int x, int z)
return ((WALL_SIZE + 1) - (x & (WALL_SIZE - 1)));
}
int TestBoundsCollideStatic(short* bounds, PHD_3DPOS* pos, int radius)
int TestBoundsCollideStatic(BOUNDING_BOX* bounds, PHD_3DPOS* pos, int radius)
{
if (!(bounds[5] | bounds[4] | bounds[0] | bounds[1] | bounds[2] | bounds[3]))
return FALSE;
if (!(bounds->Z2 != 0 || bounds->Z1 != 0 || bounds->X1 != 0 || bounds->X2 != 0 || bounds->Y1 != 0 || bounds->Y2 != 0))
return false;
short* frame = GetBestFrame(LaraItem);
if (pos->yPos + bounds[3] <= LaraItem->pos.yPos + frame[2])
return FALSE;
ANIM_FRAME* frame = GetBestFrame(LaraItem);
if (pos->yPos + bounds->Y2 <= LaraItem->pos.yPos + frame->boundingBox.Y1)
return false;
if (pos->yPos + bounds[2] >= LaraItem->pos.yPos + frame[3])
return FALSE;
if (pos->yPos + bounds->Y1 >= LaraItem->pos.yPos + frame->boundingBox.Y2)
return false;
int c, s;
int x, z, dx, dz;
@ -445,20 +475,20 @@ int TestBoundsCollideStatic(short* bounds, PHD_3DPOS* pos, int radius)
dx = (c * x - s * z) >> W2V_SHIFT;
dz = (c * z + s * x) >> W2V_SHIFT;
if (dx <= radius + bounds[1]
&& dx >= bounds[0] - radius
&& dz <= radius + bounds[5]
&& dz >= bounds[4] - radius)
if (dx <= radius + bounds->X2
&& dx >= bounds->X1 - radius
&& dz <= radius + bounds->Z2
&& dz >= bounds->Z1 - radius)
{
return TRUE;
return true;
}
else
{
return FALSE;
return false;
}
}
int ItemPushLaraStatic(ITEM_INFO* item, short* bounds, PHD_3DPOS* pos, COLL_INFO* coll)
int ItemPushLaraStatic(ITEM_INFO* item, BOUNDING_BOX* bounds, PHD_3DPOS* pos, COLL_INFO* coll)
{
int c, s;
int dx, dz, rx, rz, minX, maxX, minZ, maxZ;
@ -471,10 +501,10 @@ int ItemPushLaraStatic(ITEM_INFO* item, short* bounds, PHD_3DPOS* pos, COLL_INFO
dz = LaraItem->pos.zPos - pos->zPos;
rx = (c * dx - s * dz) >> W2V_SHIFT;
rz = (c * dz + s * dx) >> W2V_SHIFT;
minX = bounds[0] - coll->radius;
maxX = bounds[1] + coll->radius;
minZ = bounds[4] - coll->radius;
maxZ = bounds[5] + coll->radius;
minX = bounds->X1 - coll->radius;
maxX = bounds->X2 + coll->radius;
minZ = bounds->Z1 - coll->radius;
maxZ = bounds->Z2 + coll->radius;
if (abs(dx) > 4608
|| abs(dz) > 4608
@ -482,7 +512,7 @@ int ItemPushLaraStatic(ITEM_INFO* item, short* bounds, PHD_3DPOS* pos, COLL_INFO
|| rx >= maxX
|| rz <= minZ
|| rz >= maxZ)
return FALSE;
return false;
left = rx - minX;
top = maxZ - rz;
@ -530,7 +560,7 @@ int ItemPushLaraStatic(ITEM_INFO* item, short* bounds, PHD_3DPOS* pos, COLL_INFO
Lara.gunStatus = LG_NO_ARMS;
}
return TRUE;
return true;
}
int ItemPushLara(ITEM_INFO* item, ITEM_INFO* l, COLL_INFO* coll, int spazon, char bigpush)
@ -538,7 +568,7 @@ int ItemPushLara(ITEM_INFO* item, ITEM_INFO* l, COLL_INFO* coll, int spazon, cha
int c, s;
int dx, dz, rx, rz, minX, maxX, minZ, maxZ;
int left, right, bottom, top;
short* bounds;
BOUNDING_BOX* bounds;
short facing;
c = phd_cos(item->pos.yRot);
@ -549,14 +579,14 @@ int ItemPushLara(ITEM_INFO* item, ITEM_INFO* l, COLL_INFO* coll, int spazon, cha
rz = (c * dz + s * dx) >> W2V_SHIFT;
if (bigpush & 2)
bounds = (short*)&GlobalCollisionBounds;
bounds = &GlobalCollisionBounds;
else
bounds = GetBestFrame(item);
bounds = (BOUNDING_BOX*)GetBestFrame(item);
minX = bounds[0];
maxX = bounds[1];
minZ = bounds[4];
maxZ = bounds[5];
minX = bounds->X1;
maxX = bounds->X2;
minZ = bounds->Z1;
maxZ = bounds->Z2;
if (bigpush & 1)
{
@ -572,7 +602,7 @@ int ItemPushLara(ITEM_INFO* item, ITEM_INFO* l, COLL_INFO* coll, int spazon, cha
|| rx >= maxX
|| rz <= minZ
|| rz >= maxZ)
return FALSE;
return false;
left = rx - minX;
top = maxZ - rz;
@ -591,18 +621,24 @@ int ItemPushLara(ITEM_INFO* item, ITEM_INFO* l, COLL_INFO* coll, int spazon, cha
l->pos.xPos = item->pos.xPos + ((c * rx + s * rz) >> W2V_SHIFT);
l->pos.zPos = item->pos.zPos + ((c * rz - s * rx) >> W2V_SHIFT);
if (spazon && bounds[3] - bounds[2] > STEP_SIZE)
if (spazon && bounds->Y2 - bounds->Y1 > STEP_SIZE)
{
rx = (bounds[0] + bounds[1]) / 2;
rz = (bounds[4] + bounds[5]) / 2;
rx = (bounds->X1 + bounds->X2) / 2;
rz = (bounds->Z1 + bounds->Z2) / 2;
dx -= (c * rx + s * rz) >> W2V_SHIFT;
dz -= (c * rz - s * rx) >> W2V_SHIFT;
Lara.hitDirection = (l->pos.yRot - phd_atan(dz, dz) - ANGLE(135)) >> W2V_SHIFT;
if (!Lara.hitFrame)
SoundEffect(SFX_LARA_INJURY_RND, &l->pos, 0);
if ((!Lara.hitFrame) && (!hitSoundTimer > 0))
{
SoundEffect(SFX_LARA_INJURY_RND, &l->pos, 0);
hitSoundTimer = frandMinMax(5, 15);
}
if (hitSoundTimer > 0)
hitSoundTimer--;
Lara.hitFrame++;
if (Lara.hitFrame > 34)
@ -638,19 +674,19 @@ int ItemPushLara(ITEM_INFO* item, ITEM_INFO* l, COLL_INFO* coll, int spazon, cha
Lara.gunStatus = LG_NO_ARMS;
}
return TRUE;
return true;
}
void AIPickupCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* c)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (item->objectNumber == ID_SHOOT_SWITCH1 && !(item->meshBits & 1))
item->status = ITEM_INVISIBLE;
}
void ObjectCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* c)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (TestBoundsCollide(item, l, c->radius))
{
@ -705,7 +741,7 @@ void TriggerLaraBlood()
}
}
int TestLaraPosition(short* bounds, ITEM_INFO* item, ITEM_INFO* l)
int TestLaraPosition(OBJECT_COLLISION_BOUNDS* bounds, ITEM_INFO* item, ITEM_INFO* l)
{
int x, y, z, rx, ry, rz;
short xRotRel, yRotRel, zRotRel;
@ -714,23 +750,25 @@ int TestLaraPosition(short* bounds, ITEM_INFO* item, ITEM_INFO* l)
yRotRel = l->pos.yRot - item->pos.yRot;
zRotRel = l->pos.zRot - item->pos.zRot;
if (xRotRel < bounds[6])
return FALSE;
if (xRotRel > bounds[7])
return FALSE;
if (yRotRel < bounds[8])
return FALSE;
if (yRotRel > bounds[9])
return FALSE;
if (zRotRel < bounds[10])
return FALSE;
if (zRotRel > bounds[11])
return FALSE;
if (xRotRel < bounds->rotX1)
return false;
if (xRotRel > bounds->rotX2)
return false;
if (yRotRel < bounds->rotY1)
return false;
if (yRotRel > bounds->rotY2)
return false;
if (zRotRel < bounds->rotZ1)
return false;
if (zRotRel > bounds->rotX2)
return false;
Vector3 pos = Vector3(l->pos.xPos - item->pos.xPos, l->pos.yPos - item->pos.yPos, l->pos.zPos - item->pos.zPos);
// HACK: it seems that a minus sign is required here. I don't know why, but it just works (tm) but we must
// do more tests
Matrix matrix = Matrix::CreateFromYawPitchRoll(
TO_RAD(item->pos.yRot),
TO_RAD(-(item->pos.yRot)),
TO_RAD(item->pos.xRot),
TO_RAD(item->pos.zRot)
);
@ -741,10 +779,13 @@ int TestLaraPosition(short* bounds, ITEM_INFO* item, ITEM_INFO* l)
ry = pos.y;
rz = pos.z;
if (rx < bounds[0] || rx > bounds[1] || ry < bounds[2] || ry > bounds[3] || rz < bounds[4] || rz > bounds[5])
return FALSE;
return TRUE;
if (rx < bounds->boundingBox.X1 || rx > bounds->boundingBox.X2
|| ry < bounds->boundingBox.Y1 || ry > bounds->boundingBox.Y2
|| rz < bounds->boundingBox.Z1 || rz > bounds->boundingBox.Z2)
return false;
return true;
}
int Move3DPosTo3DPos(PHD_3DPOS* src, PHD_3DPOS* dest, int velocity, short angAdd)
@ -781,35 +822,35 @@ int Move3DPosTo3DPos(PHD_3DPOS* src, PHD_3DPOS* dest, int velocity, short angAdd
switch (direction)
{
case 0:
LaraItem->animNumber = ANIMATION_LARA_WALK_LEFT;
LaraItem->frameNumber = GF(ANIMATION_LARA_WALK_LEFT, 0);
LaraItem->goalAnimState = STATE_LARA_WALK_LEFT;
LaraItem->currentAnimState = STATE_LARA_WALK_LEFT;
LaraItem->animNumber = LA_SIDESTEP_LEFT;
LaraItem->frameNumber = GF(LA_SIDESTEP_LEFT, 0);
LaraItem->goalAnimState = LS_STEP_LEFT;
LaraItem->currentAnimState = LS_STEP_LEFT;
Lara.gunStatus = LG_HANDS_BUSY;
break;
case 1:
LaraItem->animNumber = ANIMATION_LARA_WALK_FORWARD;
LaraItem->frameNumber = GF(ANIMATION_LARA_WALK_FORWARD, 0);
LaraItem->goalAnimState = STATE_LARA_WALK_FORWARD;
LaraItem->currentAnimState = STATE_LARA_WALK_FORWARD;
LaraItem->animNumber = LA_WALK;
LaraItem->frameNumber = GF(LA_WALK, 0);
LaraItem->goalAnimState = LS_WALK_FORWARD;
LaraItem->currentAnimState = LS_WALK_FORWARD;
Lara.gunStatus = LG_HANDS_BUSY;
break;
case 2:
LaraItem->animNumber = ANIMATION_LARA_WALK_RIGHT;
LaraItem->frameNumber = GF(ANIMATION_LARA_WALK_RIGHT, 0);
LaraItem->goalAnimState = STATE_LARA_WALK_RIGHT;
LaraItem->currentAnimState = STATE_LARA_WALK_RIGHT;
LaraItem->animNumber = LA_WALK;
LaraItem->frameNumber = GF(LA_SIDESTEP_RIGHT, 0);
LaraItem->goalAnimState = LS_STEP_RIGHT;
LaraItem->currentAnimState = LS_STEP_RIGHT;
Lara.gunStatus = LG_HANDS_BUSY;
break;
case 3:
default:
LaraItem->animNumber = ANIMATION_LARA_WALK_BACK;
LaraItem->frameNumber = GF(ANIMATION_LARA_WALK_BACK, 0);
LaraItem->goalAnimState = STATE_LARA_WALK_BACK;
LaraItem->currentAnimState = STATE_LARA_WALK_BACK;
LaraItem->animNumber = LA_WALK_BACK;
LaraItem->frameNumber = GF(LA_WALK_BACK, 0);
LaraItem->goalAnimState = LS_WALK_BACK;
LaraItem->currentAnimState = LS_WALK_BACK;
Lara.gunStatus = LG_HANDS_BUSY;
break;
@ -899,7 +940,7 @@ int MoveLaraPosition(PHD_VECTOR* vec, ITEM_INFO* item, ITEM_INFO* l)
if (abs(height - l->pos.yPos) <= CLICK(2))
{
if (sqrt(SQUARE(dest.xPos - l->pos.xPos) + SQUARE(dest.yPos - l->pos.yPos) + SQUARE(dest.zPos - l->pos.zPos)) < (STEP_SIZE/2))
return TRUE;
return true;
return Move3DPosTo3DPos(&l->pos, &dest, LARA_VELOCITY, ANGLE(2));
}
@ -910,23 +951,23 @@ int MoveLaraPosition(PHD_VECTOR* vec, ITEM_INFO* item, ITEM_INFO* l)
Lara.gunStatus = LG_NO_ARMS;
}
return FALSE;
return false;
}
int TestBoundsCollide(ITEM_INFO* item, ITEM_INFO* l, int radius)
{
short* bounds;
short* laraBounds;
BOUNDING_BOX* bounds;
BOUNDING_BOX* laraBounds;
int c, s;
int x, z;
int dx, dz;
bounds = GetBestFrame(item);
laraBounds = GetBestFrame(l);
bounds = (BOUNDING_BOX*)GetBestFrame(item);
laraBounds = (BOUNDING_BOX*)GetBestFrame(l);
if (item->pos.yPos + bounds[3] > l->pos.yPos + laraBounds[2])
if (item->pos.yPos + bounds->Y2 > l->pos.yPos + laraBounds->Y1)
{
if (item->pos.yPos + bounds[2] < l->pos.yPos + laraBounds[3])
if (item->pos.yPos + bounds->Y1 < l->pos.yPos + laraBounds->Y2)
{
c = phd_cos(item->pos.yRot);
s = phd_sin(item->pos.yRot);
@ -935,27 +976,27 @@ int TestBoundsCollide(ITEM_INFO* item, ITEM_INFO* l, int radius)
dx = (c * x - s * z) >> W2V_SHIFT;
dz = (c * z + s * x) >> W2V_SHIFT;
if (dx >= bounds[0] - radius
&& dx <= radius + bounds[1]
&& dz >= bounds[4] - radius
&& dz <= radius + bounds[5])
if (dx >= bounds->X1 - radius
&& dx <= radius + bounds->X2
&& dz >= bounds->Z1 - radius
&& dz <= radius + bounds->Z2)
{
return TRUE;
return true;
}
}
}
return FALSE;
return false;
}
void CreatureCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
int c, s;
int x, z, rx, rz;
short* frame;
ANIM_FRAME* frame;
if (item->objectNumber != ID_HITMAN || item->currentAnimState != STATE_LARA_INSERT_PUZZLE)
if (item->objectNumber != ID_HITMAN || item->currentAnimState != LS_INSERT_PUZZLE)
{
if (TestBoundsCollide(item, l, coll->radius))
{
@ -972,10 +1013,10 @@ void CreatureCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
c = phd_cos(item->pos.yRot);
s = phd_sin(item->pos.yRot);
frame = GetBestFrame(item);
rx = (frame[0] + frame[1]) / 2;
rz = (frame[4] + frame[5]) / 2;
rx = (frame->boundingBox.X1 + frame->boundingBox.X2) / 2;
rz = (frame->boundingBox.X2 + frame->boundingBox.Z2) / 2;
if (frame[3] - frame[2] > STEP_SIZE)
if (frame->boundingBox.Y2 - frame->boundingBox.Y1 > STEP_SIZE)
{
int angle = (l->pos.yRot - phd_atan(z - ((c * rx - s * rz) >> W2V_SHIFT), x - ((c * rx + s * rz) >> W2V_SHIFT)) - ANGLE(135)) >> W2V_SHIFT;
Lara.hitDirection = (short)angle;
@ -1419,31 +1460,30 @@ void GetCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int roomNum
void LaraBaddieCollision(ITEM_INFO* l, COLL_INFO* coll)
{
ITEM_INFO* item;
ObjectInfo* obj;
OBJECT_INFO* obj;
l->hitStatus = false;
Lara.hitDirection = -1;
if (l->hitPoints > 0)
{
// Crash when using GetRoomList() with vector there but work without :x
vector<short> roomsList;
short* door, numDoors;
short roomsToCheck[128];
short numRoomsToCheck = 0;
roomsToCheck[numRoomsToCheck++] = l->roomNumber;
roomsList.push_back(l->roomNumber);
ROOM_INFO room = Rooms[l->roomNumber];
for (int i = 0; i < room.doors.size(); i++)
ROOM_INFO* room = &g_Level.Rooms[l->roomNumber];
for (int i = 0; i < room->doors.size(); i++)
{
roomsList.push_back(room.doors[i].room);
roomsToCheck[numRoomsToCheck++] = room->doors[i].room;
}
for (int i = 0; i < roomsList.size(); i++)
for (int i = 0; i < numRoomsToCheck; i++)
{
short itemNumber = Rooms[roomsList[i]].itemNumber;
short itemNumber = g_Level.Rooms[roomsToCheck[i]].itemNumber;
while (itemNumber != NO_ITEM)
{
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
if (item->collidable && item->status != ITEM_INVISIBLE)
{
obj = &Objects[item->objectNumber];
@ -1462,9 +1502,9 @@ void LaraBaddieCollision(ITEM_INFO* l, COLL_INFO* coll)
if (coll->enableSpaz)
{
for (int j = 0; j < Rooms[roomsList[i]].mesh.size(); j++)
for (int j = 0; j < g_Level.Rooms[roomsToCheck[i]].mesh.size(); j++)
{
MESH_INFO* mesh = &Rooms[roomsList[i]].mesh[j];
MESH_INFO* mesh = &g_Level.Rooms[roomsToCheck[i]].mesh[j];
if (mesh->flags & 1)
{
@ -1480,8 +1520,8 @@ void LaraBaddieCollision(ITEM_INFO* l, COLL_INFO* coll)
pos.zPos = mesh->z;
pos.yRot = mesh->yRot;
if (TestBoundsCollideStatic(&StaticObjects[mesh->staticNumber].xMinc, &pos, coll->radius))
ItemPushLaraStatic(l, &StaticObjects[mesh->staticNumber].xMinc, &pos, coll);
if (TestBoundsCollideStatic(&StaticObjects[mesh->staticNumber].collisionBox, &pos, coll->radius))
ItemPushLaraStatic(l, &StaticObjects[mesh->staticNumber].collisionBox, &pos, coll);
}
}
@ -1497,7 +1537,7 @@ void LaraBaddieCollision(ITEM_INFO* l, COLL_INFO* coll)
void GenericSphereBoxCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
if (item->status != ITEM_INVISIBLE)
{
@ -1562,20 +1602,20 @@ void GenericSphereBoxCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
void CalcItemToFloorRotation(ITEM_INFO* item, int radiusDivide)
{
FLOOR_INFO* floor;
ANIM_FRAME* bounds;
BOUNDING_BOX* bounds;
GAME_VECTOR pos;
int ratioXZ, frontHDif, sideHDif;
int frontX, frontZ, leftX, leftZ, rightX, rightZ;
int frontHeight, backHeight, leftHeight, rightHeight;
int radiusZ, radiusX;
bounds = (ANIM_FRAME*)GetBoundsAccurate(item);
bounds = GetBoundsAccurate(item);
pos.x = item->pos.xPos;
pos.y = item->pos.yPos;
pos.z = item->pos.zPos;
pos.roomNumber = item->roomNumber;
radiusX = bounds->MaxX;
radiusZ = bounds->MaxZ / radiusDivide; // need divide in any case else it's too much !
radiusX = bounds->X2;
radiusZ = bounds->Z2 / radiusDivide; // need divide in any case else it's too much !
ratioXZ = radiusZ / radiusX;
frontX = (phd_sin(item->pos.yRot) * radiusZ) >> W2V_SHIFT;

View file

@ -7,16 +7,6 @@
// used by coll->badNeg
#define NO_BAD_NEG NO_HEIGHT
struct BOUNDING_BOX
{
short X1;
short X2;
short Y1;
short Y2;
short Z1;
short Z2;
};
struct COLL_FLOOR
{
int floor;
@ -98,6 +88,17 @@ struct COLL_INFO
bool hitCeiling;
};
struct OBJECT_COLLISION_BOUNDS
{
BOUNDING_BOX boundingBox;
short rotX1;
short rotX2;
short rotY1;
short rotY2;
short rotZ1;
short rotZ2;
};
extern BOUNDING_BOX GlobalCollisionBounds;
constexpr auto MAX_ITEMS = 1024;
extern ITEM_INFO* CollidedItems[MAX_ITEMS];
@ -113,14 +114,14 @@ void ShiftItem(ITEM_INFO* item, COLL_INFO* coll);
void UpdateLaraRoom(ITEM_INFO* item, int height);
short GetTiltType(FLOOR_INFO* floor, int x, int y, int z);
int FindGridShift(int x, int z);
int TestBoundsCollideStatic(short* bounds, PHD_3DPOS* pos, int radius);
int ItemPushLaraStatic(ITEM_INFO* item, short* bounds, PHD_3DPOS* pos, COLL_INFO* coll);
int TestBoundsCollideStatic(BOUNDING_BOX* bounds, PHD_3DPOS* pos, int radius);
int ItemPushLaraStatic(ITEM_INFO* item, BOUNDING_BOX* bounds, PHD_3DPOS* pos, COLL_INFO* coll);
void AIPickupCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* c);
void ObjectCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* c);
void AlignLaraPosition(PHD_VECTOR* vec, ITEM_INFO* item, ITEM_INFO* l);
void TriggerLaraBlood();
int ItemPushLara(ITEM_INFO* item, ITEM_INFO* l, COLL_INFO* coll, int spazon, char bigpush);
int TestLaraPosition(short* bounds, ITEM_INFO* item, ITEM_INFO* l);
int TestLaraPosition(OBJECT_COLLISION_BOUNDS* bounds, ITEM_INFO* item, ITEM_INFO* l);
int Move3DPosTo3DPos(PHD_3DPOS* src, PHD_3DPOS* dest, int velocity, short angAdd);
int MoveLaraPosition(PHD_VECTOR* pos, ITEM_INFO* item, ITEM_INFO* l);
int TestBoundsCollide(ITEM_INFO* item, ITEM_INFO* l, int radius);

View file

@ -41,12 +41,16 @@
#include "tr4_locusts.h"
#include "smoke.h"
#include "spark.h"
#include <tr4_littlebeetle.h>
#include "explosion.h"
#include "drip.h"
using std::vector;
using namespace T5M::Effects::Explosion;
using namespace T5M::Effects::Spark;
using namespace T5M::Effects::Smoke;
using T5M::Renderer::g_Renderer;
short ShatterSounds[18][10] =
{
{SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS},
@ -146,7 +150,6 @@ short FlashFadeR;
short FlashFadeG;
short FlashFadeB;
short FlashFader;
short IsRoomOutsideNo;
int SplitFloor;
int SplitCeiling;
@ -154,6 +157,9 @@ int TiltXOffset;
int TiltYOffset;
int FramesCount;
std::vector<short> OutsideRoomTable[OUTSIDE_SIZE][OUTSIDE_SIZE];
short IsRoomOutsideNo;
extern GameFlow *g_GameFlow;
extern GameScript *g_GameScript;
extern Inventory g_Inventory;
@ -248,7 +254,7 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
// Does the player want to enter inventory?
SetDebounce = false;
if (CurrentLevel != 0 && !g_Renderer->IsFading())
if (CurrentLevel != 0 && !g_Renderer.IsFading())
{
if ((DbInput & IN_DESELECT || g_Inventory.GetEnterObject() != NO_ITEM) && !CutSeqTriggered && LaraItem->hitPoints > 0)
{
@ -299,7 +305,7 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
if (CurrentLevel != 0)
{
if (!(TrInput & IN_LOOK) || SniperCameraActive || UseSpotCam || TrackCameraInit ||
((LaraItem->currentAnimState != STATE_LARA_STOP || LaraItem->animNumber != ANIMATION_LARA_STAY_IDLE) && (!Lara.isDucked || TrInput & IN_DUCK || LaraItem->animNumber != ANIMATION_LARA_CROUCH_IDLE || LaraItem->goalAnimState != STATE_LARA_CROUCH_IDLE)))
((LaraItem->currentAnimState != LS_STOP || LaraItem->animNumber != LA_STAND_IDLE) && (!Lara.isDucked || TrInput & IN_DUCK || LaraItem->animNumber != LA_CROUCH_IDLE || LaraItem->goalAnimState != LS_CROUCH_IDLE)))
{
if (BinocularRange == 0)
{
@ -345,11 +351,6 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
Lara.busy = true;
LaserSight = true;
/*if (!(gfLevelFlags & GF_LVOP_TRAIN))
InfraRed = TRUE;
else*
InfraRed = false;*/
Infrared = true;
}
else
@ -359,18 +360,10 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
{
if (LaserSight)
{
/*if (!(gfLevelFlags & GF_LVOP_TRAIN))
InfraRed = TRUE;
else
InfraRed = false;*/
Infrared = true;
}
else
{
/*if ((gfLevelFlags & GF_LVOP_TRAIN) && (inputBusy & IN_ACTION))
InfraRed = TRUE;
else
InfraRed = false;*/
Infrared = false;
}
}
@ -379,7 +372,7 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
// Clear dynamic lights
ClearDynamicLights();
ClearFires();
g_Renderer->ClearDynamicLights();
g_Renderer.ClearDynamicLights();
GotLaraSpheres = false;
@ -389,7 +382,7 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
short itemNum = NextItemActive;
while (itemNum != NO_ITEM)
{
ITEM_INFO *item = &Items[itemNum];
ITEM_INFO *item = &g_Level.Items[itemNum];
short nextItem = item->nextActive;
if (item->afterDeath <= 128)
@ -419,8 +412,8 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
short fxNum = NextFxActive;
while (fxNum != NO_ITEM)
{
short nextFx = Effects[fxNum].nextActive;
FX_INFO *fx = &Effects[fxNum];
short nextFx = EffectList[fxNum].nextActive;
FX_INFO *fx = &EffectList[fxNum];
if (Objects[fx->objectNumber].control)
Objects[fx->objectNumber].control(fxNum);
fxNum = nextFx;
@ -461,7 +454,7 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
{
Lara.poisoned = 4096;
}
if (/*(gfLevelFlags & 0x80u) != 0 &&*/ !Lara.gassed)
if (!Lara.gassed)
{
if (Lara.dpoisoned)
{
@ -484,6 +477,8 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
InItemControlLoop = false;
KillMoveItems();
g_Renderer.UpdateLaraAnimations(true);
// Update Lara's ponytails
HairControl(0, 0, 0);
if (level->LaraType == LARA_YOUNG)
@ -550,12 +545,14 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
UpdateRats();
UpdateBats();
UpdateSpiders();
UpdateLittleBeetles();
UpdateSparkParticles();
UpdateSmokeParticles();
T5M::Effects::Drip::UpdateDrips();
UpdateExplosionParticles();
UpdateShockwaves();
UpdateLocusts();
UpdateLittleBeetles();
//Legacy_UpdateLightning();
AnimateWaterfalls();
@ -564,7 +561,7 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
//SoundEffects();
HealtBarTimer--;
HealthBarTimer--;
GameTimer++;
}
@ -587,7 +584,7 @@ unsigned CALLBACK GameMain(void *)
TIME_Init();
// Do a fixed time title image
g_Renderer->DoTitleImage();
g_Renderer.DoTitleImage();
// Execute the LUA gameflow and play the game
g_GameFlow->DoGameflow();
@ -598,7 +595,7 @@ unsigned CALLBACK GameMain(void *)
PostMessage(WindowsHandle, WM_CLOSE, NULL, NULL);
EndThread();
return TRUE;
return true;
}
GAME_STATUS DoTitle(int index)
@ -750,18 +747,18 @@ GAME_STATUS DoLevel(int index, int ambient, bool loadFromSavegame)
int nframes = 2;
// First control phase
g_Renderer->ResetAnimations();
g_Renderer.ResetAnimations();
GAME_STATUS result = ControlPhase(nframes, 0);
// Fade in screen
g_Renderer->FadeIn();
g_Renderer.FadeIn();
// The game loop, finally!
while (true)
{
nframes = DrawPhaseGame();
g_Renderer->ResetAnimations();
g_Renderer.ResetAnimations();
result = ControlPhase(nframes, 0);
if (result == GAME_STATUS_EXIT_TO_TITLE ||
result == GAME_STATUS_LOAD_GAME ||
@ -897,16 +894,16 @@ void TestTriggers(short *data, int heavy, int HeavyFlags)
value = *(data++) & 0x3FF;
if (flags & 0x100)
Items[value].itemFlags[0] = 1;
g_Level.Items[value].itemFlags[0] = 1;
if (!SwitchTrigger(value, timer))
return;
objectNumber = Items[value].objectNumber;
if (objectNumber >= ID_SWITCH_TYPE1 && objectNumber <= ID_SWITCH_TYPE6 && Items[value].triggerFlags == 5)
objectNumber = g_Level.Items[value].objectNumber;
if (objectNumber >= ID_SWITCH_TYPE1 && objectNumber <= ID_SWITCH_TYPE6 && g_Level.Items[value].triggerFlags == 5)
switchFlag = 1;
switchOff = (Items[value].currentAnimState == 1);
switchOff = (g_Level.Items[value].currentAnimState == 1);
break;
@ -1003,7 +1000,7 @@ void TestTriggers(short *data, int heavy, int HeavyFlags)
switch (targetType)
{
case TO_OBJECT:
item = &Items[value];
item = &g_Level.Items[value];
if (keyResult >= 2 ||
(triggerType == TRIGGER_TYPES::ANTIPAD ||
@ -1127,12 +1124,12 @@ void TestTriggers(short *data, int heavy, int HeavyFlags)
if (keyResult == 1)
break;
if (Camera.fixed[value].flags & 0x100)
if (FixedCameras[value].flags & 0x100)
break;
Camera.number = value;
if (Camera.type == LOOK_CAMERA || Camera.type == COMBAT_CAMERA && !(Camera.fixed[value].flags & 3))
if (Camera.type == LOOK_CAMERA || Camera.type == COMBAT_CAMERA && !(FixedCameras[value].flags & 3))
break;
if (triggerType == TRIGGER_TYPES::COMBAT)
@ -1146,7 +1143,7 @@ void TestTriggers(short *data, int heavy, int HeavyFlags)
Camera.timer = (trigger & 0xFF) * 30;
if (trigger & 0x100)
Camera.fixed[Camera.number].flags |= 0x100;
FixedCameras[Camera.number].flags |= 0x100;
Camera.speed = ((trigger & CODE_BITS) >> 6) + 1;
Camera.type = heavy ? HEAVY_CAMERA : FIXED_CAMERA;
@ -1191,7 +1188,7 @@ void TestTriggers(short *data, int heavy, int HeavyFlags)
break;
case TO_TARGET:
cameraItem = &Items[value];
cameraItem = &g_Level.Items[value];
break;
case TO_SINK:
@ -1316,7 +1313,7 @@ short GetDoor(FLOOR_INFO *floor)
if (!floor->index)
return NO_ROOM;
short *data = &FloorData[floor->index];
short *data = &g_Level.FloorData[floor->index];
short type = *(data++);
if (((type & DATA_TYPE) == TILT_TYPE) || ((type & DATA_TYPE) == SPLIT1) || ((type & DATA_TYPE) == SPLIT2) || ((type & DATA_TYPE) == NOCOLF1B) || ((type & DATA_TYPE) == NOCOLF1T) || ((type & DATA_TYPE) == NOCOLF2B) || ((type & DATA_TYPE) == NOCOLF2T))
@ -1355,14 +1352,14 @@ void TranslateItem(ITEM_INFO *item, int x, int y, int z)
int GetWaterSurface(int x, int y, int z, short roomNumber)
{
ROOM_INFO *room = &Rooms[roomNumber];
ROOM_INFO *room = &g_Level.Rooms[roomNumber];
FLOOR_INFO *floor = &XZ_GET_SECTOR(room, x - room->x, z - room->z);
if (room->flags & ENV_FLAG_WATER)
{
while (floor->skyRoom != NO_ROOM)
{
room = &Rooms[floor->skyRoom];
room = &g_Level.Rooms[floor->skyRoom];
if (!(room->flags & ENV_FLAG_WATER))
return (floor->ceiling << 8);
floor = &XZ_GET_SECTOR(room, x - room->x, z - room->z);
@ -1373,7 +1370,7 @@ int GetWaterSurface(int x, int y, int z, short roomNumber)
{
while (floor->pitRoom != NO_ROOM)
{
room = &Rooms[floor->pitRoom];
room = &g_Level.Rooms[floor->pitRoom];
if (room->flags & ENV_FLAG_WATER)
return (floor->floor << 8);
floor = &XZ_GET_SECTOR(room, x - room->x, z - room->z);
@ -1427,12 +1424,12 @@ int GetChange(ITEM_INFO *item, ANIM_STRUCT *anim)
for (int i = 0; i < anim->numberChanges; i++)
{
CHANGE_STRUCT *change = &Changes[anim->changeIndex + i];
CHANGE_STRUCT *change = &g_Level.Changes[anim->changeIndex + i];
if (change->goalAnimState == item->goalAnimState)
{
for (int j = 0; j < change->numberRanges; j++)
{
RANGE_STRUCT *range = &Ranges[change->rangeIndex + j];
RANGE_STRUCT *range = &g_Level.Ranges[change->rangeIndex + j];
if (item->frameNumber >= range->startFrame && item->frameNumber <= range->endFrame)
{
item->animNumber = range->linkAnimNum;
@ -1479,13 +1476,13 @@ void AlterFloorHeight(ITEM_INFO *item, int height)
floor->floor = NO_HEIGHT / STEP_SIZE;
}
box = &Boxes[floor->box];
if (box->overlapIndex & BLOCKABLE)
box = &g_Level.Boxes[floor->box];
if (box->flags & BLOCKABLE)
{
if (height >= 0)
box->overlapIndex &= ~BLOCKED;
box->flags &= ~BLOCKED;
else
box->overlapIndex |= BLOCKED;
box->flags |= BLOCKED;
}
}
@ -1499,7 +1496,7 @@ FLOOR_INFO *GetFloor(int x, int y, int z, short *roomNumber)
short roomDoor = 0;
int retval;
r = &Rooms[*roomNumber];
r = &g_Level.Rooms[*roomNumber];
do
{
xFloor = (z - r->z) >> WALL_SHIFT;
@ -1536,7 +1533,7 @@ FLOOR_INFO *GetFloor(int x, int y, int z, short *roomNumber)
if (data != NO_ROOM)
{
*roomNumber = data;
r = &Rooms[data];
r = &g_Level.Rooms[data];
}
} while (data != NO_ROOM);
@ -1551,7 +1548,7 @@ FLOOR_INFO *GetFloor(int x, int y, int z, short *roomNumber)
break;
*roomNumber = floor->skyRoom;
r = &Rooms[floor->skyRoom];
r = &g_Level.Rooms[floor->skyRoom];
floor = &XZ_GET_SECTOR(r, x - r->x, z - r->z);
if (y >= floor->ceiling * 256)
break;
@ -1567,7 +1564,7 @@ FLOOR_INFO *GetFloor(int x, int y, int z, short *roomNumber)
break;
*roomNumber = floor->pitRoom;
r = &Rooms[floor->pitRoom];
r = &g_Level.Rooms[floor->pitRoom];
floor = &XZ_GET_SECTOR(r, x - r->x, z - r->z);
if (y < floor->floor * 256)
break;
@ -1582,7 +1579,7 @@ int CheckNoColFloorTriangle(FLOOR_INFO *floor, int x, int z)
if (!floor->index)
return 0;
short *data = &FloorData[floor->index];
short *data = &g_Level.FloorData[floor->index];
short type = *(data)&DATA_TYPE;
if (type == NOCOLF1T || type == NOCOLF1B || type == NOCOLF2T || type == NOCOLF2B)
@ -1610,7 +1607,7 @@ int CheckNoColCeilingTriangle(FLOOR_INFO *floor, int x, int z)
if (!floor->index)
return 0;
short *data = &FloorData[floor->index];
short *data = &g_Level.FloorData[floor->index];
short type = *(data)&DATA_TYPE;
if (type == TILT_TYPE || type == SPLIT1 || type == SPLIT2 || type == NOCOLF1T || type == NOCOLF1B || type == NOCOLF2T || type == NOCOLF2B) // gibby
@ -1653,7 +1650,7 @@ int GetFloorHeight(FLOOR_INFO *floor, int x, int y, int z)
{
if (CheckNoColFloorTriangle(floor, x, z) == 1)
break;
r = &Rooms[floor->pitRoom];
r = &g_Level.Rooms[floor->pitRoom];
floor = &XZ_GET_SECTOR(r, x - r->x, z - r->z);
}
@ -1666,12 +1663,12 @@ int GetFloorHeight(FLOOR_INFO *floor, int x, int y, int z)
if (floor->index == 0)
return height;
short *data = &FloorData[floor->index];
short *data = &g_Level.FloorData[floor->index];
short type, hadj;
int xOff, yOff, trigger;
ITEM_INFO *item;
ObjectInfo *obj;
OBJECT_INFO *obj;
int tilts, t0, t1, t2, t3, t4, dx, dz, h1, h2;
do
@ -1733,7 +1730,7 @@ int GetFloorHeight(FLOOR_INFO *floor, int x, int y, int z)
}
else
{
item = &Items[trigger & VALUE_BITS];
item = &g_Level.Items[trigger & VALUE_BITS];
obj = &Objects[item->objectNumber];
if (obj->floor && !(item->flags & 0x8000))
@ -2174,8 +2171,8 @@ int GetTargetOnLOS(GAME_VECTOR *src, GAME_VECTOR *dest, int DrawTarget, int firi
GetFloor(target.x, target.y, target.z, &target.roomNumber);
if (itemNumber >= 0)
Lara.target = &Items[itemNumber];
if ((itemNumber >= 0) && (BaddieSlots[itemNumber].itemNum != NO_ITEM)) // BUGFIX: ensure target has AI. No more pistol desync and camera wobble when shooting non-AI movable objects.
Lara.target = &g_Level.Items[itemNumber];
if (firing)
{
@ -2200,7 +2197,7 @@ int GetTargetOnLOS(GAME_VECTOR *src, GAME_VECTOR *dest, int DrawTarget, int firi
}
else
{
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
if (item->objectNumber != ID_SHOOT_SWITCH1 && item->objectNumber != ID_SHOOT_SWITCH2)
{
if (Objects[item->objectNumber].explodableMeshbits & ShatterItem.bit && LaserSight)
@ -2301,8 +2298,8 @@ int GetTargetOnLOS(GAME_VECTOR *src, GAME_VECTOR *dest, int DrawTarget, int firi
for (count = GetSwitchTrigger(item, triggerItems, 1); count > 0; --count)
{
AddActiveItem(triggerItems[count - 1]);
Items[triggerItems[count - 1]].status = ITEM_ACTIVE;
Items[triggerItems[count - 1]].flags |= IFLAG_ACTIVATION_MASK;
g_Level.Items[triggerItems[count - 1]].status = ITEM_ACTIVE;
g_Level.Items[triggerItems[count - 1]].flags |= IFLAG_ACTIVATION_MASK;
}
}
}
@ -2322,7 +2319,7 @@ int GetTargetOnLOS(GAME_VECTOR *src, GAME_VECTOR *dest, int DrawTarget, int firi
{
if (LaserSight && itemNumber >= 0)
{
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
if (item->objectNumber == ID_ENEMY_JEEP && item->meshBits & 1)
{
/* @FIXME This turns the LaserSight sprite of the Grappling Gun green and calls FireGrapplingBoltFromLasersight() */
@ -2334,7 +2331,7 @@ int GetTargetOnLOS(GAME_VECTOR *src, GAME_VECTOR *dest, int DrawTarget, int firi
{
if (itemNumber >= 0)
{
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
if (item->objectNumber == ID_ENEMY_JEEP && Lara.gunType == WEAPON_CROSSBOW && item->meshBits & 1)
{
/* @FIXME This turns the LaserSight sprite of the Grappling Gun green */
@ -2378,17 +2375,18 @@ int ObjectOnLOS2(GAME_VECTOR *start, GAME_VECTOR *end, PHD_VECTOR *vec, MESH_INF
{
int r, m;
ROOM_INFO *room;
short linknum, *box;
short linknum;
ITEM_INFO *item;
PHD_3DPOS pos;
MESH_INFO *meshp;
BOUNDING_BOX* box;
ClosestItem = 999;
ClosestDist = SQUARE(end->x - start->x) + SQUARE(end->y - start->y) + SQUARE(end->z - start->z);
for (r = 0; r < number_los_rooms; ++r)
{
room = &Rooms[los_rooms[r]];
room = &g_Level.Rooms[los_rooms[r]];
for (m = 0; m < room->mesh.size(); m++)
{
@ -2401,7 +2399,7 @@ int ObjectOnLOS2(GAME_VECTOR *start, GAME_VECTOR *end, PHD_VECTOR *vec, MESH_INF
pos.zPos = meshp->z;
pos.yRot = meshp->yRot;
if (DoRayBox(start, end, &StaticObjects[meshp->staticNumber].xMinc, &pos, vec, -1 - meshp->staticNumber))
if (DoRayBox(start, end, &StaticObjects[meshp->staticNumber].collisionBox, &pos, vec, -1 - meshp->staticNumber))
{
*mesh = meshp;
end->roomNumber = los_rooms[r];
@ -2409,11 +2407,15 @@ int ObjectOnLOS2(GAME_VECTOR *start, GAME_VECTOR *end, PHD_VECTOR *vec, MESH_INF
}
}
for (linknum = room->itemNumber; linknum != NO_ITEM; linknum = Items[linknum].nextItem)
for (linknum = room->itemNumber; linknum != NO_ITEM; linknum = g_Level.Items[linknum].nextItem)
{
item = &Items[linknum];
item = &g_Level.Items[linknum];
if (item->status != ITEM_DEACTIVATED && item->status != ITEM_INVISIBLE && (item->objectNumber != ID_LARA && Objects[item->objectNumber].collision != NULL || item->objectNumber == ID_LARA && GetLaraOnLOS))
if (item->status != ITEM_DEACTIVATED && item->status != ITEM_INVISIBLE
&& (item->objectNumber != ID_LARA
&& Objects[item->objectNumber].collision != NULL
|| item->objectNumber == ID_LARA
&& GetLaraOnLOS))
{
box = GetBoundsAccurate(item);
@ -2474,7 +2476,7 @@ int GetCeiling(FLOOR_INFO *floor, int x, int y, int z) // (F) (D)
{
if (CheckNoColCeilingTriangle(floor, x, z) == 1) /* @ORIGINAL_BUG: the call is made with floor (which is constant in the while loop) instead of floor2 */
break;
room = &Rooms[floor2->skyRoom];
room = &g_Level.Rooms[floor2->skyRoom];
floor2 = &XZ_GET_SECTOR(room, x - room->x, z - room->z);
}
ceiling = 256 * floor2->ceiling;
@ -2482,7 +2484,7 @@ int GetCeiling(FLOOR_INFO *floor, int x, int y, int z) // (F) (D)
{
if (floor2->index)
{
data = &FloorData[floor2->index];
data = &g_Level.FloorData[floor2->index];
type = *data;
function = type & DATA_TYPE;
++data;
@ -2582,12 +2584,12 @@ int GetCeiling(FLOOR_INFO *floor, int x, int y, int z) // (F) (D)
{
if (CheckNoColFloorTriangle(floor, x, z) == 1)
break;
room = &Rooms[floor->pitRoom];
room = &g_Level.Rooms[floor->pitRoom];
floor = &XZ_GET_SECTOR(room, x - room->x, z - room->z);
}
if (floor->index)
{
data = &FloorData[floor->index];
data = &g_Level.FloorData[floor->index];
do
{
type = *data;
@ -2629,7 +2631,7 @@ int GetCeiling(FLOOR_INFO *floor, int x, int y, int z) // (F) (D)
}
else
{
item = &Items[type2 & VALUE_BITS];
item = &g_Level.Items[type2 & VALUE_BITS];
if (Objects[item->objectNumber].ceiling && !(item->flags & 0x8000))
{
Objects[item->objectNumber].ceiling(item, x, y, z, &ceiling);
@ -2643,7 +2645,7 @@ int GetCeiling(FLOOR_INFO *floor, int x, int y, int z) // (F) (D)
return ceiling;
}
int DoRayBox(GAME_VECTOR *start, GAME_VECTOR *end, short *box, PHD_3DPOS *itemOrStaticPos, PHD_VECTOR *hitPos, short closesItemNumber)
int DoRayBox(GAME_VECTOR *start, GAME_VECTOR *end, BOUNDING_BOX *box, PHD_3DPOS *itemOrStaticPos, PHD_VECTOR *hitPos, short closesItemNumber)
{
// Ray
FXMVECTOR rayStart = {start->x, start->y, start->z};
@ -2652,8 +2654,8 @@ int DoRayBox(GAME_VECTOR *start, GAME_VECTOR *end, short *box, PHD_3DPOS *itemOr
XMVECTOR rayDirNormalized = XMVector3Normalize(rayDir);
// Create the bounding box for raw collision detection
Vector3 boxCentre = Vector3(itemOrStaticPos->xPos + (box[1] + box[0]) / 2.0f, itemOrStaticPos->yPos + (box[3] + box[2]) / 2.0f, itemOrStaticPos->zPos + (box[5] + box[4]) / 2.0f);
Vector3 boxExtent = Vector3((box[1] - box[0]) / 2.0f, (box[3] - box[2]) / 2.0f, (box[5] - box[4]) / 2.0f);
Vector3 boxCentre = Vector3(itemOrStaticPos->xPos + (box->X2 + box->X1) / 2.0f, itemOrStaticPos->yPos + (box->Y2 + box->Y1) / 2.0f, itemOrStaticPos->zPos + (box->Z2 + box->Z1) / 2.0f);
Vector3 boxExtent = Vector3((box->X2 - box->X1) / 2.0f, (box->Y2 - box->Y1) / 2.0f, (box->Z2 - box->Z1) / 2.0f);
Quaternion rotation = Quaternion::CreateFromAxisAngle(Vector3::UnitY, TO_RAD(itemOrStaticPos->yRot));
BoundingOrientedBox obox = BoundingOrientedBox(boxCentre, boxExtent, rotation);
@ -2672,7 +2674,7 @@ int DoRayBox(GAME_VECTOR *start, GAME_VECTOR *end, short *box, PHD_3DPOS *itemOr
hitPos->z = collidedPoint.z - itemOrStaticPos->zPos;
// Now in the case of items we need to test single spheres
short *meshPtr = NULL;
MESH* meshPtr = NULL;
int bit = 0;
int sp = -2;
float minDistance = SECTOR(1024);
@ -2688,8 +2690,8 @@ int DoRayBox(GAME_VECTOR *start, GAME_VECTOR *end, short *box, PHD_3DPOS *itemOr
else
{
// For items instead we need to test spheres
ITEM_INFO *item = &Items[closesItemNumber];
ObjectInfo *obj = &Objects[item->objectNumber];
ITEM_INFO *item = &g_Level.Items[closesItemNumber];
OBJECT_INFO *obj = &Objects[item->objectNumber];
// Get the ransformed sphere of meshes
GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD, Matrix::Identity);
@ -2698,7 +2700,7 @@ int DoRayBox(GAME_VECTOR *start, GAME_VECTOR *end, short *box, PHD_3DPOS *itemOr
if (obj->nmeshes <= 0)
return 0;
meshPtr = Meshes[obj->meshIndex];
meshPtr = &g_Level.Meshes[obj->meshIndex];
for (int i = 0; i < obj->nmeshes; i++)
{
@ -2721,7 +2723,7 @@ int DoRayBox(GAME_VECTOR *start, GAME_VECTOR *end, short *box, PHD_3DPOS *itemOr
if (newDist < minDistance)
{
minDistance = newDist;
meshPtr = Meshes[obj->meshIndex + i];
meshPtr = &g_Level.Meshes[obj->meshIndex + i];
bit = 1 << i;
sp = i;
}
@ -2746,7 +2748,7 @@ int DoRayBox(GAME_VECTOR *start, GAME_VECTOR *end, short *box, PHD_3DPOS *itemOr
// If collided object is an item, then setup the shatter item data struct
if (sp >= 0)
{
ITEM_INFO *item = &Items[closesItemNumber];
ITEM_INFO *item = &g_Level.Items[closesItemNumber];
GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD | SPHERES_SPACE_BONE_ORIGIN, Matrix::Identity);
@ -2769,10 +2771,10 @@ void AnimateItem(ITEM_INFO *item)
item->frameNumber++;
ANIM_STRUCT *anim = &Anims[item->animNumber];
ANIM_STRUCT *anim = &g_Level.Anims[item->animNumber];
if (anim->numberChanges > 0 && GetChange(item, anim))
{
anim = &Anims[item->animNumber];
anim = &g_Level.Anims[item->animNumber];
item->currentAnimState = anim->currentAnimState;
@ -2784,7 +2786,7 @@ void AnimateItem(ITEM_INFO *item)
{
if (anim->numberCommands > 0)
{
short *cmd = &Commands[anim->commandIndex];
short *cmd = &g_Level.Commands[anim->commandIndex];
for (int i = anim->numberCommands; i > 0; i--)
{
switch (*(cmd++))
@ -2819,7 +2821,7 @@ void AnimateItem(ITEM_INFO *item)
item->animNumber = anim->jumpAnimNum;
item->frameNumber = anim->jumpFrameNum;
anim = &Anims[item->animNumber];
anim = &g_Level.Anims[item->animNumber];
if (item->currentAnimState != anim->currentAnimState)
{
@ -2833,7 +2835,7 @@ void AnimateItem(ITEM_INFO *item)
if (anim->numberCommands > 0)
{
short *cmd = &Commands[anim->commandIndex];
short *cmd = &g_Level.Commands[anim->commandIndex];
int flags;
int effectID = 0;
@ -2868,21 +2870,21 @@ void AnimateItem(ITEM_INFO *item)
SoundEffect(cmd[1] & 0x3FFF, &item->pos, 2);
}
else if (Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
else if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
{
if (!flags || flags == SFX_WATERONLY && (Rooms[Camera.pos.roomNumber].flags & ENV_FLAG_WATER || Objects[item->objectNumber].intelligent))
if (!flags || flags == SFX_WATERONLY && (g_Level.Rooms[Camera.pos.roomNumber].flags & ENV_FLAG_WATER || Objects[item->objectNumber].intelligent))
{
SoundEffect(cmd[1] & 0x3FFF, &item->pos, 2);
}
}
else if (!flags || flags == SFX_LANDONLY && !(Rooms[Camera.pos.roomNumber].flags & ENV_FLAG_WATER))
else if (!flags || flags == SFX_LANDONLY && !(g_Level.Rooms[Camera.pos.roomNumber].flags & ENV_FLAG_WATER))
{
SoundEffect(cmd[1] & 0x3FFF, &item->pos, 2);
}
}
else
{
if (Rooms[Camera.pos.roomNumber].flags & ENV_FLAG_WATER)
if (g_Level.Rooms[Camera.pos.roomNumber].flags & ENV_FLAG_WATER)
SoundEffect(cmd[1] & 0x3FFF, &item->pos, 1);
else
SoundEffect(cmd[1] & 0x3FFF, &item->pos, 0);
@ -2937,23 +2939,23 @@ void AnimateItem(ITEM_INFO *item)
item->pos.zPos += lateral * phd_cos(item->pos.yRot + ANGLE(90)) >> W2V_SHIFT;
// Update matrices
short itemNumber = item - Items;
g_Renderer->UpdateItemAnimations(itemNumber, true);
short itemNumber = item - g_Level.Items.data();
g_Renderer.UpdateItemAnimations(itemNumber, true);
}
void DoFlipMap(short group)
{
ROOM_INFO temp;
for (int i = 0; i < Rooms.size(); i++)
for (int i = 0; i < g_Level.Rooms.size(); i++)
{
ROOM_INFO *r = &Rooms[i];
ROOM_INFO *r = &g_Level.Rooms[i];
if (r->flippedRoom >= 0 && r->flipNumber == group)
{
RemoveRoomFlipItems(r);
ROOM_INFO *flipped = &Rooms[r->flippedRoom];
ROOM_INFO *flipped = &g_Level.Rooms[r->flippedRoom];
memcpy(&temp, r, sizeof(temp));
memcpy(r, flipped, sizeof(ROOM_INFO));
@ -2967,7 +2969,7 @@ void DoFlipMap(short group)
AddRoomFlipItems(r);
g_Renderer->FlipRooms(i, r->flippedRoom);
g_Renderer.FlipRooms(i, r->flippedRoom);
}
}
@ -2983,9 +2985,9 @@ void DoFlipMap(short group)
void AddRoomFlipItems(ROOM_INFO *r)
{
for (short linkNum = r->itemNumber; linkNum != NO_ITEM; linkNum = Items[linkNum].nextItem)
for (short linkNum = r->itemNumber; linkNum != NO_ITEM; linkNum = g_Level.Items[linkNum].nextItem)
{
ITEM_INFO *item = &Items[linkNum];
ITEM_INFO *item = &g_Level.Items[linkNum];
if (item->objectNumber == ID_RAISING_BLOCK1 && item->itemFlags[1])
AlterFloorHeight(item, -1024);
@ -3000,9 +3002,9 @@ void AddRoomFlipItems(ROOM_INFO *r)
void RemoveRoomFlipItems(ROOM_INFO *r)
{
for (short linkNum = r->itemNumber; linkNum != NO_ITEM; linkNum = Items[linkNum].nextItem)
for (short linkNum = r->itemNumber; linkNum != NO_ITEM; linkNum = g_Level.Items[linkNum].nextItem)
{
ITEM_INFO *item = &Items[linkNum];
ITEM_INFO *item = &g_Level.Items[linkNum];
if (item->flags & 0x100 && Objects[item->objectNumber].intelligent && item->hitPoints <= 0 && item->hitPoints != NOT_TARGETABLE)
{
@ -3086,7 +3088,7 @@ void RefreshCamera(short type, short *data)
if (Camera.type == LOOK_CAMERA || Camera.type == COMBAT_CAMERA)
break;
Camera.item = &Items[value];
Camera.item = &g_Level.Items[value];
break;
}
} while (!(trigger & END_BIT));
@ -3117,11 +3119,10 @@ int ExplodeItemNode(ITEM_INFO *item, int Node, int NoXZVel, int bits)
GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD | SPHERES_SPACE_BONE_ORIGIN, Matrix::Identity);
ShatterItem.yRot = item->pos.yRot;
ShatterItem.bit = 1 << Node;
ShatterItem.meshp = Meshes[Objects[item->objectNumber].meshIndex + Node];
ShatterItem.meshp = &g_Level.Meshes[Objects[item->objectNumber].meshIndex + Node];
ShatterItem.sphere.x = CreatureSpheres[Node].x;
ShatterItem.sphere.y = CreatureSpheres[Node].y;
ShatterItem.sphere.z = CreatureSpheres[Node].z;
ShatterItem.il = (ITEM_LIGHT *)&item->legacyLightData; // TODO: remove it or at last change it with the new renderer light...
ShatterItem.flags = item->objectNumber == ID_CROSSBOW_BOLT ? 0x400 : 0;
ShatterImpactData.impactDirection = Vector3(0, -1, 0);
ShatterImpactData.impactLocation = {(float)ShatterItem.sphere.x, (float)ShatterItem.sphere.y, (float)ShatterItem.sphere.z};
@ -3166,7 +3167,7 @@ int TriggerActive(ITEM_INFO *item)
int GetWaterHeight(int x, int y, int z, short roomNumber)
{
ROOM_INFO *r = &Rooms[roomNumber];
ROOM_INFO *r = &g_Level.Rooms[roomNumber];
FLOOR_INFO *floor;
short adjoiningRoom = NO_ROOM;
@ -3202,7 +3203,7 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
if (adjoiningRoom != NO_ROOM)
{
roomNumber = adjoiningRoom;
r = &Rooms[adjoiningRoom];
r = &g_Level.Rooms[adjoiningRoom];
}
} while (adjoiningRoom != NO_ROOM);
@ -3212,7 +3213,7 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
{
if (CheckNoColCeilingTriangle(floor, x, z) == 1)
break;
r = &Rooms[floor->skyRoom];
r = &g_Level.Rooms[floor->skyRoom];
if (!(r->flags & (ENV_FLAG_WATER | ENV_FLAG_SWAMP)))
return r->minfloor;
floor = &XZ_GET_SECTOR(r, x - r->x, z - r->z);
@ -3228,7 +3229,7 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
{
if (CheckNoColFloorTriangle(floor, x, z) == 1)
break;
r = &Rooms[floor->pitRoom];
r = &g_Level.Rooms[floor->pitRoom];
if (r->flags & (ENV_FLAG_WATER | ENV_FLAG_SWAMP))
return r->maxceiling;
floor = &XZ_GET_SECTOR(r, x - r->x, z - r->z);
@ -3242,14 +3243,14 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
int is_object_in_room(short roomNumber, short objectNumber)
{
short itemNumber = Rooms[roomNumber].itemNumber;
short itemNumber = g_Level.Rooms[roomNumber].itemNumber;
if (itemNumber == NO_ITEM)
return 0;
while (true)
{
ITEM_INFO *item = &Items[itemNumber];
ITEM_INFO *item = &g_Level.Items[itemNumber];
if (item->objectNumber == objectNumber)
break;
@ -3280,21 +3281,26 @@ void InterpolateAngle(short angle, short *rotation, short *outAngle, int shift)
int IsRoomOutside(int x, int y, int z)
{
return 0;
/*
short offset = OutsideRoomOffsets[((x >> 12) * 27) + (z >> 12)];
if (offset == -1)
if (x < 0 || z < 0)
return -2;
if (offset < 0)
int xTable = x / 1024;
int zTable = z / 1024;
if (OutsideRoomTable[xTable][zTable].size() == 0)
return -2;
for (int i = 0; i < OutsideRoomTable[xTable][zTable].size(); i++)
{
ROOM_INFO* r = &Rooms[(offset & 0x7FFF)];
short roomNumber = OutsideRoomTable[xTable][zTable][i];
ROOM_INFO* r = &g_Level.Rooms[roomNumber];
if ((y > r->maxceiling) && (y < r->minfloor)
&& ((z > (r->z + 1024)) && (z < (r->z + ((r->xSize - 1) * 1024))))
&& ((x > (r->x + 1024)) && (x < (r->x + ((r->ySize - 1) * 1024)))))
{
short roomNumber = offset & 0x7fff;
IsRoomOutsideNo = roomNumber;
FLOOR_INFO* floor = GetFloor(x, y, z, &roomNumber);
int height = GetFloorHeight(floor, x, y, z);
if (height == NO_HEIGHT || y > height)
@ -3303,44 +3309,9 @@ int IsRoomOutside(int x, int y, int z)
if (y < height)
return -2;
if (!(r->flags & (ENV_FLAG_WIND | ENV_FLAG_WATER)))
return -3;
IsRoomOutsideNo = offset & 0x7FFF;
return 1;
return ((r->flags & (ENV_FLAG_WIND | ENV_FLAG_WATER)) != 0 ? 1 : -3);
}
else
return -2;
}
else
{
unsigned char* s = &OutsideRoomTable[offset];
while (*s != 0xFF)
{
ROOM_INFO* r = &Rooms[*s];
if ((y > r->maxceiling && y < r->minfloor)
&& ((z > (r->z + 1024)) && (z < (r->z + ((r->xSize - 1) * 1024))))
&& ((x > (r->x + 1024)) && (x < (r->x + ((r->ySize - 1) * 1024)))))
{
short roomNumber = *s;
FLOOR_INFO* floor = GetFloor(x, y, z, &roomNumber);
int height = GetFloorHeight(floor, x, y, z);
if (height == NO_HEIGHT || y > height)
return -2;
height = GetCeiling(floor, x, y, z);
if (y < height)
return -2;
if (!(r->flags & (ENV_FLAG_WIND | ENV_FLAG_WATER)))
return -3;
IsRoomOutsideNo = *s;
return 1;
}
s++;
}
return -2;
}*/
return -2;
}

View file

@ -3,6 +3,8 @@
#include "items.h"
#include "room.h"
struct BOUNDING_BOX;
enum GAME_STATUS
{
GAME_STATUS_NONE,
@ -68,6 +70,9 @@ enum COMMAND_TYPES
#define TRIG_BITS(T) ((T & 0x3FFF) >> 10)
#define OUTSIDE_Z 64
#define OUTSIDE_SIZE 108
extern int KeyTriggerActive;
extern byte IsAtmospherePlaying;
extern byte FlipStatus;
@ -140,9 +145,10 @@ extern short FlashFadeR;
extern short FlashFadeG;
extern short FlashFadeB;
extern short FlashFader;
extern short IsRoomOutsideNo;
extern int TiltXOffset;
extern int TiltYOffset;
extern std::vector<short> OutsideRoomTable[OUTSIDE_SIZE][OUTSIDE_SIZE];
extern short IsRoomOutsideNo;
GAME_STATUS DoTitle(int index);
GAME_STATUS DoLevel(int index, int ambient, bool loadFromSavegame);
@ -173,7 +179,7 @@ void SeedRandomControl(int seed);
int GetRandomDraw();
void SeedRandomDraw(int seed);
int GetCeiling(FLOOR_INFO* floor, int x, int y, int z);
int DoRayBox(GAME_VECTOR* start, GAME_VECTOR* end, short* box, PHD_3DPOS* itemOrStaticPos, PHD_VECTOR* hitPos, short closesItemNumber);
int DoRayBox(GAME_VECTOR* start, GAME_VECTOR* end, BOUNDING_BOX* box, PHD_3DPOS* itemOrStaticPos, PHD_VECTOR* hitPos, short closesItemNumber);
void AnimateItem(ITEM_INFO* item);
void DoFlipMap(short group);
void AddRoomFlipItems(ROOM_INFO* r);

View file

@ -11,7 +11,7 @@ short SmashedMeshCount;
MESH_INFO* SmashedMesh[32];
short SmashedMeshRoom[32];
vector<DebrisFragment> DebrisFragments = vector<DebrisFragment>(MAX_DEBRIS);
using namespace T5M::Renderer;
DebrisFragment* GetFreeDebrisFragment()
{
for (auto frag = DebrisFragments.begin(); frag != DebrisFragments.end(); frag++) {
@ -24,13 +24,12 @@ DebrisFragment* GetFreeDebrisFragment()
void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num,short roomNumber,int noZXVel)
{
extern Renderer11* g_Renderer;
short* meshPtr = nullptr;
MESH* meshPtr = nullptr;
RendererMesh* fragmentsMesh;
short yRot = 0;
Vector3 pos;
if (mesh) {
meshPtr = Meshes[StaticObjects[mesh->staticNumber].meshNumber];
meshPtr = &g_Level.Meshes[StaticObjects[mesh->staticNumber].meshNumber];
yRot = mesh->yRot;
pos = Vector3(mesh->x, mesh->y, mesh->z);
}
@ -39,8 +38,8 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num,short roomNumber
yRot = item->yRot;
pos = Vector3(item->sphere.x, item->sphere.y, item->sphere.z);
}
fragmentsMesh = g_Renderer->getMeshFromMeshPtr(reinterpret_cast<unsigned int>(meshPtr));
for (int bucket = RENDERER_BUCKET_SOLID; bucket <= RENDERER_BUCKET_TRANSPARENT_DS; bucket++) {
fragmentsMesh = g_Renderer.getMesh(0);
for (int bucket = RENDERER_BUCKET_SOLID; bucket <= RENDERER_BUCKET_TRANSPARENT; bucket++) {
RendererBucket renderBucket = fragmentsMesh->Buckets[bucket];
vector<RendererVertex>* meshVertices = &renderBucket.Vertices;
for (int i = 0; i < renderBucket.Indices.size(); i += 3)

View file

@ -1,6 +1,8 @@
#pragma once
#include "sphere.h"
#include "Renderer11.h"
#include <sphere.h>
#include <Renderer11.h>
#include <newtypes.h>
#include <level.h>
#define MAX_DEBRIS 256
@ -25,7 +27,7 @@ typedef struct SHATTER_ITEM
{
SPHERE sphere;
ITEM_LIGHT* il;
short* meshp;
MESH* meshp;
int bit;
short yRot;
short flags;
@ -40,7 +42,7 @@ typedef struct ShatterImpactInfo
typedef struct DebrisMesh
{
RENDERER_BUCKETS bucket;
std::array<RendererVertex, 3> vertices;
std::array<T5M::Renderer::RendererVertex, 3> vertices;
};
typedef struct DebrisFragment

View file

@ -0,0 +1,26 @@
#pragma once
#if _DEBUG
constexpr bool DebugBuild = true;
#else
constexpr bool DebugBuild = false;
#endif
#include <stdexcept>
inline void assertion(const bool& expr,const char* msg) noexcept {
if constexpr (DebugBuild) {
if (!expr) throw std::runtime_error(msg);
}
};
template <typename ...T>
inline void logD(const T&... x) {
if constexpr (DebugBuild) {
(std::cout << ... << x) << std::endl;
}
};
template <typename ...T>
inline void logE(const T&... x) {
if constexpr (DebugBuild) {
(std::cerr << ... << x) << std::endl;
}
};

View file

@ -22,17 +22,17 @@ PHD_VECTOR KickDoorPos(0, 0, -917);
PHD_VECTOR UnderwaterDoorPos(-251, -540, -46);
PHD_VECTOR CrowbarDoorPos(-412, 0, 256);
static short PushPullKickDoorBounds[12] =
OBJECT_COLLISION_BOUNDS PushPullKickDoorBounds =
{
0xFE80, 0x0180, 0x0000, 0x0000, 0xFC00, 0x0200, 0xF8E4, 0x071C, 0xEAAC, 0x1554, 0xF8E4, 0x071C
};
static short UnderwaterDoorBounds[12] =
OBJECT_COLLISION_BOUNDS UnderwaterDoorBounds =
{
0xFF00, 0x0100, 0xFC00, 0x0000, 0xFC00, 0x0000, 0xC720, 0x38E0, 0xC720, 0x38E0, 0xC720, 0x38E0
};
static short CrowbarDoorBounds[12] =
OBJECT_COLLISION_BOUNDS CrowbarDoorBounds =
{
0xFE00, 0x0200, 0xFC00, 0x0000, 0x0000, 0x0200, 0xC720, 0x38E0, 0xC720, 0x38E0, 0xC720, 0x38E0
};
@ -50,7 +50,7 @@ extern Inventory g_Inventory;
void SequenceDoorControl(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
DOOR_DATA* door = (DOOR_DATA*)item->data;
if (CurrentSequence == 3)
@ -78,7 +78,7 @@ void SequenceDoorControl(short itemNumber)
OpenThatDoor(&door->d2, door);
OpenThatDoor(&door->d1flip, door);
OpenThatDoor(&door->d2flip, door);
door->opened = TRUE;
door->opened = true;
item->flags |= 0x3E;
}
}
@ -90,7 +90,7 @@ void SequenceDoorControl(short itemNumber)
ShutThatDoor(&door->d2, door);
ShutThatDoor(&door->d1flip, door);
ShutThatDoor(&door->d2flip, door);
door->opened = FALSE;
door->opened = false;
item->flags &= 0xC1;
}
}
@ -101,10 +101,10 @@ void SequenceDoorControl(short itemNumber)
void UnderwaterDoorCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
if (TrInput & IN_ACTION
&& l->currentAnimState == STATE_LARA_UNDERWATER_STOP
&& l->currentAnimState == LS_UNDERWATER_STOP
&& !(item->status && item->gravityStatus)
&& Lara.waterStatus == LW_UNDERWATER
&& !Lara.gunStatus
@ -112,17 +112,17 @@ void UnderwaterDoorCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
{
l->pos.yRot ^= ANGLE(180.0f);
if (TestLaraPosition(UnderwaterDoorBounds, item, l))
if (TestLaraPosition(&UnderwaterDoorBounds, item, l))
{
if (MoveLaraPosition(&UnderwaterDoorPos, item, l))
{
l->animNumber = ANIMATION_LARA_UNDERWATER_DOOR_OPEN;
l->frameNumber = GF(ANIMATION_LARA_UNDERWATER_DOOR_OPEN, 0);
l->currentAnimState = STATE_LARA_MISC_CONTROL;
l->animNumber = LA_UNDERWATER_DOOR_OPEN;
l->frameNumber = GF(LA_UNDERWATER_DOOR_OPEN, 0);
l->currentAnimState = LS_MISC_CONTROL;
l->fallspeed = 0;
item->status = ITEM_ACTIVE;
AddActiveItem(itemNum);
item->goalAnimState = STATE_LARA_RUN_FORWARD;
item->goalAnimState = LS_RUN_FORWARD;
AnimateItem(item);
Lara.isMoving = false;
Lara.gunStatus = LG_HANDS_BUSY;
@ -151,24 +151,24 @@ void UnderwaterDoorCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
void DoubleDoorCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
if (TrInput & IN_ACTION
&& l->currentAnimState == STATE_LARA_STOP
&& l->animNumber == ANIMATION_LARA_STAY_IDLE
&& l->currentAnimState == LS_STOP
&& l->animNumber == LA_STAND_IDLE
&& !(item->status && item->gravityStatus)
&& !(l->hitStatus)
&& !Lara.gunStatus
|| Lara.isMoving && Lara.generalPtr == (void*)itemNum)
{
item->pos.yRot ^= ANGLE(180);
if (TestLaraPosition(PushPullKickDoorBounds, item, l))
if (TestLaraPosition(&PushPullKickDoorBounds, item, l))
{
if (MoveLaraPosition(&DoubleDoorPos, item, l))
{
l->animNumber = ANIMATION_LARA_DOUBLEDOORS_PUSH;
l->frameNumber = GF(ANIMATION_LARA_DOUBLEDOORS_PUSH, 0);
l->currentAnimState = STATE_LARA_DOUBLEDOORS_PUSH;
l->animNumber = LA_DOUBLEDOOR_OPEN_PUSH;
l->frameNumber = GF(LA_DOUBLEDOOR_OPEN_PUSH, 0);
l->currentAnimState = LS_DOUBLEDOOR_PUSH;
AddActiveItem(itemNum);
@ -200,10 +200,10 @@ void DoubleDoorCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
void PushPullKickDoorCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
if (TrInput & IN_ACTION
&& l->currentAnimState == STATE_LARA_STOP
&& l->animNumber == ANIMATION_LARA_STAY_IDLE
&& l->currentAnimState == LS_STOP
&& l->animNumber == LA_STAND_IDLE
&& item->status != ITEM_ACTIVE
&& !(l->hitStatus)
&& !Lara.gunStatus
@ -217,7 +217,7 @@ void PushPullKickDoorCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
applyRot = true;
}
if (!TestLaraPosition(PushPullKickDoorBounds, item, l))
if (!TestLaraPosition(&PushPullKickDoorBounds, item, l))
{
if (Lara.isMoving && Lara.generalPtr == (void*)itemNum)
{
@ -238,15 +238,15 @@ void PushPullKickDoorCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
return;
}
l->animNumber = ANIMATION_LARA_DOOR_OPEN_BACK;
l->frameNumber = GF(ANIMATION_LARA_DOOR_OPEN_BACK, 0);
l->animNumber = LA_DOOR_OPEN_PULL;
l->frameNumber = GF(LA_DOOR_OPEN_PULL, 0);
item->goalAnimState = 3;
AddActiveItem(itemNum);
item->status = ITEM_ACTIVE;
l->currentAnimState = STATE_LARA_MISC_CONTROL;
l->goalAnimState = STATE_LARA_STOP;
l->currentAnimState = LS_MISC_CONTROL;
l->goalAnimState = LS_STOP;
Lara.isMoving = false;
Lara.gunStatus = LG_HANDS_BUSY;
@ -259,15 +259,15 @@ void PushPullKickDoorCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
{
if (MoveLaraPosition(&KickDoorPos, item, l))
{
l->animNumber = ANIMATION_LARA_DOOR_KICK;
l->frameNumber = GF(ANIMATION_LARA_DOOR_KICK, 0);
l->animNumber = LA_DOOR_OPEN_KICK;
l->frameNumber = GF(LA_DOOR_OPEN_KICK, 0);
item->goalAnimState = 2;
AddActiveItem(itemNum);
item->status = ITEM_ACTIVE;
l->currentAnimState = STATE_LARA_MISC_CONTROL;
l->goalAnimState = STATE_LARA_STOP;
l->currentAnimState = LS_MISC_CONTROL;
l->goalAnimState = LS_STOP;
Lara.isMoving = false;
Lara.gunStatus = LG_HANDS_BUSY;
@ -280,15 +280,15 @@ void PushPullKickDoorCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
{
if (MoveLaraPosition(&PushDoorPos, item, l))
{
l->animNumber = ANIMATION_LARA_DOOR_OPEN_FORWARD;
l->frameNumber = GF(ANIMATION_LARA_DOOR_OPEN_FORWARD, 0);
l->animNumber = LA_DOOR_OPEN_PUSH;
l->frameNumber = GF(LA_DOOR_OPEN_PUSH, 0);
item->goalAnimState = 2;
AddActiveItem(itemNum);
item->status = ITEM_ACTIVE;
l->currentAnimState = STATE_LARA_MISC_CONTROL;
l->goalAnimState = STATE_LARA_STOP;
l->currentAnimState = LS_MISC_CONTROL;
l->goalAnimState = LS_STOP;
Lara.isMoving = false;
Lara.gunStatus = LG_HANDS_BUSY;
@ -311,7 +311,7 @@ void PushPullKickDoorControl(short itemNumber)
ITEM_INFO* item;
DOOR_DATA* door;
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
door = (DOOR_DATA*)item->data;
if (!door->opened)
@ -320,7 +320,7 @@ void PushPullKickDoorControl(short itemNumber)
OpenThatDoor(&door->d2, door);
OpenThatDoor(&door->d1flip, door);
OpenThatDoor(&door->d2flip, door);
door->opened = TRUE;
door->opened = true;
}
AnimateItem(item);
@ -328,19 +328,19 @@ void PushPullKickDoorControl(short itemNumber)
void DoorCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
if (item->triggerFlags == 2
&& item->status == ITEM_NOT_ACTIVE && !item->gravityStatus // CHECK
&& ((TrInput & IN_ACTION || g_Inventory.GetSelectedObject() == ID_CROWBAR_ITEM)
&& l->currentAnimState == STATE_LARA_STOP
&& l->animNumber == ANIMATION_LARA_STAY_IDLE
&& l->currentAnimState == LS_STOP
&& l->animNumber == LA_STAND_IDLE
&& !l->hitStatus
&& Lara.gunStatus == LG_NO_ARMS
|| Lara.isMoving && Lara.generalPtr == (void*)itemNum))
{
item->pos.yRot ^= ANGLE(180);
if (TestLaraPosition(CrowbarDoorBounds, item, l))
if (TestLaraPosition(&CrowbarDoorBounds, item, l))
{
if (!Lara.isMoving)
{
@ -374,16 +374,16 @@ void DoorCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
g_Inventory.SetSelectedObject(NO_ITEM);
if (MoveLaraPosition(&CrowbarDoorPos, item, l))
{
l->animNumber = ANIMATION_LARA_DOOR_OPEN_CROWBAR;
l->frameNumber = GF(ANIMATION_LARA_DOOR_OPEN_CROWBAR, 0);
l->currentAnimState = STATE_LARA_MISC_CONTROL;
l->animNumber = LA_DOOR_OPEN_CROWBAR;
l->frameNumber = GF(LA_DOOR_OPEN_CROWBAR, 0);
l->currentAnimState = LS_MISC_CONTROL;
item->pos.yRot ^= ANGLE(180);
AddActiveItem(itemNum);
item->flags |= IFLAG_ACTIVATION_MASK;
item->status = ITEM_ACTIVE;
item->goalAnimState = STATE_LARA_RUN_FORWARD;
item->goalAnimState = LS_RUN_FORWARD;
Lara.isMoving = 0;
Lara.gunStatus = LG_HANDS_BUSY;
@ -418,17 +418,17 @@ void DoorCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
void DoorControl(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
DOOR_DATA* door = (DOOR_DATA*)item->data;
if (item->triggerFlags == 1)
{
if (item->itemFlags[0])
{
short* bounds = GetBoundsAccurate(item);
BOUNDING_BOX* bounds = GetBoundsAccurate(item);
--item->itemFlags[0];
item->pos.yPos -= 12;
int y = bounds[2] + item->itemFlags[2] - STEP_SIZE;
int y = bounds->Y1 + item->itemFlags[2] - STEP_SIZE;
if (item->pos.yPos < y)
{
item->pos.yPos = y;
@ -440,7 +440,7 @@ void DoorControl(short itemNumber)
OpenThatDoor(&door->d2, door);
OpenThatDoor(&door->d1flip, door);
OpenThatDoor(&door->d2flip, door);
door->opened = TRUE;
door->opened = true;
}
}
else
@ -456,7 +456,7 @@ void DoorControl(short itemNumber)
ShutThatDoor(&door->d2, door);
ShutThatDoor(&door->d1flip, door);
ShutThatDoor(&door->d2flip, door);
door->opened = FALSE;
door->opened = false;
}
}
}
@ -479,28 +479,8 @@ void DoorControl(short itemNumber)
OpenThatDoor(&door->d2, door);
OpenThatDoor(&door->d1flip, door);
OpenThatDoor(&door->d2flip, door);
door->opened = TRUE;
door->opened = true;
}
/*if (item->frameNumber == Anims[item->animNumber].frameEnd)
{
if (gfCurrentLevel == 11)
{
v9 = item->object_number;
if (v9 != 302 && v9 != 304)
{
LOBYTE(v5) = AnimateItem((int)item);
return v5;
}
LABEL_40:
v10 = item->_bf15ea;
LOBYTE(v10) = v10 | 6;
item->_bf15ea = v10;
LOBYTE(v5) = AnimateItem((int)item);
return v5;
}
if (gfCurrentLevel >= 0xCu && gfCurrentLevel <= 0xEu && item->object_number == 300)
goto LABEL_40;
}*/
}
else
{
@ -536,7 +516,7 @@ void DoorControl(short itemNumber)
ShutThatDoor(&door->d2, door);
ShutThatDoor(&door->d1flip, door);
ShutThatDoor(&door->d2flip, door);
door->opened = FALSE;
door->opened = false;
}
}
else
@ -579,7 +559,7 @@ void OpenThatDoor(DOORPOS_DATA* doorPos, DOOR_DATA* dd)
if (boxIndex != NO_BOX)
{
if (!DontUnlockBox)
Boxes[boxIndex].overlapIndex &= ~BLOCKED;
g_Level.Boxes[boxIndex].flags &= ~BLOCKED;
for (int i = 0; i < NUM_SLOTS; i++)
{
@ -670,7 +650,7 @@ void ShutThatDoor(DOORPOS_DATA* doorPos, DOOR_DATA* dd)
short boxIndex = doorPos->block;
if (boxIndex != NO_BOX)
{
Boxes[boxIndex].overlapIndex |= BLOCKED;
g_Level.Boxes[boxIndex].flags |= BLOCKED;
for (int i = 0; i < NUM_SLOTS; i++)
{
BaddieSlots[i].LOT.targetBox = NO_BOX;
@ -706,7 +686,7 @@ void ShutThatDoor(DOORPOS_DATA* doorPos, DOOR_DATA* dd)
void InitialiseDoor(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (item->objectNumber == ID_SEQUENCE_DOOR1)
item->flags &= 0xBFFFu;
@ -714,7 +694,7 @@ void InitialiseDoor(short itemNumber)
if (item->objectNumber == ID_LIFT_DOORS1 || item->objectNumber == ID_LIFT_DOORS2)
item->itemFlags[0] = 4096;
DOOR_DATA * door = (DOOR_DATA*)game_malloc(sizeof(DOOR_DATA));
DOOR_DATA * door = game_malloc<DOOR_DATA>();
item->data = door;
door->opened = false;
@ -739,7 +719,7 @@ void InitialiseDoor(short itemNumber)
else
dx++;
r = &Rooms[item->roomNumber];
r = &g_Level.Rooms[item->roomNumber];
door->d1.floor = &r->floor[(((item->pos.zPos - r->z) >> WALL_SHIFT) + dz) + (((item->pos.xPos - r->x) >> WALL_SHIFT) + dx) * r->xSize];
roomNumber = GetDoor(door->d1.floor);
@ -747,16 +727,16 @@ void InitialiseDoor(short itemNumber)
boxNumber = door->d1.floor->box;
else
{
b = &Rooms[roomNumber];
b = &g_Level.Rooms[roomNumber];
boxNumber = b->floor[(((item->pos.zPos - b->z) >> WALL_SHIFT) + dz) + (((item->pos.xPos - b->x) >> WALL_SHIFT) + dx) * b->xSize].box;
}
door->d1.block = (Boxes[boxNumber].overlapIndex & BLOCKABLE) ? boxNumber : NO_BOX;
door->d1.block = (g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX;
memcpy(&door->d1.data, door->d1.floor, sizeof(FLOOR_INFO));
if (r->flippedRoom != -1)
{
r = &Rooms[r->flippedRoom];
r = &g_Level.Rooms[r->flippedRoom];
door->d1flip.floor = &r->floor[(((item->pos.zPos - r->z) >> WALL_SHIFT) + dz) + (((item->pos.xPos - r->x) >> WALL_SHIFT) + dx) * r->xSize];
roomNumber = GetDoor(door->d1flip.floor);
@ -764,10 +744,10 @@ void InitialiseDoor(short itemNumber)
boxNumber = door->d1flip.floor->box;
else
{
b = &Rooms[roomNumber];
b = &g_Level.Rooms[roomNumber];
boxNumber = b->floor[(((item->pos.zPos - b->z) >> WALL_SHIFT) + dz) + (((item->pos.xPos - b->x) >> WALL_SHIFT) + dx) * b->xSize].box;
}
door->d1flip.block = (Boxes[boxNumber].overlapIndex & BLOCKABLE) ? boxNumber : NO_BOX;
door->d1flip.block = (g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX;
memcpy(&door->d1flip.data, door->d1flip.floor, sizeof(FLOOR_INFO));
}
@ -786,7 +766,7 @@ void InitialiseDoor(short itemNumber)
}
else
{
r = &Rooms[twoRoom];
r = &g_Level.Rooms[twoRoom];
door->d2.floor = &r->floor[((item->pos.zPos - r->z) >> WALL_SHIFT) + ((item->pos.xPos - r->x) >> WALL_SHIFT) * r->xSize];
roomNumber = GetDoor(door->d2.floor);
@ -794,16 +774,16 @@ void InitialiseDoor(short itemNumber)
boxNumber = door->d2.floor->box;
else
{
b = &Rooms[roomNumber];
b = &g_Level.Rooms[roomNumber];
boxNumber = b->floor[((item->pos.zPos - b->z) >> WALL_SHIFT) + ((item->pos.xPos - b->x) >> WALL_SHIFT) * b->xSize].box;
}
door->d2.block = (Boxes[boxNumber].overlapIndex & BLOCKABLE) ? boxNumber : NO_BOX;
door->d2.block = (g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX;
memcpy(&door->d2.data, door->d2.floor, sizeof(FLOOR_INFO));
if (r->flippedRoom != -1)
{
r = &Rooms[r->flippedRoom];
r = &g_Level.Rooms[r->flippedRoom];
door->d2flip.floor = &r->floor[((item->pos.zPos - r->z) >> WALL_SHIFT) + ((item->pos.xPos - r->x) >> WALL_SHIFT) * r->xSize];
roomNumber = GetDoor(door->d2flip.floor);
@ -811,10 +791,10 @@ void InitialiseDoor(short itemNumber)
boxNumber = door->d2flip.floor->box;
else
{
b = &Rooms[roomNumber];
b = &g_Level.Rooms[roomNumber];
boxNumber = b->floor[((item->pos.zPos - b->z) >> WALL_SHIFT) + ((item->pos.xPos - b->x) >> WALL_SHIFT) * b->xSize].box;
}
door->d2flip.block = (Boxes[boxNumber].overlapIndex & BLOCKABLE) ? boxNumber : NO_BOX;
door->d2flip.block = (g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX;
memcpy(&door->d2flip.data, door->d2flip.floor, sizeof(FLOOR_INFO));
}
@ -829,43 +809,6 @@ void InitialiseDoor(short itemNumber)
item->roomNumber = roomNumber;
item->inDrawRoom = true;
}
/*if (twoRoom != NO_ROOM && item->objectNumber >= ID_CLOSED_DOOR1 && item->objectNumber <= ID_LIFT_DOORS2)
{
FillDoorPointers(door, item, twoRoom, dz, dx);
door->dptr1[0] = 0;
door->dptr1[1] = 0;
door->dptr1[2] = 0;
door->dptr3[0] = 0;
door->dptr3[1] = 0;
door->dptr3[2] = 0;
if (Rooms[item->roomNumber].flippedRoom != -1)
{
//if (!door->dptr2)
// MEMORY[1] = 1;
door->dptr2[0] = 0;
door->dptr2[1] = 0;
door->dptr2[2] = 0;
}
if (Rooms[item->drawRoom].flippedRoom != -1)
{
//if (!door->dptr4)
// MEMORY[1] = 1;
door->dptr4[0] = 0;
door->dptr4[1] = 0;
door->dptr4[2] = 0;
}
door->item = item;
AssignClosedDoor(item);
}*/
}
void InitialiseClosedDoors()
@ -881,17 +824,17 @@ void FillDoorPointers(DOOR_DATA* doorData, ITEM_INFO* item, short roomNumber, in
dx <<= WALL_SHIFT;
dz <<= WALL_SHIFT;
ROOM_INFO* r = &Rooms[item->roomNumber];
ROOM_INFO* r = &g_Level.Rooms[item->roomNumber];
GetClosedDoorNormal(r, &doorData->dptr1, &doorData->dn1, dz, dx, absX, absZ);
if (r->flippedRoom != -1)
GetClosedDoorNormal(&Rooms[r->flippedRoom], &doorData->dptr2, &doorData->dn2, dz, dx, absX, absZ);
GetClosedDoorNormal(&g_Level.Rooms[r->flippedRoom], &doorData->dptr2, &doorData->dn2, dz, dx, absX, absZ);
r = &Rooms[roomNumber];
r = &g_Level.Rooms[roomNumber];
GetClosedDoorNormal(r, &doorData->dptr3, &doorData->dn3, dz, dx, absX, absZ);
if (r->flippedRoom != -1)
GetClosedDoorNormal(&Rooms[r->flippedRoom], &doorData->dptr4, &doorData->dn4, dz, dx, absX, absZ);
GetClosedDoorNormal(&g_Level.Rooms[r->flippedRoom], &doorData->dptr4, &doorData->dn4, dz, dx, absX, absZ);
}
void GetClosedDoorNormal(ROOM_INFO* room, short** dptr, byte* n, int z, int x, int absX, int absZ)
@ -955,10 +898,10 @@ void ProcessClosedDoors()
break;
short roomNumber = item->roomNumber;
if (!Rooms[roomNumber].boundActive && !Rooms[item->drawRoom].boundActive)
if (!g_Level.Rooms[roomNumber].boundActive && !g_Level.Rooms[item->drawRoom].boundActive)
continue;
if (Rooms[item->drawRoom].boundActive)
if (g_Level.Rooms[item->drawRoom].boundActive)
{
if (!(item->inDrawRoom))
{
@ -975,6 +918,7 @@ void ProcessClosedDoors()
}
}*/
}
// keeping these cocmments for now in case they're actually needed?
void AssignClosedDoor(ITEM_INFO* item)
{
@ -990,7 +934,7 @@ void AssignClosedDoor(ITEM_INFO* item)
void InitialiseSteelDoor(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->meshBits = 1;
item->pos.yPos -= 1024;
@ -998,7 +942,7 @@ void InitialiseSteelDoor(short itemNumber)
void SteelDoorCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (item->itemFlags[0] != 3)
{

View file

@ -4,7 +4,7 @@
#include "camera.h"
#include "level.h"
#include "Renderer11.h"
using T5M::Renderer::g_Renderer;
BITE_INFO EnemyBites[9] =
{
{ 20, -95, 240, 13 },
@ -24,7 +24,7 @@ int StormTimer;
int dLightningRand;
byte SkyStormColor[3];
byte SkyStormColor2[3];
short InterpolatedBounds[6];
BOUNDING_BOX InterpolatedBounds;
LARGE_INTEGER PerformanceCount;
double LdFreq;
double LdSync;
@ -32,8 +32,8 @@ int GnFrameCounter;
int DrawPhaseGame()
{
g_Renderer->Draw();
Camera.numberFrames = g_Renderer->SyncRenderer();
g_Renderer.Draw();
Camera.numberFrames = g_Renderer.SyncRenderer();
return Camera.numberFrames;
}
@ -66,30 +66,31 @@ void UpdateStorm()
}
}
short* GetBoundsAccurate(ITEM_INFO* item)
BOUNDING_BOX* GetBoundsAccurate(ITEM_INFO* item)
{
int rate = 0;
short* framePtr[2];
ANIM_FRAME* framePtr[2];
int frac = GetFrame_D2(item, framePtr, &rate);
if (frac == 0)
return framePtr[0];
return &framePtr[0]->boundingBox;
else
{
for (int i = 0; i < 6; i++)
{
InterpolatedBounds[i] = *(framePtr[0]) + ((*(framePtr[1]) - *(framePtr[0])) * frac) / rate;
framePtr[0]++;
framePtr[1]++;
}
return InterpolatedBounds;
InterpolatedBounds.X1 = framePtr[0]->boundingBox.X1 + (framePtr[1]->boundingBox.X1 - framePtr[0]->boundingBox.X1) / rate;
InterpolatedBounds.X2 = framePtr[0]->boundingBox.X2 + (framePtr[1]->boundingBox.X2 - framePtr[0]->boundingBox.X2) / rate;
InterpolatedBounds.Y1 = framePtr[0]->boundingBox.Y1 + (framePtr[1]->boundingBox.Y1 - framePtr[0]->boundingBox.Y1) / rate;
InterpolatedBounds.Y2 = framePtr[0]->boundingBox.Y2 + (framePtr[1]->boundingBox.Y2 - framePtr[0]->boundingBox.Y2) / rate;
InterpolatedBounds.Z1 = framePtr[0]->boundingBox.Z1 + (framePtr[1]->boundingBox.Z1 - framePtr[0]->boundingBox.Z1) / rate;
InterpolatedBounds.Z2 = framePtr[0]->boundingBox.Z2 + (framePtr[1]->boundingBox.Z2 - framePtr[0]->boundingBox.Z2) / rate;
return &InterpolatedBounds;
}
}
short* GetBestFrame(ITEM_INFO* item)
ANIM_FRAME* GetBestFrame(ITEM_INFO* item)
{
int rate = 0;
short* framePtr[2];
ANIM_FRAME* framePtr[2];
int frac = GetFrame_D2(item, framePtr, &rate);
@ -99,24 +100,22 @@ short* GetBestFrame(ITEM_INFO* item)
return framePtr[1];
}
int GetFrame_D2(ITEM_INFO* item, short* framePtr[], int* rate)
int GetFrame_D2(ITEM_INFO* item, ANIM_FRAME* framePtr[], int* rate)
{
ANIM_STRUCT *anim;
int frm;
int first, second;
int frame_size;
int interp, rat;
frm = item->frameNumber;
anim = &Anims[item->animNumber];
framePtr[0] = framePtr[1] = anim->framePtr;
anim = &g_Level.Anims[item->animNumber];
framePtr[0] = framePtr[1] = &g_Level.Frames[anim->framePtr];
rat = *rate = anim->interpolation & 0x00ff;
frame_size = anim->interpolation >> 8;
frm -= anim->frameBase;
frm -= anim->frameBase;
first = frm / rat;
interp = frm % rat;
framePtr[0] += first * frame_size; // Get Frame pointers
framePtr[1] = framePtr[0] + frame_size; // and store away
framePtr[0] += first; // Get Frame pointers
framePtr[1] = framePtr[0] + 1; // and store away
if (interp == 0)
return(0);
second = first * rat + rat;
@ -160,7 +159,7 @@ int Sync()
void DrawAnimatingItem(ITEM_INFO* item)
{
// TODO: to refactor
// Empty stub because actually we disable items drawing when drawRoutine pointer is NULL in ObjectInfo
// Empty stub because actually we disable items drawing when drawRoutine pointer is NULL in OBJECT_INFO
}
void GetLaraJointPosition(PHD_VECTOR* pos, int LM_enum)
@ -169,7 +168,7 @@ void GetLaraJointPosition(PHD_VECTOR* pos, int LM_enum)
LM_enum = LM_HEAD;
Vector3 p = Vector3(pos->x, pos->y, pos->z);
g_Renderer->GetLaraAbsBonePosition(&p, LM_enum);
g_Renderer.GetLaraAbsBonePosition(&p, LM_enum);
pos->x = p.x;
pos->y = p.y;

View file

@ -1,20 +1,6 @@
#pragma once
#include "box.h"
struct ANIM_FRAME
{
short MinX;
short MaxX;
short MinY;
short MaxY;
short MinZ;
short MaxZ;
short OffsetX;
short OffsetY;
short OffsetZ;
unsigned short AngleSets[]; // Variable size
};
extern BITE_INFO EnemyBites[9];
extern int LightningCount;
extern int LightningRand;
@ -25,10 +11,10 @@ extern byte SkyStormColor2[3];
extern int GnFrameCounter;
int DrawPhaseGame();
int GetFrame_D2(ITEM_INFO* item, short* framePtr[], int* rate);
int GetFrame_D2(ITEM_INFO* item, ANIM_FRAME* framePtr[], int* rate);
void UpdateStorm();
short* GetBoundsAccurate(ITEM_INFO* item);
short* GetBestFrame(ITEM_INFO* item);
BOUNDING_BOX* GetBoundsAccurate(ITEM_INFO* item);
ANIM_FRAME* GetBestFrame(ITEM_INFO* item);
int Sync();
bool TIME_Init();
bool TIME_Reset();

View file

@ -23,7 +23,7 @@ namespace T5M {
if (d.age > d.life)
d.active = false;
d.velocity.y += d.gravity;
if (Rooms[d.room].flags & ENV_FLAG_WIND) {
if (g_Level.Rooms[d.room].flags & ENV_FLAG_WIND) {
d.velocity.x = SmokeWindX / 2;
d.velocity.z = SmokeWindZ / 2;
}

View file

@ -18,13 +18,15 @@
#include "tr5_bats_emitter.h"
#include "tr5_spider_emitter.h"
#include "pickup.h"
#include "larafire.h"
using std::function;
constexpr auto ITEM_RADIUS_YMAX = SECTOR(3);
int wf = 256;
using namespace T5M::Effects::Footprints;
short FXType;
FX_INFO* Effects;
FX_INFO* EffectList;
function<EffectFunction> effect_routines[59] =
{
@ -41,9 +43,9 @@ function<EffectFunction> effect_routines[59] =
SoundFlipEffect,
ExplosionFX,
lara_hands_free,
void_effect,
void_effect,
void_effect,
puzzle,
draw_right_pistol,
draw_left_pistol,
shoot_right_gun,
shoot_left_gun,
void_effect,
@ -74,36 +76,19 @@ function<EffectFunction> effect_routines[59] =
void_effect,
void_effect,
LaraLocationPad,
KillActiveBaddies,
TL_1,
TL_2,
TL_3,
TL_4,
TL_5,
TL_6,
TL_7,
TL_8,
TL_9,
TL_10,
TL_11,
TL_12,
KillActiveBaddies
};
void TL_1(ITEM_INFO* item)
{
if (!Savegame.TLCount)
{
IsAtmospherePlaying = 0;
S_CDPlay(9, 0);
Savegame.TLCount = 1;
}
}
void pickup(ITEM_INFO* item)
{
do_pickup();
}
void puzzle(ITEM_INFO* item)
{
do_puzzle();
}
// TODO: here are sound for lara footstep too !
void AddFootprint(ITEM_INFO* item)
{
@ -142,116 +127,6 @@ void AddFootprint(ITEM_INFO* item)
}
}
void TL_2(ITEM_INFO* item)
{
if (Savegame.TLCount <= 1u)
{
IsAtmospherePlaying = 0;
S_CDPlay(7, 0);
Savegame.TLCount = 2;
}
}
void TL_3(ITEM_INFO* item)
{
if (Savegame.TLCount <= 2u)
{
IsAtmospherePlaying = 0;
S_CDPlay(23, 0);
Savegame.TLCount = 3;
}
}
void TL_4(ITEM_INFO* item)
{
if (Savegame.TLCount <= 3u)
{
IsAtmospherePlaying = 0;
S_CDPlay(39, 0);
Savegame.TLCount = 4;
}
}
void TL_5(ITEM_INFO* item)
{
if (Savegame.TLCount <= 4u)
{
IsAtmospherePlaying = 0;
S_CDPlay(2, 0);
Savegame.TLCount = 5;
}
}
void TL_6(ITEM_INFO* item)
{
if (Savegame.TLCount <= 5u)
{
IsAtmospherePlaying = 0;
S_CDPlay(22, 0);
Savegame.TLCount = 6;
}
}
void TL_7(ITEM_INFO* item)
{
if (Savegame.TLCount <= 6u)
{
IsAtmospherePlaying = 0;
S_CDPlay(51, 0);
Savegame.TLCount = 7;
}
}
void TL_8(ITEM_INFO* item)
{
if (Savegame.TLCount <= 7u)
{
IsAtmospherePlaying = 0;
S_CDPlay(3, 0);
Savegame.TLCount = 8;
}
}
void TL_9(ITEM_INFO* item)
{
if (Savegame.TLCount <= 8u)
{
IsAtmospherePlaying = 0;
S_CDPlay(4, 0);
Savegame.TLCount = 9;
}
}
void TL_10(ITEM_INFO* item)
{
if (Savegame.TLCount == 9)
{
IsAtmospherePlaying = 0;
S_CDPlay(13, 0);
Savegame.TLCount = 10;
}
}
void TL_11(ITEM_INFO* item)
{
if (Savegame.TLCount == 10)
{
IsAtmospherePlaying = 0;
S_CDPlay(0, 0);
Savegame.TLCount = 11;
}
}
void TL_12(ITEM_INFO* item)
{
if (Savegame.TLCount == 11)
{
IsAtmospherePlaying = 0;
S_CDPlay(35, 0);
Savegame.TLCount = 12;
}
}
void reset_hair(ITEM_INFO* item)
{
InitialiseHair();
@ -267,48 +142,39 @@ void invisibility_on(ITEM_INFO* item)
item->status = ITEM_INVISIBLE;
}
/*void SetFog()
{
FlipEffect = -1;
unsigned __int16 v0; // si
int v1; // eax
int v2; // eax
char v3; // bl
char v4; // ST14_1
char v5; // ST18_1
dword_51CE04 = 0;
v0 = TriggerTimer;
v1 = CheckVolumetric();
if (!v1)
goto LABEL_5;
if (v0 == 100)
{
dword_51CE04 = 1;
LABEL_5:
FlipEffect = -1;
return v1;
}
v2 = FogTable[v0];
v3 = FogTable[v0] >> 16;
v4 = BYTE1(v2);
v5 = FogTable[v0];
SomeDxFunctionToRemove1(BYTE2(v2), BYTE1(v2), v2);
LOBYTE(v1) = v4;
byte_51CE32 = v3;
byte_51CE31 = v4;
byte_51CE30 = v5;
FlipEffect = -1;
return v1;
}*/
void SetFog(ITEM_INFO* item)//39A44(<), 39F44(<) (F)
{
FlipEffect = -1;
}
void draw_left_pistol(ITEM_INFO* item)
{
if (Lara.meshPtrs[LM_LHAND] == Objects[ID_LARA_SKIN].meshIndex + LM_LHAND)
{
Lara.meshPtrs[LM_LHAND] = Objects[WeaponObjectMesh(WEAPON_PISTOLS)].meshIndex + LM_LHAND;
Lara.holsterInfo.leftHolster = HOLSTER_SLOT::Empty;
}
else
{
Lara.meshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
Lara.holsterInfo.leftHolster = HolsterSlotForWeapon(static_cast<LARA_WEAPON_TYPE>(WEAPON_PISTOLS));
}
}
void draw_right_pistol(ITEM_INFO* item)
{
if (Lara.meshPtrs[LM_RHAND] == Objects[ID_LARA_SKIN].meshIndex + LM_RHAND)
{
Lara.meshPtrs[LM_RHAND] = Objects[WeaponObjectMesh(WEAPON_PISTOLS)].meshIndex + LM_RHAND;
Lara.holsterInfo.rightHolster = HOLSTER_SLOT::Empty;
}
else
{
Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND;
Lara.holsterInfo.rightHolster = HolsterSlotForWeapon(static_cast<LARA_WEAPON_TYPE>(WEAPON_PISTOLS));
}
}
void shoot_left_gun(ITEM_INFO* item)//39A34(<), 39F34(<) (F)
{
Lara.leftArm.flash_gun = 3;
@ -333,7 +199,7 @@ void KillActiveBaddies(ITEM_INFO* item)//39938(<), 39E38(<) (F)
do
{
targetItem = &Items[itemNum];
targetItem = &g_Level.Items[itemNum];
if (Objects[targetItem->objectNumber].intelligent)
{
@ -380,12 +246,10 @@ void ExplosionFX(ITEM_INFO* item)//39694(<), 39B94(<) (F)
void SwapCrowbar(ITEM_INFO* item)//39638(<), 39B38(<) (F)
{
short* tmp = Meshes[Objects[ID_LARA].meshIndex + LM_RHAND];
if (Lara.meshPtrs[LM_RHAND] == tmp)
Lara.meshPtrs[LM_RHAND] = Meshes[Objects[ID_LARA_CROWBAR_ANIM].meshIndex + LM_RHAND];
if (Lara.meshPtrs[LM_RHAND] == Objects[ID_LARA].meshIndex + LM_RHAND)
Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA_CROWBAR_ANIM].meshIndex + LM_RHAND;
else
Lara.meshPtrs[LM_RHAND] = tmp;
Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA].meshIndex + LM_RHAND;
}
void ActivateKey(ITEM_INFO* item)//39624(<), 39B24(<) (F)
@ -410,7 +274,7 @@ void RubbleFX(ITEM_INFO* item)//39534(<), 39A34(<) (F)
if (itemNumber != NO_ITEM)
{
ITEM_INFO* eq = &Items[itemNumber];
ITEM_INFO* eq = &g_Level.Items[itemNumber];
AddActiveItem(itemNumber);
eq->status = ITEM_ACTIVE;
@ -460,7 +324,7 @@ void void_effect(ITEM_INFO* item)//393CC(<), 398CC(<) (F)
void ControlWaterfallMist(short itemNumber) // ControlWaterfallMist
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
int x, z;
if (item->pos.yRot == -ANGLE(180))
@ -484,7 +348,7 @@ short DoBloodSplat(int x, int y, int z, short a4, short a5, short roomNumber)
{
short roomNum = roomNumber;
GetFloor(x, y, z, &roomNum);
if (Rooms[roomNum].flags & ENV_FLAG_WATER)
if (g_Level.Rooms[roomNum].flags & ENV_FLAG_WATER)
TriggerUnderwaterBlood(x, y, z, a4);
else
TriggerBlood(x, y, z, a5 >> 4, a4);
@ -503,7 +367,7 @@ static bool ItemInRange(int x, int z, int radius)
bool ItemNearLara(PHD_3DPOS* pos, int radius)
{
ANIM_FRAME* bounds;
BOUNDING_BOX* bounds;
GAME_VECTOR target;
target.x = pos->xPos - LaraItem->pos.xPos;
target.y = pos->yPos - LaraItem->pos.yPos;
@ -515,8 +379,8 @@ bool ItemNearLara(PHD_3DPOS* pos, int radius)
if (!ItemInRange(target.x, target.z, radius))
return false;
bounds = (ANIM_FRAME*)GetBoundsAccurate(LaraItem);
if (target.y >= bounds->MinY && target.y <= (bounds->MaxY + LARA_RAD))
bounds = GetBoundsAccurate(LaraItem);
if (target.y >= bounds->Y1 && target.y <= (bounds->Y2 + LARA_RAD))
return true;
return false;
@ -524,7 +388,7 @@ bool ItemNearLara(PHD_3DPOS* pos, int radius)
bool ItemNearTarget(PHD_3DPOS* src, ITEM_INFO* target, int radius)
{
ANIM_FRAME* bounds;
BOUNDING_BOX* bounds;
PHD_VECTOR pos;
pos.x = src->xPos - target->pos.xPos;
pos.y = src->yPos - target->pos.yPos;
@ -536,8 +400,8 @@ bool ItemNearTarget(PHD_3DPOS* src, ITEM_INFO* target, int radius)
if (!ItemInRange(pos.x, pos.z, radius))
return false;
bounds = (ANIM_FRAME*)GetBoundsAccurate(target);
if (pos.y >= bounds->MinY && pos.y <= bounds->MaxY)
bounds = GetBoundsAccurate(target);
if (pos.y >= bounds->Y1 && pos.y <= bounds->Y2)
return true;
return false;

View file

@ -21,13 +21,12 @@ struct FX_INFO
};
extern std::function<EffectFunction> effect_routines[];
extern FX_INFO* Effects;
extern FX_INFO* EffectList;
bool ItemNearLara(PHD_3DPOS* pos, int radius);
bool ItemNearTarget(PHD_3DPOS* src, ITEM_INFO* target, int radius);
void StopSoundEffect(short sampleIndex);
short DoBloodSplat(int x, int y, int z, short speed, short yRot, short roomNumber);
//void SoundEffects();
void AddFootprint(ITEM_INFO* item);
void ControlWaterfallMist(short itemNumber);
void void_effect(ITEM_INFO* item);
@ -52,18 +51,9 @@ void SetFog(ITEM_INFO* item);
void invisibility_on(ITEM_INFO* item);
void invisibility_off(ITEM_INFO* item);
void reset_hair(ITEM_INFO* item);
void TL_1(ITEM_INFO* item);
void TL_2(ITEM_INFO* item);
void TL_3(ITEM_INFO* item);
void TL_4(ITEM_INFO* item);
void TL_5(ITEM_INFO* item);
void TL_6(ITEM_INFO* item);
void TL_7(ITEM_INFO* item);
void TL_8(ITEM_INFO* item);
void TL_9(ITEM_INFO* item);
void TL_10(ITEM_INFO* item);
void TL_11(ITEM_INFO* item);
void TL_12(ITEM_INFO* item);
void Richochet(PHD_3DPOS* pos);
void DoLotsOfBlood(int x, int y, int z, int speed, short direction, short roomNumber, int count);
void pickup(ITEM_INFO* item);
void puzzle(ITEM_INFO* item);
void draw_right_pistol(ITEM_INFO* item);
void draw_left_pistol(ITEM_INFO* item);

View file

@ -14,6 +14,7 @@
#include "spark.h"
#include "explosion.h"
#include <Game\drip.h>
using T5M::Renderer::g_Renderer;
using T5M::Effects::Explosion::TriggerExplosion;
using namespace T5M::Effects::Spark;
@ -81,11 +82,11 @@ void DetatchSpark(int num, SpriteEnumFlag type)// (F) (D)
case SP_FX:
if (sptr->flags & SP_USEFXOBJPOS)
{
sptr->on = FALSE;
sptr->on = false;
}
else
{
fx = &Effects[num];
fx = &EffectList[num];
sptr->x += fx->pos.xPos;
sptr->y += fx->pos.yPos;
sptr->z += fx->pos.zPos;
@ -95,11 +96,11 @@ void DetatchSpark(int num, SpriteEnumFlag type)// (F) (D)
case SP_ITEM:
if (sptr->flags & SP_USEFXOBJPOS)
{
sptr->on = FALSE;
sptr->on = false;
}
else
{
item = &Items[num];
item = &g_Level.Items[num];
sptr->x += item->pos.xPos;
sptr->y += item->pos.yPos;
sptr->z += item->pos.zPos;
@ -164,14 +165,14 @@ int GetFreeSpark()
void UpdateSparks()
{
short* bounds = GetBoundsAccurate(LaraItem);
BOUNDING_BOX* bounds = GetBoundsAccurate(LaraItem);
DeadlyBounds[0] = LaraItem->pos.xPos + bounds[0];
DeadlyBounds[1] = LaraItem->pos.xPos + bounds[1];
DeadlyBounds[2] = LaraItem->pos.yPos + bounds[2];
DeadlyBounds[3] = LaraItem->pos.yPos + bounds[3];
DeadlyBounds[4] = LaraItem->pos.zPos + bounds[4];
DeadlyBounds[5] = LaraItem->pos.zPos + bounds[5];
DeadlyBounds[0] = LaraItem->pos.xPos + bounds->X1;
DeadlyBounds[1] = LaraItem->pos.xPos + bounds->X2;
DeadlyBounds[2] = LaraItem->pos.yPos + bounds->Y1;
DeadlyBounds[3] = LaraItem->pos.yPos + bounds->Y2;
DeadlyBounds[4] = LaraItem->pos.zPos + bounds->Z1;
DeadlyBounds[5] = LaraItem->pos.zPos + bounds->Z2;
for (int i = 0; i < MAX_SPARKS; i++)
{
@ -387,128 +388,6 @@ void UpdateSparks()
void TriggerRicochetSpark(GAME_VECTOR* pos, short angle, int num, int unk)
{
/*int random;
SPARKS* spark;
if (!unk)
{
for (int i = 0; i < num; i++)
{
spark = &Sparks[GetFreeSpark()];
random = GetRandomControl();
spark->on = true;
spark->sR = -128;
spark->sG = (random & 0xF) + 16;
spark->sB = 0;
spark->dR = 96;
spark->dG = ((random >> 4) & 0x1F) + 48;
spark->dB = 0;
spark->colFadeSpeed = 2;
spark->fadeToBlack = 4;
spark->life = 9;
spark->sLife = 9;
spark->transType = COLADD;
spark->x = pos->x;
spark->y = pos->y;
spark->z = pos->z;
short ang = (((random >> 3) & 0x7FF) + angle - WALL_SIZE) & 0xFFF;
spark->xVel = -rcossin_tbl[2 * ang] >> 2;
spark->yVel = (random & 0xFFF) - 2048;
spark->zVel = rcossin_tbl[2 * ang + 1] >> 2;
spark->gravity = (random >> 7) & 0x1F;
spark->friction = 34;
spark->flags = SP_NONE;
spark->maxYvel = 0;
}
spark = &Sparks[GetFreeSpark()];
random = GetRandomControl();
spark->on = true;
spark->sR = 48;
spark->sG = (random & 0xF) + 32;
spark->sB = 0;
spark->dR = 0;
spark->dG = 0;
spark->dB = 0;
spark->colFadeSpeed = 4;
spark->fadeToBlack = 0;
spark->life = 4;
spark->sLife = 4;
spark->transType = COLADD;
spark->x = pos->x;
spark->y = pos->y;
spark->z = pos->z;
spark->xVel = 0;
spark->yVel = 0;
spark->zVel = 0;
spark->flags = 26;
spark->rotAng = (random >> 2) & 0xFFF;
if (random & 1)
spark->rotAdd = -64 - ((random >> 1) & 0x3F);
else
spark->rotAdd = ((random >> 1) & 0x3F) + 64;
spark->scalar = 3;
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex + 12;
spark->sSize = spark->size = ((random >> 10) & 7) + 8;
spark->dSize = 1;
spark->maxYvel = 0;
spark->gravity = 0;
}
if (1 - unk > 0)
{
num = (1 - unk);
for (int i = 0; i < num; i++)
{
spark = &Sparks[GetFreeSpark()];
int random = GetRandomControl();
spark->on = true;
spark->sR = 0;
spark->sG = 0;
spark->sB = 0;
spark->dR = 40;
spark->dG = 40;
spark->dB = 40;
spark->colFadeSpeed = (random & 3) + 4;
spark->fadeToBlack = 8;
spark->life =spark->sLife= ((random >> 2) & 7) + 16;
spark->x = pos->x;
spark->y = pos->y;
spark->z = pos->z;
if (unk)
{
spark->colFadeSpeed >>= 1;
spark->fadeToBlack = 4;
spark->sLife >>= 1;
spark->life >>= 1;
spark->xVel = (random & 0x1FF) - 256;
spark->yVel = ((random >> 2) & 0x1FF) - 256;
spark->zVel = ((random >> 4) & 0x1FF) - 256;
}
else
{
spark->yVel = 0;
spark->xVel = 0;
spark->zVel = 0;
}
spark->transType = COLADD;
spark->friction = 0;
spark->flags = 26;
spark->rotAng = random >> 3;
if (random & 1)
spark->rotAdd = -random - (random & 0xF);
else
spark->rotAdd = (random & 0xF) + 16;
spark->scalar = 2;
spark->gravity = -4 - ((random >> 9) & 3);
spark->sSize = spark->size= ((random >> 5) & 7) + 4;
spark->maxYvel = -4 - ((random >> 6) & 3);
spark->dSize = spark->size;
}
}*/
TriggerRicochetSpark(pos, angle, num);
}
@ -552,137 +431,7 @@ void TriggerCyborgSpark(int x, int y, int z, short xv, short yv, short zv)
void TriggerExplosionSparks(int x, int y, int z, int extraTrig, int dynamic, int uw, int roomNumber)
{
/*int shift = 0;
if ((roomNumber & 0x8000) != 0)
{
//v7 = -roomNumber;
roomNumber = -roomNumber;
shift = 1;
}
/ *if (v7 == gfMirrorRoom && gfLevelFlags & 0x2000)
v27 = 1;
z_bis = z;
do
{* /
SPARKS* spark = &Sparks[GetFreeSpark()];
spark->on = 1;
spark->sR = -1;
if (uw == 1)
{
spark->sB = 32;
spark->dR = -64;
spark->sG = (GetRandomControl() & 0x3F) + -128;
spark->dB = 0;
spark->colFadeSpeed = 7;
spark->dG = (GetRandomControl() & 0x1F) + 64;
spark->fadeToBlack = 8;
spark->transType = COLADD;
spark->life = spark->sLife = (GetRandomControl() & 7) + 16;
spark->roomNumber = roomNumber;
}
else
{
spark->sB = 0;
spark->sG = (GetRandomControl() & 0xF) + 32;
spark->dR = (GetRandomControl() & 0x3F) - 64;
spark->dB = 32;
spark->colFadeSpeed = 8;
spark->dG = (GetRandomControl() & 0x3F) + -128;
spark->fadeToBlack = 16;
spark->transType = COLADD;
spark->life = spark->sLife = (GetRandomControl() & 7) + 24;
}
spark->extras = extraTrig | 8 * (TES_extra_tab[extraTrig] + (GetRandomControl() & 7) + 28);
spark->dynamic = dynamic;
if (dynamic == -2)
{
int j;
for (j = 0; j < 8; j++)
{
SP_DYNAMIC* spdyn = &SparkDynamics[j];
if (!spdyn->On)
{
spdyn->On = 1;
spdyn->Falloff = 4;
if (uw == 1)
spdyn->Flags = SD_UWEXPLOSION;
else
spdyn->Flags = SD_EXPLOSION;
spark->dynamic = j;
break;
}
}
if (j == 8)
{
spark->dynamic = -1;
}
}
spark->xVel = (GetRandomControl() & 0xFFF) - 2048;
spark->yVel = (GetRandomControl() & 0xFFF) - 2048;
spark->zVel = (GetRandomControl() & 0xFFF) - 2048;
if (dynamic != -2 || uw == 1)
{
spark->x = (GetRandomControl() & 0x1F) + x - 16;
spark->y = (GetRandomControl() & 0x1F) + y - 16;
spark->z = (GetRandomControl() & 0x1F) + z - 16;
}
else
{
spark->x = (GetRandomControl() & 0x1FF) + x - 256;
spark->y = (GetRandomControl() & 0x1FF) + y - 256;
spark->z = (GetRandomControl() & 0x1FF) + z - 256;
}
if (uw == 1)
spark->friction = 17;
else
spark->friction = 51;
if (GetRandomControl() & 1)
{
if (uw == 1)
spark->flags = SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF | SP_UNDERWEXP;
else
spark->flags = SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF;
spark->rotAng = GetRandomControl() & 0xFFF;
spark->rotAdd = GetRandomControl() + -128;
}
else if (uw == 1)
{
spark->flags = SP_SCALE | SP_DEF | SP_EXPDEF | SP_UNDERWEXP;
}
else
{
spark->flags = SP_SCALE | SP_DEF | SP_EXPDEF;
}
spark->scalar = 3;
spark->gravity = 0;
int size = (GetRandomControl() & 0xF) + 40;
spark->maxYvel = 0;
spark->sSize = size << shift;
spark->size = size << shift;
spark->dSize = size << (shift + 1);
if (uw == 2)
{
spark->sG = spark->sR;
spark->sB = spark->sG;
spark->flags |= SP_PLASMAEXP;
spark->sR = spark->sB;
spark->dR = spark->dB;
spark->dG = spark->dR;
spark->dB = spark->dG;
}
else if (extraTrig)
{
TriggerExplosionSmoke(x, y, z, uw);
}
else
{
TriggerExplosionSmokeEnd(x, y, z, uw);
}*/
TriggerExplosion(Vector3(x, y, z), 512, true, false, true, roomNumber);
//} while (!v24);
}
void TriggerExplosionSmokeEnd(int x, int y, int z, int uw)
@ -1414,7 +1163,7 @@ void KillAllCurrentItems(short itemNumber)
void TriggerDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b)
{
g_Renderer->AddDynamicLight(x, y, z, falloff, r, g, b);
g_Renderer.AddDynamicLight(x, y, z, falloff, r, g, b);
}
// Really needed?
@ -1431,27 +1180,27 @@ void WadeSplash(ITEM_INFO* item, int wh, int wd)
short roomNumber = item->roomNumber;
GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
ROOM_INFO* room = &Rooms[roomNumber];
ROOM_INFO* room = &g_Level.Rooms[roomNumber];
if (room->flags & ENV_FLAG_WATER)
{
short roomNumber2 = item->roomNumber;
GetFloor(item->pos.xPos, room->y - 128, item->pos.zPos, &roomNumber2);
ROOM_INFO* room2 = &Rooms[roomNumber2];
ROOM_INFO* room2 = &g_Level.Rooms[roomNumber2];
if (!(room2->flags & ENV_FLAG_WATER))
{
short* frame = GetBestFrame(item);
if (item->pos.yPos + frame[2] <= wh)
ANIM_FRAME* frame = GetBestFrame(item);
if (item->pos.yPos + frame->boundingBox.Y1 <= wh)
{
if (item->pos.yPos + frame[3] >= wh)
if (item->pos.yPos + frame->boundingBox.Y2 >= wh)
{
if (item->fallspeed <= 0 || wd >= 474 || SplashCount != 0)
{
if (!(Wibble & 0xF))
{
if (!(GetRandomControl() & 0xF) || item->currentAnimState != STATE_LARA_STOP)
if (!(GetRandomControl() & 0xF) || item->currentAnimState != LS_STOP)
{
if (item->currentAnimState == STATE_LARA_STOP)
if (item->currentAnimState == LS_STOP)
{
SetupRipple(item->pos.xPos, wh, item->pos.zPos, (GetRandomControl() & 0xF) + 112, RIPPLE_FLAG_RAND_ROT | RIPPLE_FLAG_RAND_POS);
}
@ -1483,7 +1232,7 @@ void Splash(ITEM_INFO* item)
short roomNumber = item->roomNumber;
GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
ROOM_INFO* room = &Rooms[roomNumber];
ROOM_INFO* room = &g_Level.Rooms[roomNumber];
if (room->flags & ENV_FLAG_WATER)
{
int wh = GetWaterHeight(item->pos.xPos, item->pos.yPos, item->pos.zPos, roomNumber);
@ -1604,7 +1353,7 @@ void TriggerRocketSmoke(int x, int y, int z, int bodyPart)
void GrenadeExplosionEffects(int x, int y, int z, short roomNumber)
{
ROOM_INFO* room = &Rooms[roomNumber];
ROOM_INFO* room = &g_Level.Rooms[roomNumber];
bool mirror = (roomNumber == g_GameFlow->GetLevel(CurrentLevel)->Mirror.Room);
@ -1867,30 +1616,6 @@ void GrenadeLauncherSpecialEffect1(int x, int y, int z, int flag1, int flag2)
return;
}
/*if (flag2 && flag2 != 1)
{
if (flag2 < -2)
{
spark->y = y;
spark->x = (GetRandomControl() & 0xF) + x - 8;
spark->z = (GetRandomControl() & 0xF) + z - 8;
}
else
{
spark->x = (GetRandomControl() & 0x3F) + x - 32;
spark->y = y;
spark->z = (GetRandomControl() & 0x3F) + z - 32;
}
}
else
{
spark->y = y;
spark->x = (GetRandomControl() & 0x1F) + x - 16;
spark->z = (GetRandomControl() & 0x1F) + z - 16;
}
goto LABEL_POS_1;*/
}
}

View file

@ -15,10 +15,7 @@
#include "sound.h"
#include "snowmobile.h"
short FireBounds[12] =
{
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF8E4, 0x071C, 0xEAAC, 0x1554, 0xF8E4, 0x071C
};
extern OBJECT_COLLISION_BOUNDS FireBounds;
void TriggerTorchFlame(char fxObj, char node)
{
@ -72,12 +69,12 @@ void DoFlameTorch() // (F) (D)
if (TrInput & IN_DRAW
&& !(LaraItem->gravityStatus)
&& !LaraItem->fallspeed
&& LaraItem->currentAnimState != STATE_LARA_JUMP_PREPARE
&& LaraItem->currentAnimState != STATE_LARA_JUMP_UP
&& LaraItem->currentAnimState != STATE_LARA_JUMP_FORWARD
&& LaraItem->currentAnimState != STATE_LARA_JUMP_BACK
&& LaraItem->currentAnimState != STATE_LARA_JUMP_LEFT
&& LaraItem->currentAnimState != STATE_LARA_JUMP_RIGHT
&& LaraItem->currentAnimState != LS_JUMP_PREPARE
&& LaraItem->currentAnimState != LS_JUMP_UP
&& LaraItem->currentAnimState != LS_JUMP_FORWARD
&& LaraItem->currentAnimState != LS_JUMP_BACK
&& LaraItem->currentAnimState != LS_JUMP_LEFT
&& LaraItem->currentAnimState != LS_JUMP_RIGHT
|| Lara.waterStatus == LW_UNDERWATER)
{
Lara.leftArm.lock = true;
@ -110,7 +107,7 @@ void DoFlameTorch() // (F) (D)
}
else if (Lara.leftArm.frameNumber == 12)
{
LARA_MESHES(ID_LARA, LM_LHAND);
Lara.meshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
CreateFlare(ID_BURNING_TORCH_ITEM, 1);
}
}
@ -130,12 +127,12 @@ void DoFlameTorch() // (F) (D)
}
else if (Lara.leftArm.frameNumber == 36)
{
LARA_MESHES(ID_LARA, LM_LHAND);
Lara.meshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
CreateFlare(ID_BURNING_TORCH_ITEM, 0);
}
break;
case 3:
if (LaraItem->currentAnimState != STATE_LARA_MISC_CONTROL)
if (LaraItem->currentAnimState != LS_MISC_CONTROL)
{
Lara.leftArm.lock = false;
Lara.leftArm.frameNumber = 0;
@ -151,7 +148,7 @@ void DoFlameTorch() // (F) (D)
if (Lara.flareControlLeft)
Lara.gunStatus = LG_READY;
Lara.leftArm.frameBase = Anims[Lara.leftArm.animNumber].framePtr;
Lara.leftArm.frameBase = g_Level.Anims[Lara.leftArm.animNumber].framePtr;
if (Lara.litTorch)
{
@ -166,7 +163,7 @@ void DoFlameTorch() // (F) (D)
TriggerDynamicLight(pos.x, pos.y, pos.z, 12 - (GetRandomControl() & 1), (GetRandomControl() & 0x3F) + 192, (GetRandomControl() & 0x1F) + 96, 0);
if (!(Wibble & 7))
TriggerTorchFlame(LaraItem - Items, 0);
TriggerTorchFlame(LaraItem - g_Level.Items.data(), 0);
SoundEffect(SFX_LOOP_FOR_SMALL_FIRES, (PHD_3DPOS*)&pos, 0);
@ -186,13 +183,14 @@ void GetFlameTorch() // (F) (D)
Lara.gunStatus = LG_READY;
Lara.leftArm.lock = false;
Lara.leftArm.frameNumber = 0;
Lara.leftArm.frameBase = Anims[Lara.leftArm.animNumber].framePtr;
LARA_MESHES(ID_LARA_TORCH_ANIM, LM_LHAND);
Lara.leftArm.frameBase = g_Level.Anims[Lara.leftArm.animNumber].framePtr;
Lara.meshPtrs[LM_LHAND] = Objects[ID_LARA_TORCH_ANIM].meshIndex + LM_LHAND;
}
void TorchControl(short itemNumber) // (F) (D)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
int oldX = item->pos.xPos;
int oldY = item->pos.yPos;
@ -212,7 +210,7 @@ void TorchControl(short itemNumber) // (F) (D)
item->pos.xPos += xv;
item->pos.zPos += zv;
if (Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
{
item->fallspeed += (5 - item->fallspeed) / 2;
item->speed += (5 - item->speed) / 2;
@ -233,17 +231,17 @@ void TorchControl(short itemNumber) // (F) (D)
if (CollidedItems)
{
if (!Objects[CollidedItems[0]->objectNumber].intelligent)
ObjectCollision(CollidedItems[0] - Items, item, &lara_coll);
ObjectCollision(CollidedItems[0] - g_Level.Items.data(), item, &lara_coll);
}
else
{
StaticInfo* sobj = &StaticObjects[CollidedMeshes[0]->staticNumber];
STATIC_INFO* sobj = &StaticObjects[CollidedMeshes[0]->staticNumber];
PHD_3DPOS pos;
pos.xPos = CollidedMeshes[0]->x;
pos.yPos = CollidedMeshes[0]->y;
pos.zPos = CollidedMeshes[0]->z;
pos.yRot = CollidedMeshes[0]->yRot;
ItemPushLaraStatic(item, &sobj->xMinc, &pos, &lara_coll);
ItemPushLaraStatic(item, &sobj->collisionBox, &pos, &lara_coll);
}
item->speed >>= 1;
}
@ -259,7 +257,7 @@ void TorchControl(short itemNumber) // (F) (D)
void FireCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (Lara.gunType != WEAPON_TORCH
|| Lara.gunStatus != LG_READY
@ -267,8 +265,8 @@ void FireCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
|| Lara.litTorch == (item->status == ITEM_ACTIVE)
|| item->timer == -1
|| !(TrInput & IN_ACTION)
|| l->currentAnimState != STATE_LARA_STOP
|| l->animNumber != ANIMATION_LARA_STAY_IDLE
|| l->currentAnimState != LS_STOP
|| l->animNumber != LA_STAND_IDLE
|| l->gravityStatus)
{
if (item->objectNumber == ID_BURNING_ROOTS)
@ -281,47 +279,47 @@ void FireCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
switch (item->objectNumber)
{
case ID_FLAME_EMITTER:
FireBounds[0] = -256;
FireBounds[1] = 256;
FireBounds[2] = 0;
FireBounds[3] = 1024;
FireBounds[4] = -800;
FireBounds[5] = 800;
FireBounds.boundingBox.X1 = -256;
FireBounds.boundingBox.X2 = 256;
FireBounds.boundingBox.Y1 = 0;
FireBounds.boundingBox.Y2 = 1024;
FireBounds.boundingBox.Z1 = -800;
FireBounds.boundingBox.Z2 = 800;
break;
case ID_FLAME_EMITTER2:
FireBounds[1] = -256;
FireBounds[2] = 256;
FireBounds[3] = 0;
FireBounds[4] = 1024;
FireBounds[5] = -600;
FireBounds[6] = 600;
FireBounds.boundingBox.X1 = -256;
FireBounds.boundingBox.X2 = 256;
FireBounds.boundingBox.Y1 = 0;
FireBounds.boundingBox.Y2 = 1024;
FireBounds.boundingBox.Z1 = -600;
FireBounds.boundingBox.Z2 = 600;
break;
case ID_BURNING_ROOTS:
FireBounds[0] = -384;
FireBounds[1] = 384;
FireBounds[2] = 0;
FireBounds[3] = 2048;
FireBounds[4] = -384;
FireBounds[5] = 384;
FireBounds.boundingBox.X1 = -384;
FireBounds.boundingBox.X2 = 384;
FireBounds.boundingBox.Y1 = 0;
FireBounds.boundingBox.Y2 = 2048;
FireBounds.boundingBox.Z1 = -384;
FireBounds.boundingBox.Z2 = 384;
break;
}
item->pos.yRot = l->pos.yRot;
if (TestLaraPosition(FireBounds, item, l))
if (TestLaraPosition(&FireBounds, item, l))
{
if (item->objectNumber == ID_BURNING_ROOTS)
{
l->animNumber = ANIMATION_LARA_TORCH_LIGHT_5;
l->animNumber = LA_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->animNumber = (dy >> 8) + LA_TORCH_LIGHT_1;
}
l->currentAnimState = STATE_LARA_MISC_CONTROL;
l->frameNumber = Anims[l->animNumber].frameBase;
l->currentAnimState = LS_MISC_CONTROL;
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
Lara.flareControlLeft = false;
Lara.leftArm.lock = 3;
Lara.generalPtr = (void*)itemNumber;
@ -329,11 +327,11 @@ void FireCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
item->pos.yRot = rot;
}
if ((short)Lara.generalPtr == itemNumber && item->status != ITEM_ACTIVE && l->currentAnimState == STATE_LARA_MISC_CONTROL)
if ((short)Lara.generalPtr == itemNumber && item->status != ITEM_ACTIVE && l->currentAnimState == LS_MISC_CONTROL)
{
if (l->animNumber >= ANIMATION_LARA_TORCH_LIGHT_1 && l->animNumber <= ANIMATION_LARA_TORCH_LIGHT_5)
if (l->animNumber >= LA_TORCH_LIGHT_1 && l->animNumber <= LA_TORCH_LIGHT_5)
{
if (l->frameNumber - Anims[l->animNumber].frameBase == 40)
if (l->frameNumber - g_Level.Anims[l->animNumber].frameBase == 40)
{
TestTriggersAtXYZ(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 1, item->flags & 0x3E00);
item->flags |= 0x3E00;

View file

@ -9,9 +9,9 @@
#include "setup.h"
#include "sphere.h"
#include "level.h"
using T5M::Renderer::g_Renderer;
int FirstHair[HAIR_MAX];
HAIR_STRUCT Hairs[HAIR_MAX][HAIR_SEGMENTS];
HAIR_STRUCT Hairs[HAIR_MAX][HAIR_SEGMENTS + 1];
int WindAngle;
int DWindAngle;
int Wind;
@ -24,12 +24,12 @@ void InitialiseHair()
{
FirstHair[h] = 1;
int* bone = &Bones[Objects[ID_LARA_HAIR].boneIndex];
int* bone = &g_Level.Bones[Objects[ID_LARA_HAIR].boneIndex];
Hairs[h][0].pos.yRot = 0;
Hairs[h][0].pos.xRot = -0x4000;
for (int i = 1; i < HAIR_SEGMENTS; i++, bone += 4)
for (int i = 1; i < HAIR_SEGMENTS + 1; i++, bone += 4)
{
Hairs[h][i].pos.xPos = *(bone + 1);
Hairs[h][i].pos.yPos = *(bone + 2);
@ -43,11 +43,11 @@ void InitialiseHair()
}
void HairControl(int cutscene, int ponytail, short* framePtr)
void HairControl(int cutscene, int ponytail, ANIM_FRAME* framePtr)
{
SPHERE sphere[HAIR_SPHERE];
ObjectInfo* object = &Objects[ID_LARA];
short* frame;
OBJECT_INFO* object = &Objects[ID_LARA];
ANIM_FRAME* frame;
int spaz;
bool youngLara = g_GameFlow->GetLevel(CurrentLevel)->LaraType == LARA_YOUNG;
@ -86,10 +86,7 @@ void HairControl(int cutscene, int ponytail, short* framePtr)
break;
}
frame = Anims[spaz].framePtr;
int size = Anims[spaz].interpolation >> 8;
frame += (int)(Lara.hitFrame * size);
frame = &g_Level.Frames[g_Level.Anims[spaz].framePtr + Lara.hitFrame];
}
else
frame = GetBestFrame(LaraItem);
@ -100,47 +97,47 @@ void HairControl(int cutscene, int ponytail, short* framePtr)
}
// Get Lara's spheres in absolute coords, for head, torso, hips and upper arms
short* objptr = Lara.meshPtrs[LM_HIPS];
PHD_VECTOR pos = { objptr[0], objptr[1], objptr[2] };
MESH* mesh = &g_Level.Meshes[Lara.meshPtrs[LM_HIPS]];
PHD_VECTOR pos = { (int)mesh->sphere.Center.x, (int)mesh->sphere.Center.y, (int)mesh->sphere.Center.z };
GetLaraJointPosition(&pos, LM_HIPS);
sphere[0].x = pos.x;
sphere[0].y = pos.y;
sphere[0].z = pos.z;
sphere[0].r = (int) * (objptr + 3);
sphere[0].r = (int)mesh->sphere.Radius;
objptr = Lara.meshPtrs[LM_TORSO];
pos = { objptr[0], objptr[1], objptr[2] };
mesh = &g_Level.Meshes[Lara.meshPtrs[LM_TORSO]];
pos = { (int)mesh->sphere.Center.x, (int)mesh->sphere.Center.y, (int)mesh->sphere.Center.z };
GetLaraJointPosition(&pos, LM_TORSO);
sphere[1].x = pos.x;
sphere[1].y = pos.y;
sphere[1].z = pos.z;
sphere[1].r = (int) * (objptr + 3);
sphere[1].r = (int)mesh->sphere.Radius;
if (youngLara)
sphere[1].r = sphere[1].r - ((sphere[1].r >> 2) + (sphere[1].r >> 3));
objptr = Lara.meshPtrs[LM_HEAD];
pos = { objptr[0], objptr[1], objptr[2] };
mesh = &g_Level.Meshes[Lara.meshPtrs[LM_HEAD]];
pos = { (int)mesh->sphere.Center.x, (int)mesh->sphere.Center.y, (int)mesh->sphere.Center.z };
GetLaraJointPosition(&pos, LM_HEAD);
sphere[2].x = pos.x;
sphere[2].y = pos.y;
sphere[2].z = pos.z;
sphere[2].r = (int) * (objptr + 3);
sphere[2].r = (int)mesh->sphere.Radius;
objptr = Lara.meshPtrs[LM_RINARM];
pos = { objptr[0], objptr[1], objptr[2] };
mesh = &g_Level.Meshes[Lara.meshPtrs[LM_RINARM]];
pos = { (int)mesh->sphere.Center.x, (int)mesh->sphere.Center.y, (int)mesh->sphere.Center.z };
GetLaraJointPosition(&pos, LM_RINARM);
sphere[3].x = pos.x;
sphere[3].y = pos.y;
sphere[3].z = pos.z;
sphere[3].r = (int) * (objptr + 3) * 3 / 2;
sphere[3].r = (int)mesh->sphere.Radius * 3 / 2;
objptr = Lara.meshPtrs[LM_LINARM];
pos = { objptr[0], objptr[1], objptr[2] };
mesh = &g_Level.Meshes[Lara.meshPtrs[LM_LINARM]];
pos = { (int)mesh->sphere.Center.x, (int)mesh->sphere.Center.y, (int)mesh->sphere.Center.z };
GetLaraJointPosition(&pos, LM_LINARM);
sphere[4].x = pos.x;
sphere[4].y = pos.y;
sphere[4].z = pos.z;
sphere[4].r = (int) * (objptr + 3) * 3 / 2;
sphere[4].r = (int)mesh->sphere.Radius * 3 / 2;
if (youngLara)
{
@ -150,7 +147,7 @@ void HairControl(int cutscene, int ponytail, short* framePtr)
}
Matrix world;
g_Renderer->GetBoneMatrix(Lara.itemNumber, LM_HEAD, &world);
g_Renderer.GetBoneMatrix(Lara.itemNumber, LM_HEAD, &world);
if (ponytail)
{
@ -169,7 +166,7 @@ void HairControl(int cutscene, int ponytail, short* framePtr)
pos.y = world.Translation().y;
pos.z = world.Translation().z;
int* bone = &Bones[Objects[ID_LARA_HAIR].boneIndex];
int* bone = &g_Level.Bones[Objects[ID_LARA_HAIR].boneIndex];
if (FirstHair[ponytail])
{
@ -179,7 +176,7 @@ void HairControl(int cutscene, int ponytail, short* framePtr)
Hairs[ponytail][0].pos.yPos = pos.y;
Hairs[ponytail][0].pos.zPos = pos.z;
for (int i = 0; i < HAIR_SEGMENTS - 1; i++, bone += 4)
for (int i = 0; i < HAIR_SEGMENTS; i++, bone += 4)
{
world = Matrix::CreateTranslation(Hairs[ponytail][i].pos.xPos, Hairs[ponytail][i].pos.yPos, Hairs[ponytail][i].pos.zPos);
world = Matrix::CreateFromYawPitchRoll(TO_RAD(Hairs[ponytail][i].pos.yRot), TO_RAD(Hairs[ponytail][i].pos.xRot), 0) * world;
@ -208,9 +205,9 @@ void HairControl(int cutscene, int ponytail, short* framePtr)
}
else
{
int x = LaraItem->pos.xPos + (frame[0] + frame[1]) / 2;
int y = LaraItem->pos.yPos + (frame[2] + frame[3]) / 2;
int z = LaraItem->pos.zPos + (frame[4] + frame[5]) / 2;
int x = LaraItem->pos.xPos + (frame->boundingBox.X1 + frame->boundingBox.X2) / 2;
int y = LaraItem->pos.yPos + (frame->boundingBox.Y1 + frame->boundingBox.Y2) / 2;
int z = LaraItem->pos.zPos + (frame->boundingBox.Z1 + frame->boundingBox.Z2) / 2;
wh = GetWaterHeight(x, y, z, roomNumber);
}
@ -235,7 +232,7 @@ void HairControl(int cutscene, int ponytail, short* framePtr)
SmokeWindX = (((rcossin_tbl[WindAngle]) * Wind) >> 12);
SmokeWindZ = (((rcossin_tbl[WindAngle + 1]) * Wind) >> 12);
for (int i = 1; i < HAIR_SEGMENTS; i++, bone += 4)
for (int i = 1; i < HAIR_SEGMENTS + 1; i++, bone += 4)
{
Hairs[ponytail][0].hvel.x = Hairs[ponytail][i].pos.xPos;
Hairs[ponytail][0].hvel.y = Hairs[ponytail][i].pos.yPos;
@ -257,7 +254,7 @@ void HairControl(int cutscene, int ponytail, short* framePtr)
Hairs[ponytail][i].pos.yPos += Hairs[ponytail][i].hvel.y * 3 / 4;
Hairs[ponytail][i].pos.zPos += Hairs[ponytail][i].hvel.z * 3 / 4;
if (Lara.waterStatus == LW_ABOVE_WATER && Rooms[roomNumber].flags & ENV_FLAG_WIND)
if (Lara.waterStatus == LW_ABOVE_WATER && g_Level.Rooms[roomNumber].flags & ENV_FLAG_WIND)
{
Hairs[ponytail][i].pos.xPos += SmokeWindX;
Hairs[ponytail][i].pos.zPos += SmokeWindZ;
@ -316,7 +313,7 @@ void HairControl(int cutscene, int ponytail, short* framePtr)
world = Matrix::CreateTranslation(Hairs[ponytail][i - 1].pos.xPos, Hairs[ponytail][i - 1].pos.yPos, Hairs[ponytail][i - 1].pos.zPos);
world = Matrix::CreateFromYawPitchRoll(TO_RAD(Hairs[ponytail][i - 1].pos.yRot), TO_RAD(Hairs[ponytail][i - 1].pos.xRot), 0) * world;
if (i == HAIR_SEGMENTS - 1)
if (i == HAIR_SEGMENTS)
world = Matrix::CreateTranslation(*(bone - 3), *(bone - 2), *(bone - 1)) * world;
else
world = Matrix::CreateTranslation(*(bone + 1), *(bone + 2), *(bone + 3)) * world;

View file

@ -3,16 +3,18 @@
#include "phd_global.h"
constexpr auto HAIR_MAX = 2; // HAIR_NORMAL = 0, HAIR_YOUNG = 1
constexpr auto HAIR_SEGMENTS = 7; // classic = 7, young = 14
constexpr auto HAIR_SEGMENTS = 6; // classic = 7, young = 14
constexpr auto HAIR_SPHERE = 5; // current hair max collision
struct ANIM_FRAME;
struct HAIR_STRUCT
{
PHD_3DPOS pos;
PHD_VECTOR hvel;
PHD_VECTOR unknown;
};
extern HAIR_STRUCT Hairs[HAIR_MAX][HAIR_SEGMENTS];
extern HAIR_STRUCT Hairs[HAIR_MAX][HAIR_SEGMENTS + 1];
void InitialiseHair();
void HairControl(int cutscene, int ponytail, short* framePtr);
void HairControl(int cutscene, int ponytail, ANIM_FRAME* framePtr);

View file

@ -7,13 +7,16 @@
#include "level.h"
#include "control.h"
using namespace T5M::Renderer;
short PickupX;
short PickupY;
short CurrentPickup;
DISPLAY_PICKUP Pickups[MAX_COLLECTED_PICKUPS];
short PickupVel;
int OldHitPoints = 1000;
int HealtBarTimer = 40;
int HealthBarTimer = 40;
float HealthBar = OldHitPoints;
float MutateAmount = 0;
int FlashState = 0;
int FlashCount = 0;
int PoisonFlag = 0;
@ -22,6 +25,8 @@ extern RendererHUDBar* g_HealthBar;
extern RendererHUDBar* g_DashBar;
extern RendererHUDBar* g_AirBar;
bool EnableSmoothHealthBar = true;
void DrawHealthBarOverlay(int value)
{
if (CurrentLevel)
@ -31,7 +36,7 @@ void DrawHealthBarOverlay(int value)
color2 = 0xA0A000;
else
color2 = 0xA00000;
g_Renderer->DrawBar(value, g_HealthBar);
g_Renderer.DrawBar(value, ::g_HealthBar);
}
}
@ -39,16 +44,11 @@ void DrawHealthBar(float value)
{
if (CurrentLevel)
{
//int color2;
//if (Lara.poisoned || Lara.gassed)
// color2 = 0xA0A000;
//else
// color2 = 0xA00000;
g_Renderer->DrawBar(value,g_HealthBar);
g_Renderer.DrawBar(value, ::g_HealthBar);
}
}
void UpdateHealtBar(int flash)
void UpdateHealthBar(int flash)
{
int hitPoints = LaraItem->hitPoints;
@ -57,44 +57,75 @@ void UpdateHealtBar(int flash)
else if (hitPoints > 1000)
hitPoints = 1000;
if (OldHitPoints != hitPoints)
// OPT: smoothly transition health bar display.
if (EnableSmoothHealthBar)
{
OldHitPoints = hitPoints;
HealtBarTimer = 40;
if (OldHitPoints != hitPoints)
{
MutateAmount += OldHitPoints - hitPoints;
OldHitPoints = hitPoints;
HealthBarTimer = 40;
}
if (HealthBar - MutateAmount < 0)
MutateAmount = HealthBar;
else if (HealthBar - MutateAmount > 1000)
MutateAmount = HealthBar - 1000;
HealthBar -= MutateAmount / 3;
MutateAmount -= MutateAmount / 3;
if (MutateAmount > -0.5f && MutateAmount < 0.5f)
{
MutateAmount = 0;
HealthBar = hitPoints;
}
}
if (HealtBarTimer < 0)
HealtBarTimer = 0;
// OG: discretely transition health bar display.
else
{
if (OldHitPoints != hitPoints)
{
OldHitPoints = hitPoints;
HealthBar = hitPoints;
HealthBarTimer = 40;
}
}
if (hitPoints <= 1000 / 4)
if (HealthBarTimer < 0)
HealthBarTimer = 0;
// Flash when at 1/4 capacity AND HP bar is not transitioning.
if (HealthBar <= 1000 / 4 && MutateAmount == 0)
{
if (!BinocularRange)
{
if (flash)
DrawHealthBar(hitPoints / 1000.0f);
DrawHealthBar(HealthBar / 1000.0f);
else
DrawHealthBar(0);
}
else
else
{
if (flash)
DrawHealthBarOverlay(hitPoints / 1000.0f);
DrawHealthBarOverlay(HealthBar / 1000.0f);
else
DrawHealthBarOverlay(0);
}
}
else if ((HealtBarTimer > 0)
|| (hitPoints <= 0)
else if ((HealthBarTimer > 0)
|| (HealthBar <= 0)
|| (Lara.gunStatus == LG_READY && Lara.gunType != WEAPON_TORCH)
|| (Lara.poisoned >= 256))
{
if (!BinocularRange && !SniperOverlay)
{
DrawHealthBar(hitPoints / 1000.0f);
DrawHealthBar(HealthBar / 1000.0f);
}
else
{
DrawHealthBarOverlay(hitPoints / 1000.0f);
DrawHealthBarOverlay(HealthBar / 1000.0f);
}
}
@ -106,7 +137,7 @@ void DrawAirBar(float value)
{
if (CurrentLevel)
{
g_Renderer->DrawBar(value, g_AirBar);
g_Renderer.DrawBar(value, ::g_AirBar);
}
}
@ -116,11 +147,11 @@ void UpdateAirBar(int flash)
return;
if ((Lara.Vehicle == NO_ITEM)
|| (Items[Lara.Vehicle].objectNumber != ID_UPV))
|| (g_Level.Items[Lara.Vehicle].objectNumber != ID_UPV))
{
if ((Lara.waterStatus != LW_UNDERWATER)
&& (Lara.waterStatus != LW_SURFACE)
&& (!((Rooms[LaraItem->roomNumber].flags & ENV_FLAG_SWAMP)
&& (!((g_Level.Rooms[LaraItem->roomNumber].flags & ENV_FLAG_SWAMP)
&& (Lara.waterSurfaceDist < -775))))
return;
}
@ -133,7 +164,7 @@ void UpdateAirBar(int flash)
if (air <= 450)
{
if (flash)
DrawAirBar(air/ 1800.0f);
DrawAirBar(air / 1800.0f);
else
DrawAirBar(0);
}
@ -152,7 +183,7 @@ void DrawDashBar(int value)
{
if (CurrentLevel)
{
g_Renderer->DrawBar(value, g_DashBar);
g_Renderer.DrawBar(value, ::g_DashBar);
}
}
@ -163,12 +194,12 @@ int DrawAllPickups()
if (PickupX > 0)
{
PickupX += -PickupX >> 5;
return g_Renderer->DrawPickup(Pickups[CurrentPickup].objectNumber);
return g_Renderer.DrawPickup(Pickups[CurrentPickup].objectNumber);
}
else
{
Pickups[CurrentPickup].life--;
return g_Renderer->DrawPickup(Pickups[CurrentPickup].objectNumber);
return g_Renderer.DrawPickup(Pickups[CurrentPickup].objectNumber);
}
}
else if (Pickups[CurrentPickup].life == 0)
@ -178,13 +209,13 @@ int DrawAllPickups()
if (PickupVel < 16)
PickupVel++;
PickupX += PickupVel >> 2;
return g_Renderer->DrawPickup(Pickups[CurrentPickup].objectNumber);
return g_Renderer.DrawPickup(Pickups[CurrentPickup].objectNumber);
}
else
{
Pickups[CurrentPickup].life = -1;
PickupVel = 0;
return g_Renderer->DrawPickup(Pickups[CurrentPickup].objectNumber);
return g_Renderer.DrawPickup(Pickups[CurrentPickup].objectNumber);
}
}
@ -199,7 +230,7 @@ int DrawAllPickups()
CurrentPickup = pickupIndex;
if (i != MAX_COLLECTED_PICKUPS)
return g_Renderer->DrawPickup(Pickups[CurrentPickup].objectNumber);
return g_Renderer.DrawPickup(Pickups[CurrentPickup].objectNumber);
CurrentPickup = 0;

View file

@ -9,7 +9,7 @@ typedef struct DISPLAY_PICKUP
void DrawHealthBarOverlay(int value);
void DrawHealthBar(float value);
void UpdateHealtBar(int flash);
void UpdateHealthBar(int flash);
void DrawAirBar(float value);
void UpdateAirBar(int flash);
void DrawDashBar(int value);
@ -24,7 +24,11 @@ extern short CurrentPickup;
extern DISPLAY_PICKUP Pickups[MAX_COLLECTED_PICKUPS];
extern short PickupVel;
extern int OldHitPoints;
extern int HealtBarTimer;
extern int HealthBarTimer;
extern float HealthBar;
extern float MutateAmount;
extern int FlashState;
extern int PoisonFlag;
extern int DashTimer;
extern bool EnableSmoothHealthBar;

View file

@ -16,6 +16,7 @@
#include "lara2gun.h"
#include "level.h"
#include "input.h"
using namespace T5M::Renderer;
using std::vector;
Inventory g_Inventory;
extern GameFlow* g_GameFlow;
@ -571,18 +572,18 @@ int Inventory::DoInventory()
m_activeRing = INV_RING_OPTIONS;
m_rings[m_activeRing].currentObject = 0;
g_Renderer->DumpGameScene();
g_Renderer.DumpGameScene();
OpenRing(m_activeRing, true);
int passportResult = DoPassport();
// Fade out
g_Renderer->FadeOut();
for (int i = 0; i < FADE_FRAMES_COUNT; i++)
{
//g_Renderer.FadeOut();
//for (int i = 0; i < FADE_FRAMES_COUNT; i++)
//{
UpdateSceneAndDrawInventory();
}
//}
return passportResult;
}
@ -614,7 +615,7 @@ int Inventory::DoInventory()
int result = INV_RESULT_NONE;
g_Renderer->DumpGameScene();
g_Renderer.DumpGameScene();
SoundEffect(SFX_TR3_MENU_SPININ, NULL, 0);
@ -725,7 +726,7 @@ int Inventory::DoInventory()
passportResult == INV_RESULT_LOAD_GAME)
{
// Fade out
g_Renderer->FadeOut();
g_Renderer.FadeOut();
for (int i = 0; i < FADE_FRAMES_COUNT; i++)
{
UpdateSceneAndDrawInventory();
@ -823,7 +824,7 @@ bool Inventory::IsCurrentObjectExamine()
int Inventory::DoPuzzle()
{
InventoryRing* ring = &m_rings[m_activeRing];
ring->frameIndex = 0;
ring->framePtr = 0;
ring->selectedIndex = 0;
ring->numActions = 0;
@ -913,7 +914,7 @@ int Inventory::DoPuzzle()
int Inventory::DoWeapon()
{
InventoryRing* ring = &m_rings[m_activeRing];
ring->frameIndex = 0;
ring->framePtr = 0;
ring->selectedIndex = 0;
ring->numActions = 0;
@ -1060,7 +1061,7 @@ void Inventory::AddCombination(short piece1, short piece2, short combinedObject,
int Inventory::DoGenericObject()
{
InventoryRing* ring = &m_rings[m_activeRing];
ring->frameIndex = 0;
ring->framePtr = 0;
return INV_RESULT_USE_ITEM;
}
@ -1068,14 +1069,14 @@ int Inventory::DoGenericObject()
void Inventory::DoStatistics()
{
InventoryRing* ring = &m_rings[m_activeRing];
ring->frameIndex = 0;
ring->framePtr = 0;
}
void Inventory::DoExamine()
{
InventoryRing* ring = &m_rings[m_activeRing];
ring->frameIndex = 0;
ring->framePtr = 0;
}
@ -1501,7 +1502,7 @@ void Inventory::UseCurrentItem()
// Binoculars
if (objectNumber == ID_BINOCULARS_ITEM)
{
if (LaraItem->currentAnimState == STATE_LARA_STOP && LaraItem->animNumber == ANIMATION_LARA_STAY_IDLE || Lara.isDucked && !(TrInput & 0x20000000))
if (LaraItem->currentAnimState == LS_STOP && LaraItem->animNumber == LA_STAND_IDLE || Lara.isDucked && !(TrInput & 0x20000000))
{
if (!SniperCameraActive && !UseSpotCam && !TrackCameraInit)
{
@ -1564,15 +1565,15 @@ void Inventory::UseCurrentItem()
}
// TODO: can cause problem with harpoongun in underwater and wading !
bool canUseWeapons = !(LaraItem->currentAnimState == STATE_LARA_CRAWL_IDLE ||
LaraItem->currentAnimState == STATE_LARA_CRAWL_FORWARD ||
LaraItem->currentAnimState == STATE_LARA_CRAWL_TURN_LEFT ||
LaraItem->currentAnimState == STATE_LARA_CRAWL_TURN_RIGHT ||
LaraItem->currentAnimState == STATE_LARA_CRAWL_BACK ||
LaraItem->currentAnimState == STATE_LARA_CRAWL_TO_CLIMB ||
LaraItem->currentAnimState == STATE_LARA_CROUCH_IDLE ||
LaraItem->currentAnimState == STATE_LARA_CROUCH_TURN_LEFT ||
LaraItem->currentAnimState == STATE_LARA_CROUCH_TURN_RIGHT ||
bool canUseWeapons = !(LaraItem->currentAnimState == LS_CRAWL_IDLE ||
LaraItem->currentAnimState == LS_CRAWL_FORWARD ||
LaraItem->currentAnimState == LS_CRAWL_TURN_LEFT ||
LaraItem->currentAnimState == LS_CRAWL_TURN_RIGHT ||
LaraItem->currentAnimState == LS_CRAWL_BACK ||
LaraItem->currentAnimState == LS_CRAWL_TO_HANG ||
LaraItem->currentAnimState == LS_CROUCH_IDLE ||
LaraItem->currentAnimState == LS_CROUCH_TURN_LEFT ||
LaraItem->currentAnimState == LS_CROUCH_TURN_RIGHT ||
Lara.waterStatus != LW_ABOVE_WATER);
// Pistols
@ -1732,12 +1733,12 @@ void Inventory::UseCurrentItem()
{
if (!Lara.gunStatus)
{
if (LaraItem->currentAnimState != STATE_LARA_CRAWL_IDLE &&
LaraItem->currentAnimState != STATE_LARA_CRAWL_FORWARD &&
LaraItem->currentAnimState != STATE_LARA_CRAWL_TURN_LEFT &&
LaraItem->currentAnimState != STATE_LARA_CRAWL_TURN_RIGHT &&
LaraItem->currentAnimState != STATE_LARA_CRAWL_BACK &&
LaraItem->currentAnimState != STATE_LARA_CRAWL_TO_CLIMB &&
if (LaraItem->currentAnimState != LS_CRAWL_IDLE &&
LaraItem->currentAnimState != LS_CRAWL_FORWARD &&
LaraItem->currentAnimState != LS_CRAWL_TURN_LEFT &&
LaraItem->currentAnimState != LS_CRAWL_TURN_RIGHT &&
LaraItem->currentAnimState != LS_CRAWL_BACK &&
LaraItem->currentAnimState != LS_CRAWL_TO_HANG &&
Lara.waterStatus == LW_ABOVE_WATER)
{
if (Lara.gunType != WEAPON_FLARE)
@ -1803,17 +1804,16 @@ bool Inventory::UpdateSceneAndDrawInventory()
if (CurrentLevel == 0 && g_GameFlow->TitleType == TITLE_FLYBY)
{
g_Renderer->DumpGameScene();
g_Renderer->DrawInventory();
Camera.numberFrames = g_Renderer->SyncRenderer();
g_Renderer.DrawTitle();
Camera.numberFrames = g_Renderer.SyncRenderer();
nframes = Camera.numberFrames;
ControlPhase(nframes, 0);
}
else
{
g_Renderer->DrawInventory();
g_Renderer->SyncRenderer();
g_Renderer.DrawInventory();
g_Renderer.SyncRenderer();
}
return true;
@ -1831,7 +1831,7 @@ int Inventory::DoTitleInventory()
m_activeRing = INV_RING_OPTIONS;
// Fade in
g_Renderer->FadeIn();
g_Renderer.FadeIn();
for (int i = 0; i < FADE_FRAMES_COUNT; i++)
{
UpdateSceneAndDrawInventory();
@ -1931,7 +1931,7 @@ int Inventory::DoTitleInventory()
CloseRing(INV_RING_OPTIONS, true);
// Fade out
g_Renderer->FadeOut();
g_Renderer.FadeOut();
for (int i = 0; i < FADE_FRAMES_COUNT; i++)
{
UpdateSceneAndDrawInventory();
@ -1948,7 +1948,7 @@ InventoryObjectDefinition* Inventory::GetInventoryObject(int index)
int Inventory::DoPassport()
{
InventoryRing* ring = &m_rings[m_activeRing];
ring->frameIndex = 0;
ring->framePtr = 0;
short choice = 0;
@ -1978,7 +1978,7 @@ int Inventory::DoPassport()
for (int i = 0; i < 14; i++)
{
UpdateSceneAndDrawInventory();
ring->frameIndex++;
ring->framePtr++;
}
bool moveLeft = false;
@ -2016,11 +2016,11 @@ int Inventory::DoPassport()
if (choice > 0)
{
ring->frameIndex = 19;
ring->framePtr = 19;
for (int i = 0; i < 5; i++)
{
UpdateSceneAndDrawInventory();
ring->frameIndex--;
ring->framePtr--;
}
choice--;
@ -2036,11 +2036,11 @@ int Inventory::DoPassport()
if (choice < choices.size() - 1)
{
ring->frameIndex = 14;
ring->framePtr = 14;
for (int i = 0; i < 5; i++)
{
UpdateSceneAndDrawInventory();
ring->frameIndex++;
ring->framePtr++;
}
choice++;
@ -2433,14 +2433,14 @@ int Inventory::DoPassport()
}
// Close the passport
ring->frameIndex = 24;
ring->framePtr = 24;
for (int i = 24; i < 30; i++)
{
UpdateSceneAndDrawInventory();
ring->frameIndex++;
ring->framePtr++;
}
ring->frameIndex = 0;
ring->framePtr = 0;
PopoverObject();
@ -2505,7 +2505,7 @@ int Inventory::GetType()
void Inventory::DoControlsSettings()
{
InventoryRing* ring = &m_rings[m_activeRing];
ring->frameIndex = 0;
ring->framePtr = 0;
ring->selectedIndex = 0;
ring->waitingForKey = false;
@ -2642,7 +2642,7 @@ void Inventory::DoControlsSettings()
void Inventory::DoGraphicsSettings()
{
InventoryRing* ring = &m_rings[m_activeRing];
ring->frameIndex = 0;
ring->framePtr = 0;
ring->selectedIndex = 0;
PopupObject();
@ -2651,7 +2651,7 @@ void Inventory::DoGraphicsSettings()
memcpy(&ring->Configuration, &g_Configuration, sizeof(GameConfiguration));
// Get current display mode
vector<RendererVideoAdapter>* adapters = g_Renderer->GetAdapters();
vector<RendererVideoAdapter>* adapters = g_Renderer.GetAdapters();
RendererVideoAdapter* adapter = &(*adapters)[ring->Configuration.Adapter];
ring->SelectedVideoMode = 0;
for (int i = 0; i < adapter->DisplayModes.size(); i++)
@ -2782,7 +2782,7 @@ void Inventory::DoGraphicsSettings()
SaveConfiguration();
// Reset screen and go back
g_Renderer->ChangeScreenResolution(ring->Configuration.Width, ring->Configuration.Height,
g_Renderer.ChangeScreenResolution(ring->Configuration.Width, ring->Configuration.Height,
ring->Configuration.RefreshRate, ring->Configuration.Windowed);
closeObject = true;
@ -2810,7 +2810,7 @@ void Inventory::DoGraphicsSettings()
void Inventory::DoSoundSettings()
{
InventoryRing* ring = &m_rings[m_activeRing];
ring->frameIndex = 0;
ring->framePtr = 0;
ring->selectedIndex = 0;
PopupObject();

View file

@ -271,7 +271,7 @@ struct InventoryRing
int rotation;
int distance;
int focusState;
int frameIndex;
int framePtr;
bool draw;
int y;
int titleStringIndex;

View file

@ -8,8 +8,8 @@
void ClearItem(short itemNum)
{
ITEM_INFO* item = &Items[itemNum];
ROOM_INFO* room = &Rooms[item->roomNumber];
ITEM_INFO* item = &g_Level.Items[itemNum];
ROOM_INFO* room = &g_Level.Rooms[item->roomNumber];
item->collidable = true;
item->data = NULL;
@ -27,7 +27,7 @@ void KillItem(short itemNum)
}
else
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
DetatchSpark(itemNum, SP_ITEM);
@ -41,11 +41,11 @@ void KillItem(short itemNum)
else
{
short linknum;
for (linknum = NextItemActive; linknum != NO_ITEM; linknum = Items[linknum].nextActive)
for (linknum = NextItemActive; linknum != NO_ITEM; linknum = g_Level.Items[linknum].nextActive)
{
if (Items[linknum].nextActive == itemNum)
if (g_Level.Items[linknum].nextActive == itemNum)
{
Items[linknum].nextActive = item->nextActive;
g_Level.Items[linknum].nextActive = item->nextActive;
break;
}
}
@ -53,18 +53,18 @@ void KillItem(short itemNum)
if (item->roomNumber != NO_ROOM)
{
if (Rooms[item->roomNumber].itemNumber == itemNum)
if (g_Level.Rooms[item->roomNumber].itemNumber == itemNum)
{
Rooms[item->roomNumber].itemNumber = item->nextItem;
g_Level.Rooms[item->roomNumber].itemNumber = item->nextItem;
}
else
{
short linknum;
for (linknum = Rooms[item->roomNumber].itemNumber; linknum != NO_ITEM; linknum = Items[linknum].nextItem)
for (linknum = g_Level.Rooms[item->roomNumber].itemNumber; linknum != NO_ITEM; linknum = g_Level.Items[linknum].nextItem)
{
if (Items[linknum].nextItem == itemNum)
if (g_Level.Items[linknum].nextItem == itemNum)
{
Items[linknum].nextItem = item->nextItem;
g_Level.Items[linknum].nextItem = item->nextItem;
break;
}
}
@ -74,7 +74,7 @@ void KillItem(short itemNum)
if (item == Lara.target)
Lara.target = NULL;
if (itemNum >= LevelItems)
if (itemNum >= g_Level.NumItems)
{
item->nextItem = NextItemFree;
NextItemFree = itemNum;
@ -88,12 +88,12 @@ void KillItem(short itemNum)
void RemoveAllItemsInRoom(short roomNumber, short objectNumber)
{
ROOM_INFO* room = &Rooms[roomNumber];
ROOM_INFO* room = &g_Level.Rooms[roomNumber];
short currentItemNum = room->itemNumber;
while (currentItemNum != NO_ITEM)
{
ITEM_INFO* item = &Items[currentItemNum];
ITEM_INFO* item = &g_Level.Items[currentItemNum];
if (item->objectNumber == objectNumber)
{
@ -108,7 +108,7 @@ void RemoveAllItemsInRoom(short roomNumber, short objectNumber)
void AddActiveItem(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->flags |= 0x20;
@ -136,11 +136,11 @@ void ItemNewRoom(short itemNumber, short roomNumber)
}
else
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (item->roomNumber != 255)
{
ROOM_INFO* r = &Rooms[item->roomNumber];
ROOM_INFO* r = &g_Level.Rooms[item->roomNumber];
if (r->itemNumber == itemNumber)
{
@ -148,11 +148,11 @@ void ItemNewRoom(short itemNumber, short roomNumber)
}
else
{
for (short linknum = r->itemNumber; linknum != -1; linknum = Items[linknum].nextItem)
for (short linknum = r->itemNumber; linknum != -1; linknum = g_Level.Items[linknum].nextItem)
{
if (Items[linknum].nextItem == itemNumber)
if (g_Level.Items[linknum].nextItem == itemNumber)
{
Items[linknum].nextItem = item->nextItem;
g_Level.Items[linknum].nextItem = item->nextItem;
break;
}
}
@ -160,8 +160,8 @@ void ItemNewRoom(short itemNumber, short roomNumber)
}
item->roomNumber = roomNumber;
item->nextItem = Rooms[roomNumber].itemNumber;
Rooms[roomNumber].itemNumber = itemNumber;
item->nextItem = g_Level.Rooms[roomNumber].itemNumber;
g_Level.Rooms[roomNumber].itemNumber = itemNumber;
}
}
@ -175,8 +175,8 @@ void EffectNewRoom(short fxNumber, short roomNumber)
}
else
{
FX_INFO* fx = &Effects[fxNumber];
ROOM_INFO* r = &Rooms[fx->roomNumber];
FX_INFO* fx = &EffectList[fxNumber];
ROOM_INFO* r = &g_Level.Rooms[fx->roomNumber];
if (r->fxNumber == fxNumber)
{
@ -185,19 +185,19 @@ void EffectNewRoom(short fxNumber, short roomNumber)
else
{
short linknum;
for (linknum = r->fxNumber; linknum != -1; linknum = Effects[linknum].nextFx)
for (linknum = r->fxNumber; linknum != -1; linknum = EffectList[linknum].nextFx)
{
if (Effects[linknum].nextFx == fxNumber)
if (EffectList[linknum].nextFx == fxNumber)
{
Effects[linknum].nextFx = fx->nextFx;
EffectList[linknum].nextFx = fx->nextFx;
break;
}
}
}
fx->roomNumber = roomNumber;
fx->nextFx = Rooms[roomNumber].fxNumber;
Rooms[roomNumber].fxNumber = fxNumber;
fx->nextFx = g_Level.Rooms[roomNumber].fxNumber;
g_Level.Rooms[roomNumber].fxNumber = fxNumber;
}
}
@ -210,7 +210,7 @@ void KillEffect(short fxNumber)
}
else
{
FX_INFO* fx = &Effects[fxNumber];
FX_INFO* fx = &EffectList[fxNumber];
DetatchSpark(fxNumber, SP_FX);
if (NextFxActive == fxNumber)
@ -219,27 +219,27 @@ void KillEffect(short fxNumber)
}
else
{
for (short linknum = NextFxActive; linknum != NO_ITEM; linknum = Effects[linknum].nextActive)
for (short linknum = NextFxActive; linknum != NO_ITEM; linknum = EffectList[linknum].nextActive)
{
if (Effects[linknum].nextActive == fxNumber)
if (EffectList[linknum].nextActive == fxNumber)
{
Effects[linknum].nextActive = fx->nextActive;
EffectList[linknum].nextActive = fx->nextActive;
break;
}
}
}
if (Rooms[fx->roomNumber].fxNumber == fxNumber)
if (g_Level.Rooms[fx->roomNumber].fxNumber == fxNumber)
{
Rooms[fx->roomNumber].fxNumber = fx->nextFx;
g_Level.Rooms[fx->roomNumber].fxNumber = fx->nextFx;
}
else
{
for (short linknum = Rooms[fx->roomNumber].fxNumber; linknum != NO_ITEM; linknum = Effects[linknum].nextFx)
for (short linknum = g_Level.Rooms[fx->roomNumber].fxNumber; linknum != NO_ITEM; linknum = EffectList[linknum].nextFx)
{
if (Effects[linknum].nextFx == fxNumber)
if (EffectList[linknum].nextFx == fxNumber)
{
Effects[linknum].nextFx = fx->nextFx;
EffectList[linknum].nextFx = fx->nextFx;
break;
}
}
@ -256,9 +256,9 @@ short CreateNewEffect(short roomNum)
if (NextFxFree != NO_ITEM)
{
FX_INFO* fx = &Effects[NextFxFree];
FX_INFO* fx = &EffectList[NextFxFree];
NextFxFree = fx->nextFx;
ROOM_INFO* r = &Rooms[roomNum];
ROOM_INFO* r = &g_Level.Rooms[roomNum];
fx->roomNumber = roomNum;
fx->nextFx = r->fxNumber;
r->fxNumber = fxNumber;
@ -273,13 +273,15 @@ short CreateNewEffect(short roomNum)
void InitialiseFXArray(int allocmem)
{
if (allocmem)
Effects = (FX_INFO*)game_malloc(NUM_EFFECTS * sizeof(FX_INFO));
EffectList = game_malloc<FX_INFO>(NUM_EFFECTS);
FX_INFO* fx;
FX_INFO* fx = Effects;
NextFxActive = NO_ITEM;
NextFxFree = 0;
for (int i = 1; i < NUM_EFFECTS; i++, fx++)
{
fx = &EffectList[i];
fx->nextFx = i;
}
fx->nextFx = -1;
@ -287,19 +289,19 @@ void InitialiseFXArray(int allocmem)
void RemoveDrawnItem(short itemNum)
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
if (Rooms[item->roomNumber].itemNumber == itemNum)
if (g_Level.Rooms[item->roomNumber].itemNumber == itemNum)
{
Rooms[item->roomNumber].itemNumber = item->nextItem;
g_Level.Rooms[item->roomNumber].itemNumber = item->nextItem;
}
else
{
for (short linknum = Rooms[item->roomNumber].itemNumber; linknum != NO_ITEM; linknum = Items[linknum].nextItem)
for (short linknum = g_Level.Rooms[item->roomNumber].itemNumber; linknum != NO_ITEM; linknum = g_Level.Items[linknum].nextItem)
{
if (Items[linknum].nextItem == itemNum)
if (g_Level.Items[linknum].nextItem == itemNum)
{
Items[linknum].nextItem = item->nextItem;
g_Level.Items[linknum].nextItem = item->nextItem;
break;
}
}
@ -308,21 +310,21 @@ void RemoveDrawnItem(short itemNum)
void RemoveActiveItem(short itemNum)
{
if (Items[itemNum].active)
if (g_Level.Items[itemNum].active)
{
Items[itemNum].active = false;
g_Level.Items[itemNum].active = false;
if (NextItemActive == itemNum)
{
NextItemActive = Items[itemNum].nextActive;
NextItemActive = g_Level.Items[itemNum].nextActive;
}
else
{
for (short linknum = NextItemActive; linknum != NO_ITEM; linknum = Items[linknum].nextActive)
for (short linknum = NextItemActive; linknum != NO_ITEM; linknum = g_Level.Items[linknum].nextActive)
{
if (Items[linknum].nextActive == itemNum)
if (g_Level.Items[linknum].nextActive == itemNum)
{
Items[linknum].nextActive = Items[itemNum].nextActive;
g_Level.Items[linknum].nextActive = g_Level.Items[itemNum].nextActive;
break;
}
}
@ -332,14 +334,14 @@ void RemoveActiveItem(short itemNum)
void InitialiseItem(short itemNum)
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
item->animNumber = Objects[item->objectNumber].animIndex;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->requiredAnimState = 0;
item->goalAnimState = Anims[item->animNumber].currentAnimState;
item->currentAnimState = Anims[item->animNumber].currentAnimState;
item->goalAnimState = g_Level.Anims[item->animNumber].currentAnimState;
item->currentAnimState = g_Level.Anims[item->animNumber].currentAnimState;
item->pos.zRot = 0;
item->pos.xRot = 0;
@ -403,7 +405,7 @@ void InitialiseItem(short itemNum)
item->status = ITEM_ACTIVE;
}
ROOM_INFO* r = &Rooms[item->roomNumber];
ROOM_INFO* r = &g_Level.Rooms[item->roomNumber];
item->nextItem = r->itemNumber;
r->itemNumber = itemNum;
@ -416,8 +418,6 @@ void InitialiseItem(short itemNum)
{
Objects[item->objectNumber].initialise(itemNum);
}
//item->unk_thing = 0;
}
short CreateItem()
@ -427,22 +427,22 @@ short CreateItem()
if (NextItemFree == -1) return NO_ITEM;
itemNum = NextItemFree;
Items[NextItemFree].flags = 0;
NextItemFree = Items[NextItemFree].nextItem;
g_Level.Items[NextItemFree].flags = 0;
NextItemFree = g_Level.Items[NextItemFree].nextItem;
return itemNum;
}
void InitialiseItemArray(int numitems)
void InitialiseItemArray(int numitems)
{
ITEM_INFO* item = &Items[LevelItems];
ITEM_INFO* item = &g_Level.Items[g_Level.NumItems];
NextItemActive = NO_ITEM;
NextItemFree = LevelItems;
NextItemFree = g_Level.NumItems;
if (LevelItems + 1 < numitems)
if (g_Level.NumItems + 1 < numitems)
{
for (int i = LevelItems + 1; i < numitems; i++, item++)
for (int i = g_Level.NumItems + 1; i < numitems; i++, item++)
{
item->nextItem = i;
item->active = false;
@ -457,7 +457,7 @@ short SpawnItem(ITEM_INFO* item, short objectNumber)
short itemNumber = CreateItem();
if (itemNumber != NO_ITEM)
{
ITEM_INFO* spawn = &Items[itemNumber];
ITEM_INFO* spawn = &g_Level.Items[itemNumber];
spawn->objectNumber = objectNumber;
spawn->roomNumber = item->roomNumber;
@ -475,14 +475,14 @@ short SpawnItem(ITEM_INFO* item, short objectNumber)
int GlobalItemReplace(short search, short replace)
{
int changed = 0;
for (int i = 0; i < Rooms.size(); i++)
for (int i = 0; i < g_Level.Rooms.size(); i++)
{
ROOM_INFO* room = &Rooms[i];
for (short itemNumber = room->itemNumber; itemNumber != NO_ITEM; itemNumber = Items[itemNumber].nextItem)
ROOM_INFO* room = &g_Level.Rooms[i];
for (short itemNumber = room->itemNumber; itemNumber != NO_ITEM; itemNumber = g_Level.Items[itemNumber].nextItem)
{
if (Items[itemNumber].objectNumber == search)
if (g_Level.Items[itemNumber].objectNumber == search)
{
Items[itemNumber].objectNumber = replace;
g_Level.Items[itemNumber].objectNumber = replace;
changed++;
}
}
@ -494,14 +494,14 @@ int GlobalItemReplace(short search, short replace)
ITEM_INFO* find_a_fucking_item(short objectNum)
{
int itemNumber = FindItemNumber(objectNum);
return (itemNumber != NO_ITEM ? &Items[itemNumber] : NULL);
return (itemNumber != NO_ITEM ? &g_Level.Items[itemNumber] : NULL);
}
int FindItemNumber(short objectNum)
{
for (int i = 0; i < LevelItems; i++)
for (int i = 0; i < g_Level.NumItems; i++)
{
ITEM_INFO* item = &Items[i];
ITEM_INFO* item = &g_Level.Items[i];
if (item->objectNumber == objectNum)
return i;
}
@ -515,12 +515,12 @@ ITEM_INFO* FindItem(short objectNumber)
printf("Called FindItem()\n");
#endif
if (LevelItems > 0)
if (g_Level.NumItems > 0)
{
for (int i = 0; i < LevelItems; i++)
for (int i = 0; i < g_Level.NumItems; i++)
{
if (Items[i].objectNumber == objectNumber)
return &Items[i];
if (g_Level.Items[i].objectNumber == objectNumber)
return &g_Level.Items[i];
}
}

View file

@ -47,7 +47,7 @@ typedef struct ITEM_INFO
short speed;
short fallspeed;
short hitPoints;
unsigned short boxNumber;
int boxNumber;
short timer;
unsigned short flags; // ItemFlags enum
short shade;
@ -55,10 +55,9 @@ typedef struct ITEM_INFO
short carriedItem;
short afterDeath;
short firedWeapon;
short itemFlags[4];
short itemFlags[8];
void* data;
PHD_3DPOS pos;
byte legacyLightData[5528];
bool active;
short status; // ItemStatus enum
bool gravityStatus;
@ -73,6 +72,7 @@ typedef struct ITEM_INFO
int swapMeshFlags;
short drawRoom;
short TOSSPAD;
PHD_3DPOS startPos;
};
// used by fx->shade !
@ -99,7 +99,7 @@ void InitialiseFXArray(int allocmem);
short CreateNewEffect(short roomNum);
void KillEffect(short fxNumber);
void InitialiseItem(short itemNum);
void InitialiseItemArray(int numitems);
void InitialiseItemArray(int numItems);
void KillItem(short itemNum);
ITEM_INFO* find_a_fucking_item(short objectNum);
int FindItemNumber(short objectNumber);

File diff suppressed because it is too large Load diff

View file

@ -45,7 +45,7 @@ void FireHarpoon()
{
GAME_VECTOR pos;
PHD_VECTOR handr;
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->shade = 0x4210 | 0x8000;
item->objectNumber = ID_HARPOON;
@ -92,7 +92,7 @@ void FireHarpoon()
void ControlHarpoonBolt(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
int oldX = item->pos.xPos;
int oldY = item->pos.yPos;
int oldZ = item->pos.zPos;
@ -112,23 +112,17 @@ void ControlHarpoonBolt(short itemNumber)
// First check if the harpoon has it an item
short targetItemNumber = 0;
ITEM_INFO* target;
for (targetItemNumber = Rooms[item->roomNumber].itemNumber; targetItemNumber != NO_ITEM; targetItemNumber = target->nextItem)
for (targetItemNumber = g_Level.Rooms[item->roomNumber].itemNumber; targetItemNumber != NO_ITEM; targetItemNumber = target->nextItem)
{
target = &Items[targetItemNumber];
target = &g_Level.Items[targetItemNumber];
if (target == LaraItem || !target->collidable)
continue;
if (/*target->objectNumber == SMASH_WINDOW ||
target->objectNumber == SMASH_OBJECT1 ||
target->objectNumber == SMASH_OBJECT2 ||
target->objectNumber == SMASH_OBJECT3 ||
target->objectNumber == CARCASS ||
target->objectNumber == EXTRAFX6 ||*/
(target->status != ITEM_INVISIBLE && Objects[target->objectNumber].collision))
if (target->status != ITEM_INVISIBLE && Objects[target->objectNumber].collision)
{
// check against bounds of target for collision
short* bounds = GetBestFrame(target);
if (item->pos.yPos < target->pos.yPos + bounds[2] || item->pos.yPos > target->pos.yPos + bounds[3])
BOUNDING_BOX* bounds = (BOUNDING_BOX*)GetBestFrame(target);
if (item->pos.yPos < target->pos.yPos + bounds->Y1 || item->pos.yPos > target->pos.yPos + bounds->Y2)
continue;
// get vector from target to bolt and check against x,z bounds
@ -143,13 +137,13 @@ void ControlHarpoonBolt(short itemNumber)
int oz = oldZ - target->pos.zPos;
int sx = (c * ox - s * oz) >> W2V_SHIFT;
if ((rx < bounds[0] && sx < bounds[0]) || (rx > bounds[1] && sx > bounds[1]))
if ((rx < bounds->X1 && sx < bounds->X1) || (rx > bounds->X2 && sx > bounds->X2))
continue;
int rz = (c * z + s * x) >> W2V_SHIFT;
int sz = (c * oz + s * ox) >> W2V_SHIFT;
if ((rz < bounds[4] && sz < bounds[4]) || (rz > bounds[5] && sz > bounds[5]))
if ((rz < bounds->Z1 && sz < bounds->Z1) || (rz > bounds->Z2 && sz > bounds->Z2))
continue;
// TODO:
@ -213,7 +207,7 @@ void ControlHarpoonBolt(short itemNumber)
else
{
item->pos.zRot += ANGLE(35);
if (!(Rooms[item->roomNumber].flags & 1))
if (!(g_Level.Rooms[item->roomNumber].flags & 1))
{
item->pos.xRot -= ANGLE(1);
if (item->pos.xRot < -16384)
@ -256,7 +250,7 @@ void FireGrenade()
short itemNumber = CreateItem();
if (itemNumber != NO_ITEM)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->shade = 0xC210;
item->objectNumber = ID_GRENADE;
@ -343,7 +337,7 @@ enum GRENADE_TYPE
void ControlGrenade(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (item->itemFlags[1])
{
@ -370,12 +364,6 @@ void ControlGrenade(short itemNumber)
FlashFader = 32;
// if Volumetric then FlashFader = 0?
/*if (sub_47F960())
{
FlashFader = 0;
}*/
GrenadeExplosionEffects(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber);
GrenadeExplosionEffects(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber);
}
@ -385,7 +373,7 @@ void ControlGrenade(short itemNumber)
if (newGrenadeItemNumber != NO_ITEM)
{
ITEM_INFO* newGrenade = &Items[newGrenadeItemNumber];
ITEM_INFO* newGrenade = &g_Level.Items[newGrenadeItemNumber];
newGrenade->shade = 0xC210;
newGrenade->objectNumber = ID_GRENADE;
@ -411,7 +399,7 @@ void ControlGrenade(short itemNumber)
newGrenade->itemFlags[2] = item->itemFlags[2];
newGrenade->hitPoints = 3000;
if (Rooms[newGrenade->roomNumber].flags & ENV_FLAG_WATER)
if (g_Level.Rooms[newGrenade->roomNumber].flags & ENV_FLAG_WATER)
newGrenade->hitPoints = 1;
}
}
@ -434,7 +422,7 @@ void ControlGrenade(short itemNumber)
item->shade = 0xC210;
bool aboveWater = false;
if (Rooms[item->roomNumber].flags & 1)
if (g_Level.Rooms[item->roomNumber].flags & 1)
{
aboveWater = false;
item->fallspeed += (5 - item->fallspeed) >> 1;
@ -475,43 +463,9 @@ void ControlGrenade(short itemNumber)
int wy = world.Translation().y;
int wz = world.Translation().z;
// For now keep this legacy math
// PHD_MATH
/*phd_PushUnitMatrix();
MatrixPtr[M03] = 0;
MatrixPtr[M13] = 0;
MatrixPtr[M23] = 0;
phd_RotYXZ(item->pos.yRot - ANGLE(180), item->pos.xRot, item->pos.zRot);
phd_TranslateRel(0, 0, -64);
int wx = (MatrixPtr[M03] >> W2V_SHIFT);
int wy = (MatrixPtr[M13] >> W2V_SHIFT);
int wz = (MatrixPtr[M23] >> W2V_SHIFT);
phd_PopMatrix();*/
TriggerRocketSmoke(wx + item->pos.xPos, wy + item->pos.yPos, wz + item->pos.zPos, -1);
}
/*XMMATRIX transform;
XMMATRIX translation;
XMMATRIX rotation;
XMMATRIXRotationYawPitchRoll(&rotation, TO_RAD(item->pos.yRot), TO_RAD(item->pos.xRot),
TO_RAD(item->pos.zRot));
XMMATRIXTranslation(&translation, 0, 0, -64);
XMMATRIXMultiply(&transform, &rotation, &translation);
int wx = transform._14;
int wy = transform._24;
int wz = transform._34;
if (item->speed && aboveWater)
TriggerRocketSmoke(wx + item->pos.xPos, wy + item->pos.yPos, wz + item->pos.zPos, -1);
*/
xv = ((item->speed * phd_sin(item->goalAnimState)) >> W2V_SHIFT);
yv = item->fallspeed;
zv = ((item->speed * phd_cos(item->goalAnimState)) >> W2V_SHIFT);
@ -550,7 +504,7 @@ void ControlGrenade(short itemNumber)
roomNumber = item->roomNumber;
floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
if ((Rooms[roomNumber].flags & ENV_FLAG_WATER) && aboveWater)
if ((g_Level.Rooms[roomNumber].flags & ENV_FLAG_WATER) && aboveWater)
{
// Setup splash
/*dword_804E20 = item->pos.xPos;
@ -574,6 +528,7 @@ void ControlGrenade(short itemNumber)
goto LABEL_35;
}
item->hitPoints = 1;*/
// what is this lol
}
if (item->itemFlags[0] == GRENADE_ULTRA)
@ -657,8 +612,8 @@ void ControlGrenade(short itemNumber)
for (int i = 0; i < sw; i++)
{
AddActiveItem(itemNos[i]);
Items[itemNos[i]].status = ITEM_ACTIVE;
Items[itemNos[i]].triggerFlags |= 0x3E00;
g_Level.Items[itemNos[i]].status = ITEM_ACTIVE;
g_Level.Items[itemNos[i]].triggerFlags |= 0x3E00;
}
}
}
@ -669,7 +624,7 @@ void ControlGrenade(short itemNumber)
ExplodeItemNode(currentItem, Objects[ID_SHOOT_SWITCH1].nmeshes - 1, 0, 64);
}
AddActiveItem((currentItem - Items));
AddActiveItem((currentItem - g_Level.Items.data()));
currentItem->status = ITEM_ACTIVE;
currentItem->triggerFlags |= 0x3E40;
}
@ -680,7 +635,7 @@ void ControlGrenade(short itemNumber)
//TriggerShockwave(&currentItem->pos, 48, 304, 64, 0, 96, 128, 24, 0, 0); // CHECK
currentItem->pos.yPos += 128;
ExplodeItemNode(currentItem, 0, 0, 128);
short currentItemNumber = (currentItem - Items);
short currentItemNumber = (currentItem - g_Level.Items.data());
SmashObject(currentItemNumber);
KillItem(currentItemNumber);
}
@ -734,18 +689,10 @@ void ControlGrenade(short itemNumber)
FlashFadeG = 255;
FlashFadeB = 255;
/*
if ( sub_47F960() )
{
FlashFader = 0;
sub_47F880(item->pos.xPos, item->pos.yPos, item->pos.zPos, 4096, 255, 255, 255, 255, item->roomNumber);
}
*/
GrenadeExplosionEffects(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber);
GrenadeExplosionEffects(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber);
}
else if (Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
else if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
{
TriggerUnderwaterExplosion(item);
}
@ -783,7 +730,7 @@ void draw_shotgun(int weaponType)
{
Lara.weaponItem = CreateItem();
item = &Items[Lara.weaponItem];
item = &g_Level.Items[Lara.weaponItem];
item->objectNumber = WeaponObject(weaponType);
@ -794,7 +741,7 @@ void draw_shotgun(int weaponType)
else
item->animNumber = Objects[item->objectNumber].animIndex + HARPOON_DRAW_ANIM; // M16 too
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = 1;
item->currentAnimState = 1;
item->status = ITEM_ACTIVE;
@ -805,14 +752,14 @@ void draw_shotgun(int weaponType)
}
else
{
item = &Items[Lara.weaponItem];
item = &g_Level.Items[Lara.weaponItem];
}
AnimateItem(item);
if (item->currentAnimState != 0 && item->currentAnimState != 6)
{
if (item->frameNumber - Anims[item->animNumber].frameBase == Weapons[weaponType].drawFrame)
if (item->frameNumber - g_Level.Anims[item->animNumber].frameBase == Weapons[weaponType].drawFrame)
draw_shotgun_meshes(weaponType);
else if (Lara.waterStatus == 1)
item->goalAnimState = 6;
@ -822,8 +769,8 @@ void draw_shotgun(int weaponType)
ready_shotgun(weaponType);
}
Lara.leftArm.frameBase = Lara.rightArm.frameBase = Anims[item->animNumber].framePtr;
Lara.leftArm.frameNumber = Lara.rightArm.frameNumber = item->frameNumber - Anims[item->animNumber].frameBase;
Lara.leftArm.frameBase = Lara.rightArm.frameBase = g_Level.Anims[item->animNumber].framePtr;
Lara.leftArm.frameNumber = Lara.rightArm.frameNumber = item->frameNumber - g_Level.Anims[item->animNumber].frameBase;
Lara.leftArm.animNumber = Lara.rightArm.animNumber = item->animNumber;
}
@ -870,7 +817,7 @@ void AnimateShotgun(int weaponType)
TriggerGunSmoke(pos.x, pos.y, pos.z, 0, 0, 0, 0, SmokeWeapon, SmokeCountL);
}
ITEM_INFO* item = &Items[Lara.weaponItem];
ITEM_INFO* item = &g_Level.Items[Lara.weaponItem];
bool running = (weaponType == WEAPON_HK && LaraItem->speed != 0);
bool harpoonFired = false;
@ -908,7 +855,7 @@ void AnimateShotgun(int weaponType)
break;
case 2:
if (item->frameNumber == Anims[item->animNumber].frameBase)
if (item->frameNumber == g_Level.Anims[item->animNumber].frameBase)
{
item->goalAnimState = 4;
@ -982,12 +929,12 @@ void AnimateShotgun(int weaponType)
item->goalAnimState = 4;
}
if (item->frameNumber - Anims[item->animNumber].frameBase == 12 && weaponType == WEAPON_SHOTGUN)
if (item->frameNumber - g_Level.Anims[item->animNumber].frameBase == 12 && weaponType == WEAPON_SHOTGUN)
TriggerGunShell(1, ID_SHOTGUNSHELL, 4);
break;
case 8:
if (item->frameNumber - Anims[item->animNumber].frameBase == 0)
if (item->frameNumber - g_Level.Anims[item->animNumber].frameBase == 0)
{
item->goalAnimState = 7;
@ -1054,8 +1001,8 @@ void AnimateShotgun(int weaponType)
AnimateItem(item);
Lara.leftArm.frameBase = Lara.rightArm.frameBase = Anims[item->animNumber].framePtr;
Lara.leftArm.frameNumber = Lara.rightArm.frameNumber = item->frameNumber - Anims[item->animNumber].frameBase;
Lara.leftArm.frameBase = Lara.rightArm.frameBase = g_Level.Anims[item->animNumber].framePtr;
Lara.leftArm.frameNumber = Lara.rightArm.frameNumber = item->frameNumber - g_Level.Anims[item->animNumber].frameBase;
Lara.leftArm.animNumber = Lara.rightArm.animNumber = item->animNumber;
}
@ -1068,7 +1015,7 @@ enum CROSSBOW_TYPE
void ControlCrossbowBolt(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
int oldX = item->pos.xPos;
int oldY = item->pos.yPos;
@ -1078,7 +1025,7 @@ void ControlCrossbowBolt(short itemNumber)
bool land = false;
bool explode = false;
if (Rooms[roomNumber].flags & ENV_FLAG_WATER)
if (g_Level.Rooms[roomNumber].flags & ENV_FLAG_WATER)
{
PHD_VECTOR bubblePos(item->pos.xPos, item->pos.yPos, item->pos.zPos);
if (item->speed > 64)
@ -1125,9 +1072,9 @@ void ControlCrossbowBolt(short itemNumber)
ItemNewRoom(itemNumber, roomNumber);
// If now in water and before in land, add a ripple
if ((Rooms[item->roomNumber].flags & ENV_FLAG_WATER) && land)
if ((g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER) && land)
{
SetupRipple(item->pos.xPos, Rooms[item->roomNumber].minfloor, item->pos.zPos, (GetRandomControl() & 7) + 8, 0);
SetupRipple(item->pos.xPos, g_Level.Rooms[item->roomNumber].minfloor, item->pos.zPos, (GetRandomControl() & 7) + 8, 0);
}
int radius = (explode ? CROSSBOW_EXPLODE_RADIUS : CROSSBOW_HIT_RADIUS);
@ -1242,7 +1189,7 @@ void ControlCrossbowBolt(short itemNumber)
}
// At this point, for sure bolt must explode
if (Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
{
TriggerUnderwaterExplosion(item);
}
@ -1299,11 +1246,6 @@ void RifleHandler(int weaponType)
if (weaponType == WEAPON_SHOTGUN || weaponType == WEAPON_HK)
{
PHD_VECTOR pos = {};
/*
pos.x = GetRandomControl() - 128;
pos.y = (GetRandomControl() & 0x7F) - 63;
pos.z = GetRandomControl() - 128;
*/
pos.y = -64;
GetLaraJointPosition(&pos, LM_RHAND);
TriggerDynamicLight(
@ -1319,11 +1261,6 @@ void RifleHandler(int weaponType)
else if (weaponType == WEAPON_REVOLVER)
{
PHD_VECTOR pos = {};
/*
pos.x = GetRandomControl() - 128;
pos.y = (GetRandomControl() & 0x7F) - 63;
pos.z = GetRandomControl() - 128;
*/
pos.y = -32;
GetLaraJointPosition(&pos, LM_RHAND);
TriggerDynamicLight(pos.x, pos.y, pos.z, 12, (GetRandomControl() & 0x3F) + 192, (GetRandomControl() & 0x1F) + 128, (GetRandomControl() & 0x3F));
@ -1342,7 +1279,7 @@ void FireCrossbow(PHD_3DPOS* pos)
short itemNumber = CreateItem();
if (itemNumber != NO_ITEM)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->objectNumber = ID_CROSSBOW_BOLT;
item->shade = 0xC210;
if (pos)
@ -1425,7 +1362,7 @@ void DoGrenadeDamageOnBaddie(ITEM_INFO* dest, ITEM_INFO* src)
{
dest->hitStatus = true;
ObjectInfo* obj = &Objects[dest->objectNumber];
OBJECT_INFO* obj = &Objects[dest->objectNumber];
if (!obj->undead)
{
HitTarget(dest, 0, 30, 1);
@ -1435,7 +1372,7 @@ void DoGrenadeDamageOnBaddie(ITEM_INFO* dest, ITEM_INFO* src)
if (src->hitPoints <= 0)
{
++Savegame.Level.Kills;
CreatureDie((dest - Items), 1);
CreatureDie((dest - g_Level.Items.data()), 1);
}
}
}
@ -1444,7 +1381,7 @@ void DoGrenadeDamageOnBaddie(ITEM_INFO* dest, ITEM_INFO* src)
else
{
LaraItem->hitPoints -= 50;
if (!(Rooms[dest->roomNumber].flags & ENV_FLAG_WATER) && LaraItem->hitPoints <= 50)
if (!(g_Level.Rooms[dest->roomNumber].flags & ENV_FLAG_WATER) && LaraItem->hitPoints <= 50)
LaraBurn();
}
}
@ -1479,7 +1416,7 @@ void TriggerUnderwaterExplosion(ITEM_INFO* item)
void undraw_shotgun(int weapon)
{
ITEM_INFO* item = &Items[Lara.weaponItem];
ITEM_INFO* item = &g_Level.Items[Lara.weaponItem];
item->goalAnimState = 3;
AnimateItem(item);
@ -1495,29 +1432,31 @@ void undraw_shotgun(int weapon)
Lara.rightArm.frameNumber = 0;
Lara.leftArm.frameNumber = 0;
}
else if (item->currentAnimState == 3 && item->frameNumber - Anims[item->animNumber].frameBase == 21)
else if (item->currentAnimState == 3 && item->frameNumber - g_Level.Anims[item->animNumber].frameBase == 21)
{
undraw_shotgun_meshes(weapon);
}
Lara.rightArm.frameBase = Anims[item->animNumber].framePtr;
Lara.leftArm.frameBase = Anims[item->animNumber].framePtr;
Lara.rightArm.frameNumber = item->frameNumber - Anims[item->animNumber].frameBase;
Lara.leftArm.frameNumber = item->frameNumber - Anims[item->animNumber].frameBase;
Lara.rightArm.frameBase = g_Level.Anims[item->animNumber].framePtr;
Lara.leftArm.frameBase = g_Level.Anims[item->animNumber].framePtr;
Lara.rightArm.frameNumber = item->frameNumber - g_Level.Anims[item->animNumber].frameBase;
Lara.leftArm.frameNumber = item->frameNumber - g_Level.Anims[item->animNumber].frameBase;
Lara.rightArm.animNumber = item->animNumber;
Lara.leftArm.animNumber = Lara.rightArm.animNumber;
}
void undraw_shotgun_meshes(int weapon)
{
Lara.backGun = WeaponObject(weapon);
LARA_MESHES(ID_LARA, LM_RHAND);
Lara.holsterInfo.backHolster = HolsterSlotForWeapon(static_cast<LARA_WEAPON_TYPE>(weapon));
//LARA_MESHES(ID_LARA, LM_RHAND);
Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND;
}
void draw_shotgun_meshes(int weaponType)
{
Lara.backGun = WEAPON_NONE;
LARA_MESHES(WeaponObjectMesh(weaponType), LM_RHAND);
Lara.holsterInfo.backHolster = HOLSTER_SLOT::Empty;
//LARA_MESHES(WeaponObjectMesh(weaponType), LM_RHAND);
Lara.meshPtrs[LM_RHAND] = Objects[WeaponObjectMesh(weaponType)].meshIndex + LM_RHAND;
}
void DoCrossbowDamage(ITEM_INFO* item1, ITEM_INFO* item2, signed int search)
@ -1597,8 +1536,8 @@ void DoCrossbowDamage(ITEM_INFO* item1, ITEM_INFO* item2, signed int search)
AddActiveItem(*v16);
v17 = *v16;
--v16;
Items[v17]._bf15ea = Items[v17]._bf15ea & 0xFFFFFFFB | 2;
HIBYTE(Items[v16[1]].flags) |= 0x3Eu;
Items[v17]._bf15ea = g_Level.Items[v17]._bf15ea & 0xFFFFFFFB | 2;
HIBYTE(g_Level.Items[v16[1]].flags) |= 0x3Eu;
--v15;
} while (v15);
}
@ -1612,6 +1551,7 @@ void DoCrossbowDamage(ITEM_INFO* item1, ITEM_INFO* item2, signed int search)
item2->status = ITEM_ACTIVE;
}
}*/
// what is this 2.0
}
void FireHK(int mode)

View file

@ -11,7 +11,6 @@
#include "input.h"
#include "sound.h"
#include "savegame.h"
struct PISTOL_DEF
{
short objectNum;
@ -33,7 +32,7 @@ bool UziRight;
void AnimatePistols(int weaponType)
{
PISTOL_DEF* p = &PistolsTable[Lara.gunType];
PISTOL_DEF* p = &PistolsTable[static_cast<int>(Lara.gunType)];
WEAPON_INFO* weapon = &Weapons[weaponType];
int soundPlayed = false;
short angleLeft[2], angleRight[2];
@ -44,19 +43,19 @@ void AnimatePistols(int weaponType)
{
PHD_VECTOR pos;
switch (SmokeWeapon)
switch (static_cast<LARA_WEAPON_TYPE>(SmokeWeapon))
{
case WEAPON_PISTOLS:
case LARA_WEAPON_TYPE::WEAPON_PISTOLS:
pos.x = 4;
pos.y = 128;
pos.z = 40;
break;
case WEAPON_REVOLVER:
case LARA_WEAPON_TYPE::WEAPON_REVOLVER:
pos.x = 16;
pos.y = 160;
pos.z = 56;
break;
case WEAPON_UZI:
case LARA_WEAPON_TYPE::WEAPON_UZI:
pos.x = 8;
pos.y = 140;
pos.z = 48;
@ -71,19 +70,19 @@ void AnimatePistols(int weaponType)
{
PHD_VECTOR pos;
switch (SmokeWeapon)
switch (static_cast<LARA_WEAPON_TYPE>(SmokeWeapon))
{
case WEAPON_PISTOLS:
case LARA_WEAPON_TYPE::WEAPON_PISTOLS:
pos.x = -16;
pos.y = 128;
pos.z = 40;
break;
case WEAPON_REVOLVER:
case LARA_WEAPON_TYPE::WEAPON_REVOLVER:
pos.x = -32;
pos.y = 160;
pos.z = 56;
break;
case WEAPON_UZI:
case LARA_WEAPON_TYPE::WEAPON_UZI:
pos.x = -16;
pos.y = 140;
pos.z = 48;
@ -112,7 +111,7 @@ void AnimatePistols(int weaponType)
// actually shoot, bang bang
if (TrInput & IN_ACTION)
{
if (weaponType != WEAPON_REVOLVER)
if (static_cast<LARA_WEAPON_TYPE>(weaponType) != LARA_WEAPON_TYPE::WEAPON_REVOLVER)
{
angleRight[0] = Lara.rightArm.yRot + LaraItem->pos.yRot;
angleRight[1] = Lara.rightArm.xRot;
@ -129,7 +128,7 @@ void AnimatePistols(int weaponType)
SoundEffect(weapon->sampleNum, &LaraItem->pos, 0);
soundPlayed = true;
if (weaponType == WEAPON_UZI)
if (static_cast<LARA_WEAPON_TYPE>(weaponType) == LARA_WEAPON_TYPE::WEAPON_UZI)
UziRight = true;
Savegame.Game.AmmoUsed++;
@ -148,7 +147,7 @@ void AnimatePistols(int weaponType)
// at or beyond (3) SHOOT_CONTINUE start frame
else if (frameRight >= p->recoilAnim)
{
if (weaponType == WEAPON_UZI)
if (static_cast<LARA_WEAPON_TYPE>(weaponType) == LARA_WEAPON_TYPE::WEAPON_UZI)
{
SoundEffect(weapon->sampleNum, &LaraItem->pos, 0);
UziRight = true;
@ -207,10 +206,10 @@ void AnimatePistols(int weaponType)
if (FireWeapon(weaponType, Lara.target, LaraItem, angleLeft))
{
if (weaponType == WEAPON_REVOLVER)
if (static_cast<LARA_WEAPON_TYPE>(weaponType) == LARA_WEAPON_TYPE::WEAPON_REVOLVER)
{
SmokeCountR = 28;
SmokeWeapon = WEAPON_REVOLVER;
SmokeWeapon = static_cast<int>(LARA_WEAPON_TYPE::WEAPON_REVOLVER);
Lara.rightArm.flash_gun = weapon->flashTime;
}
else
@ -227,7 +226,7 @@ void AnimatePistols(int weaponType)
SoundEffect(weapon->sampleNum, &LaraItem->pos, 0);
}
if (weaponType == WEAPON_UZI)
if (static_cast<LARA_WEAPON_TYPE>(weaponType) == LARA_WEAPON_TYPE::WEAPON_UZI)
UziLeft = true;
Savegame.Game.AmmoUsed++;
@ -243,7 +242,7 @@ void AnimatePistols(int weaponType)
}
else if (frameLeft >= p->recoilAnim)
{
if (weaponType == WEAPON_UZI)
if (static_cast<LARA_WEAPON_TYPE>(weaponType) == LARA_WEAPON_TYPE::WEAPON_UZI)
{
SoundEffect(weapon->sampleNum, &LaraItem->pos, 0);
UziLeft = true;
@ -335,64 +334,38 @@ void PistolHandler(int weaponType)
pos.z = (byte)GetRandomControl() - 128;
GetLaraJointPosition(&pos, Lara.leftArm.flash_gun != 0 ? LM_LHAND : LM_RHAND);
/*if (gfLevelFlags & 0x2000 && LaraItem->roomNumber == gfMirrorRoom)
{
v8 = GetRandomControl() & 0x3F;
v9 = (GetRandomControl() & 0x1F) + 128;
v10 = GetRandomControl();
sub_4015A5(v14, v15, v16, 10, (v10 & 0x3F) + 192, v9, v8); // TODO: TriggerDynamicLightMirror !
}
else
{*/
TriggerDynamicLight(pos.x+frandMinMax(-128,128), pos.y + frandMinMax(-128, 128), pos.z + frandMinMax(-128, 128), frandMinMax(8,11), (GetRandomControl() & 0x3F) + 192, (GetRandomControl() & 0x1F) + 128, GetRandomControl() & 0x3F);
//}
}
}
void undraw_pistol_mesh_right(int weaponType)
{
LARA_MESHES(ID_LARA, LM_RHAND);
Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND;
switch (weaponType)
{
case WEAPON_PISTOLS:
Lara.holster = ID_LARA_HOLSTERS_PISTOLS;
break;
case WEAPON_UZI:
Lara.holster = ID_LARA_HOLSTERS_UZIS;
break;
case WEAPON_REVOLVER:
Lara.holster = ID_LARA_HOLSTERS_REVOLVER;
break;
}
Lara.holsterInfo.rightHolster = HolsterSlotForWeapon(static_cast<LARA_WEAPON_TYPE>(weaponType));
}
void undraw_pistol_mesh_left(int weaponType)
{
if (weaponType != WEAPON_REVOLVER)
if (static_cast<LARA_WEAPON_TYPE>(weaponType) != LARA_WEAPON_TYPE::WEAPON_REVOLVER)
{
LARA_MESHES(ID_LARA, LM_LHAND);
Lara.meshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
switch (weaponType)
{
case WEAPON_PISTOLS:
Lara.holster = ID_LARA_HOLSTERS_PISTOLS;
break;
case WEAPON_UZI:
Lara.holster = ID_LARA_HOLSTERS_UZIS;
break;
}
Lara.holsterInfo.leftHolster = HolsterSlotForWeapon(static_cast<LARA_WEAPON_TYPE>(weaponType));
}
}
void draw_pistol_meshes(int weaponType)
{
Lara.holster = ID_LARA_HOLSTERS;
if(static_cast<LARA_WEAPON_TYPE>(weaponType) != LARA_WEAPON_TYPE::WEAPON_REVOLVER){
Lara.holsterInfo.leftHolster = HOLSTER_SLOT::Empty;
}
Lara.holsterInfo.rightHolster = HOLSTER_SLOT::Empty;
LARA_MESHES(WeaponObjectMesh(weaponType), LM_RHAND);
if (weaponType != WEAPON_REVOLVER)
LARA_MESHES(WeaponObjectMesh(weaponType), LM_LHAND);
Lara.meshPtrs[LM_RHAND] = Objects[WeaponObjectMesh(weaponType)].meshIndex + LM_RHAND;
if (static_cast<LARA_WEAPON_TYPE>(weaponType) != LARA_WEAPON_TYPE::WEAPON_REVOLVER)
Lara.meshPtrs[LM_LHAND] = Objects[WeaponObjectMesh(weaponType)].meshIndex + LM_LHAND;
}
void ready_pistols(int weaponType)
@ -415,7 +388,7 @@ void ready_pistols(int weaponType)
void undraw_pistols(int weaponType)
{
PISTOL_DEF* p = &PistolsTable[Lara.gunType];
PISTOL_DEF* p = &PistolsTable[static_cast<int>(Lara.gunType)];
WEAPON_INFO* weapon = &Weapons[weaponType];
short frameLeft = Lara.leftArm.frameNumber;
@ -514,7 +487,7 @@ void undraw_pistols(int weaponType)
void set_arm_info(LARA_ARM* arm, int frame)
{
PISTOL_DEF* p = &PistolsTable[Lara.gunType];
PISTOL_DEF* p = &PistolsTable[static_cast<int>(Lara.gunType)];
short animBase = Objects[p->objectNum].animIndex;
if (frame < p->draw1Anim)
@ -527,13 +500,13 @@ void set_arm_info(LARA_ARM* arm, int frame)
arm->animNumber = animBase + 3;
arm->frameNumber = frame;
arm->frameBase = Anims[arm->animNumber].framePtr;
arm->frameBase = g_Level.Anims[arm->animNumber].framePtr;
}
void draw_pistols(int weaponType)
{
short frame = Lara.leftArm.frameNumber + 1;
PISTOL_DEF* p = &PistolsTable[Lara.gunType];
PISTOL_DEF* p = &PistolsTable[static_cast<int>(Lara.gunType)];
if (frame < p->draw1Anim || frame > p->recoilAnim - 1)
{

File diff suppressed because it is too large Load diff

View file

@ -55,10 +55,10 @@ void lara_as_climbend(ITEM_INFO* item, COLL_INFO* coll)//46DF8(<), 4725C(<) (F)
void lara_col_climbdown(ITEM_INFO* item, COLL_INFO* coll)//46BD0, 47034 (F)
{
if (LaraCheckForLetGo(item, coll)
|| item->animNumber != ANIMATION_LARA_LADDER_DOWN)
|| item->animNumber != LA_LADDER_DOWN)
return;
int frame = item->frameNumber - Anims[ANIMATION_LARA_LADDER_DOWN].frameBase;
int frame = item->frameNumber - g_Level.Anims[LA_LADDER_DOWN].frameBase;
int xShift;
int yShift;
@ -98,7 +98,7 @@ void lara_col_climbdown(ITEM_INFO* item, COLL_INFO* coll)//46BD0, 47034 (F)
{
if (shiftRight < 0 != shiftLeft < 0)
{
item->goalAnimState = STATE_LARA_LADDER_IDLE;
item->goalAnimState = LS_LADDER_IDLE;
AnimateLara(item);
return;
}
@ -112,22 +112,22 @@ void lara_col_climbdown(ITEM_INFO* item, COLL_INFO* coll)//46BD0, 47034 (F)
if (resultRight == -1 || resultLeft == -1)
{
item->animNumber = ANIMATION_LARA_LADDER_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_LADDER_IDLE;
item->goalAnimState = STATE_LARA_HANG;
item->animNumber = LA_LADDER_IDLE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = LS_LADDER_IDLE;
item->goalAnimState = LS_HANG;
AnimateLara(item);
}
else
{
item->goalAnimState = STATE_LARA_LADDER_DOWN;
item->goalAnimState = LS_LADDER_DOWN;
item->pos.yPos -= yShift;
}
return;
}
item->goalAnimState = STATE_LARA_LADDER_IDLE;
item->goalAnimState = LS_LADDER_IDLE;
if (yShift != 0)
AnimateLara(item);
@ -144,9 +144,9 @@ void lara_as_climbdown(ITEM_INFO* item, COLL_INFO* coll)//46BA4(<), 47008(<) (F)
void lara_col_climbing(ITEM_INFO* item, COLL_INFO* coll)//469B0, 46E14 (F)
{
if (!LaraCheckForLetGo(item, coll)
&& item->animNumber == ANIMATION_LARA_LADDER_UP)
&& item->animNumber == LA_LADDER_UP)
{
int frame = item->frameNumber - Anims[ANIMATION_LARA_LADDER_UP].frameBase;
int frame = item->frameNumber - g_Level.Anims[LA_LADDER_UP].frameBase;
int yShift;
int resultRight, resultLeft;
int shiftRight, shiftLeft;
@ -180,7 +180,7 @@ void lara_col_climbing(ITEM_INFO* item, COLL_INFO* coll)//469B0, 46E14 (F)
{
if (resultRight < 0 || resultLeft < 0)
{
item->goalAnimState = STATE_LARA_LADDER_IDLE;
item->goalAnimState = LS_LADDER_IDLE;
AnimateLara(item);
@ -188,25 +188,25 @@ void lara_col_climbing(ITEM_INFO* item, COLL_INFO* coll)//469B0, 46E14 (F)
{
if (resultRight != -1 || resultLeft != -1)
{
item->goalAnimState = STATE_LARA_UNKNOWN_138;
item->requiredAnimState = STATE_LARA_CROUCH_IDLE;
item->goalAnimState = LS_UNKNOWN_6;
item->requiredAnimState = LS_CROUCH_IDLE;
}
else
{
item->goalAnimState = STATE_LARA_GRABBING;
item->goalAnimState = LS_GRABBING;
item->pos.yPos += (ledgeRight + ledgeLeft) / 2 - 256;
}
}
}
else
{
item->goalAnimState = STATE_LARA_LADDER_UP;
item->goalAnimState = LS_LADDER_UP;
item->pos.yPos -= yShift;
}
}
else
{
item->goalAnimState = STATE_LARA_LADDER_IDLE;
item->goalAnimState = LS_LADDER_IDLE;
if (yShift != 0)
AnimateLara(item);
@ -241,7 +241,7 @@ void lara_as_climbright(ITEM_INFO* item, COLL_INFO* coll)//468B8(<), 46D1C(<) (F
Camera.targetElevation = -ANGLE(15);
if (!(TrInput & (IN_RIGHT | IN_RSTEP)))
item->goalAnimState = STATE_LARA_LADDER_IDLE;
item->goalAnimState = LS_LADDER_IDLE;
}
void lara_col_climbleft(ITEM_INFO* item, COLL_INFO* coll)//46834(<), 46C98(<) (F)
@ -263,7 +263,7 @@ void lara_as_climbleft(ITEM_INFO* item, COLL_INFO* coll)//467E4(<), 46C48(<) (F)
Camera.targetElevation = -ANGLE(15);
if (!(TrInput & (IN_LEFT | IN_LSTEP)))
item->goalAnimState = STATE_LARA_LADDER_IDLE;
item->goalAnimState = LS_LADDER_IDLE;
}
void lara_col_climbstnc(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
@ -274,7 +274,7 @@ void lara_col_climbstnc(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
int ledgeRight, ledgeLeft;
if (LaraCheckForLetGo(item, coll)
|| item->animNumber != ANIMATION_LARA_LADDER_IDLE)
|| item->animNumber != LA_LADDER_IDLE)
return;
if (!(TrInput & IN_FORWARD))
@ -282,10 +282,10 @@ void lara_col_climbstnc(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
if (!(TrInput & IN_BACK))
return;
if (item->goalAnimState == STATE_LARA_HANG)
if (item->goalAnimState == LS_HANG)
return;
item->goalAnimState = STATE_LARA_LADDER_IDLE;
item->goalAnimState = LS_LADDER_IDLE;
item->pos.yPos += 256;
resultRight = LaraTestClimbPos(item, coll->radius, coll->radius + 120, -512, 512, &ledgeRight);
@ -308,17 +308,17 @@ void lara_col_climbstnc(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
if (resultRight == 1 && resultLeft == 1)
{
item->goalAnimState = STATE_LARA_LADDER_DOWN;
item->goalAnimState = LS_LADDER_DOWN;
item->pos.yPos += yShift;
}
else
{
item->goalAnimState = STATE_LARA_HANG;
item->goalAnimState = LS_HANG;
}
}
else if (item->goalAnimState != STATE_LARA_GRABBING)
else if (item->goalAnimState != LS_GRABBING)
{
item->goalAnimState = STATE_LARA_LADDER_IDLE;
item->goalAnimState = LS_LADDER_IDLE;
resultRight = LaraTestClimbUpPos(item, coll->radius, coll->radius + 120, &shiftRight, &ledgeRight);
resultLeft = LaraTestClimbUpPos(item, coll->radius, -120 - coll->radius, &shiftLeft, &ledgeLeft);
@ -344,20 +344,20 @@ void lara_col_climbstnc(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
}
}
item->goalAnimState = STATE_LARA_LADDER_UP;
item->goalAnimState = LS_LADDER_UP;
item->pos.yPos += yShift;
}
else if (abs(ledgeLeft - ledgeRight) <= 120)
{
if (resultRight == -1 && resultLeft == -1)
{
item->goalAnimState = STATE_LARA_GRABBING;
item->goalAnimState = LS_GRABBING;
item->pos.yPos += (ledgeRight + ledgeLeft) / 2 - 256;
}
else
{
item->goalAnimState = STATE_LARA_UNKNOWN_138;
item->requiredAnimState = STATE_LARA_CROUCH_IDLE;
item->goalAnimState = LS_UNKNOWN_6;
item->requiredAnimState = LS_CROUCH_IDLE;
}
}
}
@ -372,6 +372,11 @@ void lara_as_climbstnc(ITEM_INFO* item, COLL_INFO* coll)//463F0, 46854 (F)
Camera.targetElevation = -ANGLE(20);
if (item->animNumber == LA_LADDER_DISMOUNT_LEFT_START)
Camera.targetAngle = -ANGLE(60.0f);
if (item->animNumber == LA_LADDER_DISMOUNT_RIGHT_START)
Camera.targetAngle = ANGLE(60.0f);
if (TrInput & IN_LOOK)
{
LookUpDown();
@ -379,25 +384,47 @@ void lara_as_climbstnc(ITEM_INFO* item, COLL_INFO* coll)//463F0, 46854 (F)
if (TrInput & IN_LEFT || TrInput & IN_LSTEP)
{
item->goalAnimState = STATE_LARA_LADDER_LEFT;
item->goalAnimState = LS_LADDER_LEFT;
Lara.moveAngle = -ANGLE(90);
}
else if (TrInput & IN_RIGHT || TrInput & IN_RSTEP)
{
item->goalAnimState = STATE_LARA_LADDER_RIGHT;
item->goalAnimState = LS_LADDER_RIGHT;
Lara.moveAngle = ANGLE(90);
}
else if (TrInput & IN_JUMP)
{
if (item->animNumber == ANIMATION_LARA_LADDER_IDLE)
if (item->animNumber == LA_LADDER_IDLE)
{
item->goalAnimState = STATE_LARA_JUMP_BACK;
item->goalAnimState = LS_JUMP_BACK;
Lara.gunStatus = LG_NO_ARMS;
Lara.moveAngle = ANGLE(180);
}
}
}
void lara_as_stepoff_left(ITEM_INFO* item, COLL_INFO* coll)
{
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = -ANGLE(60.0f);
Camera.targetElevation = -ANGLE(15.0f);
item->pos.yRot -= ANGLE(90.0f);
}
void lara_as_stepoff_right(ITEM_INFO* item, COLL_INFO* coll)
{
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = ANGLE(60.0f);
Camera.targetElevation = -ANGLE(15.0f);
item->pos.yRot += ANGLE(90.0f);
}
int LaraTestClimbPos(ITEM_INFO* item, int front, int right, int origin, int height, int* shift) // (F) (D)
{
int x;
@ -442,15 +469,15 @@ void LaraDoClimbLeftRight(ITEM_INFO* item, COLL_INFO* coll, int result, int shif
{
if (TrInput & IN_LEFT)
{
item->goalAnimState = STATE_LARA_LADDER_LEFT;
item->goalAnimState = LS_LADDER_LEFT;
}
else if (TrInput & IN_RIGHT)
{
item->goalAnimState = STATE_LARA_LADDER_RIGHT;
item->goalAnimState = LS_LADDER_RIGHT;
}
else
{
item->goalAnimState = STATE_LARA_LADDER_IDLE;
item->goalAnimState = LS_LADDER_IDLE;
}
item->pos.yPos += shift;
@ -460,12 +487,12 @@ void LaraDoClimbLeftRight(ITEM_INFO* item, COLL_INFO* coll, int result, int shif
if (result != 0)
{
item->goalAnimState = STATE_LARA_HANG;
item->goalAnimState = LS_HANG;
do
{
AnimateItem(item);
} while (item->currentAnimState != STATE_LARA_HANG);
} while (item->currentAnimState != LS_HANG);
item->pos.xPos = coll->old.x;
item->pos.zPos = coll->old.z;
@ -476,16 +503,43 @@ void LaraDoClimbLeftRight(ITEM_INFO* item, COLL_INFO* coll, int result, int shif
item->pos.xPos = coll->old.x;
item->pos.zPos = coll->old.z;
item->goalAnimState = STATE_LARA_LADDER_IDLE;
item->currentAnimState = STATE_LARA_LADDER_IDLE;
item->goalAnimState = LS_LADDER_IDLE;
item->currentAnimState = LS_LADDER_IDLE;
if (coll->oldAnimState != STATE_LARA_LADDER_IDLE)
{
item->animNumber = ANIMATION_LARA_LADDER_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase;
if (coll->oldAnimState != LS_LADDER_IDLE)
{
item->animNumber = LA_LADDER_IDLE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
return;
}
if (TrInput & IN_LEFT)
{
short troomnumber = item->roomNumber;
int dx = int(sin(TO_RAD(item->pos.yRot - ANGLE(90.0f))) * 10);
int dz = int(cos(TO_RAD(item->pos.yRot - ANGLE(90.0f))) * 10);
int height = GetFloorHeight(GetFloor(item->pos.xPos + dx, item->pos.yPos, item->pos.zPos + dz, &troomnumber),
item->pos.xPos, item->pos.yPos, item->pos.zPos) - item->pos.yPos;
if (height < 3 * STEP_SIZE / 2) // LADDER dismounts (left/right)
{
item->goalAnimState = LS_LADDER_DISMOUNT_LEFT;
item->currentAnimState = LS_MISC_CONTROL;
}
}
else if (TrInput & IN_RIGHT)
{
short troomnumber = item->roomNumber;
int dx = int(sin(TO_RAD(item->pos.yRot + ANGLE(90.0f))) * 10);
int dz = int(cos(TO_RAD(item->pos.yRot + ANGLE(90.0f))) * 10);
int height = GetFloorHeight(GetFloor(item->pos.xPos + dx, item->pos.yPos, item->pos.zPos + dz, &troomnumber),
item->pos.xPos, item->pos.yPos, item->pos.zPos) - item->pos.yPos;
if (height < 3 * STEP_SIZE / 2) // LADDER dismounts (left/right)
{
item->goalAnimState = LS_LADDER_DISMOUNT_RIGHT;
item->currentAnimState = LS_MISC_CONTROL;
}
}
if (TrInput & IN_LEFT)
{
int flag = LaraClimbLeftCornerTest(item, coll);
@ -494,17 +548,17 @@ void LaraDoClimbLeftRight(ITEM_INFO* item, COLL_INFO* coll, int result, int shif
{
if (flag <= 0)
{
item->animNumber = ANIMATION_LARA_LADDER_AROUND_LEFT_INNER_BEGIN;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_CLIMB_CORNER_LEFT_INNER;
item->currentAnimState = STATE_LARA_CLIMB_CORNER_LEFT_INNER;
item->animNumber = LA_LADDER_LEFT_CORNER_INNER_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_SHIMMY_INNER_LEFT;
item->currentAnimState = LS_SHIMMY_INNER_LEFT;
}
else
{
item->animNumber = ANIMATION_LARA_LADDER_AROUND_LEFT_OUTER_BEGIN;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_CLIMB_CORNER_LEFT_OUTER;
item->currentAnimState = STATE_LARA_CLIMB_CORNER_LEFT_OUTER;
item->animNumber = LA_LADDER_LEFT_CORNER_OUTER_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_SHIMMY_OUTER_LEFT;
item->currentAnimState = LS_SHIMMY_OUTER_LEFT;
}
return;
@ -518,17 +572,17 @@ void LaraDoClimbLeftRight(ITEM_INFO* item, COLL_INFO* coll, int result, int shif
{
if (flag <= 0)
{
item->animNumber = ANIMATION_LARA_LADDER_AROUND_RIGHT_INNER_BEGIN;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_CLIMB_CORNER_RIGHT_INNER;
item->currentAnimState = STATE_LARA_CLIMB_CORNER_RIGHT_INNER;
item->animNumber = LA_LADDER_RIGHT_CORNER_INNER_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_SHIMMY_INNER_RIGHT;
item->currentAnimState = LS_SHIMMY_INNER_RIGHT;
}
else
{
item->animNumber = ANIMATION_LARA_LADDER_AROUND_RIGHT_OUTER_BEGIN;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_CLIMB_CORNER_RIGHT_OUTER;
item->currentAnimState = STATE_LARA_CLIMB_CORNER_RIGHT_OUTER;
item->animNumber = LA_LADDER_RIGHT_CORNER_OUTER_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_SHIMMY_OUTER_RIGHT;
item->currentAnimState = LS_SHIMMY_OUTER_RIGHT;
}
return;
@ -545,7 +599,7 @@ int LaraClimbRightCornerTest(ITEM_INFO* item, COLL_INFO* coll)//45DE4, 46248
{
int result = 0;
if (item->animNumber != ANIMATION_LARA_LADDER_RIGHT)
if (item->animNumber != LA_LADDER_RIGHT)
return 0;
int oldYrot = item->pos.yRot;
@ -643,7 +697,7 @@ int LaraClimbLeftCornerTest(ITEM_INFO* item, COLL_INFO* coll)//45ABC, 45F20
{
int result = 0;
if (item->animNumber != ANIMATION_LARA_LADDER_LEFT)
if (item->animNumber != LA_LADDER_LEFT)
return 0;
int oldYrot = item->pos.yRot;
@ -957,10 +1011,10 @@ int LaraCheckForLetGo(ITEM_INFO* item, COLL_INFO* coll)//45434, 45898 (F)
Lara.headYrot = 0;
Lara.headXrot = 0;
item->goalAnimState = STATE_LARA_JUMP_FORWARD;
item->currentAnimState = STATE_LARA_JUMP_FORWARD;
item->animNumber = ANIMATION_LARA_FREE_FALL_FORWARD;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = LS_JUMP_FORWARD;
item->currentAnimState = LS_JUMP_FORWARD;
item->animNumber = LA_FALL_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->speed = 2;
item->gravityStatus = true;

View file

@ -15,6 +15,8 @@ void lara_col_climbleft(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_climbleft(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_climbstnc(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_climbstnc(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_stepoff_left(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_stepoff_right(ITEM_INFO* item, COLL_INFO* coll);
int LaraTestClimbPos(ITEM_INFO* item, int front, int right, int origin, int height, int* shift);
void LaraDoClimbLeftRight(ITEM_INFO* item, COLL_INFO* coll, int result, int shift);

View file

@ -18,6 +18,7 @@
#include "sound.h"
#include "savegame.h"
#include "GameFlowScript.h"
#include "lara_struct.h"
WEAPON_INFO Weapons[NUM_WEAPONS] =
{
@ -219,23 +220,23 @@ WEAPON_INFO Weapons[NUM_WEAPONS] =
};
short HoldStates[] = {
STATE_LARA_WALK_FORWARD,
STATE_LARA_RUN_FORWARD,
STATE_LARA_STOP,
STATE_LARA_POSE,
STATE_LARA_TURN_RIGHT_SLOW,
STATE_LARA_TURN_LEFT_SLOW,
STATE_LARA_WALK_BACK,
STATE_LARA_TURN_FAST,
STATE_LARA_WALK_RIGHT,
STATE_LARA_WALK_LEFT,
STATE_LARA_PICKUP,
STATE_LARA_SWITCH_DOWN,
STATE_LARA_SWITCH_UP,
STATE_LARA_WADE_FORWARD,
STATE_LARA_CROUCH_IDLE,
STATE_LARA_CROUCH_TURN_LEFT,
STATE_LARA_CROUCH_TURN_RIGHT,
LS_WALK_FORWARD,
LS_RUN_FORWARD,
LS_STOP,
LS_POSE,
LS_TURN_RIGHT_SLOW,
LS_TURN_LEFT_SLOW,
LS_WALK_BACK,
LS_TURN_FAST,
LS_STEP_RIGHT,
LS_STEP_LEFT,
LS_PICKUP,
LS_SWITCH_DOWN,
LS_SWITCH_UP,
LS_WADE_FORWARD,
LS_CROUCH_IDLE,
LS_CROUCH_TURN_LEFT,
LS_CROUCH_TURN_RIGHT,
-1
};
@ -310,13 +311,13 @@ void AimWeapon(WEAPON_INFO* winfo, LARA_ARM* arm) // (F) (D)
rotX -= speed;
arm->xRot = rotX;
// TODO: set arm rotations to inherit rotations of parent bones. -Sezz
// TODO: set arm rotations to inherit rotations of parent Bones. -Sezz
arm->zRot = 0;
}
void SmashItem(short itemNum) // (F) (D)
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
if (item->objectNumber >= ID_SMASH_OBJECT1 && item->objectNumber <= ID_SMASH_OBJECT8)
SmashObject(itemNum);
}
@ -346,7 +347,7 @@ void LaraGun() // (F) (D)
}
else if (TrInput & IN_FLARE && (g_GameFlow->GetLevel(CurrentLevel)->LaraType != LARA_YOUNG))
{
if (LaraItem->currentAnimState == STATE_LARA_CROUCH_IDLE && LaraItem->animNumber != ANIMATION_LARA_CROUCH_IDLE)
if (LaraItem->currentAnimState == LS_CROUCH_IDLE && LaraItem->animNumber != LA_CROUCH_IDLE)
return;
if (Lara.gunType == WEAPON_FLARE)
@ -366,9 +367,9 @@ void LaraGun() // (F) (D)
if ((Lara.requestGunType != Lara.gunType) || (TrInput & IN_DRAW))
{
if ((LaraItem->currentAnimState == STATE_LARA_CROUCH_IDLE
|| LaraItem->currentAnimState == STATE_LARA_CROUCH_TURN_LEFT
|| LaraItem->currentAnimState == STATE_LARA_CROUCH_TURN_RIGHT)
if ((LaraItem->currentAnimState == LS_CROUCH_IDLE
|| LaraItem->currentAnimState == LS_CROUCH_TURN_LEFT
|| LaraItem->currentAnimState == LS_CROUCH_TURN_RIGHT)
&& (Lara.requestGunType == WEAPON_HK
|| Lara.requestGunType == WEAPON_CROSSBOW
#if 1
@ -423,7 +424,7 @@ void LaraGun() // (F) (D)
#endif
Lara.gunStatus = LG_UNDRAW_GUNS;
}
else if (Lara.gunStatus == LG_HANDS_BUSY && (TrInput & IN_FLARE) && LaraItem->currentAnimState == STATE_LARA_CRAWL_IDLE && LaraItem->animNumber == ANIMATION_LARA_CRAWL_IDLE)
else if (Lara.gunStatus == LG_HANDS_BUSY && (TrInput & IN_FLARE) && LaraItem->currentAnimState == LS_CRAWL_IDLE && LaraItem->animNumber == LA_CRAWL_IDLE)
{
Lara.requestGunType = WEAPON_FLARE;
}
@ -472,7 +473,8 @@ void LaraGun() // (F) (D)
break;
case LG_UNDRAW_GUNS:
LARA_MESHES(ID_LARA, LM_HEAD);
//LARA_MESHES(ID_LARA, LM_HEAD);
Lara.meshPtrs[LM_HEAD] = Objects[ID_LARA_SKIN].meshIndex + LM_HEAD;
switch (Lara.gunType)
{
@ -504,9 +506,11 @@ void LaraGun() // (F) (D)
case LG_READY:
if (!(TrInput & IN_ACTION))
LARA_MESHES(ID_LARA, LM_HEAD);
//LARA_MESHES(ID_LARA, LM_HEAD);
Lara.meshPtrs[LM_HEAD] = Objects[ID_LARA_SKIN].meshIndex + LM_HEAD;
else
LARA_MESHES(ID_LARA_SCREAM, LM_HEAD);
//LARA_MESHES(ID_LARA_SCREAM, LM_HEAD);
Lara.meshPtrs[LM_HEAD] = Objects[ID_LARA_SCREAM].meshIndex + LM_HEAD;
if (Camera.type != CINEMATIC_CAMERA && Camera.type != LOOK_CAMERA && Camera.type != HEAVY_CAMERA)
Camera.type = COMBAT_CAMERA;
@ -580,7 +584,7 @@ void LaraGun() // (F) (D)
case LG_HANDS_BUSY:
if (Lara.gunType == WEAPON_FLARE)
{
if (CHECK_LARA_MESHES(ID_LARA_FLARE_ANIM, LM_LHAND))
if (Lara.meshPtrs[LM_LHAND] == Objects[ID_LARA_FLARE_ANIM].meshIndex + LM_LHAND)
{
#if 0
Lara.flareControlLeft = (Lara.Vehicle != NO_ITEM || CheckForHoldingState(LaraItem->currentAnimState));
@ -646,8 +650,8 @@ void InitialiseNewWeapon()
break;
default:
Lara.rightArm.frameBase = Anims[LaraItem->animNumber].framePtr;
Lara.leftArm.frameBase = Anims[LaraItem->animNumber].framePtr;
Lara.rightArm.frameBase = g_Level.Anims[LaraItem->animNumber].framePtr;
Lara.leftArm.frameBase = g_Level.Anims[LaraItem->animNumber].framePtr;
break;
}
}
@ -689,7 +693,7 @@ int WeaponObjectMesh(int weaponType)
void HitTarget(ITEM_INFO* item, GAME_VECTOR* hitPos, int damage, int flag)
{
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
ObjectInfo* obj = &Objects[item->objectNumber];
OBJECT_INFO* obj = &Objects[item->objectNumber];
item->hitStatus = true;
if (creature != nullptr && item != LaraItem)
@ -850,13 +854,13 @@ FireWeaponType FireWeapon(int weaponType, ITEM_INFO* target, ITEM_INFO* src, sho
void find_target_point(ITEM_INFO* item, GAME_VECTOR* target) // (F) (D)
{
ANIM_FRAME* bounds;
BOUNDING_BOX* bounds;
int x, y, z, c, s;
bounds = (ANIM_FRAME*)GetBestFrame(item);
x = (int)(bounds->MinX + bounds->MaxX) / 2;
y = (int) bounds->MinY + (bounds->MaxY - bounds->MinY) / 3;
z = (int)(bounds->MinZ + bounds->MaxZ) / 2;
bounds = (BOUNDING_BOX*)GetBestFrame(item);
x = (int)(bounds->X1 + bounds->X2) / 2;
y = (int) bounds->Y1 + (bounds->Y2 - bounds->Y1) / 3;
z = (int)(bounds->Z1 + bounds->Z2) / 2;
c = phd_cos(item->pos.yRot);
s = phd_sin(item->pos.yRot);
@ -982,7 +986,7 @@ void LaraGetNewTarget(WEAPON_INFO* weapon) // (F) (D)
{
if (BaddieSlots[slot].itemNum != NO_ITEM)
{
item = &Items[BaddieSlots[slot].itemNum];
item = &g_Level.Items[BaddieSlots[slot].itemNum];
if (item->hitPoints > 0)
{
x = item->pos.xPos - src.x;
@ -1086,7 +1090,7 @@ void DoProperDetection(short itemNumber, int x, int y, int z, int xv, int yv, in
int ceiling, height, oldonobj, oldheight;
int bs, yang;
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
short roomNumber = item->roomNumber;
FLOOR_INFO* floor = GetFloor(x, y, z, &roomNumber);
@ -1577,4 +1581,30 @@ void DoProperDetection(short itemNumber, int x, int y, int z, int xv, int yv, in
floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
if (roomNumber != item->roomNumber)
ItemNewRoom(itemNumber, roomNumber);
}
}
HOLSTER_SLOT HolsterSlotForWeapon(LARA_WEAPON_TYPE weapon)
{
switch(weapon){
case WEAPON_PISTOLS:
return HOLSTER_SLOT::Pistols;
case WEAPON_UZI:
return HOLSTER_SLOT::Uzis;
case WEAPON_REVOLVER:
return HOLSTER_SLOT::Revolver;
case WEAPON_SHOTGUN:
return HOLSTER_SLOT::Shotgun;
case WEAPON_HK:
return HOLSTER_SLOT::HK;
case WEAPON_HARPOON_GUN:
return HOLSTER_SLOT::Harpoon;
case WEAPON_CROSSBOW:
return HOLSTER_SLOT::Crowssbow;
case WEAPON_GRENADE_LAUNCHER:
return HOLSTER_SLOT::GrenadeLauncher;
case WEAPON_ROCKET_LAUNCHER:
return HOLSTER_SLOT::RocketLauncher;
default:
return HOLSTER_SLOT::Empty;
}
}

View file

@ -23,7 +23,7 @@ typedef struct WEAPON_INFO
byte drawFrame;
short sampleNum;
};
extern WEAPON_INFO Weapons[NUM_WEAPONS];
extern WEAPON_INFO Weapons[static_cast<int>(LARA_WEAPON_TYPE::NUM_WEAPONS)];
void SmashItem(short itemNum);
int WeaponObject(int weaponType);
@ -38,4 +38,5 @@ void find_target_point(ITEM_INFO* item, GAME_VECTOR* target);
void LaraTargetInfo(WEAPON_INFO* weapon);
bool CheckForHoldingState(int state);
void LaraGetNewTarget(WEAPON_INFO* weapon);
void DoProperDetection(short itemNumber, int x, int y, int z, int xv, int yv, int zv);
void DoProperDetection(short itemNumber, int x, int y, int z, int xv, int yv, int zv);
HOLSTER_SLOT HolsterSlotForWeapon(LARA_WEAPON_TYPE weapon);

View file

@ -21,9 +21,9 @@ constexpr std::array<float, 28> FlareFlickerTableLow = { 0.7590,0.1880,0.0790,0.
void FlareControl(short itemNumber) // (AF) (D)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP)
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP)
{
KillItem(itemNumber);
return;
@ -51,7 +51,7 @@ void FlareControl(short itemNumber) // (AF) (D)
item->pos.zPos += zv;
if (Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
{
item->fallspeed += (5 - item->fallspeed) / 2;
item->speed += (5 - item->speed) / 2;
@ -104,12 +104,12 @@ void ready_flare() // (F) (D)
void undraw_flare_meshes() // (F) (D)
{
LARA_MESHES(ID_LARA, LM_LHAND);
Lara.meshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
}
void draw_flare_meshes() // (F) (D)
{
LARA_MESHES(ID_LARA_FLARE_ANIM, LM_LHAND);
Lara.meshPtrs[LM_LHAND] = Objects[ID_LARA_FLARE_ANIM].meshIndex + LM_LHAND;
}
void undraw_flare() // (F) (D)
@ -120,25 +120,25 @@ void undraw_flare() // (F) (D)
short frame2 = Lara.leftArm.frameNumber;
#if 0
if (LaraItem->goalAnimState == STATE_LARA_STOP &&
if (LaraItem->goalAnimState == LS_STOP &&
Lara.Vehicle == NO_ITEM)
#else
if (LaraItem->goalAnimState == STATE_LARA_STOP)
if (LaraItem->goalAnimState == LS_STOP)
#endif
{
if (LaraItem->animNumber == ANIMATION_LARA_STAY_IDLE)
if (LaraItem->animNumber == LA_STAND_IDLE)
{
LaraItem->animNumber = ANIMATION_LARA_FLARE_THROW;
frame1 = frame2 + Anims[LaraItem->animNumber].frameBase;
LaraItem->animNumber = LA_DISCARD_FLARE;
frame1 = frame2 + g_Level.Anims[LaraItem->animNumber].frameBase;
Lara.flareFrame = frame1;
LaraItem->frameNumber = frame1;
}
if (LaraItem->animNumber == ANIMATION_LARA_FLARE_THROW)
if (LaraItem->animNumber == LA_DISCARD_FLARE)
{
Lara.flareControlLeft = false;
if (frame1 >= Anims[LaraItem->animNumber].frameBase + 31)
if (frame1 >= g_Level.Anims[LaraItem->animNumber].frameBase + 31)
{
Lara.requestGunType = Lara.lastGunType;
Lara.gunType = Lara.lastGunType;
@ -149,21 +149,21 @@ void undraw_flare() // (F) (D)
Lara.target = NULL;
Lara.rightArm.lock = false;
Lara.leftArm.lock = false;
LaraItem->animNumber = ANIMATION_LARA_STAY_SOLID;
Lara.flareFrame = Anims[LaraItem->animNumber].frameBase;
LaraItem->frameNumber = Anims[LaraItem->animNumber].frameBase;
LaraItem->currentAnimState = STATE_LARA_STOP;
LaraItem->goalAnimState = STATE_LARA_STOP;
LaraItem->animNumber = LA_STAND_SOLID;
Lara.flareFrame = g_Level.Anims[LaraItem->animNumber].frameBase;
LaraItem->frameNumber = g_Level.Anims[LaraItem->animNumber].frameBase;
LaraItem->currentAnimState = LS_STOP;
LaraItem->goalAnimState = LS_STOP;
return;
}
Lara.flareFrame++;
}
}
else if (LaraItem->currentAnimState == STATE_LARA_STOP) /* @ORIGINAL_BUG: this code block makes flare cancels possible */
else if (LaraItem->currentAnimState == LS_STOP) /* @ORIGINAL_BUG: this code block makes flare cancels possible */
{
LaraItem->animNumber = ANIMATION_LARA_STAY_SOLID;
LaraItem->frameNumber = Anims[LaraItem->animNumber].frameBase;
LaraItem->animNumber = LA_STAND_SOLID;
LaraItem->frameNumber = g_Level.Anims[LaraItem->animNumber].frameBase;
}
if (frame2 >= 33 && frame2 < 72)
@ -232,8 +232,8 @@ void draw_flare() // (F) (D)
{
short frame;
if (LaraItem->currentAnimState == STATE_LARA_FLARE_PICKUP ||
LaraItem->currentAnimState == STATE_LARA_PICKUP)
if (LaraItem->currentAnimState == LS_PICKUP_FLARE ||
LaraItem->currentAnimState == LS_PICKUP)
{
DoFlareInHand(Lara.flareAge);
Lara.flareControlLeft = false;
@ -257,7 +257,7 @@ void draw_flare() // (F) (D)
{
if (frame == 72)
{
SoundEffect(SFX_RAVESTICK, &LaraItem->pos, Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WATER);
SoundEffect(SFX_RAVESTICK, &LaraItem->pos, g_Level.Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WATER);
Lara.flareAge = 1;
}
@ -300,7 +300,7 @@ void set_flare_arm(int frame) // (F) (D)
}
Lara.leftArm.animNumber = anim;
Lara.leftArm.frameBase = Anims[anim].framePtr;
Lara.leftArm.frameBase = g_Level.Anims[anim].framePtr;
}
void CreateFlare(short objectNum, int thrown) // (F) (D)
@ -309,7 +309,7 @@ void CreateFlare(short objectNum, int thrown) // (F) (D)
if (itemNum != NO_ITEM)
{
bool flag = false;
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
item->objectNumber = objectNum;
item->roomNumber = LaraItem->roomNumber;

View file

@ -18,7 +18,7 @@
#include "camera.h"
#include "input.h"
#include "sound.h"
using T5M::Renderer::g_Renderer;
extern GameFlow* g_GameFlow;
extern short FXType;
COLL_INFO lara_coll;
@ -27,45 +27,45 @@ short cheatHitPoints;
void GetLaraDeadlyBounds() // (F) (D)
{
short* bounds;
short tbounds[6];
BOUNDING_BOX* bounds;
BOUNDING_BOX tbounds;
bounds = GetBoundsAccurate(LaraItem);
phd_RotBoundingBoxNoPersp(&LaraItem->pos, bounds, tbounds);
phd_RotBoundingBoxNoPersp(&LaraItem->pos, bounds, &tbounds);
DeadlyBounds[0] = LaraItem->pos.xPos + tbounds[0];
DeadlyBounds[1] = LaraItem->pos.xPos + tbounds[1];
DeadlyBounds[2] = LaraItem->pos.yPos + tbounds[2];
DeadlyBounds[3] = LaraItem->pos.yPos + tbounds[3];
DeadlyBounds[4] = LaraItem->pos.zPos + tbounds[4];
DeadlyBounds[5] = LaraItem->pos.zPos + tbounds[5];
DeadlyBounds[0] = LaraItem->pos.xPos + tbounds.X1;
DeadlyBounds[1] = LaraItem->pos.xPos + tbounds.X2;
DeadlyBounds[2] = LaraItem->pos.yPos + tbounds.Y1;
DeadlyBounds[3] = LaraItem->pos.yPos + tbounds.Y2;
DeadlyBounds[4] = LaraItem->pos.zPos + tbounds.Z1;
DeadlyBounds[5] = LaraItem->pos.zPos + tbounds.Z2;
}
void InitialiseLaraAnims(ITEM_INFO* item) // (F) (D)
{
if (Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
{
Lara.waterStatus = LW_UNDERWATER;
item->goalAnimState = STATE_LARA_UNDERWATER_STOP;
item->currentAnimState = STATE_LARA_UNDERWATER_STOP;
item->goalAnimState = LS_UNDERWATER_STOP;
item->currentAnimState = LS_UNDERWATER_STOP;
item->fallspeed = 0;
item->animNumber = ANIMATION_LARA_UNDERWATER_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase;
item->animNumber = LA_UNDERWATER_IDLE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
}
else
{
Lara.waterStatus = LW_ABOVE_WATER;
item->goalAnimState = STATE_LARA_STOP;
item->currentAnimState = STATE_LARA_STOP;
item->animNumber = ANIMATION_LARA_STAY_SOLID;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = LS_STOP;
item->currentAnimState = LS_STOP;
item->animNumber = LA_STAND_SOLID;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
}
}
void InitialiseLaraLoad(short itemNum) // (F) (D)
{
Lara.itemNumber = itemNum;
LaraItem = &Items[itemNum];
LaraItem = &g_Level.Items[itemNum];
}
void DelsGiveLaraItemsCheat() // (AF) (D)
@ -216,10 +216,10 @@ void LaraCheatyBits() // (F) (D)
if (Lara.waterStatus != LW_FLYCHEAT)
{
Lara.waterStatus = LW_FLYCHEAT;
LaraItem->animNumber = ANIMATION_LARA_DOZY;
LaraItem->frameNumber = Anims[LaraItem->animNumber].frameBase;
LaraItem->currentAnimState = ANIMATION_LARA_ONWATER_IDLE_TO_SWIM;
LaraItem->goalAnimState = ANIMATION_LARA_ONWATER_IDLE_TO_SWIM;
LaraItem->animNumber = LA_DOZY;
LaraItem->frameNumber = g_Level.Anims[LaraItem->animNumber].frameBase;
LaraItem->currentAnimState = LA_ONWATER_IDLE_TO_SWIM;
LaraItem->goalAnimState = LA_ONWATER_IDLE_TO_SWIM;
LaraItem->gravityStatus = false;
LaraItem->pos.xRot = ANGLE(30);
LaraItem->fallspeed = 30;
@ -259,23 +259,23 @@ void LaraControl(short itemNumber) // (AF) (D)
int oldZ = LaraItem->pos.zPos;
if (Lara.gunStatus == LG_HANDS_BUSY &&
LaraItem->currentAnimState == STATE_LARA_STOP &&
LaraItem->goalAnimState == STATE_LARA_STOP &&
LaraItem->animNumber == ANIMATION_LARA_STAY_IDLE &&
LaraItem->currentAnimState == LS_STOP &&
LaraItem->goalAnimState == LS_STOP &&
LaraItem->animNumber == LA_STAND_IDLE &&
!LaraItem->gravityStatus)
{
Lara.gunStatus = LG_NO_ARMS;
}
if (item->currentAnimState != STATE_LARA_SPRINT && DashTimer < 120)
if (item->currentAnimState != LS_SPRINT && DashTimer < 120)
DashTimer++;
Lara.isDucked = false;
#if 1
bool isWater = Rooms[item->roomNumber].flags & ENV_FLAG_WATER;
bool isWater = g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER;
#else
bool isWater = Rooms[item->roomNumber].flags & (ENV_FLAG_WATER|ENV_FLAG_SWAMP);
bool isWater = g_Level.Rooms[item->roomNumber].flags & (ENV_FLAG_WATER|ENV_FLAG_SWAMP);
#endif
int wd = GetWaterDepth(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber);
@ -311,18 +311,18 @@ void LaraControl(short itemNumber) // (AF) (D)
Lara.waterStatus = LW_WADE;
if (!(item->gravityStatus))
{
item->goalAnimState = STATE_LARA_STOP;
item->goalAnimState = LS_STOP;
}
#if 0
else if (isWater & ENV_FLAG_SWAMP)
{
if (item->currentAnimState == STATE_LARA_SWANDIVE_BEGIN || item->currentAnimState == STATE_LARA_SWANDIVE_END) // Is Lara swan-diving?
if (item->currentAnimState == LS_SWANDIVE_BEGIN || item->currentAnimState == LS_SWANDIVE_END) // Is Lara swan-diving?
item->pos.yPos = wh + 1000;
item->goalAnimState = STATE_LARA_WADE_FORWARD;
item->currentAnimState = STATE_LARA_WADE_FORWARD;
item->animNumber = ANIMATION_LARA_WADE;
item->frameNumber = GF(ANIMATION_LARA_WADE, 0);
item->goalAnimState = LS_WADE_FORWARD;
item->currentAnimState = LS_WADE_FORWARD;
item->animNumber = LA_WADE;
item->frameNumber = GF(LA_WADE, 0);
}
#endif
}
@ -341,27 +341,27 @@ void LaraControl(short itemNumber) // (AF) (D)
UpdateLaraRoom(LaraItem, 0);
StopSoundEffect(SFX_LARA_FALL);
if (item->currentAnimState == STATE_LARA_SWANDIVE_BEGIN)
if (item->currentAnimState == LS_SWANDIVE_START)
{
item->pos.xRot = -ANGLE(45);
item->goalAnimState = STATE_LARA_UNDERWATER_DIVING;
item->goalAnimState = LS_DIVE;
AnimateLara(item);
item->fallspeed *= 2;
}
else if (item->currentAnimState == STATE_LARA_SWANDIVE_END)
else if (item->currentAnimState == LS_SWANDIVE_END)
{
item->pos.xRot = -ANGLE(85);
item->goalAnimState = STATE_LARA_UNDERWATER_DIVING;
item->goalAnimState = LS_DIVE;
AnimateLara(item);
item->fallspeed *= 2;
}
else
{
item->pos.xRot = -ANGLE(45);
item->animNumber = ANIMATION_LARA_FREE_FALL_TO_UNDERWATER;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_UNDERWATER_DIVING;
item->goalAnimState = STATE_LARA_UNDERWATER_FORWARD;
item->animNumber = LA_FREEFALL_DIVE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = LS_DIVE;
item->goalAnimState = LS_UNDERWATER_FORWARD;
item->fallspeed = 3 * item->fallspeed / 2;
}
@ -383,32 +383,32 @@ void LaraControl(short itemNumber) // (AF) (D)
switch (item->currentAnimState)
{
case STATE_LARA_WALK_BACK:
item->animNumber = ANIMATION_LARA_ONWATER_IDLE_TO_SWIM_BACK;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_ONWATER_BACK;
item->currentAnimState = STATE_LARA_ONWATER_BACK;
case LS_WALK_BACK:
item->animNumber = LA_ONWATER_IDLE_TO_SWIM_BACK;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_BACK;
item->currentAnimState = LS_ONWATER_BACK;
break;
case STATE_LARA_WALK_RIGHT:
item->animNumber = ANIMATION_LARA_ONWATER_SWIM_RIGHT;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_ONWATER_RIGHT;
item->currentAnimState = STATE_LARA_ONWATER_RIGHT;
case LS_STEP_RIGHT:
item->animNumber = LA_ONWATER_SWIM_RIGHT;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_RIGHT;
item->currentAnimState = LS_ONWATER_RIGHT;
break;
case STATE_LARA_WALK_LEFT:
item->animNumber = ANIMATION_LARA_ONWATER_SWIM_LEFT;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_ONWATER_LEFT;
item->currentAnimState = STATE_LARA_ONWATER_LEFT;
case LS_STEP_LEFT:
item->animNumber = LA_ONWATER_SWIM_LEFT;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_LEFT;
item->currentAnimState = LS_ONWATER_LEFT;
break;
default:
item->animNumber = ANIMATION_LARA_ONWATER_SWIM_FORWARD;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_ONWATER_FORWARD;
item->currentAnimState = STATE_LARA_ONWATER_FORWARD;
item->animNumber = LA_ONWATER_SWIM;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_FORWARD;
item->currentAnimState = LS_ONWATER_FORWARD;
break;
}
@ -428,8 +428,8 @@ void LaraControl(short itemNumber) // (AF) (D)
else
{
Lara.waterStatus = LW_ABOVE_WATER;
if (item->currentAnimState == STATE_LARA_WADE_FORWARD)
item->goalAnimState = STATE_LARA_RUN_FORWARD;
if (item->currentAnimState == LS_WADE_FORWARD)
item->goalAnimState = LS_RUN_FORWARD;
}
}
@ -441,19 +441,19 @@ void LaraControl(short itemNumber) // (AF) (D)
if (wd == NO_HEIGHT
|| abs(hfw) >= 256
|| Rooms[roomNumber].flags & ENV_FLAG_WATER
|| item->animNumber == ANIMATION_LARA_UNDERWATER_TO_ONWATER
|| item->animNumber == ANIMATION_LARA_FREE_FALL_TO_UNDERWATER_ALTERNATE)
|| g_Level.Rooms[roomNumber].flags & ENV_FLAG_WATER
|| item->animNumber == LA_UNDERWATER_RESURFACE
|| item->animNumber == LA_ONWATER_DIVE)
{
if (!isWater)
{
if (wd == NO_HEIGHT || abs(hfw) >= 256)
{
Lara.waterStatus = LW_ABOVE_WATER;
item->animNumber = ANIMATION_LARA_FREE_FALL_FORWARD;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_JUMP_FORWARD;
item->currentAnimState = STATE_LARA_JUMP_FORWARD;
item->animNumber = LA_FALL_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_JUMP_FORWARD;
item->currentAnimState = LS_JUMP_FORWARD;
item->speed = item->fallspeed / 4;
item->gravityStatus = true;
@ -469,10 +469,10 @@ void LaraControl(short itemNumber) // (AF) (D)
{
Lara.waterStatus = LW_SURFACE;
item->pos.yPos = wh;
item->animNumber = ANIMATION_LARA_UNDERWATER_TO_ONWATER;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_ONWATER_STOP;
item->currentAnimState = STATE_LARA_ONWATER_STOP;
item->animNumber = LA_UNDERWATER_RESURFACE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_STOP;
item->currentAnimState = LS_ONWATER_STOP;
item->fallspeed = 0;
Lara.diveCount = 11;
LaraItem->pos.zRot = 0;
@ -491,10 +491,10 @@ void LaraControl(short itemNumber) // (AF) (D)
{
Lara.waterStatus = LW_SURFACE;
item->pos.yPos = wh + 1;
item->animNumber = ANIMATION_LARA_UNDERWATER_TO_ONWATER;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_ONWATER_STOP;
item->currentAnimState = STATE_LARA_ONWATER_STOP;
item->animNumber = LA_UNDERWATER_RESURFACE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_STOP;
item->currentAnimState = LS_ONWATER_STOP;
item->fallspeed = 0;
Lara.diveCount = 11;
LaraItem->pos.zRot = 0;
@ -515,20 +515,20 @@ void LaraControl(short itemNumber) // (AF) (D)
if (hfw <= 256)
{
Lara.waterStatus = LW_ABOVE_WATER;
item->animNumber = ANIMATION_LARA_FREE_FALL_FORWARD;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_JUMP_FORWARD;
item->currentAnimState = STATE_LARA_JUMP_FORWARD;
item->animNumber = LA_FALL_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_JUMP_FORWARD;
item->currentAnimState = LS_JUMP_FORWARD;
item->speed = item->fallspeed / 4;
item->gravityStatus = true;
}
else
{
Lara.waterStatus = LW_WADE; /* @DEAD_CODE: Lara has to reach a room without water while in the surface but then GetWaterHeight() return value never will make hfw > 256 */
item->animNumber = ANIMATION_LARA_STAY_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_WADE_FORWARD;
item->currentAnimState = STATE_LARA_STOP;
item->animNumber = LA_STAND_IDLE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_WADE_FORWARD;
item->currentAnimState = LS_STOP;
AnimateItem(item);
}
@ -558,32 +558,32 @@ void LaraControl(short itemNumber) // (AF) (D)
switch (item->currentAnimState)
{
case STATE_LARA_WALK_BACK:
item->animNumber = ANIMATION_LARA_ONWATER_IDLE_TO_SWIM_BACK;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_ONWATER_BACK;
item->currentAnimState = STATE_LARA_ONWATER_BACK;
case LS_WALK_BACK:
item->animNumber = LA_ONWATER_IDLE_TO_SWIM_BACK;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_BACK;
item->currentAnimState = LS_ONWATER_BACK;
break;
case STATE_LARA_WALK_RIGHT:
item->animNumber = ANIMATION_LARA_ONWATER_SWIM_RIGHT;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_ONWATER_RIGHT;
item->currentAnimState = STATE_LARA_ONWATER_RIGHT;
case LS_STEP_RIGHT:
item->animNumber = LA_ONWATER_SWIM_RIGHT;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_RIGHT;
item->currentAnimState = LS_ONWATER_RIGHT;
break;
case STATE_LARA_WALK_LEFT:
item->animNumber = ANIMATION_LARA_ONWATER_SWIM_LEFT;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_ONWATER_LEFT;
item->currentAnimState = STATE_LARA_ONWATER_LEFT;
case LS_STEP_LEFT:
item->animNumber = LA_ONWATER_SWIM_LEFT;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_LEFT;
item->currentAnimState = LS_ONWATER_LEFT;
break;
default:
item->animNumber = ANIMATION_LARA_ONWATER_SWIM_FORWARD;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_ONWATER_FORWARD;
item->currentAnimState = STATE_LARA_ONWATER_FORWARD;
item->animNumber = LA_ONWATER_SWIM;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_FORWARD;
item->currentAnimState = LS_ONWATER_FORWARD;
break;
}
@ -603,8 +603,8 @@ void LaraControl(short itemNumber) // (AF) (D)
else
{
Lara.waterStatus = LW_ABOVE_WATER;
if (item->currentAnimState == STATE_LARA_WADE_FORWARD)
item->goalAnimState = STATE_LARA_RUN_FORWARD;
if (item->currentAnimState == LS_WADE_FORWARD)
item->goalAnimState = LS_RUN_FORWARD;
}
break;
}
@ -632,7 +632,7 @@ void LaraControl(short itemNumber) // (AF) (D)
case LW_ABOVE_WATER:
case LW_WADE:
#if 0
if (Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && Lara.waterSurfaceDist < -775)
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && Lara.waterSurfaceDist < -775)
{
if (item->hitPoints >= 0)
{
@ -723,8 +723,8 @@ void LaraCheat(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
if (TrInput & IN_WALK && !(TrInput & IN_LOOK))
{
Lara.waterStatus = LW_ABOVE_WATER;
item->animNumber = ANIMATION_LARA_STAY_SOLID;
item->frameNumber = Anims[item->animNumber].frameBase;
item->animNumber = LA_STAND_SOLID;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->pos.zRot = 0;
item->pos.xRot = 0;
Lara.torsoYrot = 0;
@ -742,24 +742,25 @@ void LaraInitialiseMeshes() // (AF) (D)
{
for (int i = 0; i < NUM_LARA_MESHES; i++)
{
MESHES(ID_LARA, i) = MESHES(ID_LARA_SKIN, i);
LARA_MESHES(ID_LARA, i);
//Meshes[i] = Meshes[MESHES(ID_LARA_SKIN, i)];
//LARA_MESHES(ID_LARA, MESHES(ID_LARA_SKIN, i));
Lara.meshPtrs[i] = Objects[ID_LARA_SKIN].meshIndex + i;
}
/* Hardcoded code */
if (Lara.gunType == WEAPON_HK)
{
Lara.backGun = WEAPON_HK;
Lara.holsterInfo.backHolster = HOLSTER_SLOT::HK;
}
else if (!Lara.Weapons[WEAPON_SHOTGUN].Present)
{
if (Lara.Weapons[WEAPON_HK].Present)
Lara.backGun = WEAPON_HK;
Lara.holsterInfo.backHolster = HOLSTER_SLOT::HK;
}
else
{
Lara.backGun = WEAPON_UZI;
Lara.holsterInfo.backHolster = HOLSTER_SLOT::Uzis;
}
Lara.gunStatus = LG_NO_ARMS;
@ -802,7 +803,20 @@ void InitialiseLara(int restore)
Lara.dpoisoned = 0;
Lara.poisoned = 0;
Lara.waterSurfaceDist = 100;
Lara.holster = ID_LARA_HOLSTERS_PISTOLS;
if(Lara.Weapons[static_cast<int>(LARA_WEAPON_TYPE::WEAPON_PISTOLS)].Present){
Lara.holsterInfo.leftHolster = HOLSTER_SLOT::Pistols;
Lara.holsterInfo.rightHolster = HOLSTER_SLOT::Pistols;
} else{
Lara.holsterInfo.leftHolster = HOLSTER_SLOT::Empty;
Lara.holsterInfo.rightHolster = HOLSTER_SLOT::Empty;
}
if(Lara.Weapons[static_cast<int>(LARA_WEAPON_TYPE::WEAPON_SHOTGUN)].Present){
Lara.holsterInfo.backHolster = HOLSTER_SLOT::Shotgun;
} else{
Lara.holsterInfo.backHolster = HOLSTER_SLOT::Empty;
}
Lara.location = -1;
Lara.highestLocation = -1;
Lara.ropePtr = -1;
@ -856,10 +870,10 @@ void AnimateLara(ITEM_INFO* item)
{
item->frameNumber++;
ANIM_STRUCT* anim = &Anims[item->animNumber];
ANIM_STRUCT* anim = &g_Level.Anims[item->animNumber];
if (anim->numberChanges > 0 && GetChange(item, anim))
{
anim = &Anims[item->animNumber];
anim = &g_Level.Anims[item->animNumber];
item->currentAnimState = anim->currentAnimState;
}
@ -867,7 +881,7 @@ void AnimateLara(ITEM_INFO* item)
{
if (anim->numberCommands > 0)
{
short* cmd = &Commands[anim->commandIndex];
short* cmd = &g_Level.Commands[anim->commandIndex];
for (int i = anim->numberCommands; i > 0; i--)
{
switch (*(cmd++))
@ -908,13 +922,13 @@ void AnimateLara(ITEM_INFO* item)
item->animNumber = anim->jumpAnimNum;
item->frameNumber = anim->jumpFrameNum;
anim = &Anims[item->animNumber];
anim = &g_Level.Anims[item->animNumber];
item->currentAnimState = anim->currentAnimState;
}
if (anim->numberCommands > 0)
{
short* cmd = &Commands[anim->commandIndex];
short* cmd = &g_Level.Commands[anim->commandIndex];
int flags;
int effectID = 0;
@ -940,7 +954,7 @@ void AnimateLara(ITEM_INFO* item)
flags = cmd[1] & 0xC000;
if (flags == SFX_LANDANDWATER ||
(flags == SFX_LANDONLY && (Lara.waterSurfaceDist >= 0 || Lara.waterSurfaceDist == NO_HEIGHT)) ||
(flags == SFX_WATERONLY && Lara.waterSurfaceDist < 0 && Lara.waterSurfaceDist != NO_HEIGHT && !(Rooms[LaraItem->roomNumber].flags & ENV_FLAG_SWAMP)))
(flags == SFX_WATERONLY && Lara.waterSurfaceDist < 0 && Lara.waterSurfaceDist != NO_HEIGHT && !(g_Level.Rooms[LaraItem->roomNumber].flags & ENV_FLAG_SWAMP)))
{
SoundEffect(cmd[1] & 0x3FFF, &item->pos, 2);
}
@ -976,7 +990,7 @@ void AnimateLara(ITEM_INFO* item)
if (item->gravityStatus) // If gravity ON (Do Up/Down movement)
{
if (Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP)
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP)
{
item->speed -= item->speed >> 3;
if (abs(item->speed) < 8)
@ -1004,7 +1018,7 @@ void AnimateLara(ITEM_INFO* item)
{
int velocity;
if (Lara.waterStatus == LW_WADE && Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP)
if (Lara.waterStatus == LW_WADE && g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP)
{
velocity = (anim->velocity >> 1);
if (anim->acceleration)
@ -1033,7 +1047,7 @@ void AnimateLara(ITEM_INFO* item)
}
// Update matrices
g_Renderer->UpdateLaraAnimations(true);
g_Renderer.UpdateLaraAnimations(true);
}
void DelAlignLaraToRope(ITEM_INFO* item) // (F) (D)
@ -1051,8 +1065,8 @@ void DelAlignLaraToRope(ITEM_INFO* item) // (F) (D)
frame = (ANIM_FRAME*) GetBestFrame(item);
ropeY = Lara.ropeY - ANGLE(90);
rope = &Ropes[Lara.ropePtr];
_0x0046D130(rope, (Lara.ropeSegment - 1 << 7) + frame->OffsetY, &pos.x, &pos.y, &pos.z);
_0x0046D130(rope, (Lara.ropeSegment - 1 << 7) + frame->OffsetY - 192, &pos2.x, &pos2.y, &pos2.z);
_0x0046D130(rope, (Lara.ropeSegment - 1 << 7) + frame->offsetY, &pos.x, &pos.y, &pos.z);
_0x0046D130(rope, (Lara.ropeSegment - 1 << 7) + frame->offsetY - 192, &pos2.x, &pos2.y, &pos2.z);
diff.x = pos.x - pos2.x << 16;
diff.y = pos.y - pos2.y << 16;
diff.z = pos.z - pos2.z << 16;

View file

@ -16,12 +16,12 @@ bool EnableCrawlFlexWaterPullUp, EnableCrawlFlexSubmerged;
void lara_col_surftread(ITEM_INFO* item, COLL_INFO* coll)
{
if (item->goalAnimState == STATE_LARA_UNDERWATER_FORWARD)
if (item->goalAnimState == LS_UNDERWATER_FORWARD)
{
item->currentAnimState = STATE_LARA_UNDERWATER_DIVING;
item->animNumber = ANIMATION_LARA_FREE_FALL_TO_UNDERWATER_ALTERNATE;
item->currentAnimState = LS_DIVE;
item->animNumber = LA_ONWATER_DIVE;
item->pos.xRot = -8190;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->fallspeed = 80;
Lara.waterStatus = LW_UNDERWATER;
}
@ -53,6 +53,7 @@ void lara_col_surfswim(ITEM_INFO* item, COLL_INFO* coll)//4DCE8(<), 4E14C(<) (F)
Lara.moveAngle = 0;
LaraSurfaceCollision(item, coll);
LaraTestWaterClimbOut(item, coll);
LaraTestLadderClimbOut(item, coll);
}
void lara_as_surftread(ITEM_INFO* item, COLL_INFO* coll)//4DBA0, 4E004 (F)
@ -63,7 +64,7 @@ void lara_as_surftread(ITEM_INFO* item, COLL_INFO* coll)//4DBA0, 4E004 (F)
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_WATER_DEATH;
item->goalAnimState = LS_WATER_DEATH;
return;
}
@ -84,27 +85,27 @@ void lara_as_surftread(ITEM_INFO* item, COLL_INFO* coll)//4DBA0, 4E004 (F)
if (TrInput & IN_FORWARD)
{
item->goalAnimState = STATE_LARA_ONWATER_FORWARD;
item->goalAnimState = LS_ONWATER_FORWARD;
}
else if (TrInput & IN_BACK)
{
item->goalAnimState = STATE_LARA_ONWATER_BACK;
item->goalAnimState = LS_ONWATER_BACK;
}
if (TrInput & IN_LSTEP)
{
item->goalAnimState = STATE_LARA_ONWATER_LEFT;
item->goalAnimState = LS_ONWATER_LEFT;
}
else if (TrInput & IN_RSTEP)
{
item->goalAnimState = STATE_LARA_ONWATER_RIGHT;
item->goalAnimState = LS_ONWATER_RIGHT;
}
if (TrInput & IN_JUMP)
{
Lara.diveCount++;
if (Lara.diveCount == 10)
item->goalAnimState = STATE_LARA_UNDERWATER_FORWARD;
item->goalAnimState = LS_UNDERWATER_FORWARD;
}
else
{
@ -116,7 +117,7 @@ void lara_as_surfright(ITEM_INFO* item, COLL_INFO* coll)//4DAF8, 4DF5C (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_WATER_DEATH;
item->goalAnimState = LS_WATER_DEATH;
return;
}
@ -133,7 +134,7 @@ void lara_as_surfright(ITEM_INFO* item, COLL_INFO* coll)//4DAF8, 4DF5C (F)
if (!(TrInput & IN_RSTEP))
{
item->goalAnimState = STATE_LARA_ONWATER_STOP;
item->goalAnimState = LS_ONWATER_STOP;
}
item->fallspeed += 8;
@ -145,7 +146,7 @@ void lara_as_surfleft(ITEM_INFO* item, COLL_INFO* coll)//4DA50(<), 4DEB4(<) (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_WATER_DEATH;
item->goalAnimState = LS_WATER_DEATH;
return;
}
@ -162,7 +163,7 @@ void lara_as_surfleft(ITEM_INFO* item, COLL_INFO* coll)//4DA50(<), 4DEB4(<) (F)
if (!(TrInput & IN_LSTEP))
{
item->goalAnimState = STATE_LARA_ONWATER_STOP;
item->goalAnimState = LS_ONWATER_STOP;
}
item->fallspeed += 8;
@ -174,7 +175,7 @@ void lara_as_surfback(ITEM_INFO* item, COLL_INFO* coll)//4D9A8(<), 4DE0C(<) (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_WATER_DEATH;
item->goalAnimState = LS_WATER_DEATH;
return;
}
@ -191,7 +192,7 @@ void lara_as_surfback(ITEM_INFO* item, COLL_INFO* coll)//4D9A8(<), 4DE0C(<) (F)
if (!(TrInput & IN_BACK))
{
item->goalAnimState = STATE_LARA_ONWATER_STOP;
item->goalAnimState = LS_ONWATER_STOP;
}
item->fallspeed += 8;
@ -203,7 +204,7 @@ void lara_as_surfswim(ITEM_INFO* item, COLL_INFO* coll)//4D8E4(<), 4DD48(<) (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_WATER_DEATH;
item->goalAnimState = LS_WATER_DEATH;
return;
}
@ -219,9 +220,9 @@ void lara_as_surfswim(ITEM_INFO* item, COLL_INFO* coll)//4D8E4(<), 4DD48(<) (F)
}
if (!(TrInput & IN_FORWARD))
item->goalAnimState = STATE_LARA_ONWATER_STOP;
item->goalAnimState = LS_ONWATER_STOP;
if (TrInput & IN_JUMP)
item->goalAnimState = STATE_LARA_ONWATER_STOP;
item->goalAnimState = LS_ONWATER_STOP;
item->fallspeed += 8;
if (item->fallspeed > 60)
@ -314,11 +315,11 @@ void LaraSurfaceCollision(ITEM_INFO* item, COLL_INFO* coll)//4D4F0(<), 4D954(<)
}
else
{
item->goalAnimState = STATE_LARA_UNDERWATER_FORWARD;
item->currentAnimState = STATE_LARA_UNDERWATER_DIVING;
item->animNumber = ANIMATION_LARA_FREE_FALL_TO_UNDERWATER_ALTERNATE;
item->goalAnimState = LS_UNDERWATER_FORWARD;
item->currentAnimState = LS_DIVE;
item->animNumber = LA_ONWATER_DIVE;
item->pos.xRot = -8190;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->fallspeed = 80;
Lara.waterStatus = LW_UNDERWATER;
}
@ -388,49 +389,49 @@ int LaraTestWaterClimbOut(ITEM_INFO* item, COLL_INFO* coll)//4D22C, 4D690
{
if ((LaraCeilingFront(item, item->pos.yRot, 384, 512) >= -512) && EnableCrawlFlexWaterPullUp == true)
{
item->animNumber = ANIMATION_LARA_CLIMB_OUT_OF_WATER_TO_2CLICK;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = ANIMATION_LARA_CROUCH_IDLE;
item->animNumber = LA_ONWATER_TO_CROUCH_1CLICK;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LA_CROUCH_IDLE;
}
else
{
item->animNumber = ANIMATION_LARA_CLIMB_OUT_OF_WATER;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_STOP;
item->animNumber = LA_ONWATER_TO_STAND_1CLICK;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_STOP;
}
}
else if (frontFloor > 128)
{
if ((LaraCeilingFront(item, item->pos.yRot, 384, 512) >= -512) && EnableCrawlFlexSubmerged == true)
{
item->animNumber = ANIMATION_LARA_WATER_TO_SUBMERGED_CRAWL;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = ANIMATION_LARA_CROUCH_IDLE;
item->animNumber = LA_ONWATER_TO_CROUCH_M1CLICK;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LA_CROUCH_IDLE;
}
else
item->animNumber = ANIMATION_LARA_ONWATER_TO_WADE;
item->frameNumber = Anims[item->animNumber].frameBase;
item->animNumber = LA_ONWATER_TO_STAND_M1CLICK;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
}
else
{
if ((LaraCeilingFront(item, item->pos.yRot, 384, 512) >= -512) && EnableCrawlFlexWaterPullUp == true)
{
item->animNumber = ANIMATION_LARA_ONWATER_TO_LAND_LOW_TO_2CLICK;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = ANIMATION_LARA_CROUCH_IDLE;
item->animNumber = LA_ONWATER_TO_CROUCH_0CLICK;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LA_CROUCH_IDLE;
}
else
{
item->animNumber = ANIMATION_LARA_ONWATER_TO_LAND_LOW;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_STOP;
item->animNumber = LA_ONWATER_TO_STAND_0CLICK;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_STOP;
}
}
item->currentAnimState = STATE_LARA_ONWATER_EXIT;
item->currentAnimState = LS_ONWATER_EXIT;
item->pos.yRot = rot;
Lara.gunStatus = LG_HANDS_BUSY;
item->pos.zRot = 0;
@ -455,28 +456,28 @@ int LaraTestWaterStepOut(ITEM_INFO* item, COLL_INFO* coll)//4D100, 4D564 (F)
if (coll->midFloor >= -128)
{
if (item->goalAnimState == STATE_LARA_ONWATER_LEFT)
if (item->goalAnimState == LS_ONWATER_LEFT)
{
item->goalAnimState = STATE_LARA_WALK_LEFT;
item->goalAnimState = LS_STEP_LEFT;
}
else if (item->goalAnimState == STATE_LARA_ONWATER_RIGHT)
else if (item->goalAnimState == LS_ONWATER_RIGHT)
{
item->goalAnimState = STATE_LARA_WALK_RIGHT;
item->goalAnimState = LS_STEP_RIGHT;
}
else
{
item->animNumber = ANIMATION_LARA_WADE;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_WADE_FORWARD;
item->currentAnimState = STATE_LARA_WADE_FORWARD;
item->animNumber = LA_WADE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_WADE_FORWARD;
item->currentAnimState = LS_WADE_FORWARD;
}
}
else
{
item->animNumber = ANIMATION_LARA_ONWATER_TO_WADE_DEEP;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_ONWATER_EXIT;
item->goalAnimState = STATE_LARA_STOP;
item->animNumber = LA_ONWATER_TO_WADE_1CLICK;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = LS_ONWATER_EXIT;
item->goalAnimState = LS_STOP;
}
item->pos.yPos += coll->frontFloor + 695;
@ -493,3 +494,65 @@ int LaraTestWaterStepOut(ITEM_INFO* item, COLL_INFO* coll)//4D100, 4D564 (F)
return 1;
}
int LaraTestLadderClimbOut(ITEM_INFO* item, COLL_INFO* coll) // NEW function for water to ladder move
{
if (!Lara.climbStatus || coll->collType != CT_FRONT || !(TrInput & IN_ACTION))
return 0;
if (Lara.gunStatus && (Lara.gunStatus != LG_READY || Lara.gunType != WEAPON_FLARE))
return 0;
if (!LaraTestClimbStance(item, coll))
return 0;
short rot = item->pos.yRot;
if (rot >= -ANGLE(35.0f) && rot <= ANGLE(35.0f))
rot = 0;
else if (rot >= ANGLE(55.0f) && rot <= ANGLE(125.0f))
rot = ANGLE(90.0f);
else if (rot >= ANGLE(145.0f) || rot <= -ANGLE(145.0f))
rot = ANGLE(180.0f);
else if (rot >= -ANGLE(125.0f) && rot <= -ANGLE(55.0f))
rot = -ANGLE(90.0f);
if (rot & 0x3FFF)
return 0;
switch ((unsigned short)rot / ANGLE(90.0f))
{
case NORTH:
item->pos.zPos = (item->pos.zPos | (WALL_SIZE - 1)) - LARA_RAD - 1;
break;
case EAST:
item->pos.xPos = (item->pos.xPos | (WALL_SIZE - 1)) - LARA_RAD - 1;
break;
case SOUTH:
item->pos.zPos = (item->pos.zPos & -WALL_SIZE) + LARA_RAD + 1;
break;
case WEST:
item->pos.xPos = (item->pos.xPos & -WALL_SIZE) + LARA_RAD + 1;
break;
}
item->animNumber = LA_ONWATER_IDLE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = LS_ONWATER_STOP;
item->goalAnimState = LS_LADDER_IDLE;
AnimateLara(item);
item->pos.yRot = rot;
Lara.gunStatus = LG_HANDS_BUSY;
item->pos.zRot = 0;
item->pos.xRot = 0;
item->gravityStatus = false;
item->speed = 0;
item->fallspeed = 0;
Lara.waterStatus = LW_ABOVE_WATER;
return 1;
}

View file

@ -16,4 +16,5 @@ void _cdecl lara_as_surfswim(ITEM_INFO* item, COLL_INFO* coll);
void _cdecl LaraSurface(ITEM_INFO* item, COLL_INFO* coll);
void _cdecl LaraSurfaceCollision(ITEM_INFO* item, COLL_INFO* coll);
int _cdecl LaraTestWaterClimbOut(ITEM_INFO* item, COLL_INFO* coll);
int _cdecl LaraTestWaterStepOut(ITEM_INFO* item, COLL_INFO* coll);
int _cdecl LaraTestWaterStepOut(ITEM_INFO* item, COLL_INFO* coll);
int _cdecl LaraTestLadderClimbOut(ITEM_INFO* item, COLL_INFO* coll); // NEW function for water to ladder move

View file

@ -32,7 +32,7 @@ void LaraWaterCurrent(COLL_INFO* coll) // (F) (D)
{
if (Lara.currentActive)
{
OBJECT_VECTOR* sink = &Camera.fixed[Lara.currentActive - 1];
OBJECT_VECTOR* sink = &FixedCameras[Lara.currentActive - 1];
short angle = mGetAngle(sink->x, sink->z, LaraItem->pos.xPos, LaraItem->pos.zPos);
Lara.currentXvel += ((sink->data * (phd_sin(angle - ANGLE(90)) / 4) >> 2) - Lara.currentXvel) >> 4;
@ -113,7 +113,7 @@ void LaraWaterCurrent(COLL_INFO* coll) // (F) (D)
int GetWaterDepth(int x, int y, int z, short roomNumber)//4CA38, 4CE9C
{
FLOOR_INFO* floor;
ROOM_INFO* r = &Rooms[roomNumber];
ROOM_INFO* r = &g_Level.Rooms[roomNumber];
short roomIndex = NO_ROOM;
do
@ -147,7 +147,7 @@ int GetWaterDepth(int x, int y, int z, short roomNumber)//4CA38, 4CE9C
if (roomIndex != NO_ROOM)
{
roomNumber = roomIndex;
r = &Rooms[roomIndex];
r = &g_Level.Rooms[roomIndex];
}
} while (roomIndex != NO_ROOM);
@ -155,7 +155,7 @@ int GetWaterDepth(int x, int y, int z, short roomNumber)//4CA38, 4CE9C
{
while (floor->skyRoom != NO_ROOM)
{
r = &Rooms[floor->skyRoom];
r = &g_Level.Rooms[floor->skyRoom];
if (!(r->flags & (ENV_FLAG_WATER|ENV_FLAG_SWAMP)))
{
int wh = floor->ceiling << 8;
@ -170,7 +170,7 @@ int GetWaterDepth(int x, int y, int z, short roomNumber)//4CA38, 4CE9C
{
while (floor->pitRoom != NO_ROOM)
{
r = &Rooms[floor->pitRoom];
r = &g_Level.Rooms[floor->pitRoom];
if (r->flags & (ENV_FLAG_WATER|ENV_FLAG_SWAMP))
{
int wh = floor->floor << 8;
@ -260,15 +260,15 @@ void lara_as_tread(ITEM_INFO* item, COLL_INFO* coll)//4C730, 4CB94 (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_WATER_DEATH;
item->goalAnimState = LS_WATER_DEATH;
return;
}
if (TrInput & IN_ROLL && LaraDrawType != LARA_DIVESUIT)
{
item->currentAnimState = STATE_LARA_UNDERWATER_TURNAROUND;
item->animNumber = ANIMATION_LARA_UNDERWATER_ROLL_BEGIN;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = LS_UNDERWATER_ROLL;
item->animNumber = LA_UNDERWATER_ROLL_180_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
}
else
{
@ -281,7 +281,7 @@ void lara_as_tread(ITEM_INFO* item, COLL_INFO* coll)//4C730, 4CB94 (F)
SwimTurn(item);
if (TrInput & IN_JUMP)
item->goalAnimState = STATE_LARA_UNDERWATER_FORWARD;
item->goalAnimState = LS_UNDERWATER_FORWARD;
item->fallspeed -= 6;
@ -297,7 +297,7 @@ void lara_as_glide(ITEM_INFO* item, COLL_INFO* coll)//4C634(<), 4CA98(<) (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_WATER_DEATH;
item->goalAnimState = LS_WATER_DEATH;
return;
}
@ -305,9 +305,9 @@ void lara_as_glide(ITEM_INFO* item, COLL_INFO* coll)//4C634(<), 4CA98(<) (F)
{
if (LaraDrawType != LARA_DIVESUIT)
{
item->currentAnimState = STATE_LARA_UNDERWATER_TURNAROUND;
item->animNumber = ANIMATION_LARA_UNDERWATER_ROLL_BEGIN;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = LS_UNDERWATER_ROLL;
item->animNumber = LA_UNDERWATER_ROLL_180_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
return;
}
}
@ -321,21 +321,21 @@ void lara_as_glide(ITEM_INFO* item, COLL_INFO* coll)//4C634(<), 4CA98(<) (F)
}
if (TrInput & IN_JUMP)
item->goalAnimState = STATE_LARA_UNDERWATER_FORWARD;
item->goalAnimState = LS_UNDERWATER_FORWARD;
item->fallspeed -= 6;
if (item->fallspeed < 0)
item->fallspeed = 0;
if (item->fallspeed <= 133)
item->goalAnimState = STATE_LARA_UNDERWATER_STOP;
item->goalAnimState = LS_UNDERWATER_STOP;
}
void lara_as_swim(ITEM_INFO* item, COLL_INFO* coll)//4C548(<), 4C9AC(<) (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_WATER_DEATH;
item->goalAnimState = LS_WATER_DEATH;
return;
}
@ -343,9 +343,9 @@ void lara_as_swim(ITEM_INFO* item, COLL_INFO* coll)//4C548(<), 4C9AC(<) (F)
{
if (LaraDrawType != LARA_DIVESUIT)
{
item->currentAnimState = STATE_LARA_UNDERWATER_TURNAROUND;
item->animNumber = ANIMATION_LARA_UNDERWATER_ROLL_BEGIN;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = LS_UNDERWATER_ROLL;
item->animNumber = LA_UNDERWATER_ROLL_180_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
return;
}
}
@ -364,7 +364,7 @@ void lara_as_swim(ITEM_INFO* item, COLL_INFO* coll)//4C548(<), 4C9AC(<) (F)
item->fallspeed = 200;
if (!(TrInput & IN_JUMP))
item->goalAnimState = STATE_LARA_UNDERWATER_INERTIA;
item->goalAnimState = LS_UNDERWATER_INERTIA;
}
void lara_as_swimcheat(ITEM_INFO* item, COLL_INFO* coll)//4C3A8, 4C80C (F)
@ -806,7 +806,6 @@ void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll)//4B608, 4BA6C
&& oldZ == item->pos.zPos
&& oldXrot == item->pos.xRot
&& oldYrot == item->pos.yRot
/*|| (LOBYTE(v21) = byte_51CEE4) != 0*/
|| flag != 1)
{
if (flag == 2)
@ -819,8 +818,6 @@ void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll)//4B608, 4BA6C
SoundEffect(SFX_SWIMSUIT_METAL_CLASH, &LaraItem->pos, ((2 * GetRandomControl() + 0x8000) << 8) | 6);
}
// CHECK related to cutscene?
//byte_51CEE4 = 30;
if (Lara.anxiety < 96)
{
Lara.anxiety += 16;
@ -846,15 +843,15 @@ void LaraTestWaterDepth(ITEM_INFO* item, COLL_INFO* coll)//4B4F8(<), 4B95C(<) (F
}
else if (wd <= 512)
{
item->animNumber = ANIMATION_LARA_UNDERWATER_TO_WADE;
item->currentAnimState = STATE_LARA_ONWATER_EXIT;
item->goalAnimState = STATE_LARA_STOP;
item->animNumber = LA_UNDERWATER_TO_STAND;
item->currentAnimState = LS_ONWATER_EXIT;
item->goalAnimState = LS_STOP;
item->pos.zRot = 0;
item->pos.xRot = 0;
item->speed = 0;
item->fallspeed = 0;
item->gravityStatus = false;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
Lara.waterStatus = LW_WADE;
item->pos.yPos = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
}

View file

@ -10,18 +10,29 @@
#define DEFAULT_SWIM_UPDOWN_SPEED 32
int SlotsUsed;
CREATURE_INFO* BaddieSlots;
std::vector<CREATURE_INFO> BaddieSlots;
void InitialiseLOTarray(int allocMem)
{
if (allocMem)
BaddieSlots = (CREATURE_INFO*)game_malloc(sizeof(CREATURE_INFO) * NUM_SLOTS);
{
BaddieSlots.clear();
BaddieSlots.resize(NUM_SLOTS);
}
CREATURE_INFO* creature = BaddieSlots;
CREATURE_INFO* creature = BaddieSlots.data();
for (int i = 0; i < NUM_SLOTS; i++, creature++)
{
creature->itemNum = NO_ITEM;
creature->LOT.node = (BOX_NODE*)game_malloc(sizeof(BOX_NODE) * NumberBoxes);
if (allocMem)
{
creature->LOT.node.clear();
creature->LOT.node.resize(g_Level.Boxes.size());
for (int j = 0; j < g_Level.Boxes.size(); j++)
{
creature->LOT.node.emplace_back(BOX_NODE());
}
}
}
SlotsUsed = 0;
@ -29,7 +40,7 @@ void InitialiseLOTarray(int allocMem)
int EnableBaddieAI(short itemNum, int always)
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
if (item->data != NULL)
return true;
@ -46,10 +57,10 @@ int EnableBaddieAI(short itemNum, int always)
}
int slotToDisable = -1;
CREATURE_INFO* creature = BaddieSlots;
CREATURE_INFO* creature = BaddieSlots.data();
for (int slot = 0; slot < NUM_SLOTS; slot++, creature++)
{
item = &Items[creature->itemNum];
item = &g_Level.Items[creature->itemNum];
int deltaX = (item->pos.xPos - Camera.pos.x) >> 8;
int deltaY = (item->pos.yPos - Camera.pos.y) >> 8;
@ -66,7 +77,7 @@ int EnableBaddieAI(short itemNum, int always)
if (slotToDisable < 0 || slotToDisable > NUM_SLOTS)
return false;
ITEM_INFO* itemToDisable = &Items[BaddieSlots[slotToDisable].itemNum];
ITEM_INFO* itemToDisable = &g_Level.Items[BaddieSlots[slotToDisable].itemNum];
CREATURE_INFO* creatureToDisable = &BaddieSlots[slotToDisable];
itemToDisable->status = ITEM_INVISIBLE;
@ -76,7 +87,7 @@ int EnableBaddieAI(short itemNum, int always)
}
else
{
CREATURE_INFO* creature = BaddieSlots;
CREATURE_INFO* creature = BaddieSlots.data();
for (int slot = 0; slot < NUM_SLOTS; slot++, creature++)
{
if (creature->itemNum == NO_ITEM)
@ -92,7 +103,7 @@ int EnableBaddieAI(short itemNum, int always)
void DisableBaddieAI(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
item->data = NULL;
@ -105,8 +116,8 @@ void DisableBaddieAI(short itemNumber)
void InitialiseSlot(short itemNum, short slot)
{
ITEM_INFO* item = &Items[itemNum];
ObjectInfo* obj = &Objects[item->objectNumber];
ITEM_INFO* item = &g_Level.Items[itemNum];
OBJECT_INFO* obj = &Objects[item->objectNumber];
CREATURE_INFO* creature = &BaddieSlots[slot];
item->data = creature;
@ -261,8 +272,8 @@ void ClearLOT(LOT_INFO* LOT)
LOT->targetBox = NO_BOX;
LOT->requiredBox = NO_BOX;
BOX_NODE* node = LOT->node;
for (int i = 0; i < NumberBoxes; i++)
BOX_NODE* node = LOT->node.data();
for (int i = 0; i < g_Level.Boxes.size(); i++)
{
node->exitBox = NO_BOX;
node->nextExpansion = NO_BOX;
@ -274,16 +285,16 @@ void ClearLOT(LOT_INFO* LOT)
void CreateZone(ITEM_INFO* item)
{
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
ROOM_INFO* r = &Rooms[item->roomNumber];
ROOM_INFO* r = &g_Level.Rooms[item->roomNumber];
item->boxNumber = XZ_GET_SECTOR(r, item->pos.xPos - r->x, item->pos.zPos - r->z).box;
if (creature->LOT.fly)
{
BOX_NODE* node = creature->LOT.node;
BOX_NODE* node = creature->LOT.node.data();
creature->LOT.zoneCount = 0;
for (int i = 0; i < NumberBoxes; i++)
for (int i = 0; i < g_Level.Boxes.size(); i++)
{
node->boxNumber = i;
node++;
@ -292,16 +303,16 @@ void CreateZone(ITEM_INFO* item)
}
else
{
short* zone = Zones[creature->LOT.zone][FALSE];
short* flippedZone = Zones[creature->LOT.zone][TRUE];
int* zone = g_Level.Zones[creature->LOT.zone][0].data();
int* flippedZone = g_Level.Zones[creature->LOT.zone][1].data();
short zoneNumber = zone[item->boxNumber];
short flippedZoneNumber = flippedZone[item->boxNumber];
int zoneNumber = zone[item->boxNumber];
int flippedZoneNumber = flippedZone[item->boxNumber];
BOX_NODE* node = creature->LOT.node;
BOX_NODE* node = creature->LOT.node.data();
creature->LOT.zoneCount = 0;
for (int i = 0; i < NumberBoxes; i++)
for (int i = 0; i < g_Level.Boxes.size(); i++)
{
if (*zone == zoneNumber || *flippedZone == flippedZoneNumber)
{

View file

@ -3,7 +3,7 @@
constexpr auto NUM_SLOTS = 32;
extern int SlotsUsed;
extern CREATURE_INFO* BaddieSlots;
extern std::vector<CREATURE_INFO> BaddieSlots;
void InitialiseLOTarray(int allocMem);
int EnableBaddieAI(short itemNum, int always);

View file

@ -1,43 +0,0 @@
#include "framework.h"
#include "malloc.h"
char* malloc_buffer;
int malloc_size;
char* malloc_ptr;
int malloc_free;
int malloc_used;
char* game_malloc(int size)
{
char* ptr;
size = (size + 3) & 0xfffffffc;
if (size <= malloc_free)
{
ptr = malloc_ptr;
malloc_free -= size;
malloc_used += size;
malloc_ptr += size;
return ptr;
}
return 0;
}
void init_game_malloc()
{
malloc_size = 1048576 * 128;
malloc_buffer = (char*)malloc(malloc_size);
malloc_ptr = malloc_buffer;
malloc_free = malloc_size;
malloc_used = 0;
}
void game_free(int size, int type)
{
size = (size + 3) & (~3);
malloc_ptr -= size;
malloc_free += size;
malloc_used -= size;
}

View file

@ -1,11 +0,0 @@
#pragma once
extern char* malloc_buffer;
extern int malloc_size;
extern char* malloc_ptr;
extern int malloc_free;
extern int malloc_used;
char* game_malloc(int size);
void init_game_malloc();
void game_free(int size, int type);

View file

@ -0,0 +1,48 @@
#pragma once
#include <cstdint>
#include <iterator>
#include <vector>
#include <iostream>
#include "pool.h"
#include <limits>
namespace T5M::Memory {
template <typename T,typename Pool>
class PoolAllocator {
public:
Pool* pool;
typedef std::size_t size_type;
typedef T* pointer;
typedef T value_type;
PoolAllocator(Pool* pool) : pool(pool) {}
PoolAllocator(const PoolAllocator& other) throw() : pool(other.pool) {};
template<typename U>
PoolAllocator(const PoolAllocator<U,Pool>& other) throw() : pool(other.pool) {};
template<typename U>
PoolAllocator& operator = (const PoolAllocator<U,Pool>& other) {
return *this;
}
PoolAllocator<T,Pool>& operator = (const PoolAllocator& other) {
return *this;
}
~PoolAllocator() {}
pointer allocate(size_type n, const void* hint = 0) {
return (pool)->malloc<value_type>(n);
}
void deallocate(T* ptr, size_type n) {
(pool)->free(ptr);
}
size_type max_size() const {
#pragma push_macro("max") //thanks Microsoft
#undef max
return std::numeric_limits<size_type>::max();
#pragma pop_macro("max")
}
};
}

View file

@ -0,0 +1,43 @@
#pragma once
#include <memory>
#include "Game/debug/assert.h"
#include "Game/debug/log.h"
namespace T5M::Memory {
enum class MemoryUnit : size_t {
Byte = 1,
KByte = Byte*1024,
MByte = KByte*1024,
GByte = MByte*1024,
};
class LinearPool {
private:
const size_t allocatedBytes;
const std::unique_ptr<uint8_t> bytes;
size_t offset;
public:
LinearPool(size_t amount, MemoryUnit unit) : allocatedBytes(amount* static_cast<size_t>(unit)), bytes(new uint8_t[allocatedBytes]) {
offset = 0;
}
template<typename T>
[[nodiscard]]T* malloc(size_t count = 1) noexcept {
assertm(sizeof(T) * count >= 1, "Requested memory needs to be greater than 0!");
size_t requestedBytes = sizeof(T) * count;
Log("LinearPool - Malloc :" << requestedBytes << " Bytes")
assertm(offset + requestedBytes > allocatedBytes, "Memory must not overflow linear pool!");
T* returnValue = reinterpret_cast<T*>(bytes.get()[offset]);
offset += requestedBytes;
Log("LinearPool - Malloc : New Offset at " << offset)
return returnValue;
}
void flush() noexcept {
std::memset(bytes.get(), 0, allocatedBytes);
offset = 0;
}
public:
size_t size() const {
return allocatedBytes;
}
};
}

View file

@ -0,0 +1,41 @@
#pragma once
#include <cstdint>
#include <iterator>
#include <vector>
#include <iostream>
#include "linearPool.h"
template <typename T>
class LinearPoolAllocator {
private:
LinearPool* pool;
public:
typedef std::size_t size_type;
typedef T* pointer;
typedef T value_type;
LinearPoolAllocator(LinearPool* pool) : pool(pool){}
LinearPoolAllocator(const LinearPoolAllocator& other) throw() : pool(other.pool) {};
template<typename U>
LinearPoolAllocator(const LinearPoolAllocator<U>& other) throw() : pool(other.pool) {};
template<typename U>
LinearPoolAllocator& operator = (const LinearPoolAllocator<U>& other) {
return *this;
}
LinearPoolAllocator<T>& operator = (const LinearPoolAllocator& other) {
return *this;
}
~LinearPoolAllocator() {}
pointer allocate(size_type n, const void* hint = 0) {
return pool->malloc<value_type>(n);
}
void deallocate(T* ptr, size_type n) {}
size_type max_size() const {
return pool->size();
}
};

View file

@ -0,0 +1,20 @@
#include "framework.h"
#include "malloc.h"
#include "door.h"
#include "PoolAllocator.h"
using namespace T5M::Memory;
char* malloc_buffer;
int malloc_size;
char* malloc_ptr;
int malloc_free;
int malloc_used;
TGPool* gameMemory;
void init_game_malloc() noexcept
{
gameMemory = new TGPool(8 * 1024 * 1024);
}
void game_free(void* ptr) noexcept
{
gameMemory->free(ptr);
}

View file

@ -0,0 +1,17 @@
#pragma once
#include "pool.h"
#include <utility>
#include "memory/memory.h"
extern char* malloc_buffer;
extern int malloc_size;
extern char* malloc_ptr;
extern int malloc_free;
extern int malloc_used;
extern T5M::Memory::TGPool* gameMemory;
template <typename T,typename ... Args>
[[nodiscard]] T* game_malloc(size_t count = 1,Args&&...args) noexcept {
return gameMemory->malloc<T>(count,std::forward<Args>(args)...);
}
void init_game_malloc() noexcept;
void game_free(void* ptr) noexcept;

View file

@ -0,0 +1,8 @@
#pragma once
#include "pool.h"
#include "PoolAllocator.h"
#include <vector>
namespace T5M::Memory {
using TGPool = Pool<BlockSize::Medium>;
template<typename T> using vector = std::vector <T, PoolAllocator<T, TGPool>>;
}

202
TR5Main/Game/memory/pool.h Normal file
View file

@ -0,0 +1,202 @@
#pragma once
#include <stdint.h>
#include <memory>
#include <iostream>
#include "../debug/debug.h"
#include <type_traits>
namespace T5M::Memory {
//Block Size suggestions
enum class BlockSize : size_t {
Minimal = 4,
Tiny = 8,
Small = 16,
Medium = 32,
Big = 64,
Huge = 128,
};
//A multi purpose Memory pool
template<BlockSize BlkSz>
class Pool {
static constexpr char MAGIC[] = "Everything's okay";
using Size = size_t;
using Byte = uint8_t;
using Magic = uint32_t;
//Block representation
struct Block {
Byte data[static_cast<Size>(BlkSz)];
};
// Block Header Data. Contains either Data about Free Blocks in the case of Free
// Or Number of Blocks that were allocated in the case of Used
union BlockHeader;
struct BlockHeaderData {
const char* magic;
//pointer to the next BlockHeader, nullptr if tail
BlockHeader* nextFreeBlock;
//pointer to the previous BlockHeader, nullptr if head
BlockHeader* previousFreeBlock;
//number of Free Blocks / Used Blocks
Size managedBlocks;
//whether this Header is Free or Used
bool isFree;
//pointer to the next physical block header
BlockHeader* nextPhysicalBlock;
//pointer to the previous physical block header
BlockHeader* previousPhysicalBlock;
//pointer to first physical block header
BlockHeaderData() : magic(MAGIC), nextFreeBlock(nullptr), previousFreeBlock(nullptr), managedBlocks(0), nextPhysicalBlock(nullptr), previousPhysicalBlock(nullptr), isFree(false) {}
BlockHeaderData(BlockHeaderData&&) = default;
BlockHeaderData(const BlockHeaderData&) = default;
};
union BlockHeader {
BlockHeaderData data;
//Padding to ensure BlockHeader is always the next multiple of BlkSz blocks large
Block padding[getBlockCount(sizeof(BlockHeaderData))];
BlockHeader() : data(BlockHeaderData()) {};
BlockHeader(BlockHeader&&) = default;
BlockHeader(const BlockHeader&) = default;
};
private:
Size allocatedBlockCount;
Size allocatedBytesCount;
const std::unique_ptr<Block> allocatedBlocks;
BlockHeader* head;
BlockHeader* firstPhysicalBlock;
void initialize() {
std::memset(allocatedBlocks.get(), 0, allocatedBytesCount);
// Place initial BlockHeader at the beginning of all blocks
head = new(allocatedBlocks.get())BlockHeader();
head->data.nextFreeBlock = nullptr;
head->data.managedBlocks = allocatedBlockCount - getHeaderBlockCount();
head->data.previousFreeBlock = nullptr;
head->data.nextPhysicalBlock = nullptr;
head->data.previousPhysicalBlock = nullptr;
this->firstPhysicalBlock = head;
}
public:
Pool(Size numBlocks) : allocatedBlockCount(numBlocks), allocatedBytesCount(sizeof(Block)* numBlocks) , allocatedBlocks(new Block[numBlocks]) {
initialize();
logD("Pool Init: Initialized Pool with ", numBlocks ," Blocks");
logD("Pool Init: Free Blocks :" , head->data.managedBlocks);
}
Pool(Pool&&) = delete;
Pool(const Pool&) = delete;
~Pool() = default;
private:
static constexpr Size getBlockCount(Size bytes) {
return (bytes + (static_cast<Size>(BlkSz) - 1)) / static_cast<Size>(BlkSz);
}
constexpr Size getHeaderBlockCount() const {
return getBlockCount(sizeof(BlockHeader));
};
BlockHeader*& getFreeListHead() {
return head;
}
void tryCoalesce(BlockHeader* origin) {
BlockHeader* left = origin->data.previousPhysicalBlock;
BlockHeader* right = origin->data.nextPhysicalBlock;
if (right != nullptr && right->data.isFree)
coalesce(origin, right);
if (left != nullptr && left->data.isFree)
coalesce(left, origin);
}
void coalesce(BlockHeader* left, BlockHeader* right) {
logD("Coalescing BlockHeader at " , left , " & " , right);
left->data.managedBlocks += right->data.managedBlocks;
left->data.managedBlocks += getHeaderBlockCount();
left->data.nextFreeBlock = right->data.nextFreeBlock;
left->data.nextPhysicalBlock = right->data.nextPhysicalBlock;
if (right->data.nextFreeBlock != nullptr) {
right->data.nextFreeBlock->data.previousFreeBlock = left;
right->data.nextPhysicalBlock->data.previousPhysicalBlock = left;
}
}
void splitBlocks(BlockHeader*& nodeToSplit, size_t& requestedBlocks, Block* whereToSplit) {
Size numFreeBlocksAfterSplit = nodeToSplit->data.managedBlocks - getHeaderBlockCount();
nodeToSplit->data.managedBlocks = requestedBlocks;
nodeToSplit->data.isFree = false;
Block* splitBlock = whereToSplit;
placeNewFreeHead(splitBlock, nodeToSplit, numFreeBlocksAfterSplit);
logD("Malloc: New Free Blocks : ", numFreeBlocksAfterSplit);
}
void placeNewFreeHead(Block*& position, BlockHeader*& oldFreeBlock, size_t& numManagedBlocks) {
BlockHeader* newHead = new(position)BlockHeader();
logD("Malloc: New Head at ", newHead);
newHead->data.previousPhysicalBlock = oldFreeBlock;
BlockHeader* physicalRightBlock = oldFreeBlock->data.nextPhysicalBlock;
newHead->data.nextPhysicalBlock = physicalRightBlock;
if (physicalRightBlock != nullptr)
physicalRightBlock->data.previousPhysicalBlock = newHead;
oldFreeBlock->data.nextPhysicalBlock = newHead;
newHead->data.isFree = true;
head = newHead;
head->data.nextFreeBlock = oldFreeBlock->data.nextFreeBlock;
head->data.managedBlocks = numManagedBlocks;
}
Block* getFirstManagedBlock(BlockHeader* header) const {
return reinterpret_cast<Block*>(header + 1);
}
BlockHeader* getBlockHeaderFromBlock(Block* block) const {
return (reinterpret_cast<BlockHeader*>(block)) - 1;
}
public:
template <typename T>
void free(T* ptr) noexcept {
assertion((static_cast<void*>(ptr) >= allocatedBlocks.get() && static_cast<void*>(ptr) < (allocatedBlocks.get() + allocatedBlockCount)), "memory must be in Pool range!");
ptr->~T();
Block* block = reinterpret_cast<Block*>(ptr);
BlockHeader* blockHead = getBlockHeaderFromBlock(block);
if (blockHead->data.magic == MAGIC) {
logD("Free: BlockHeader at ", blockHead);
BlockHeader* oldHead = head;
BlockHeader* newHead = blockHead;
head = newHead;
head->data.isFree = true;
head->data.nextFreeBlock = oldHead;
oldHead->data.previousFreeBlock = head;
tryCoalesce(blockHead);
tryCoalesce(oldHead);
}
}
template <typename T,typename ... Args>
[[nodiscard]]T* malloc(Size count = 1,Args&&...args) noexcept {
if (count < 1) return nullptr;
Size requestedBlocks = getBlockCount(sizeof(T) * count);
logD("Malloc: Requested Blocks for " , typeid(T).name() , " x " , count , ": " , requestedBlocks);
BlockHeader* currentFreeNode = getFreeListHead();
while (currentFreeNode != nullptr && currentFreeNode->data.isFree && currentFreeNode->data.managedBlocks < requestedBlocks+getHeaderBlockCount()) {
assertion(currentFreeNode->data.magic == MAGIC, "Pool is corrupt");
currentFreeNode = currentFreeNode->data.nextFreeBlock;
}
assertion(currentFreeNode != nullptr, "Pool is full");
Block* blockToReturn = getFirstManagedBlock(currentFreeNode);
logD("Malloc: Return block at " , blockToReturn);
splitBlocks(currentFreeNode, requestedBlocks, blockToReturn + requestedBlocks + 1);
return new(blockToReturn)T(std::forward<Args>(args)...);
}
void reset() {
initialize();
}
};
}

View file

@ -7,12 +7,12 @@
using std::vector;
short GF(short animIndex, short frameToStart)
{
return Anims[animIndex].frameBase + frameToStart;
return g_Level.Anims[animIndex].frameBase + frameToStart;
}
short GF2(short objectID, short animIndex, short frameToStart)
{
return Anims[Objects[objectID].animIndex + animIndex].frameBase + frameToStart;
return g_Level.Anims[Objects[objectID].animIndex + animIndex].frameBase + frameToStart;
}
CREATURE_INFO* GetCreatureInfo(ITEM_INFO* item)
@ -28,9 +28,9 @@ void TargetNearestEntity(ITEM_INFO* item, CREATURE_INFO* creature)
int x, z;
bestdistance = MAXINT;
for (int i = 0; i < LevelItems; i++)
for (int i = 0; i < g_Level.NumItems; i++)
{
target = &Items[i];
target = &g_Level.Items[i];
if (target != nullptr)
{
if (target != item && target->hitPoints > 0 && target->status != ITEM_INVISIBLE)
@ -50,12 +50,14 @@ void TargetNearestEntity(ITEM_INFO* item, CREATURE_INFO* creature)
void GetRoomList(short roomNumber, short* roomArray, short* numRooms)
{
if (*numRooms <= 0)
return;
short numDoors, * door, adjoiningRoom;
int i, j;
bool adjoiningRoomFound;
roomArray[0] = roomNumber;
ROOM_INFO* room = &Rooms[roomNumber];
ROOM_INFO* room = &g_Level.Rooms[roomNumber];
for (i = 0; i < room->doors.size(); i++)
{
@ -84,7 +86,7 @@ void GetRoomList(short roomNumber, vector<short>* destRoomList)
bool adjoiningRoomFound;
roomList.push_back(roomNumber);
ROOM_INFO* room = &Rooms[roomNumber];
ROOM_INFO* room = &g_Level.Rooms[roomNumber];
for (i = 0; i < room->doors.size(); i++)
{

View file

@ -20,14 +20,14 @@
void ShootAtLara(FX_INFO *fx)
{
int x, y, z, distance;
short* bounds;
BOUNDING_BOX* bounds;
x = LaraItem->pos.xPos - fx->pos.xPos;
y = LaraItem->pos.yPos - fx->pos.yPos;
z = LaraItem->pos.zPos - fx->pos.zPos;
bounds = GetBoundsAccurate(LaraItem);
y += bounds[3] + (bounds[2] - bounds[3]) * 3 / 4;
y += bounds->Y2 + (bounds->Y1 - bounds->Y2) * 3 / 4;
distance = sqrt(SQUARE(x) + SQUARE(z));
fx->pos.xRot = -phd_atan(distance, y);
@ -45,10 +45,10 @@ void ControlMissile(short fxNumber)
short roomNumber;
int speed;
fx = &Effects[fxNumber];
fx = &EffectList[fxNumber];
printf("ControlMissile\n");
if (fx->objectNumber == ID_SCUBA_HARPOON && !(Rooms[fx->roomNumber].flags & 1) && fx->pos.xRot > -0x3000)
if (fx->objectNumber == ID_SCUBA_HARPOON && !(g_Level.Rooms[fx->roomNumber].flags & 1) && fx->pos.xRot > -0x3000)
fx->pos.xRot -= ONE_DEGREE;
fx->pos.yPos += (fx->speed * phd_sin(-fx->pos.xRot) >> W2V_SHIFT);
@ -115,7 +115,7 @@ void ControlMissile(short fxNumber)
}
/* Create bubbles in wake of harpoon bolt */
//if (fx->objectNumber == ID_SCUBA_HARPOON && Rooms[fx->roomNumber].flags & 1)
//if (fx->objectNumber == ID_SCUBA_HARPOON && g_Level.Rooms[fx->roomNumber].flags & 1)
// CreateBubble(&fx->pos, fx->roomNumber, 1, 0);
/*else if (fx->objectNumber == DRAGON_FIRE && !fx->counter--)
{
@ -130,12 +130,12 @@ void ControlMissile(short fxNumber)
void ControlNatlaGun(short fx_number)
{
FX_INFO* fx, *newfx;
ObjectInfo* object;
OBJECT_INFO* object;
FLOOR_INFO* floor;
short roomNumber;
int x, y, z;
fx = &Effects[fx_number];
fx = &EffectList[fx_number];
object = &Objects[fx->objectNumber];
fx->frameNumber--;
if (fx->frameNumber <= Objects[fx->objectNumber].nmeshes)
@ -157,7 +157,7 @@ void ControlNatlaGun(short fx_number)
fx_number = CreateNewEffect(roomNumber);
if (fx_number != NO_ITEM)
{
newfx = &Effects[fx_number];
newfx = &EffectList[fx_number];
newfx->pos.xPos = x;
newfx->pos.yPos = y;
newfx->pos.zPos = z;
@ -178,7 +178,7 @@ short ShardGun(int x, int y, int z, short speed, short yrot, short roomNumber)
fx_number = CreateNewEffect(roomNumber);
if (fx_number != NO_ITEM)
{
fx = &Effects[fx_number];
fx = &EffectList[fx_number];
fx->pos.xPos = x;
fx->pos.yPos = y;
fx->pos.zPos = z;
@ -203,7 +203,7 @@ short BombGun(int x, int y, int z, short speed, short yrot, short roomNumber)
fx_number = CreateNewEffect(roomNumber);
if (fx_number != NO_ITEM)
{
fx = &Effects[fx_number];
fx = &EffectList[fx_number];
fx->pos.xPos = x;
fx->pos.yPos = y;
fx->pos.zPos = z;
@ -228,7 +228,7 @@ short NatlaGun(int x, int y, int z, short speed, short yrot, short roomNumber)
fx_number = CreateNewEffect(roomNumber);
if (fx_number != NO_ITEM)
{
fx = &Effects[fx_number];
fx = &EffectList[fx_number];
fx->pos.xPos = x;
fx->pos.yPos = y;
fx->pos.zPos = z;

View file

@ -19,30 +19,26 @@
OBJECT_TEXTURE* WaterfallTextures[6];
float WaterfallY[6];
int lastWaterfallY = 0;
short TightRopeBounds[12] =
OBJECT_COLLISION_BOUNDS TightRopeBounds =
{
0xFF00, 0x0100, 0x0000, 0x0000, 0xFF00, 0x0100, 0xF8E4, 0x071C, 0xEAAC, 0x1554,
0xF8E4, 0x071C
};
PHD_VECTOR TightRopePos = { 0, 0, 0 };
short ParallelBarsBounds[12] =
OBJECT_COLLISION_BOUNDS ParallelBarsBounds =
{
0xFD80, 0x0280, 0x02C0, 0x0340, 0xFFA0, 0x0060, 0xF8E4, 0x071C, 0xEAAC, 0x1554, 0xF8E4, 0x071C
};
PHD_VECTOR PolePos = { 0, 0, -208 };
PHD_VECTOR PolePosR = { 0, 0, 0 };
short PoleBounds[12] = // offset 0xA1250
OBJECT_COLLISION_BOUNDS PoleBounds = // offset 0xA1250
{
0xFF00, 0x0100, 0x0000, 0x0000, 0xFE00, 0x0200, 0xF8E4, 0x071C, 0xEAAC, 0x1554,
0xF8E4, 0x071C
};
void BridgeFlatFloor(ITEM_INFO* item, int x, int y, int z, int* height)
{
if (item->pos.yPos >= y)
@ -128,7 +124,7 @@ void BridgeTilt2Ceiling(ITEM_INFO* item, int x, int y, int z, int* height)
void ControlAnimatingSlots(short itemNumber)
{
// TODO: TR5 has here a series of hardcoded OCB codes, this function actually is just a placeholder
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (TriggerActive(item))
AnimateItem(item);
@ -136,21 +132,21 @@ void ControlAnimatingSlots(short itemNumber)
void PoleCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if ((TrInput & IN_ACTION) && !Lara.gunStatus && l->currentAnimState == STATE_LARA_STOP &&
l->animNumber == ANIMATION_LARA_STAY_IDLE
if ((TrInput & IN_ACTION) && !Lara.gunStatus && l->currentAnimState == LS_STOP &&
l->animNumber == LA_STAND_IDLE
|| Lara.isMoving && Lara.generalPtr == (void*)itemNumber)
{
short rot = item->pos.yRot;
item->pos.yRot = l->pos.yRot;
if (TestLaraPosition(PoleBounds, item, l))
if (TestLaraPosition(&PoleBounds, item, l))
{
if (MoveLaraPosition(&PolePos, item, l))
{
l->animNumber = ANIMATION_LARA_STAY_TO_POLE_GRAB;
l->currentAnimState = STATE_LARA_POLE_IDLE;
l->frameNumber = Anims[l->animNumber].frameBase;
l->animNumber = LA_STAND_TO_POLE;
l->currentAnimState = LS_POLE_IDLE;
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
Lara.isMoving = false;
Lara.gunStatus = LG_HANDS_BUSY;
}
@ -174,7 +170,7 @@ void PoleCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
&& !Lara.gunStatus
&& l->gravityStatus
&& l->fallspeed > Lara.gunStatus
&& (l->currentAnimState == STATE_LARA_REACH || l->currentAnimState == STATE_LARA_JUMP_UP))
&& (l->currentAnimState == LS_REACH || l->currentAnimState == LS_JUMP_UP))
{
if (TestBoundsCollide(item, l, 100))
{
@ -182,23 +178,23 @@ void PoleCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
{
short rot = item->pos.yRot;
item->pos.yRot = l->pos.yRot;
if (l->currentAnimState == STATE_LARA_REACH)
if (l->currentAnimState == LS_REACH)
{
PolePosR.y = l->pos.yPos - item->pos.yPos + 10;
AlignLaraPosition(&PolePosR, item, l);
l->animNumber = ANIMATION_LARA_JUMP_FORWARD_TO_POLE_GRAB;
l->frameNumber = Anims[l->animNumber].frameBase;
l->animNumber = LA_REACH_TO_POLE;
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
}
else
{
PolePosR.y = l->pos.yPos - item->pos.yPos + 66;
AlignLaraPosition(&PolePosR, item, l);
l->animNumber = ANIMATION_LARA_JUMP_UP_TO_POLE_GRAB;
l->frameNumber = Anims[l->animNumber].frameBase;
l->animNumber = LA_JUMP_UP_TO_POLE;
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
}
l->gravityStatus = false;
l->fallspeed = false;
l->currentAnimState = STATE_LARA_POLE_IDLE;
l->currentAnimState = LS_POLE_IDLE;
Lara.gunStatus = LG_HANDS_BUSY;
item->pos.yRot = rot;
}
@ -206,15 +202,15 @@ void PoleCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
}
else
{
if ((l->currentAnimState < STATE_LARA_POLE_IDLE || l->currentAnimState > STATE_LARA_POLE_TURN_RIGHT) &&
l->currentAnimState != STATE_LARA_JUMP_BACK)
if ((l->currentAnimState < LS_POLE_IDLE || l->currentAnimState > LS_POLE_TURN_COUNTER_CLOCKWISE) &&
l->currentAnimState != LS_JUMP_BACK)
ObjectCollision(itemNumber, l, coll);
}
}
void ControlTriggerTriggerer(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &item->roomNumber);
int height = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
@ -285,7 +281,7 @@ void AnimateWaterfalls()
void ControlWaterfall(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
TriggerActive(item);
if (itemNumber != 0)
@ -312,17 +308,17 @@ void ControlWaterfall(short itemNumber)
void TightRopeCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
if (((TrInput & IN_ACTION) == 0
|| l->currentAnimState != STATE_LARA_STOP
|| l->animNumber != ANIMATION_LARA_STAY_IDLE
|| l->currentAnimState != LS_STOP
|| l->animNumber != LA_STAND_IDLE
|| l->status == ITEM_INVISIBLE
|| Lara.gunStatus)
&& (!Lara.isMoving || Lara.generalPtr != (void*)itemNum))
{
if (l->currentAnimState == STATE_LARA_TIGHTROPE_FORWARD &&
l->goalAnimState != STATE_LARA_TIGHTROPE_EXIT &&
if (l->currentAnimState == LS_TIGHTROPE_FORWARD &&
l->goalAnimState != LS_TIGHTROPE_EXIT &&
!Lara.tightRopeOff)
{
if (item->pos.yRot == l->pos.yRot)
@ -335,13 +331,13 @@ void TightRopeCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
else
{
item->pos.yRot += -ANGLE(180);
if (TestLaraPosition(TightRopeBounds, item, l))
if (TestLaraPosition(&TightRopeBounds, item, l))
{
if (MoveLaraPosition(&TightRopePos, item, l))
{
l->currentAnimState = STATE_LARA_TIGHTROPE_ENTER;
l->animNumber = ANIMATION_LARA_TIGHTROPE_START;
l->frameNumber = Anims[l->animNumber].frameBase;
l->currentAnimState = LS_TIGHTROPE_ENTER;
l->animNumber = LA_TIGHTROPE_START;
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
Lara.isMoving = false;
Lara.headYrot = 0;
Lara.headXrot = 0;
@ -368,23 +364,23 @@ void TightRopeCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
void ParallelBarsCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
{
ITEM_INFO* item = &Items[itemNumber];
if (TrInput & IN_ACTION && l->currentAnimState == STATE_LARA_REACH && l->animNumber == ANIMATION_LARA_TRY_HANG_SOLID)
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (TrInput & IN_ACTION && l->currentAnimState == LS_REACH && l->animNumber == LA_REACH)
{
int test1 = TestLaraPosition(ParallelBarsBounds, item, l);
int test1 = TestLaraPosition(&ParallelBarsBounds, item, l);
int test2 = 0;
if (!test1)
{
item->pos.yRot += -ANGLE(180);
test2 = TestLaraPosition(ParallelBarsBounds, item, l);
test2 = TestLaraPosition(&ParallelBarsBounds, item, l);
item->pos.yRot += -ANGLE(180);
}
if (test1 || test2)
{
l->currentAnimState = STATE_LARA_MISC_CONTROL;
l->animNumber = ANIMATION_LARA_BARS_GRAB;
l->frameNumber = Anims[l->animNumber].frameBase;
l->currentAnimState = LS_MISC_CONTROL;
l->animNumber = LA_SWINGBAR_GRAB;
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
l->fallspeed = false;
l->gravityStatus = false;
@ -424,7 +420,7 @@ void ParallelBarsCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
ObjectCollision(itemNumber, l, coll);
}
}
else if (l->currentAnimState != STATE_LARA_BARS_SWING)
else if (l->currentAnimState != LS_BARS_SWING)
{
ObjectCollision(itemNumber, l, coll);
}
@ -432,7 +428,7 @@ void ParallelBarsCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
void ControlXRayMachine(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (!TriggerActive(item))
return;
@ -497,7 +493,7 @@ void ControlXRayMachine(short itemNumber)
if (item->itemFlags[1] < 128)
{
SoundEffect(SFX_LOOP_FOR_SMALL_FIRES, &item->pos, 0);
TriggerFontFire(&Items[item->itemFlags[0]], item->itemFlags[1], item->itemFlags[1] == 0 ? 16 : 1);
TriggerFontFire(&g_Level.Items[item->itemFlags[0]], item->itemFlags[1], item->itemFlags[1] == 0 ? 16 : 1);
}
++item->itemFlags[1];
@ -505,7 +501,7 @@ void ControlXRayMachine(short itemNumber)
case 333:
{
ROOM_INFO* r = &Rooms[item->roomNumber];
ROOM_INFO* r = &g_Level.Rooms[item->roomNumber];
MESH_INFO* mesh = r->mesh;
int j;
@ -545,17 +541,17 @@ void CutsceneRopeControl(short itemNumber)
int dy;
int dz;
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
pos1.x = -128;
pos1.y = -72;
pos1.z = -16;
GetJointAbsPosition(&Items[item->itemFlags[2]], &pos1, 0);
GetJointAbsPosition(&g_Level.Items[item->itemFlags[2]], &pos1, 0);
pos2.x = 830;
pos2.z = -12;
pos2.y = 0;
GetJointAbsPosition(&Items[item->itemFlags[3]], &pos2, 0);
GetJointAbsPosition(&g_Level.Items[item->itemFlags[3]], &pos2, 0);
item->pos.xPos = pos2.x;
item->pos.yPos = pos2.y;
@ -573,11 +569,11 @@ void HybridCollision(short itemNum, ITEM_INFO* laraitem, COLL_INFO* coll)
{
ITEM_INFO* item;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
/*if (gfCurrentLevel == LVL5_SINKING_SUBMARINE)
{
if (item->frameNumber < Anims[item->animNumber].frame_end)
if (item->frameNumber < g_Level.Anims[item->animNumber].frame_end)
{
ObjectCollision(itemNum, laraitem, coll);
}
@ -586,7 +582,7 @@ void HybridCollision(short itemNum, ITEM_INFO* laraitem, COLL_INFO* coll)
void InitialiseTightRope(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (item->pos.yRot > 0)
{
@ -612,35 +608,35 @@ void InitialiseTightRope(short itemNumber)
void InitialiseAnimating(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
/*ITEM_INFO* item = &g_Level.Items[itemNumber];
item->currentAnimState = 0;
item->animNumber = Objects[item->objectNumber].animIndex;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;*/
}
void AnimatingControl(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (!TriggerActive(item))
return;
item->status = ITEM_ACTIVE;
AnimateItem(item);
if (item->frameNumber >= Anims[item->animNumber].frameEnd)
// TODO: ID_SHOOT_SWITCH2 probably the bell in Trajan Markets, use LUA for that
/*if (item->frameNumber >= g_Level.Anims[item->animNumber].frameEnd)
{
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
RemoveActiveItem(itemNumber);
item->aiBits = 0;
item->status = ITEM_NOT_ACTIVE;
}
}*/
}
void HighObject2Control(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (!TriggerActive(item))
return;

View file

@ -125,20 +125,20 @@ int Targetable(ITEM_INFO* item, AI_INFO* info)
{
GAME_VECTOR start, target;
short* bounds = GetBestFrame(item);
BOUNDING_BOX* bounds = (BOUNDING_BOX*)GetBestFrame(item);
start.x = item->pos.xPos;
if (item->objectNumber == ID_SNIPER)
start.y = item->pos.yPos - 768;
else
start.y = item->pos.yPos + ((bounds[3] + 3 * bounds[2]) >> 2);
start.y = item->pos.yPos + ((bounds->Y2 + 3 * bounds->Y1) / 4);
start.z = item->pos.zPos;
start.roomNumber = item->roomNumber;
bounds = GetBestFrame(enemy);
bounds = (BOUNDING_BOX*)GetBestFrame(enemy);
target.x = enemy->pos.xPos;
target.y = enemy->pos.yPos + ((bounds[3] + 3 * bounds[2]) >> 2);
target.y = enemy->pos.yPos + ((bounds->Y2 + 3 * bounds->Y1) / 4);
target.z = enemy->pos.zPos;
return LOS(&start, &target);
@ -165,8 +165,8 @@ int TargetVisible(ITEM_INFO* item, AI_INFO* info)
GAME_VECTOR target;
target.x = enemy->pos.xPos;
short* bounds = GetBestFrame(enemy);
target.y = enemy->pos.yPos + ((((bounds[2] << 1) + bounds[2]) + bounds[3]) >> 2);
BOUNDING_BOX* bounds = (BOUNDING_BOX*)GetBestFrame(enemy);
target.y = enemy->pos.yPos + ((((bounds->Y1 * 2) + bounds->Y1) + bounds->Y2) / 4);
target.z = enemy->pos.zPos;
return LOS(&start, &target);

View file

@ -76,8 +76,8 @@ typedef struct GAME_VECTOR
int x;
int y;
int z;
int boxNumber;
short roomNumber;
short boxNumber;
GAME_VECTOR()
{
@ -121,8 +121,8 @@ typedef struct OBJECT_VECTOR
int x;
int y;
int z;
short data;
short flags;
int data;
int flags;
OBJECT_VECTOR()
{
@ -224,4 +224,14 @@ typedef struct MATRIX3D
int tx;
int ty;
int tz;
};
struct BOUNDING_BOX
{
short X1;
short X2;
short Y1;
short Y2;
short Z1;
short Z2;
};

File diff suppressed because it is too large Load diff

View file

@ -13,7 +13,7 @@ void PuzzleDoneCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll);
void KeyHoleCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll);
void PickupCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll);
void RegeneratePickups();
short* FindPlinth(ITEM_INFO* item);
BOUNDING_BOX* FindPlinth(ITEM_INFO* item);
void PuzzleDone(ITEM_INFO* item, short itemNum);
void PickupControl(short itemNum);
@ -21,3 +21,4 @@ void InitialiseSearchObject(short itemNumber);
void SearchObjectCollision(short itemNumber, ITEM_INFO* laraitem, COLL_INFO* laracoll);
void SearchObjectControl(short itemNumber);
void do_pickup();
void do_puzzle();

View file

@ -1,40 +1,17 @@
#pragma once
#include <framework.h>
#include <newtypes.h>
typedef struct tr5_room_layer
{
unsigned int NumLayerVertices; // Number of vertices in this layer (4 bytes)
unsigned short UnknownL1;
unsigned short NumLayerRectangles; // Number of rectangles in this layer (2 bytes)
unsigned short NumLayerTriangles; // Number of triangles in this layer (2 bytes)
unsigned short UnknownL2;
unsigned short Filler; // Always 0
unsigned short Filler2; // Always 0
/// The following 6 floats define the bounding box for the layer
float LayerBoundingBoxX1;
float LayerBoundingBoxY1;
float LayerBoundingBoxZ1;
float LayerBoundingBoxX2;
float LayerBoundingBoxY2;
float LayerBoundingBoxZ2;
unsigned int Filler3; // Always 0 (4 bytes)
void* VerticesOffset;
void* PolyOffset;
void* PolyOffset2;
};
struct ANIM_FRAME;
typedef struct tr5_vertex
struct ROOM_VERTEX
{
float x;
float y;
float z;
};
typedef struct tr5_room_vertex
{
tr5_vertex Vertex; // Vertex is now floating-point
tr5_vertex Normal;
DWORD Colour; // 32-bit colour
Vector3 position;
Vector3 normal;
Vector2 textureCoordinates;
Vector3 color;
int effects;
int index;
};
struct ROOM_DOOR
@ -44,48 +21,18 @@ struct ROOM_DOOR
Vector3 vertices[4];
};
typedef struct tr4_mesh_face3 // 10 bytes
{
short Vertices[3];
short Texture;
short Effects; // TR4-5 ONLY: alpha blending and environment mapping strength
};
typedef struct tr4_mesh_face4 // 12 bytes
{
short Vertices[4];
short Texture;
short Effects;
};
typedef struct tr_ROOM_DOOR // 32 bytes
{
short AdjoiningRoom; // Which room this portal leads to
TR_VERTEX Normal;
TR_VERTEX Vertices[4];
};
typedef struct tr_room_sector // 8 bytes
{
unsigned short FDindex; // Index into FloorData[]
unsigned short BoxIndex; // Index into Boxes[] (-1 if none)
unsigned char RoomBelow; // 255 is none
signed char Floor; // Absolute height of floor
unsigned char RoomAbove; // 255 if none
signed char Ceiling; // Absolute height of ceiling
};
typedef struct ROOM_LIGHT
{
float x, y, z; // Position of light, in world coordinates
int x, y, z; // Position of light, in world coordinates
float r, g, b; // Colour of the light
float intensity;
float in; // Cosine of the IN value for light / size of IN value
float out; // Cosine of the OUT value for light / size of OUT value
float radIn; // (IN radians) * 2
float radOut; // (OUT radians) * 2
float range; // Range of light
float length; // Range of light
float cutoff; // Range of light
float dx, dy, dz; // Direction - used only by sun and spot lights
byte type;
bool castShadows;
};
typedef struct MESH_INFO
@ -147,7 +94,7 @@ struct SECTOR_COLLISION_INFO
SECTOR_PLANE planes[2];
};
typedef struct FLOOR_INFO
struct FLOOR_INFO
{
int index;
int box;
@ -161,7 +108,7 @@ typedef struct FLOOR_INFO
SECTOR_COLLISION_INFO ceilingCollision;
};
typedef enum RoomEnumFlag
enum RoomEnumFlag
{
ENV_FLAG_WATER = 0x0001,
ENV_FLAG_SWAMP = 0x0004,
@ -175,36 +122,37 @@ typedef enum RoomEnumFlag
ENV_FLAG_UNKNOWN3 = 0x0400
};
typedef struct ROOM_INFO
struct ROOM_INFO
{
int x;
int y;
int z;
int minfloor;
int maxceiling;
std::vector<tr5_room_vertex> vertices;
std::vector<tr4_mesh_face4> quads;
std::vector<tr4_mesh_face3> triangles;
std::vector<Vector3> positions;
std::vector<Vector3> normals;
std::vector<Vector3> colors;
std::vector<BUCKET> buckets;
std::vector<ROOM_DOOR> doors;
short xSize;
short ySize;
int xSize;
int ySize;
std::vector<FLOOR_INFO> floor;
Vector3 ambient;
std::vector<ROOM_LIGHT> lights;
std::vector<MESH_INFO> mesh;
short flippedRoom;
unsigned short flags;
byte meshEffect;
unsigned char reverbType;
unsigned char flipNumber;
int flippedRoom;
int flags;
int meshEffect;
int reverbType;
int flipNumber;
short itemNumber;
short fxNumber;
bool boundActive;
};
typedef struct ANIM_STRUCT
struct ANIM_STRUCT
{
short* framePtr;
int framePtr;
short interpolation;
short currentAnimState;
int velocity;
@ -222,5 +170,5 @@ typedef struct ANIM_STRUCT
};
constexpr auto NUM_ROOMS = 1024;
constexpr auto NO_ROOM = 0xFF;
constexpr auto NO_ROOM = -1;
constexpr auto NO_HEIGHT = (-0x7F00);

View file

@ -16,7 +16,7 @@ void InitialiseRope(short itemNumber) // (F) (D)
{
PHD_VECTOR itemPos;
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
short roomNumber = item->roomNumber;
itemPos.x = item->pos.xPos;
@ -153,7 +153,7 @@ void RopeControl(short itemNumber) // (F) (D)
ITEM_INFO* item;
ROPE_STRUCT* rope;
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
rope = &Ropes[item->triggerFlags];
if (TriggerActive(item))
{
@ -170,30 +170,30 @@ void RopeCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll) // (F) (D)
{
ITEM_INFO* item;
ROPE_STRUCT* rope;
ANIM_FRAME* frame;
BOUNDING_BOX* frame;
int segment;
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
rope = &Ropes[item->triggerFlags];
if (TrInput & IN_ACTION && Lara.gunStatus == LG_NO_ARMS && (l->currentAnimState == STATE_LARA_REACH || l->currentAnimState == STATE_LARA_JUMP_UP) && l->gravityStatus && l->fallspeed > 0 && rope->active)
if (TrInput & IN_ACTION && Lara.gunStatus == LG_NO_ARMS && (l->currentAnimState == LS_REACH || l->currentAnimState == LS_JUMP_UP) && l->gravityStatus && l->fallspeed > 0 && rope->active)
{
frame = (ANIM_FRAME*) GetBoundsAccurate(l);
segment = _0x0046D200(rope, l->pos.xPos, l->pos.yPos + frame->MinY + 512, l->pos.zPos + (frame->MaxZ * phd_cos(l->pos.yRot) >> W2V_SHIFT), l->currentAnimState == STATE_LARA_REACH ? 128 : 320);
frame = GetBoundsAccurate(l);
segment = _0x0046D200(rope, l->pos.xPos, l->pos.yPos + frame->Y1 + 512, l->pos.zPos + ((int)(frame->Z2 * phd_cos(l->pos.yRot)) >> W2V_SHIFT), l->currentAnimState == LS_REACH ? 128 : 320);
if (segment >= 0)
{
if (l->currentAnimState == STATE_LARA_REACH)
if (l->currentAnimState == LS_REACH)
{
l->animNumber = ANIMATION_LARA_ROPE_JUMP_TO_GRAB;
l->currentAnimState = STATE_LARA_ROPE_SWING;
Lara.ropeFrame = Anims[ANIMATION_LARA_ROPE_SWING_FORWARD_SEMIHARD].frameBase + 32 << 8;
Lara.ropeDFrame = Anims[ANIMATION_LARA_ROPE_SWING_FORWARD_SEMIHARD].frameBase + 60 << 8;
l->animNumber = LA_REACH_TO_ROPE_SWING;
l->currentAnimState = LS_ROPE_SWING;
Lara.ropeFrame = g_Level.Anims[LA_ROPE_SWING].frameBase + 32 << 8;
Lara.ropeDFrame = g_Level.Anims[LA_ROPE_SWING].frameBase + 60 << 8;
}
else
{
l->animNumber = ANIMATION_LARA_MONKEY_TO_ROPE_BEGIN;
l->currentAnimState = STATE_LARA_ROPE_IDLE;
l->animNumber = LA_JUMP_UP_TO_ROPE_START;
l->currentAnimState = LS_ROPE_IDLE;
}
l->frameNumber = Anims[l->animNumber].frameBase;
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
l->gravityStatus = false;
l->fallspeed = 0;
Lara.gunStatus = LG_HANDS_BUSY;

View file

@ -77,13 +77,13 @@ extern byte CurrentSequence;
void SaveGame::saveItems()
{
// Save level items
for (int i = 0; i < NumItems; i++)
for (int i = 0; i < g_Level.NumItems; i++)
m_writer->WriteChunkWithChildren(m_chunkItem, &saveItem, i, 0);
// Save items created at runtime (flares, missiles...)
for (int i = NumItems; i < NUM_ITEMS; i++)
for (int i = g_Level.NumItems; i < NUM_ITEMS; i++)
{
ITEM_INFO* item = &Items[i];
ITEM_INFO* item = &g_Level.Items[i];
if (item->active)
{
// Some items are very special and are saved in specific functions, all the others use the general function
@ -121,8 +121,8 @@ void SaveGame::saveItems()
void SaveGame::saveItem(int itemNumber, int runtimeItem)
{
ITEM_INFO* item = &Items[itemNumber];
ObjectInfo* obj = &Objects[item->objectNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
OBJECT_INFO* obj = &Objects[item->objectNumber];
LEB128::Write(m_stream, itemNumber);
LEB128::Write(m_stream, runtimeItem);
@ -186,8 +186,8 @@ void SaveGame::saveGameStatus(int arg1, int arg2)
LEB128::Write(m_stream, CurrentSequence);
// Now the sub-chunks
for (int i = 0; i < Rooms.size(); i++)
for (int j = 0; j < Rooms[i].mesh.size(); j++)
for (int i = 0; i < g_Level.Rooms.size(); i++)
for (int j = 0; j < g_Level.Rooms[i].mesh.size(); j++)
m_writer->WriteChunk(m_chunkStaticFlags, &saveStaticFlag, i, j);
for (int i = 0; i < 6; i++)
@ -200,7 +200,7 @@ void SaveGame::saveGameStatus(int arg1, int arg2)
m_writer->WriteChunk(m_chunkCdFlags, &saveCdFlags, i, g_AudioTracks[i].Mask);
for (int i = 0; i < NumberCameras; i++)
m_writer->WriteChunk(m_chunkCamera, &saveCamera, i, Camera.fixed[i].flags);
m_writer->WriteChunk(m_chunkCamera, &saveCamera, i, FixedCameras[i].flags);
for (int i = 0; i < 255; i++)
m_writer->WriteChunk(m_chunkFlipStats, &saveFlipStats, i, FlipStats[i]);
@ -215,11 +215,8 @@ void SaveGame::saveLara(int arg1, int arg2)
LaraInfo lara;
memcpy(&lara, &Lara, sizeof(Lara));
for (int i = 0; i < 15; i++)
lara.meshPtrs[i] = (short*)((char*)lara.meshPtrs[i] - (ptrdiff_t)MeshBase);
lara.leftArm.frameBase = (short*)((char *)lara.leftArm.frameBase - (ptrdiff_t)Objects[ID_LARA].frameBase);
lara.rightArm.frameBase = (short*)((char *)lara.rightArm.frameBase - (ptrdiff_t)Objects[ID_LARA].frameBase);
//lara.leftArm.frameBase = (short*)((char *)lara.leftArm.frameBase - (ptrdiff_t)Objects[ID_LARA].frameBase);
//lara.rightArm.frameBase = (short*)((char *)lara.rightArm.frameBase - (ptrdiff_t)Objects[ID_LARA].frameBase);
lara.generalPtr = (char *)lara.generalPtr - (ptrdiff_t)malloc_buffer;
m_stream->Write(reinterpret_cast<char*>(&lara), sizeof(Lara));
@ -289,7 +286,7 @@ void SaveGame::saveLara(int arg1, int arg2)
void SaveGame::saveWeaponItem(int arg1, int arg2)
{
ITEM_INFO* weaponItem = &Items[arg1];
ITEM_INFO* weaponItem = &g_Level.Items[arg1];
LEB128::Write(m_stream, weaponItem->objectNumber);
LEB128::Write(m_stream, weaponItem->animNumber);
@ -512,13 +509,8 @@ bool SaveGame::readLara()
memcpy(&Lara, lara, sizeof(LaraInfo));
free(buffer);
for (int i = 0; i < NUM_LARA_MESHES; i++)
{
Lara.meshPtrs[i] = AddPtr(Lara.meshPtrs[i], short, MeshBase);
}
Lara.leftArm.frameBase = AddPtr(Lara.leftArm.frameBase, short, Objects[ID_LARA].frameBase);
Lara.rightArm.frameBase = AddPtr(Lara.rightArm.frameBase, short, Objects[ID_LARA].frameBase);
//Lara.leftArm.frameBase = AddPtr(Lara.leftArm.frameBase, short, Objects[ID_LARA].frameBase);
//Lara.rightArm.frameBase = AddPtr(Lara.rightArm.frameBase, short, Objects[ID_LARA].frameBase);
Lara.target = NULL;
Lara.spazEffect = NULL;
@ -555,10 +547,10 @@ bool SaveGame::readItem()
if (runtimeItem)
itemNumber = CreateItem();
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->objectNumber = LEB128::ReadInt16(m_stream);
ObjectInfo* obj = &Objects[item->objectNumber];
OBJECT_INFO* obj = &Objects[item->objectNumber];
// Runtime items must be initialised
// TODO: test test test!!!
@ -739,7 +731,7 @@ void SaveGame::saveStaticFlag(int arg1, int arg2)
{
LEB128::Write(m_stream, arg1);
LEB128::Write(m_stream, arg2);
LEB128::Write(m_stream, Rooms[arg1].mesh[arg2].flags);
LEB128::Write(m_stream, g_Level.Rooms[arg1].mesh[arg2].flags);
}
bool SaveGame::readLaraChunks(ChunkId* chunkId, int maxSize, int arg)
@ -828,7 +820,7 @@ bool SaveGame::readLaraChunks(ChunkId* chunkId, int maxSize, int arg)
short weaponItemNum = CreateItem();
Lara.weaponItem = weaponItemNum;
ITEM_INFO* weaponItem = &Items[Lara.weaponItem];
ITEM_INFO* weaponItem = &g_Level.Items[Lara.weaponItem];
weaponItem->objectNumber = LEB128::ReadInt16(m_stream);
weaponItem->animNumber = LEB128::ReadInt16(m_stream);
@ -849,17 +841,17 @@ bool SaveGame::readGameStatusChunks(ChunkId* chunkId, int maxSize, int arg)
short roomIndex = LEB128::ReadInt16(m_stream);
short staticIndex = LEB128::ReadInt16(m_stream);
short flags = LEB128::ReadInt16(m_stream);
Rooms[roomIndex].mesh[staticIndex].flags = flags;
g_Level.Rooms[roomIndex].mesh[staticIndex].flags = flags;
if (!flags)
{
FLOOR_INFO* floor = GetFloor(Rooms[roomIndex].mesh[staticIndex].x,
Rooms[roomIndex].mesh[staticIndex].y,
Rooms[roomIndex].mesh[staticIndex].z,
FLOOR_INFO* floor = GetFloor(g_Level.Rooms[roomIndex].mesh[staticIndex].x,
g_Level.Rooms[roomIndex].mesh[staticIndex].y,
g_Level.Rooms[roomIndex].mesh[staticIndex].z,
&roomIndex);
int height = GetFloorHeight(floor, Rooms[roomIndex].mesh[staticIndex].x,
Rooms[roomIndex].mesh[staticIndex].y,
Rooms[roomIndex].mesh[staticIndex].z);
int height = GetFloorHeight(floor, g_Level.Rooms[roomIndex].mesh[staticIndex].x,
g_Level.Rooms[roomIndex].mesh[staticIndex].y,
g_Level.Rooms[roomIndex].mesh[staticIndex].z);
TestTriggers(TriggerIndex, 1, 0);
floor->stopper = false;
}
@ -895,7 +887,7 @@ bool SaveGame::readGameStatusChunks(ChunkId* chunkId, int maxSize, int arg)
{
short index = LEB128::ReadInt16(m_stream);
short value = LEB128::ReadInt16(m_stream);
Camera.fixed[index].flags = value;
FixedCameras[index].flags = value;
return true;
}
else if (chunkId->EqualsTo(m_chunkSequenceSwitch))
@ -953,7 +945,7 @@ void SaveGame::saveCdFlags(int arg1, int arg2)
bool SaveGame::readItemChunks(ChunkId* chunkId, int maxSize, int itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (chunkId->EqualsTo(m_chunkItemDummy))
return m_reader->ReadChunkInt32(maxSize);
@ -1020,7 +1012,7 @@ bool SaveGame::readItemChunks(ChunkId* chunkId, int maxSize, int itemNumber)
{
EnableBaddieAI(itemNumber, 1);
ObjectInfo* obj = &Objects[item->objectNumber];
OBJECT_INFO* obj = &Objects[item->objectNumber];
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
creature->jointRotation[0] = LEB128::ReadInt16(m_stream);
@ -1063,7 +1055,7 @@ bool SaveGame::readItemChunks(ChunkId* chunkId, int maxSize, int itemNumber)
}
else if (chunkId->EqualsTo(m_chunkItemQuadInfo))
{
QUAD_INFO* quadInfo = (QUAD_INFO*)game_malloc(sizeof(QUAD_INFO));
QUAD_INFO* quadInfo = game_malloc<QUAD_INFO>();
m_stream->ReadBytes(reinterpret_cast<byte*>(quadInfo), sizeof(QUAD_INFO));
if (item->objectNumber == ID_QUAD)
item->data = (void*)quadInfo;
@ -1123,8 +1115,8 @@ bool SaveGame::readStatistics()
void SaveGame::saveItemFlags(int arg1, int arg2)
{
ITEM_INFO* item = &Items[arg1];
ObjectInfo* obj = &Objects[item->objectNumber];
ITEM_INFO* item = &g_Level.Items[arg1];
OBJECT_INFO* obj = &Objects[item->objectNumber];
LEB128::Write(m_stream, item->flags);
LEB128::Write(m_stream, item->active);
@ -1147,8 +1139,8 @@ void SaveGame::saveItemFlags(int arg1, int arg2)
void SaveGame::saveItemIntelligentData(int arg1, int arg2)
{
ITEM_INFO* item = &Items[arg1];
ObjectInfo* obj = &Objects[item->objectNumber];
ITEM_INFO* item = &g_Level.Items[arg1];
OBJECT_INFO* obj = &Objects[item->objectNumber];
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
ITEM_INFO* enemy = (ITEM_INFO*)((char*)creature->enemy - (ptrdiff_t)malloc_buffer);
@ -1190,14 +1182,14 @@ void SaveGame::saveItemIntelligentData(int arg1, int arg2)
void SaveGame::saveItemHitPoints(int arg1, int arg2)
{
ITEM_INFO* item = &Items[arg1];
ITEM_INFO* item = &g_Level.Items[arg1];
LEB128::Write(m_stream, item->hitPoints);
}
void SaveGame::saveItemPosition(int arg1, int arg2)
{
ITEM_INFO* item = &Items[arg1];
ITEM_INFO* item = &g_Level.Items[arg1];
LEB128::Write(m_stream, item->pos.xPos);
LEB128::Write(m_stream, item->pos.yPos);
@ -1212,7 +1204,7 @@ void SaveGame::saveItemPosition(int arg1, int arg2)
void SaveGame::saveItemMesh(int arg1, int arg2)
{
ITEM_INFO* item = &Items[arg1];
ITEM_INFO* item = &g_Level.Items[arg1];
LEB128::Write(m_stream, item->meshBits);
LEB128::Write(m_stream, item->swapMeshFlags);
@ -1220,7 +1212,7 @@ void SaveGame::saveItemMesh(int arg1, int arg2)
void SaveGame::saveItemAnims(int arg1, int arg2)
{
ITEM_INFO* item = &Items[arg1];
ITEM_INFO* item = &g_Level.Items[arg1];
LEB128::Write(m_stream, item->currentAnimState);
LEB128::Write(m_stream, item->goalAnimState);
@ -1231,7 +1223,7 @@ void SaveGame::saveItemAnims(int arg1, int arg2)
void SaveGame::saveBurningTorch(int itemNumber, int arg2)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
LEB128::Write(m_stream, itemNumber);
LEB128::Write(m_stream, item->pos.xPos);
@ -1249,7 +1241,7 @@ void SaveGame::saveBurningTorch(int itemNumber, int arg2)
void SaveGame::saveChaff(int itemNumber, int arg2)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
LEB128::Write(m_stream, itemNumber);
LEB128::Write(m_stream, item->pos.xPos);
@ -1268,7 +1260,7 @@ void SaveGame::saveChaff(int itemNumber, int arg2)
void SaveGame::saveTorpedo(int itemNumber, int arg2)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
LEB128::Write(m_stream, itemNumber);
LEB128::Write(m_stream, item->pos.xPos);
@ -1290,7 +1282,7 @@ void SaveGame::saveTorpedo(int itemNumber, int arg2)
void SaveGame::saveCrossbowBolt(int itemNumber, int arg2)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
LEB128::Write(m_stream, itemNumber);
LEB128::Write(m_stream, item->pos.xPos);
@ -1306,7 +1298,7 @@ void SaveGame::saveCrossbowBolt(int itemNumber, int arg2)
void SaveGame::saveFlare(int itemNumber, int arg2)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
LEB128::Write(m_stream, itemNumber);
LEB128::Write(m_stream, item->pos.xPos);
@ -1328,7 +1320,7 @@ bool SaveGame::readBurningTorch()
LEB128::ReadInt16(m_stream);
short itemNumber = CreateItem();
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->objectNumber = ID_BURNING_TORCH_ITEM;
item->pos.xPos = LEB128::ReadInt32(m_stream);
@ -1364,7 +1356,7 @@ bool SaveGame::readChaff()
LEB128::ReadInt16(m_stream);
short itemNumber = CreateItem();
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->objectNumber = ID_CHAFF;
item->pos.xPos = LEB128::ReadInt32(m_stream);
@ -1401,7 +1393,7 @@ bool SaveGame::readCrossbowBolt()
LEB128::ReadInt16(m_stream);
short itemNumber = CreateItem();
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->objectNumber = ID_CROSSBOW_BOLT;
item->pos.xPos = LEB128::ReadInt32(m_stream);
@ -1435,7 +1427,7 @@ bool SaveGame::readFlare()
LEB128::ReadInt16(m_stream);
short itemNumber = CreateItem();
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->objectNumber = ID_FLARE_ITEM;
item->pos.xPos = LEB128::ReadInt32(m_stream);
@ -1472,7 +1464,7 @@ bool SaveGame::readTorpedo()
LEB128::ReadInt16(m_stream);
short itemNumber = CreateItem();
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->objectNumber = ID_TORPEDO;
item->pos.xPos = LEB128::ReadInt32(m_stream);
@ -1509,7 +1501,7 @@ bool SaveGame::readTorpedo()
void SaveGame::saveItemQuadInfo(int itemNumber, int arg2)
{
m_stream->WriteBytes(reinterpret_cast<byte*>(Items[itemNumber].data), sizeof(QUAD_INFO));
m_stream->WriteBytes(reinterpret_cast<byte*>(g_Level.Items[itemNumber].data), sizeof(QUAD_INFO));
}
void SaveGame::saveRats(int arg1, int arg2)

View file

@ -30,7 +30,7 @@ namespace T5M {
}
s.position += s.velocity;
if (s.affectedByWind) {
if (Rooms[s.room].flags & ENV_FLAG_WIND) {
if (g_Level.Rooms[s.room].flags & ENV_FLAG_WIND) {
s.position.x += SmokeWindX / 2;
s.position.z += SmokeWindZ / 2;
}
@ -88,29 +88,38 @@ namespace T5M {
Vector3(xv, yv, zv).Normalize(s.velocity);
s.velocity *= frand() * 24 + 16;
s.gravity = -.1f;
s.affectedByWind = Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WIND;
s.affectedByWind = g_Level.Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WIND;
s.sourceColor = Vector4(.4, .4, .4, 1);
s.destinationColor = Vector4(0, 0, 0, 0);
float size = (float)((GetRandomControl() & 0x0F) + 48); // -TriggerGunSmoke_SubFunction(weaponType);
if (initial)
{
s.sourceSize = size;
s.destinationSize = (size * 8) + 8;
float size = (frand() * 25) + 48;
s.sourceSize = size *2;
s.destinationSize = size * 8;
s.terminalVelocity = 0;
s.friction = 0.90f;
s.life = frand() * 30 + 60;
}
else
{
float size = (float)((GetRandomControl() & 0x0F) + 48); // -TriggerGunSmoke_SubFunction(weaponType);
s.sourceSize = size / 2;
s.destinationSize = size * 2;
s.destinationSize = size * 4;
s.terminalVelocity = 0;
s.friction = 0.97f;
s.life = frand() * 20 + 42;
}
s.terminalVelocity = 0;
s.friction = 0.89f;
s.life = frand() * 10 + 35;
s.position = Vector3(x, y, z);
s.position += Vector3(frandMinMax(-8, 8), frandMinMax(-8, 8), frandMinMax(-8, 8));
s.angularVelocity = frandMinMax(-PI, PI);
s.angularVelocity = frandMinMax(-PI / 4, PI / 4);
s.angularDrag = 0.8f;
s.room = LaraItem->roomNumber;
}
}

View file

@ -24,10 +24,6 @@ const BASS_BFX_FREEVERB BASS_ReverbTypes[NUM_REVERB_TYPES] = // Reverb preset
};
vector<AudioTrack> g_AudioTracks;
short SampleLUT[SOUND_NEW_SOUNDMAP_MAX_SIZE];
short SoundMapSize;
int NumSamplesInfos;
SAMPLE_INFO* SampleInfo;
int GlobalMusicVolume;
int GlobalFXVolume;
@ -112,7 +108,7 @@ bool Sound_LoadSample(char *pointer, int compSize, int uncompSize, int index) //
long SoundEffect(int effectID, PHD_3DPOS* position, int env_flags)
{
if (effectID >= SoundMapSize)
if (effectID >= g_Level.SoundMap.size())
return 0;
if (BASS_GetDevice() == -1)
@ -121,25 +117,25 @@ long SoundEffect(int effectID, PHD_3DPOS* position, int env_flags)
if (!(env_flags & SFX_ALWAYS))
{
// Don't play effect if effect's environment isn't the same as camera position's environment
if ((env_flags & ENV_FLAG_WATER) != (Rooms[Camera.pos.roomNumber].flags & ENV_FLAG_WATER))
if ((env_flags & ENV_FLAG_WATER) != (g_Level.Rooms[Camera.pos.roomNumber].flags & ENV_FLAG_WATER))
return 0;
}
// Get actual sample index from SoundMap
int sampleIndex = SampleLUT[effectID];
int sampleIndex = g_Level.SoundMap[effectID];
// -1 means no such effect exists in level file.
// We set it to -2 afterwards to prevent further debug message firings.
if (sampleIndex == -1)
{
printf("Non present effect %d \n", effectID);
SampleLUT[effectID] = -2;
g_Level.SoundMap[effectID] = -2;
return 0;
}
else if (sampleIndex == -2)
return 0;
SAMPLE_INFO *sampleInfo = &SampleInfo[sampleIndex];
SAMPLE_INFO *sampleInfo = &g_Level.SoundDetails[sampleIndex];
if (sampleInfo->number < 0)
{
@ -184,7 +180,7 @@ long SoundEffect(int effectID, PHD_3DPOS* position, int env_flags)
float distance = Sound_DistanceToListener(position);
// Don't play sound if it's too far from listener's position.
if (distance > radius)
if (distance > radius && false)
return 0;
// Set and randomize volume (if needed)
@ -561,9 +557,9 @@ void Sound_UpdateScene()
static int currentReverb = -1;
if (currentReverb == -1 || Rooms[Camera.pos.roomNumber].reverbType != currentReverb)
if (currentReverb == -1 || g_Level.Rooms[Camera.pos.roomNumber].reverbType != currentReverb)
{
currentReverb = Rooms[Camera.pos.roomNumber].reverbType;
currentReverb = g_Level.Rooms[Camera.pos.roomNumber].reverbType;
if (currentReverb < NUM_REVERB_TYPES)
BASS_FXSetParameters(BASS_FXHandler[SOUND_FILTER_REVERB], &BASS_ReverbTypes[currentReverb]);
}
@ -572,7 +568,7 @@ void Sound_UpdateScene()
{
if ((SoundSlot[i].channel != NULL) && (BASS_ChannelIsActive(SoundSlot[i].channel) == BASS_ACTIVE_PLAYING))
{
SAMPLE_INFO *sampleInfo = &SampleInfo[SampleLUT[SoundSlot[i].effectID]];
SAMPLE_INFO *sampleInfo = &g_Level.SoundDetails[g_Level.SoundMap[SoundSlot[i].effectID]];
// Stop and clean up sounds which were in ending state in previous frame.
// In case sound is looping, make it ending unless they are re-fired in next frame.

View file

@ -619,7 +619,7 @@ typedef enum sound_effects
SFX_TR1_BULLET_HITTING_LARA = 500,
SFX_TR1_LARA_HEH_STARTING_TO_PULL_BLOCK = 501,
SFX_TR1_LARA_TREADING_WATER = 502,
SFX_TR1_LARA_S_BONES_BREAKING_DYING = 503,
SFX_TR1_LARA_S_Bones_BREAKING_DYING = 503,
SFX_TR1_LEDGE_GRAB_BY_LARA = 504,
SFX_TR1_LARA_OOMPH_HITTING_WALL_AFTER_GRABBING_LEDGE = 505,
SFX_TR1_FOOTSTEP_LEDGE_SHIMMY_BY_LARA = 506,
@ -877,7 +877,7 @@ typedef enum sound_effects
SFX_TR2_BULLET_HITTING_LARA = 756,
SFX_TR2_LARA_HEH_PULLING_UP = 757,
SFX_TR2_LARA_TREADING_WATER1 = 758,
SFX_TR2_LARA_S_BONES_BREAKING_DYING = 759,
SFX_TR2_LARA_S_Bones_BREAKING_DYING = 759,
SFX_TR2_LEDGE_GRAB_BY_LARA = 760,
SFX_TR2_LARA_OOMPH_HITTING_WALL_AFTER_GRABBING_LEDGE = 761,
SFX_TR2_FOOTSTEP_LEDGE_SHIMMY_BY_LARA = 762,
@ -2042,10 +2042,6 @@ typedef struct AudioTrack
};
extern std::vector<AudioTrack> g_AudioTracks;
extern short SampleLUT[SOUND_NEW_SOUNDMAP_MAX_SIZE];
extern short SoundMapSize;
extern int NumSamplesInfos;
extern SAMPLE_INFO* SampleInfo;
extern int GlobalMusicVolume;
extern int GlobalFXVolume;

View file

@ -6,7 +6,7 @@
#include "setup.h"
#include "Renderer11.h"
#include "trmath.h"
using namespace T5M::Renderer;
int NumLaraSpheres;
bool GotLaraSpheres;
SPHERE LaraSpheres[MAX_SPHERES];
@ -18,9 +18,9 @@ int GetSpheres(ITEM_INFO* item, SPHERE* ptr, int worldSpace, Matrix local)
return 0;
BoundingSphere spheres[MAX_SPHERES];
short itemNumber = (item - Items);
short itemNumber = (item - g_Level.Items.data());
int num = g_Renderer->GetSpheres(itemNumber, spheres, worldSpace, local);
int num = g_Renderer.GetSpheres(itemNumber, spheres, worldSpace, local);
for (int i = 0; i < MAX_SPHERES; i++)
{
@ -164,11 +164,11 @@ void GetMatrixFromTrAngle(Matrix* matrix, short* frameptr, int index)
void GetJointAbsPosition(ITEM_INFO* item, PHD_VECTOR* vec, int joint)
{
// Get the real item number
short itemNumber = item - Items;
short itemNumber = item - g_Level.Items.data();
// Use matrices done in the renderer and transform the input vector
Vector3 p = Vector3(vec->x, vec->y, vec->z);
g_Renderer->GetItemAbsBonePosition(itemNumber, &p, joint);
g_Renderer.GetItemAbsBonePosition(itemNumber, &p, joint);
// Store the result
vec->x = p.x;

View file

@ -7,7 +7,7 @@
#include "switch.h"
#include "lara.h"
#include "input.h"
using namespace T5M::Renderer;
int LastSequence;
int SpotcamTimer;
int SpotcamLoopCnt;
@ -162,10 +162,10 @@ void InitialiseSpotCam(short Sequence)
LastCamera = CurrentSplineCamera + (CameraCnt[SpotCamRemap[Sequence]] - 1);
CurrentCameraCnt = CameraCnt[SpotCamRemap[Sequence]];
if ((s->flags & SCF_DISABLE_LARA_CONTROLS) /*|| gfGameMode == 1*/)
if ((s->flags & SCF_DISABLE_LARA_CONTROLS))
{
DisableLaraControl = 1;
g_Renderer->EnableCinematicBars(true);
g_Renderer.EnableCinematicBars(true);
//SetFadeClip(16, 1);
}
@ -266,14 +266,7 @@ void InitialiseSpotCam(short Sequence)
if (s->flags & SCF_VIGNETTE)
{
/*if (s->timer < 0)
{
SCOverlay = 1;
}//loc_37C8C
else if (SlowMotion == 0)
{
SlowMotion = s->timer;
}*/
/*Hardcoded code*/
}
if (s->flags & SCF_HIDE_LARA)
@ -421,28 +414,12 @@ void CalculateSpotCameras()
&& CameraFade != CurrentSplineCamera)
{
CameraFade = CurrentSplineCamera;
/*if (gfCurrentLevel != LVL5_TITLE)
{
ScreenFadedOut = 0;
ScreenFade = 255;
dScreenFade = 0;
SetScreenFadeIn(16);
}*/
}
if ((SpotCam[CurrentSplineCamera].flags & SCF_SCREEN_FADE_OUT)
&& CameraFade != CurrentSplineCamera)
{
CameraFade = CurrentSplineCamera;
/*if (gfCurrentLevel != LVL5_TITLE)
{
ScreenFadedOut = 0;
ScreenFade = 0;
dScreenFade = 255;
SetScreenFadeOut(16, 0);
}*/
}
sp = 0;
@ -516,7 +493,7 @@ void CalculateSpotCameras()
}
if (s->flags & SCF_DISABLE_BREAKOUT
|| !(TrInput & IN_LOOK) /*&& gfGameMode != 1*/)
|| !(TrInput & IN_LOOK))
{
Camera.pos.x = cpx;
Camera.pos.y = cpy;
@ -570,7 +547,7 @@ void CalculateSpotCameras()
}
}
LookAt(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.target.x, Camera.target.y, Camera.target.z, 0);
LookAt(&Camera, 0);
if (CheckTrigger)
{
@ -682,7 +659,7 @@ void CalculateSpotCameras()
{
//SetFadeClip(16, 1);
if (CurrentLevel)
g_Renderer->EnableCinematicBars(true);
g_Renderer.EnableCinematicBars(true);
DisableLaraControl = true;
}
@ -783,7 +760,7 @@ void CalculateSpotCameras()
}
//SetFadeClip(0, 1);
g_Renderer->EnableCinematicBars(false);
g_Renderer.EnableCinematicBars(false);
UseSpotCam = 0;
DisableLaraControl = 0;
@ -874,7 +851,7 @@ void CalculateSpotCameras()
Camera.targetElevation = elevation;
LookAt(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.target.x, Camera.target.y, Camera.target.z, croll);
LookAt(&Camera, croll);
SplineToCamera = 1;
}
@ -893,7 +870,7 @@ void CalculateSpotCameras()
}
else
{
g_Renderer->EnableCinematicBars(false);
g_Renderer.EnableCinematicBars(false);
UseSpotCam = false;
DisableLaraControl = false;
Camera.speed = 1;

File diff suppressed because it is too large Load diff

View file

@ -2,8 +2,8 @@
#include "text.h"
#include "draw.h"
#include "Renderer11.h"
void PrintString(int x, int y, int unk1, char* string, int unk2)
{
g_Renderer->PrintString(x, y, string, D3DCOLOR_RGBA(0xFF, 0xFF, 0xFF, 255), 0);
namespace T5M::Renderer {
void PrintString(int x, int y, int unk1, char* string, int unk2) {
g_Renderer.PrintString(x, y, string, D3DCOLOR_RGBA(0xFF, 0xFF, 0xFF, 255), 0);
}
}

View file

@ -528,7 +528,7 @@ void TriggerGunSmoke(int x, int y, int z, short xv, short yv, short zv, byte ini
if (GetRandomControl() & 1)
{
if (Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WIND)
if (g_Level.Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WIND)
spark->flags = SP_ROTATE | SP_WIND;
else
spark->flags = SP_ROTATE;
@ -540,7 +540,7 @@ void TriggerGunSmoke(int x, int y, int z, short xv, short yv, short zv, byte ini
else
spark->rotAdd = (GetRandomControl() & 0x0F) + 16;
}
else if (Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WIND)
else if (g_Level.Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WIND)
{
spark->flags = SP_WIND;
}
@ -607,7 +607,7 @@ void TriggerShatterSmoke(int x, int y, int z)
else
spark->rotAdd = (GetRandomControl() & 0x3F) + 64;
}
else if (Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WIND)
else if (g_Level.Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WIND)
{
spark->flags = SP_WIND;
}
@ -920,7 +920,7 @@ void UpdateGunShells()
short oldRoomNumber = gs->roomNumber;
if (Rooms[gs->roomNumber].flags & ENV_FLAG_WATER)
if (g_Level.Rooms[gs->roomNumber].flags & ENV_FLAG_WATER)
{
gs->fallspeed++;
@ -949,13 +949,13 @@ void UpdateGunShells()
gs->pos.zPos += gs->speed * phd_cos(gs->dirXrot) >> W2V_SHIFT;
FLOOR_INFO* floor = GetFloor(gs->pos.xPos, gs->pos.yPos, gs->pos.zPos, &gs->roomNumber);
if (Rooms[gs->roomNumber].flags & ENV_FLAG_WATER
&& !(Rooms[oldRoomNumber].flags & ENV_FLAG_WATER))
if (g_Level.Rooms[gs->roomNumber].flags & ENV_FLAG_WATER
&& !(g_Level.Rooms[oldRoomNumber].flags & ENV_FLAG_WATER))
{
T5M::Effects::Drip::SpawnGunshellDrips(Vector3(gs->pos.xPos, Rooms[gs->roomNumber].maxceiling, gs->pos.zPos), gs->roomNumber);
//AddWaterSparks(gs->pos.xPos, Rooms[gs->roomNumber].maxceiling, gs->pos.zPos, 8);
SetupRipple(gs->pos.xPos, Rooms[gs->roomNumber].maxceiling, gs->pos.zPos, (GetRandomControl() & 3) + 8, 2);
T5M::Effects::Drip::SpawnGunshellDrips(Vector3(gs->pos.xPos, g_Level.Rooms[gs->roomNumber].maxceiling, gs->pos.zPos), gs->roomNumber);
//AddWaterSparks(gs->pos.xPos, g_Level.Rooms[gs->roomNumber].maxceiling, gs->pos.zPos, 8);
SetupRipple(gs->pos.xPos, g_Level.Rooms[gs->roomNumber].maxceiling, gs->pos.zPos, (GetRandomControl() & 3) + 8, 2);
gs->fallspeed >>= 5;
continue;
}
@ -1132,7 +1132,7 @@ void UpdateDrips()
drip->yVel += drip->gravity;
if (Rooms[drip->roomNumber].flags & ENV_FLAG_WIND)
if (g_Level.Rooms[drip->roomNumber].flags & ENV_FLAG_WIND)
{
drip->x += SmokeWindX >> 1;
drip->z += SmokeWindZ >> 1;
@ -1141,7 +1141,7 @@ void UpdateDrips()
drip->y += drip->yVel >> 5;
FLOOR_INFO* floor = GetFloor(drip->x, drip->y, drip->z, &drip->roomNumber);
if (Rooms[drip->roomNumber].flags & ENV_FLAG_WATER)
if (g_Level.Rooms[drip->roomNumber].flags & ENV_FLAG_WATER)
drip->on = false;
int height = GetFloorHeight(floor, drip->x, drip->y, drip->z);
@ -1194,10 +1194,10 @@ void TriggerLaraDrips()// (F)
int ExplodingDeath(short itemNumber, int meshBits, short flags)
{
ITEM_INFO* item = &Items[itemNumber];
ObjectInfo* obj = &Objects[item->objectNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
OBJECT_INFO* obj = &Objects[item->objectNumber];
short* frame = GetBestFrame(item);
ANIM_FRAME* frame = GetBestFrame(item);
Matrix world = Matrix::CreateFromYawPitchRoll(
TO_RAD(item->pos.yRot),
@ -1464,14 +1464,14 @@ void UpdateShockwaves()
{
if (sw->flags & 3)
{
short* frame = GetBestFrame(LaraItem);
ANIM_FRAME* frame = GetBestFrame(LaraItem);
int dx = LaraItem->pos.xPos - sw->x;
int dz = LaraItem->pos.zPos - sw->z;
int distance = sqrt(SQUARE(dx) + SQUARE(dz));
if (sw->y <= LaraItem->pos.yPos + frame[2]
|| sw->y >= LaraItem->pos.yPos + frame[3] + 256
if (sw->y <= LaraItem->pos.yPos + frame->boundingBox.Y1
|| sw->y >= LaraItem->pos.yPos + frame->boundingBox.Y2 + 256
|| distance <= sw->innerRad
|| distance >= sw->outerRad)
{

View file

@ -16,9 +16,9 @@
#include "input.h"
#include "sound.h"
static short CeilingTrapDoorBounds[12] = {-256, 256, 0, 900, -768, -256, -1820, 1820, -5460, 5460, -1820, 1820};
OBJECT_COLLISION_BOUNDS CeilingTrapDoorBounds = {-256, 256, 0, 900, -768, -256, -1820, 1820, -5460, 5460, -1820, 1820};
static PHD_VECTOR CeilingTrapDoorPos = {0, 1056, -480};
static short FloorTrapDoorBounds[12] = {-256, 256, 0, 0, -1024, -256, -1820, 1820, -5460, 5460, -1820, 1820};
OBJECT_COLLISION_BOUNDS FloorTrapDoorBounds = {-256, 256, 0, 0, -1024, -256, -1820, 1820, -5460, 5460, -1820, 1820};
static PHD_VECTOR FloorTrapDoorPos = {0, 0, -655};
static short WreckingBallData[2] = {0, 0};
ITEM_INFO* WBItem;
@ -43,7 +43,7 @@ byte Flame3xzoffs[16][2] =
{ 0x28, 0x37 },
{ 0x37, 0x37 }
};
static short FireBounds[12] = {0, 0, 0, 0, 0, 0, -1820, 1820, -5460, 5460, -1820, 1820};
OBJECT_COLLISION_BOUNDS FireBounds = {0, 0, 0, 0, 0, 0, -1820, 1820, -5460, 5460, -1820, 1820};
void LaraBurn()
{
@ -52,7 +52,7 @@ void LaraBurn()
short fxNum = CreateNewEffect(LaraItem->roomNumber);
if (fxNum != NO_ITEM)
{
Effects[fxNum].objectNumber = ID_FLAME;
EffectList[fxNum].objectNumber = ID_FLAME;
Lara.burn = true;
}
}
@ -63,7 +63,7 @@ void FlameEmitterControl(short itemNumber)
byte r, g, b;
int falloff;
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (TriggerActive(item))
{
if (item->triggerFlags < 0)
@ -151,7 +151,8 @@ void FlameEmitterControl(short itemNumber)
if (!Lara.burn
&& item->triggerFlags != 33
&& ItemNearLara(&item->pos, 600)
&& (SQUARE(LaraItem->pos.xPos - item->pos.xPos) + SQUARE(LaraItem->pos.zPos - item->pos.zPos) < 0x40000))
&& (SQUARE(LaraItem->pos.xPos - item->pos.xPos) + SQUARE(LaraItem->pos.zPos - item->pos.zPos) < 0x40000)
&& Lara.waterStatus != LW_FLYCHEAT)
{
LaraBurn();
}
@ -160,7 +161,7 @@ void FlameEmitterControl(short itemNumber)
void FlameEmitter2Control(short itemNumber)//5A1BC, 5A638 (F)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (TriggerActive(item))
{
@ -214,7 +215,7 @@ void FlameEmitter2Control(short itemNumber)//5A1BC, 5A638 (F)
void FlameControl(short fxNumber)
{
FX_INFO* fx = &Effects[fxNumber];
FX_INFO* fx = &EffectList[fxNumber];
for (int i = 0; i < 14; i++)
{
@ -279,6 +280,12 @@ void FlameControl(short fxNumber)
KillEffect(fxNumber);
Lara.burn = false;
}
if (Lara.waterStatus == LW_FLYCHEAT)
{
KillEffect(fxNumber);
Lara.burn = false;
}
}
void LavaBurn(ITEM_INFO* item)
@ -300,7 +307,7 @@ void InitialiseTrapDoor(short itemNumber) // (F) (D)
{
ITEM_INFO* item;
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
CloseTrapDoor(item);
}
@ -308,8 +315,8 @@ void TrapDoorCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll) // (F) (
{
ITEM_INFO* item;
item = &Items[itemNumber];
if (item->currentAnimState == 1 && item->frameNumber == Anims[item->animNumber].frameEnd)
item = &g_Level.Items[itemNumber];
if (item->currentAnimState == 1 && item->frameNumber == g_Level.Anims[item->animNumber].frameEnd)
ObjectCollision(itemNumber, l, coll);
}
@ -318,12 +325,12 @@ void CeilingTrapDoorCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll) /
ITEM_INFO* item;
int result, result2;
item = &Items[itemNumber];
result = TestLaraPosition(CeilingTrapDoorBounds, item, l);
item = &g_Level.Items[itemNumber];
result = TestLaraPosition(&CeilingTrapDoorBounds, item, l);
l->pos.yRot += ANGLE(180);
result2 = TestLaraPosition(CeilingTrapDoorBounds, item, l);
result2 = TestLaraPosition(&CeilingTrapDoorBounds, item, l);
l->pos.yRot += ANGLE(180);
if (TrInput & IN_ACTION && item->status != ITEM_DEACTIVATED && l->currentAnimState == STATE_LARA_JUMP_UP && l->gravityStatus && Lara.gunStatus == LG_NO_ARMS && (result || result2))
if (TrInput & IN_ACTION && item->status != ITEM_DEACTIVATED && l->currentAnimState == LS_JUMP_UP && l->gravityStatus && Lara.gunStatus == LG_NO_ARMS && (result || result2))
{
AlignLaraPosition(&CeilingTrapDoorPos, item, l);
if (result2)
@ -335,9 +342,9 @@ void CeilingTrapDoorCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll) /
Lara.gunStatus = LG_HANDS_BUSY;
l->gravityStatus = false;
l->fallspeed = 0;
l->animNumber = ANIMATION_LARA_CEILING_TRAPDOOR_OPEN;
l->frameNumber = Anims[l->animNumber].frameBase;
l->currentAnimState = STATE_LARA_FREEFALL_BIS;
l->animNumber = LA_TRAPDOOR_CEILING_OPEN;
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
l->currentAnimState = LS_FREEFALL_BIS;
AddActiveItem(itemNumber);
item->status = ITEM_ACTIVE;
item->goalAnimState = 1;
@ -354,7 +361,7 @@ void CeilingTrapDoorCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll) /
UseForcedFixedCamera = 0;
}
if (item->currentAnimState == 1 && item->frameNumber == Anims[item->animNumber].frameEnd)
if (item->currentAnimState == 1 && item->frameNumber == g_Level.Anims[item->animNumber].frameEnd)
ObjectCollision(itemNumber, l, coll);
}
@ -362,17 +369,17 @@ void FloorTrapDoorCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll) //
{
ITEM_INFO* item;
item = &Items[itemNumber];
if (TrInput & IN_ACTION && item->status != ITEM_DEACTIVATED && l->currentAnimState == STATE_LARA_STOP && l->animNumber == ANIMATION_LARA_STAY_IDLE && Lara.gunStatus == LG_NO_ARMS
item = &g_Level.Items[itemNumber];
if (TrInput & IN_ACTION && item->status != ITEM_DEACTIVATED && l->currentAnimState == LS_STOP && l->animNumber == LA_STAND_IDLE && Lara.gunStatus == LG_NO_ARMS
|| Lara.isMoving && Lara.generalPtr == (void *) itemNumber)
{
if (TestLaraPosition(FloorTrapDoorBounds, item, l))
if (TestLaraPosition(&FloorTrapDoorBounds, item, l))
{
if (MoveLaraPosition(&FloorTrapDoorPos, item, l))
{
l->animNumber = ANIMATION_LARA_FLOOR_TRAPDOOR_OPEN;
l->frameNumber = Anims[l->animNumber].frameBase;
l->currentAnimState = STATE_LARA_TRAPDOOR_FLOOR_OPEN;
l->animNumber = LA_TRAPDOOR_FLOOR_OPEN;
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
l->currentAnimState = LS_TRAPDOOR_FLOOR_OPEN;
Lara.isMoving = false;
Lara.headYrot = 0;
Lara.headXrot = 0;
@ -386,8 +393,8 @@ void FloorTrapDoorCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll) //
UseForcedFixedCamera = 1;
ForcedFixedCamera.x = item->pos.xPos - phd_sin(item->pos.yRot) / 8;
ForcedFixedCamera.y = item->pos.yPos - 2048;
if (ForcedFixedCamera.y < Rooms[item->roomNumber].maxceiling)
ForcedFixedCamera.y = Rooms[item->roomNumber].maxceiling;
if (ForcedFixedCamera.y < g_Level.Rooms[item->roomNumber].maxceiling)
ForcedFixedCamera.y = g_Level.Rooms[item->roomNumber].maxceiling;
ForcedFixedCamera.z = item->pos.zPos - phd_cos(item->pos.yRot) / 8;
ForcedFixedCamera.roomNumber = item->roomNumber;
}
@ -403,7 +410,7 @@ void FloorTrapDoorCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll) //
UseForcedFixedCamera = 0;
}
if (item->currentAnimState == 1 && item->frameNumber == Anims[item->animNumber].frameEnd)
if (item->currentAnimState == 1 && item->frameNumber == g_Level.Anims[item->animNumber].frameEnd)
ObjectCollision(itemNumber, l, coll);
}
@ -411,14 +418,14 @@ void TrapDoorControl(short itemNumber) // (F) (D)
{
ITEM_INFO* item;
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
if (TriggerActive(item))
{
if (!item->currentAnimState && item->triggerFlags >= 0)
{
item->goalAnimState = 1;
}
else if (item->frameNumber == Anims[item->animNumber].frameEnd && CurrentLevel == 14 && item->objectNumber == ID_TRAPDOOR1)
else if (item->frameNumber == g_Level.Anims[item->animNumber].frameEnd && CurrentLevel == 14 && item->objectNumber == ID_TRAPDOOR1)
{
item->status = ITEM_INVISIBLE;
}
@ -451,7 +458,7 @@ void CloseTrapDoor(ITEM_INFO* item) // (F) (D)
FLOOR_INFO* floor;
unsigned short pitsky;
r = &Rooms[item->roomNumber];
r = &g_Level.Rooms[item->roomNumber];
floor = &XZ_GET_SECTOR(r, item->pos.xPos - r->x, item->pos.zPos - r->z);
pitsky = 0;
@ -459,7 +466,7 @@ void CloseTrapDoor(ITEM_INFO* item) // (F) (D)
{
pitsky = floor->pitRoom;
floor->pitRoom = NO_ROOM;
r = &Rooms[pitsky];
r = &g_Level.Rooms[pitsky];
floor = &XZ_GET_SECTOR(r, item->pos.xPos - r->x, item->pos.zPos - r->z);
pitsky |= floor->skyRoom << 8;
floor->skyRoom = NO_ROOM;
@ -468,7 +475,7 @@ void CloseTrapDoor(ITEM_INFO* item) // (F) (D)
{
pitsky = floor->skyRoom;
floor->skyRoom = NO_ROOM;
r = &Rooms[pitsky];
r = &g_Level.Rooms[pitsky];
floor = &XZ_GET_SECTOR(r, item->pos.xPos - r->x, item->pos.zPos - r->z);
pitsky = pitsky << 8 | floor->pitRoom;
floor->pitRoom = NO_ROOM;
@ -484,21 +491,21 @@ void OpenTrapDoor(ITEM_INFO* item) // (F) (D)
FLOOR_INFO* floor;
unsigned short pitsky;
r = &Rooms[item->roomNumber];
r = &g_Level.Rooms[item->roomNumber];
floor = &XZ_GET_SECTOR(r, item->pos.xPos - r->x, item->pos.zPos - r->z);
pitsky = item->itemFlags[3];
if (item->pos.yPos == r->minfloor)
{
floor->pitRoom = (unsigned char) pitsky;
r = &Rooms[floor->pitRoom];
r = &g_Level.Rooms[floor->pitRoom];
floor = &XZ_GET_SECTOR(r, item->pos.xPos - r->x, item->pos.zPos - r->z);
floor->skyRoom = pitsky >> 8;
}
else
{
floor->skyRoom = pitsky >> 8;
r = &Rooms[floor->skyRoom];
r = &g_Level.Rooms[floor->skyRoom];
floor = &XZ_GET_SECTOR(r, item->pos.xPos - r->x, item->pos.zPos - r->z);
floor->pitRoom = (unsigned char) pitsky;
}
@ -508,12 +515,12 @@ void OpenTrapDoor(ITEM_INFO* item) // (F) (D)
void InitialiseFallingBlock(short itemNumber)
{
Items[itemNumber].meshBits = 1;
g_Level.Items[itemNumber].meshBits = 1;
}
void FallingBlockCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
if (!item->itemFlags[0] && !item->triggerFlags && item->pos.yPos == l->pos.yPos)
{
if (!((item->pos.xPos ^ l->pos.xPos) & 0xFFFFFC00) && !((l->pos.zPos ^ item->pos.zPos) & 0xFFFFFC00))
@ -530,7 +537,7 @@ void FallingBlockCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
void FallingBlockControl(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (item->triggerFlags)
{
@ -598,8 +605,8 @@ void InitialiseWreckingBall(short itemNumber)
ITEM_INFO* item;
short room;
item = &Items[itemNumber];
item->itemFlags[3] = find_a_fucking_item(ID_ANIMATING16) - Items;
item = &g_Level.Items[itemNumber];
item->itemFlags[3] = find_a_fucking_item(ID_ANIMATING16) - g_Level.Items.data();
room = item->roomNumber;
item->pos.yPos = GetCeiling(GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &room), item->pos.xPos, item->pos.yPos, item->pos.zPos) + 1644;
GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &room);
@ -613,7 +620,7 @@ void WreckingBallCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
int x, y, z, test;
short damage;
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
if (TestBoundsCollide(item, l, coll->radius))
{
x = l->pos.xPos;
@ -654,9 +661,9 @@ void WreckingBallControl(short itemNumber)
int test, x, z, oldX, oldZ, wx, wz, flagX, flagZ, height, dx, dz, ceilingX, ceilingZ, adx, adz;
short room;
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
test = 1;
item2 = &Items[item->itemFlags[3]];
item2 = &g_Level.Items[item->itemFlags[3]];
if (LaraItem->pos.xPos >= 45056 && LaraItem->pos.xPos <= 57344 && LaraItem->pos.zPos >= 26624 && LaraItem->pos.zPos <= 43008
|| item->itemFlags[2] < 900)
{
@ -800,7 +807,7 @@ void WreckingBallControl(short itemNumber)
{
item->goalAnimState = 1;
}
else if (item->frameNumber == Anims[item->animNumber].frameEnd)
else if (item->frameNumber == g_Level.Anims[item->animNumber].frameEnd)
{
SoundEffect(SFX_GRAB_DROP, &item->pos, 0);
++item->itemFlags[1];
@ -880,7 +887,7 @@ void WreckingBallControl(short itemNumber)
void FlameEmitterCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll) // (F) (D)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (Lara.gunType != WEAPON_TORCH
|| Lara.gunStatus != LG_READY
@ -888,8 +895,8 @@ void FlameEmitterCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll) // (
|| Lara.litTorch == (item->status & 1)
|| item->timer == -1
|| !(TrInput & IN_ACTION)
|| l->currentAnimState != STATE_LARA_STOP
|| l->animNumber != ANIMATION_LARA_STAY_IDLE
|| l->currentAnimState != LS_STOP
|| l->animNumber != LA_STAND_IDLE
|| l->gravityStatus)
{
if (item->objectNumber == ID_BURNING_ROOTS)
@ -900,30 +907,30 @@ void FlameEmitterCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll) // (
switch (item->objectNumber)
{
case ID_FLAME_EMITTER:
FireBounds[0] = -256;
FireBounds[1] = 256;
FireBounds[2] = 0;
FireBounds[3] = 1024;
FireBounds[4] = -800;
FireBounds[5] = 800;
FireBounds.boundingBox.X1 = -256;
FireBounds.boundingBox.X2 = 256;
FireBounds.boundingBox.Y1 = 0;
FireBounds.boundingBox.Y2 = 1024;
FireBounds.boundingBox.Z1 = -800;
FireBounds.boundingBox.Z2 = 800;
break;
case ID_FLAME_EMITTER2:
FireBounds[0] = -256;
FireBounds[1] = 256;
FireBounds[2] = 0;
FireBounds[3] = 1024;
FireBounds[4] = -600;
FireBounds[5] = 600;
FireBounds.boundingBox.X1 = -256;
FireBounds.boundingBox.X2 = 256;
FireBounds.boundingBox.Y1 = 0;
FireBounds.boundingBox.Y2 = 1024;
FireBounds.boundingBox.Z1 = -600;
FireBounds.boundingBox.Z2 = 600;
break;
case ID_BURNING_ROOTS:
FireBounds[0] = -384;
FireBounds[1] = 384;
FireBounds[2] = 0;
FireBounds[3] = 2048;
FireBounds[4] = -384;
FireBounds[5] = 384;
FireBounds.boundingBox.X1 = -384;
FireBounds.boundingBox.X2 = 384;
FireBounds.boundingBox.Y1 = 0;
FireBounds.boundingBox.Y2 = 2048;
FireBounds.boundingBox.Z1 = -384;
FireBounds.boundingBox.Z2 = 384;
break;
}
@ -931,21 +938,21 @@ void FlameEmitterCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll) // (
short oldYrot = item->pos.yRot;
item->pos.yRot = l->pos.yRot;
if (TestLaraPosition(FireBounds, item, l))
if (TestLaraPosition(&FireBounds, item, l))
{
if (item->objectNumber == ID_BURNING_ROOTS)
{
l->animNumber = ANIMATION_LARA_TORCH_LIGHT_5;
l->animNumber = LA_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->animNumber = (dy >> 8) + LA_TORCH_LIGHT_1;
}
l->currentAnimState = STATE_LARA_MISC_CONTROL;
l->frameNumber = Anims[l->animNumber].frameBase;
l->currentAnimState = LS_MISC_CONTROL;
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
Lara.flareControlLeft = false;
Lara.leftArm.lock = 3;
Lara.generalPtr = (void*)itemNumber;
@ -956,11 +963,11 @@ void FlameEmitterCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll) // (
if (Lara.generalPtr == (void*)itemNumber
&& item->status != ITEM_ACTIVE
&& l->currentAnimState == STATE_LARA_MISC_CONTROL)
&& l->currentAnimState == LS_MISC_CONTROL)
{
if (l->animNumber >= ANIMATION_LARA_TORCH_LIGHT_1 && l->animNumber <= ANIMATION_LARA_TORCH_LIGHT_5)
if (l->animNumber >= LA_TORCH_LIGHT_1 && l->animNumber <= LA_TORCH_LIGHT_5)
{
if (l->frameNumber - Anims[l->animNumber].frameBase == 40)
if (l->frameNumber - g_Level.Anims[l->animNumber].frameBase == 40)
{
TestTriggersAtXYZ(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 1, item->flags & 0x3E00);
@ -976,7 +983,7 @@ void FlameEmitterCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll) // (
void InitialiseFlameEmitter2(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->pos.yPos -= 64;
@ -1021,7 +1028,7 @@ void InitialiseFlameEmitter2(short itemNumber)
void InitialiseFlameEmitter(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (item->triggerFlags > 0)
{
@ -1093,7 +1100,7 @@ void InitialiseFlameEmitter(short itemNumber)
void FlameEmitter3Control(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (TriggerActive(item))
{
@ -1137,7 +1144,7 @@ void FlameEmitter3Control(short itemNumber)
if (item->triggerFlags >= 3 && !(GlobalCounter & 1))
{
short targetItemNumber = item->itemFlags[((GlobalCounter >> 2) & 1) + 2];
ITEM_INFO* targetItem = &Items[targetItemNumber];
ITEM_INFO* targetItem = &g_Level.Items[targetItemNumber];
dest.x = 0;
dest.y = -64;
@ -1218,7 +1225,7 @@ void FlameEmitter3Control(short itemNumber)
if (ItemNearLara(&pos, 600))
{
if (!Lara.burn)
if ((!Lara.burn) && Lara.waterStatus != LW_FLYCHEAT)
{
LaraItem->hitPoints -= 5;
LaraItem->hitStatus = true;

View file

@ -1464,7 +1464,7 @@ void phd_GetVectorAngles(int x, int y, int z, short* angles)
angles[1] = angle;
}
void phd_RotBoundingBoxNoPersp(PHD_3DPOS* pos, short* bounds, short* tbounds)
void phd_RotBoundingBoxNoPersp(PHD_3DPOS* pos, BOUNDING_BOX* bounds, BOUNDING_BOX* tbounds)
{
Matrix world = Matrix::CreateFromYawPitchRoll(
TO_RAD(pos->yRot),
@ -1472,16 +1472,16 @@ void phd_RotBoundingBoxNoPersp(PHD_3DPOS* pos, short* bounds, short* tbounds)
TO_RAD(pos->zRot)
);
Vector3 bMin = Vector3(bounds[0], bounds[2], bounds[4]);
Vector3 bMax = Vector3(bounds[1], bounds[3], bounds[5]);
Vector3 bMin = Vector3(bounds->X1, bounds->Y1, bounds->Z1);
Vector3 bMax = Vector3(bounds->X2, bounds->Y2, bounds->Z2);
bMin = Vector3::Transform(bMin, world);
bMax = Vector3::Transform(bMax, world);
tbounds[0] = bMin.x;
tbounds[1] = bMax.x;
tbounds[2] = bMin.y;
tbounds[3] = bMax.y;
tbounds[4] = bMin.z;
tbounds[5] = bMax.z;
tbounds->X1 = bMin.x;
tbounds->X2 = bMax.x;
tbounds->Y1 = bMin.y;
tbounds->Y2 = bMax.y;
tbounds->Z1 = bMin.z;
tbounds->Z2 = bMax.z;
}

View file

@ -38,4 +38,4 @@ const float lerp(float v0, float v1, float t);
int mGetAngle(int x1, int y1, int x2, int y2);
int phd_atan(int dz, int dx);
void phd_GetVectorAngles(int x, int y, int z, short* angles);
void phd_RotBoundingBoxNoPersp(PHD_3DPOS* pos, short* bounds, short* tbounds);
void phd_RotBoundingBoxNoPersp(PHD_3DPOS* pos, BOUNDING_BOX* bounds, BOUNDING_BOX* tbounds);

View file

@ -13,7 +13,7 @@
void BubblesEffect1(short fxNum, short xVel, short yVel, short zVel)
{
FX_INFO* fx = &Effects[fxNum];
FX_INFO* fx = &EffectList[fxNum];
int dx = LaraItem->pos.xPos - fx->pos.xPos;
int dz = LaraItem->pos.zPos - fx->pos.zPos;
@ -68,7 +68,7 @@ void BubblesEffect1(short fxNum, short xVel, short yVel, short zVel)
void BubblesEffect2(short fxNum, short xVel, short yVel, short zVel)
{
FX_INFO* fx = &Effects[fxNum];
FX_INFO* fx = &EffectList[fxNum];
int dx = LaraItem->pos.xPos - fx->pos.xPos;
int dz = LaraItem->pos.zPos - fx->pos.zPos;
@ -115,7 +115,7 @@ void BubblesEffect2(short fxNum, short xVel, short yVel, short zVel)
void BubblesEffect4(short fxNum, short xVel, short yVel, short zVel)
{
FX_INFO* fx = &Effects[fxNum];
FX_INFO* fx = &EffectList[fxNum];
int dx = LaraItem->pos.xPos - fx->pos.xPos;
int dz = LaraItem->pos.zPos - fx->pos.zPos;
@ -176,7 +176,7 @@ void BubblesEffect4(short fxNum, short xVel, short yVel, short zVel)
void BubblesShatterFunction(FX_INFO* fx, int param1, int param2)
{
ShatterItem.yRot = fx->pos.yRot;
ShatterItem.meshp = Meshes[fx->frameNumber];
ShatterItem.meshp = &g_Level.Meshes[fx->frameNumber];
ShatterItem.sphere.x = fx->pos.xPos;
ShatterItem.sphere.y = fx->pos.yPos;
ShatterItem.sphere.z = fx->pos.zPos;
@ -187,7 +187,7 @@ void BubblesShatterFunction(FX_INFO* fx, int param1, int param2)
void BubblesControl(short fxNum)
{
FX_INFO* fx = &Effects[fxNum];
FX_INFO* fx = &EffectList[fxNum];
short angles[2];
phd_GetVectorAngles(
@ -291,7 +291,7 @@ void BubblesControl(short fxNum)
if (fx->flag1 == 1)
{
TriggerShockwave(&fx->pos, 32, 160, 64, 64, 128, 00, 24, (((~Rooms[fx->roomNumber].flags) >> 4) & 2) << 16, 0);
TriggerShockwave(&fx->pos, 32, 160, 64, 64, 128, 00, 24, (((~g_Level.Rooms[fx->roomNumber].flags) >> 4) & 2) << 16, 0);
TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 2, fx->roomNumber);
}
else
@ -400,7 +400,7 @@ void BubblesControl(short fxNum)
}
else
{
TriggerShockwave( &fx->pos, 24, 88, 48, 64, 128, 0, 16, (((~Rooms[fx->roomNumber].flags) >> 4) & 2) << 16, 0);
TriggerShockwave( &fx->pos, 24, 88, 48, 64, 128, 0, 16, (((~g_Level.Rooms[fx->roomNumber].flags) >> 4) & 2) << 16, 0);
}
}
else

View file

@ -92,7 +92,7 @@ void SpawnLocust(ITEM_INFO* item)
void InitialiseLocust(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (item->pos.yRot > 0)
{
@ -114,7 +114,7 @@ void InitialiseLocust(short itemNumber)
void LocustControl(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (TriggerActive(item))
{
@ -152,7 +152,7 @@ void UpdateLocusts(void)
locust->counter--;
if (locust->counter == 0)
{
locust->on = FALSE;
locust->on = false;
break;
}

View file

@ -129,7 +129,7 @@ void ElectricityWiresControl(short itemNumber)
bool flag = false;
int counter = 3;
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (item->itemFlags[0] > 2)
{
@ -224,7 +224,7 @@ void ElectricityWiresControl(short itemNumber)
roomNumber = item->roomNumber;
GetFloor(pos.x, pos.y, pos.z, &roomNumber);
ROOM_INFO* r = &Rooms[roomNumber];
ROOM_INFO* r = &g_Level.Rooms[roomNumber];
if (r->flags & ENV_FLAG_WATER)
{
@ -241,7 +241,7 @@ void ElectricityWiresControl(short itemNumber)
{
if (water)
{
int flipNumber = Rooms[roomNumber].flipNumber;
int flipNumber = g_Level.Rooms[roomNumber].flipNumber;
PHD_VECTOR pos1;
pos1.x = 0;
@ -261,7 +261,7 @@ void ElectricityWiresControl(short itemNumber)
short roomNumber2 = LaraItem->roomNumber;
GetFloor(pos2.x, pos2.y, pos2.z, &roomNumber2);
if (Rooms[roomNumber1].flipNumber == flipNumber || Rooms[roomNumber2].flipNumber == flipNumber)
if (g_Level.Rooms[roomNumber1].flipNumber == flipNumber || g_Level.Rooms[roomNumber2].flipNumber == flipNumber)
{
if (LaraItem->hitPoints > 32)
{

View file

@ -13,7 +13,7 @@ void ApeControl(short itemNum)
if (!CreatureActive(itemNum))
return;
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
short head = 0;
@ -25,7 +25,7 @@ void ApeControl(short itemNum)
if (item->currentAnimState != 5)
{
item->animNumber = Objects[item->objectNumber].animIndex + 7 + (short)(GetRandomControl() / 0x4000);
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 5;
}
}
@ -174,7 +174,7 @@ void ApeControl(short itemNum)
creature->maximumTurn = 0;
item->animNumber = Objects[item->objectNumber].animIndex + 19;
item->currentAnimState = 11;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
break;
default:

View file

@ -13,7 +13,7 @@ void BearControl(short itemNum)
if (!CreatureActive(itemNum))
return;
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
short head = 0;
@ -54,7 +54,7 @@ void BearControl(short itemNum)
}
item->animNumber = Objects[item->objectNumber].animIndex + 20;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 9;
break;
}

View file

@ -85,14 +85,14 @@ static bool RatIsInWater(ITEM_INFO* item, CREATURE_INFO* big_rat)
// initialised at loading level
void InitialiseBigRat(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
InitialiseCreature(itemNumber);
// if the room is a "water room"
if (Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
{
item->animNumber = Objects[item->objectNumber].animIndex + BIG_RAT_ANIM_SWIM;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = BIG_RAT_SWIM;
item->goalAnimState = BIG_RAT_SWIM;
}
@ -100,7 +100,7 @@ void InitialiseBigRat(short itemNumber)
else
{
item->animNumber = Objects[item->objectNumber].animIndex + BIG_RAT_ANIM_EMPTY;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = BIG_RAT_STOP;
item->goalAnimState = BIG_RAT_STOP;
}
@ -113,13 +113,13 @@ void BigRatControl(short itemNumber)
return;
ITEM_INFO* item;
ObjectInfo* obj;
OBJECT_INFO* obj;
CREATURE_INFO* big_rat;
AI_INFO info;
short head, angle;
int WaterHeight;
item = &Items[itemNumber];
item = &g_Level.Items[itemNumber];
obj = &Objects[item->objectNumber];
big_rat = GetCreatureInfo(item);
head = angle = 0;
@ -130,10 +130,10 @@ void BigRatControl(short itemNumber)
if (item->currentAnimState != BIG_RAT_LAND_DEATH && item->currentAnimState != BIG_RAT_WATER_DEATH)
{
// water
if (Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
{
item->animNumber = obj->animIndex + BIG_RAT_ANIM_WATER_DEATH;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = BIG_RAT_WATER_DEATH;
item->goalAnimState = BIG_RAT_WATER_DEATH;
}
@ -141,14 +141,14 @@ void BigRatControl(short itemNumber)
else
{
item->animNumber = obj->animIndex + BIG_RAT_ANIM_LAND_DEATH;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = BIG_RAT_LAND_DEATH;
item->goalAnimState = BIG_RAT_LAND_DEATH;
}
}
// creatures in water are floating after death.
if (Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
CreatureFloat(itemNumber);
}
else
@ -171,7 +171,7 @@ void BigRatControl(short itemNumber)
if ((item->hitStatus || info.distance < BIG_RAT_ALERT_RANGE) || (TargetVisible(item, &info) && info.distance < BIG_RAT_VISIBILITY_RANGE))
{
if (!big_rat->alerted)
big_rat->alerted = TRUE;
big_rat->alerted = true;
AlertAllGuards(itemNumber);
}
@ -213,7 +213,7 @@ void BigRatControl(short itemNumber)
{
CreatureEffect(item, &big_ratBite, DoBloodSplat);
LaraItem->hitPoints -= BIG_RAT_BITE_DAMAGE;
LaraItem->hitStatus = TRUE;
LaraItem->hitStatus = true;
item->requiredAnimState = BIG_RAT_STOP;
}
break;
@ -223,7 +223,7 @@ void BigRatControl(short itemNumber)
{
CreatureEffect(item, &big_ratBite, DoBloodSplat);
LaraItem->hitPoints -= BIG_RAT_CHARGE_DAMAGE;
LaraItem->hitStatus = TRUE;
LaraItem->hitStatus = true;
item->requiredAnimState = BIG_RAT_RUN;
}
break;
@ -253,7 +253,7 @@ void BigRatControl(short itemNumber)
{
CreatureEffect(item, &big_ratBite, DoBloodSplat);
LaraItem->hitPoints -= BIG_RAT_BITE_DAMAGE;
LaraItem->hitStatus = TRUE;
LaraItem->hitStatus = true;
}
item->goalAnimState = BIG_RAT_SWIM;

View file

@ -29,7 +29,7 @@ void DoppelgangerControl(short itemNum)
int x, y, z;
short room_num;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
if (item->hitPoints < 1000) // If Evil Lara being Injured
{ // then take the hits off Lara instead...
@ -62,10 +62,10 @@ void DoppelgangerControl(short itemNum)
if (h >= lh + WALL_SIZE && !LaraItem->gravityStatus)
{
item->goalAnimState = STATE_LARA_FREEFALL; // Make Player Stop Immediately
item->currentAnimState = STATE_LARA_FREEFALL; // and Skip directly into fastfall
item->frameNumber = GF(ANIMATION_LARA_SMASH_JUMP, 0);
item->animNumber = ANIMATION_LARA_SMASH_JUMP;
item->goalAnimState = LS_FREEFALL; // Make Player Stop Immediately
item->currentAnimState = LS_FREEFALL; // and Skip directly into fastfall
item->frameNumber = GF(LA_JUMP_WALL_SMASH_START, 0);
item->animNumber = LA_JUMP_WALL_SMASH_START;
item->gravityStatus = true;
item->fallspeed = 0;
item->speed = 0;
@ -93,8 +93,8 @@ void DoppelgangerControl(short itemNum)
TestTriggers(TriggerIndex, TRUE, 0);
item->gravityStatus = false;
item->fallspeed = 0;
item->goalAnimState = STATE_LARA_DEATH;
item->requiredAnimState = STATE_LARA_DEATH;
item->goalAnimState = LS_DEATH;
item->requiredAnimState = LS_DEATH;
}
}
}

View file

@ -42,7 +42,7 @@ void NatlaControl(short itemNum)
short facing = 0;
short fx_number, timer;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
natla = (CREATURE_INFO*)item->data;
head = angle = tilt = 0;
gun = natla->jointRotation[0] * 7 / 8;
@ -101,7 +101,7 @@ void NatlaControl(short itemNum)
fx_number = CreatureEffect(item, &natla_gun, ShardGun);
if (fx_number != NO_ITEM)
{
fx = &Effects[fx_number];
fx = &EffectList[fx_number];
gun = fx->pos.xRot;
SoundEffect(123, &fx->pos, NULL);
}
@ -117,7 +117,7 @@ void NatlaControl(short itemNum)
fx_number = CreatureEffect(item, &natla_gun, ShardGun);
if (fx_number != NO_ITEM)
{
fx = &Effects[fx_number];
fx = &EffectList[fx_number];
gun = fx->pos.xRot;
SoundEffect(123, &fx->pos, NULL);
}
@ -225,7 +225,7 @@ void NatlaControl(short itemNum)
fx_number = CreatureEffect(item, &natla_gun, BombGun);
if (fx_number != NO_ITEM)
{
fx = &Effects[fx_number];
fx = &EffectList[fx_number];
gun = fx->pos.xRot;
SoundEffect(123, &fx->pos, NULL);
}
@ -248,13 +248,13 @@ void NatlaControl(short itemNum)
/* Eat this ... */
fx_number = CreatureEffect(item, &natla_gun, BombGun);
if (fx_number != NO_ITEM)
gun = Effects[fx_number].pos.xRot;
gun = EffectList[fx_number].pos.xRot;
fx_number = CreatureEffect(item, &natla_gun, BombGun);
if (fx_number != NO_ITEM)
Effects[fx_number].pos.yRot += (short)((GetRandomControl() - 0x4000) / 4);
EffectList[fx_number].pos.yRot += (short)((GetRandomControl() - 0x4000) / 4);
fx_number = CreatureEffect(item, &natla_gun, BombGun);
if (fx_number != NO_ITEM)
Effects[fx_number].pos.yRot += (short)((GetRandomControl() - 0x4000) / 4);
EffectList[fx_number].pos.yRot += (short)((GetRandomControl() - 0x4000) / 4);
item->requiredAnimState = NATLA_STOP;
}

View file

@ -40,7 +40,7 @@ void NatlaEvilControl(short itemNum)
FLOOR_INFO* floor;
short head, angle;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
abort = (CREATURE_INFO*)item->data;
head = angle = 0;
@ -50,7 +50,7 @@ void NatlaEvilControl(short itemNum)
if (item->currentAnimState != ABORT_DEATH)
{
item->animNumber = Objects[item->objectNumber].animIndex + ABORT_DIE_ANIM;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = ABORT_DEATH;
}
}
@ -169,7 +169,7 @@ void NatlaEvilControl(short itemNum)
item->goalAnimState = ABORT_KILL;
LaraItem->animNumber = Objects[ID_LARA_EXTRA_ANIMS].animIndex;
LaraItem->frameNumber = Anims[LaraItem->animNumber].frameBase;
LaraItem->frameNumber = g_Level.Anims[LaraItem->animNumber].frameBase;
LaraItem->currentAnimState = LaraItem->goalAnimState = 46;
LaraItem->roomNumber = item->roomNumber;
LaraItem->pos.xPos = item->pos.xPos;

View file

@ -11,7 +11,7 @@ BITE_INFO wolfBite = { 0, -14, 174, 6 };
void InitialiseWolf(short itemNum)
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
ClearItem(itemNum);
item->frameNumber = 96;
}
@ -21,7 +21,7 @@ void WolfControl(short itemNum)
if (!CreatureActive(itemNum))
return;
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
short head = 0;
@ -33,7 +33,7 @@ void WolfControl(short itemNum)
if (item->currentAnimState != 11)
{
item->animNumber = Objects[item->objectNumber].animIndex + 20 + (short)(GetRandomControl() / 11000);
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 11;
}
}

View file

@ -18,7 +18,7 @@
#include "setup.h"
#include "level.h"
static void StartBaddy(ObjectInfo* obj)
static void StartBaddy(OBJECT_INFO* obj)
{
obj = &Objects[ID_WOLF];
if (obj->loaded)
@ -36,7 +36,7 @@ static void StartBaddy(ObjectInfo* obj)
obj->saveAnim = true;
obj->saveFlags = true;
Bones[obj->boneIndex + 2 * 4] |= ROT_Y;
g_Level.Bones[obj->boneIndex + 2 * 4] |= ROT_Y;
}
obj = &Objects[ID_BEAR];
@ -55,7 +55,7 @@ static void StartBaddy(ObjectInfo* obj)
obj->saveAnim = true;
obj->saveFlags = true;
Bones[obj->boneIndex + 13 * 4] |= ROT_Y;
g_Level.Bones[obj->boneIndex + 13 * 4] |= ROT_Y;
}
obj = &Objects[ID_APE];
@ -92,7 +92,7 @@ static void StartBaddy(ObjectInfo* obj)
obj->saveFlags = true;
obj->waterCreature = true; // dont want the rat to be killed when going in water !
obj->zoneType = ZONE_WATER;
Bones[obj->boneIndex + 4] |= ROT_Y;
g_Level.Bones[obj->boneIndex + 4] |= ROT_Y;
}
obj = &Objects[ID_NATLA];
@ -109,7 +109,7 @@ static void StartBaddy(ObjectInfo* obj)
obj->saveFlags = true;
obj->savePosition = true;
obj->saveHitpoints = true;
Bones[obj->boneIndex + 2 * 4] |= (ROT_Z | ROT_X);
g_Level.Bones[obj->boneIndex + 2 * 4] |= (ROT_Z | ROT_X);
}
obj = &Objects[ID_WINGED_NATLA];
@ -126,7 +126,7 @@ static void StartBaddy(ObjectInfo* obj)
obj->saveFlags = true;
obj->savePosition = true;
obj->saveHitpoints = true;
Bones[obj->boneIndex + 1 * 4] |= ROT_Y;
g_Level.Bones[obj->boneIndex + 1 * 4] |= ROT_Y;
}
obj = &Objects[ID_LARA_DOPPELGANGER];
@ -150,17 +150,17 @@ static void StartBaddy(ObjectInfo* obj)
}
}
static void StartObject(ObjectInfo* obj)
static void StartObject(OBJECT_INFO* obj)
{
}
static void StartTrap(ObjectInfo* obj)
static void StartTrap(OBJECT_INFO* obj)
{
}
static ObjectInfo* objToInit;
static OBJECT_INFO* objToInit;
void InitialiseTR1Objects()
{
StartBaddy(objToInit);

View file

@ -13,7 +13,7 @@ void BarracudaControl(short itemNum)
if (!CreatureActive(itemNum))
return;
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
short angle = 0;
short head = 0;
@ -23,7 +23,7 @@ void BarracudaControl(short itemNum)
if (item->currentAnimState != 6)
{
item->animNumber = Objects[ID_BARRACUDA].animIndex + 6;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 6;
}

View file

@ -19,7 +19,7 @@ void BirdMonsterControl(short itemNum)
AI_INFO info;
short angle, head;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
monster = (CREATURE_INFO*)item->data;
angle = head = 0;
@ -28,7 +28,7 @@ void BirdMonsterControl(short itemNum)
if (item->currentAnimState != 9)
{
item->animNumber = Objects[item->objectNumber].animIndex + 20;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 9;
}
}

View file

@ -61,7 +61,7 @@ enum DRAGON_STATE {
static void createBartoliLight(short ItemIndex, int type)
{
ITEM_INFO* item;
item = &Items[ItemIndex];
item = &g_Level.Items[ItemIndex];
if (type == 0)
TriggerDynamicLight(item->pos.xPos, item->pos.yPos - STEP_SIZE, item->pos.zPos, (GetRandomControl() & 150) + 25, (GetRandomControl() & 30) + 200, (GetRandomControl() & 25) + 200, (GetRandomControl() & 20) + 200);
@ -106,7 +106,7 @@ static void createExplosion(ITEM_INFO* item)
ExplIndex = CreateItem();
if (ExplIndex != NO_ITEM)
{
itemExplo = &Items[ExplIndex];
itemExplo = &g_Level.Items[ExplIndex];
if (item->timer == BOOM_TIME)
itemExplo->objectNumber = ID_SPHERE_OF_DOOM;
@ -134,7 +134,7 @@ static void createExplosion(ITEM_INFO* item)
static void createDragonBone(short front_number)
{
/* Create the bones of the dragon */
/* Create the Bones of the dragon */
short bone_back, bone_front;
ITEM_INFO* back_dragon, *front_dragon, *item;
@ -143,9 +143,9 @@ static void createDragonBone(short front_number)
if (bone_back != NO_ITEM && bone_front != NO_ITEM)
{
item = &Items[front_number];
item = &g_Level.Items[front_number];
back_dragon = &Items[bone_back];
back_dragon = &g_Level.Items[bone_back];
back_dragon->objectNumber = ID_DRAGON_BONE_BACK;
back_dragon->pos.xPos = item->pos.xPos;
back_dragon->pos.yPos = item->pos.yPos;
@ -156,7 +156,7 @@ static void createDragonBone(short front_number)
InitialiseItem(bone_back);
front_dragon = &Items[bone_front];
front_dragon = &g_Level.Items[bone_front];
front_dragon->objectNumber = ID_DRAGON_BONE_FRONT;
front_dragon->pos.xPos = item->pos.xPos;
front_dragon->pos.yPos = item->pos.yPos;
@ -178,7 +178,7 @@ void DragonCollision(short itemNum, ITEM_INFO* laraitem, COLL_INFO* coll)
int anim, frame;
/* If Lara has collided with correct bit of dragon, then start him up */
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
if (!TestBoundsCollide(item, laraitem, coll->radius))
return;
@ -205,7 +205,7 @@ void DragonCollision(short itemNum, ITEM_INFO* laraitem, COLL_INFO* coll)
/* Check if in a position to pull dagger from dragon */
anim = item->animNumber - Objects[ID_DRAGON_BACK].animIndex;
frame = item->frameNumber - Anims[item->animNumber].frameBase;
frame = item->frameNumber - g_Level.Anims[item->animNumber].frameBase;
if ((anim == DRAGON_DEAD_ANIM || (anim == DRAGON_DEAD_ANIM + 1 && frame <= DRAGON_ALMOST_LIVE)) &&
(TrInput & IN_ACTION) && item->objectNumber == ID_DRAGON_BACK && !laraitem->gravityStatus &&
shift <= DRAGON_MID && shift > DRAGON_CLOSE - 350 && side_shift > -350 && side_shift < 350 &&
@ -213,7 +213,7 @@ void DragonCollision(short itemNum, ITEM_INFO* laraitem, COLL_INFO* coll)
{
/* Jump to animation state in LARA_EXTRA */
laraitem->animNumber = Objects[ID_LARA_EXTRA_ANIMS].animIndex;
laraitem->frameNumber = Anims[laraitem->animNumber].frameBase;
laraitem->frameNumber = g_Level.Anims[laraitem->animNumber].frameBase;
laraitem->currentAnimState = 0;
laraitem->goalAnimState = 7;
@ -239,7 +239,8 @@ void DragonCollision(short itemNum, ITEM_INFO* laraitem, COLL_INFO* coll)
Lara.gunStatus = LG_HANDS_BUSY;
Lara.hitDirection = -1;
LARA_MESHES(ID_LARA_EXTRA_ANIMS, LM_RHAND);
//LARA_MESHES(ID_LARA_EXTRA_ANIMS, LM_RHAND);
Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA_EXTRA_ANIMS].meshIndex + LM_RHAND;
/* Do cinematic camera */
Camera.type = CINEMATIC_CAMERA;
@ -247,7 +248,7 @@ void DragonCollision(short itemNum, ITEM_INFO* laraitem, COLL_INFO* coll)
//memcpy(&CinematicPos, &laraitem->pos, sizeof(PHD_3DPOS));
/* Flag dragon is dead forever */
((CREATURE_INFO*)Items[(short)item->data].data)->flags = -1;
((CREATURE_INFO*)g_Level.Items[(short)item->data].data)->flags = -1;
return;
}
@ -277,7 +278,7 @@ void DragonControl(short backNum)
short head, angle;
short itemNum;
back = &Items[backNum];
back = &g_Level.Items[backNum];
if (back->data != NULL && back->objectNumber == ID_DRAGON_FRONT) // check if data is not null and back is front
return;
@ -285,7 +286,7 @@ void DragonControl(short backNum)
if (!CreatureActive(itemNum))
return;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
dragon = (CREATURE_INFO*)item->data;
head = angle = 0;
@ -294,7 +295,7 @@ void DragonControl(short backNum)
if (item->currentAnimState != DRAGON_DEATH)
{
item->animNumber = Objects[ID_DRAGON_FRONT].animIndex + 21;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = item->goalAnimState = DRAGON_DEATH;
dragon->flags = 0;
}
@ -481,7 +482,7 @@ void DragonControl(short backNum)
/* Set back end to same frame */
back->currentAnimState = item->currentAnimState;
back->animNumber = Objects[ID_DRAGON_BACK].animIndex + (item->animNumber - Objects[ID_DRAGON_FRONT].animIndex);
back->frameNumber = Anims[back->animNumber].frameBase + (item->frameNumber - Anims[item->animNumber].frameBase);
back->frameNumber = g_Level.Anims[back->animNumber].frameBase + (item->frameNumber - g_Level.Anims[item->animNumber].frameBase);
back->pos.xPos = item->pos.xPos;
back->pos.yPos = item->pos.yPos;
back->pos.zPos = item->pos.zPos;
@ -497,7 +498,7 @@ void InitialiseBartoli(short itemNum)
ITEM_INFO* item, *back, *front;
short back_item, front_item;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
item->pos.xPos -= STEP_SIZE * 2;
item->pos.zPos -= STEP_SIZE * 2;
@ -506,7 +507,7 @@ void InitialiseBartoli(short itemNum)
front_item = CreateItem();
if (back_item != NO_ITEM && front_item != NO_ITEM)
{
back = &Items[back_item];
back = &g_Level.Items[back_item];
back->objectNumber = ID_DRAGON_BACK;
back->pos.xPos = item->pos.xPos;
back->pos.yPos = item->pos.yPos;
@ -521,7 +522,7 @@ void InitialiseBartoli(short itemNum)
item->data = (void*)back_item; // Bartoli points at back of dragon
front = &Items[front_item];
front = &g_Level.Items[front_item];
front->objectNumber = ID_DRAGON_FRONT;
front->pos.xPos = item->pos.xPos;
front->pos.yPos = item->pos.yPos;
@ -535,7 +536,7 @@ void InitialiseBartoli(short itemNum)
back->data = (void*)front_item; // back of dragon points at front
LevelItems += 2;
g_Level.NumItems += 2;
}
}
@ -544,7 +545,7 @@ void BartoliControl(short itemNum)
ITEM_INFO* item, *back, *front;
short front_item, back_item;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
if (item->timer)
{
@ -561,7 +562,7 @@ void BartoliControl(short itemNum)
front_item = CreateItem();
if (front_item != NO_ITEM)
{
front = &Items[front_item];
front = &g_Level.Items[front_item];
if (item->timer == BOOM_TIME)
front->objectNumber = ID_SPHERE_OF_DOOM;
else if (item->timer == BOOM_TIME + 10)
@ -582,10 +583,10 @@ void BartoliControl(short itemNum)
{
/* Convert Bartoli into a dragon */
back_item = (short)item->data;
back = &Items[back_item];
back = &g_Level.Items[back_item];
front_item = (short)back->data;
front = &Items[front_item];
front = &g_Level.Items[front_item];
front->touchBits = back->touchBits = 0;
EnableBaddieAI(front_item, 1);

View file

@ -12,19 +12,19 @@ BITE_INFO crowBite = { 2, 10, 60, 14 };
void InitialiseEagle(short itemNum)
{
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
ClearItem(itemNum);
if (item->objectNumber == ID_CROW)
{
item->animNumber = Objects[ID_CROW].animIndex + 14;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = item->goalAnimState = 7;
}
else
{
item->animNumber = Objects[ID_EAGLE].animIndex + 5;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = item->goalAnimState = 2;
}
}
@ -34,7 +34,7 @@ void EagleControl(short itemNum)
if (!CreatureActive(itemNum))
return;
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
short angle = 0;
@ -63,7 +63,7 @@ void EagleControl(short itemNum)
else
item->animNumber = Objects[ID_EAGLE].animIndex + 8;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 4;
item->gravityStatus = 1;
item->speed = 0;

View file

@ -19,7 +19,7 @@ void KnifeControl(short fxNum)
short roomNumber;
FLOOR_INFO* floor;
fx = &Effects[fxNum];
fx = &EffectList[fxNum];
if (fx->counter <= 0)
{
@ -107,7 +107,7 @@ void KnifethrowerControl(short itemNum)
AI_INFO info;
short angle, torso, head, tilt;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
knife = (CREATURE_INFO*)item->data;
angle = torso = head = tilt = 0;
@ -116,7 +116,7 @@ void KnifethrowerControl(short itemNum)
if (item->currentAnimState != 10)
{
item->animNumber = Objects[item->objectNumber].animIndex + 23;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 10;
}
}

View file

@ -20,7 +20,7 @@ void MercenaryUziControl(short itemNum)
AI_INFO info;
short angle, head_y, head_x, torso_y, torso_x, tilt;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
mc1 = (CREATURE_INFO*)item->data;
angle = head_y = head_x = torso_y = torso_x = tilt = 0;
@ -29,7 +29,7 @@ void MercenaryUziControl(short itemNum)
if (item->currentAnimState != 13)
{
item->animNumber = Objects[item->objectNumber].animIndex + 14;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 13;
}
}
@ -209,7 +209,7 @@ void MercenaryAutoPistolControl(short itemNum)
AI_INFO info;
short angle, head_y, head_x, torso_y, torso_x, tilt;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
mc2 = (CREATURE_INFO*)item->data;
angle = head_y = head_x = torso_y = torso_x = tilt = 0;
@ -218,7 +218,7 @@ void MercenaryAutoPistolControl(short itemNum)
if (item->currentAnimState != 11)
{
item->animNumber = Objects[item->objectNumber].animIndex + 9;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 11;
}
}

View file

@ -22,7 +22,7 @@ void MonkControl(short itemNum)
AI_INFO info;
int random;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
monk = (CREATURE_INFO*)item->data;
torso = angle = tilt = 0;
@ -31,7 +31,7 @@ void MonkControl(short itemNum)
if (item->currentAnimState != 9)
{
item->animNumber = Objects[item->objectNumber].animIndex + 20 + (GetRandomControl() / 0x4000);
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 9;
}
}

View file

@ -13,7 +13,7 @@ void RatControl(short itemNum)
if (!CreatureActive(itemNum))
return;
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
short head = 0;
short angle = 0;
@ -24,7 +24,7 @@ void RatControl(short itemNum)
if (item->currentAnimState != 6)
{
item->animNumber = Objects[item->objectNumber].animIndex + 9;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 6;
}
}

View file

@ -13,7 +13,7 @@ void SharkControl(short itemNum)
if (!CreatureActive(itemNum))
return;
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
short angle = 0;
short head = 0;
@ -23,7 +23,7 @@ void SharkControl(short itemNum)
if (item->currentAnimState != 5)
{
item->animNumber = Objects[ID_SHARK].animIndex + 4;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 5;
}
CreatureFloat(itemNum);

View file

@ -13,7 +13,7 @@ void SilencerControl(short itemNum)
if (!CreatureActive(itemNum))
return;
ITEM_INFO* item = &Items[itemNum];
ITEM_INFO* item = &g_Level.Items[itemNum];
CREATURE_INFO* silencer = (CREATURE_INFO*)item->data;
AI_INFO info;
short angle = 0, torso_y = 0, torso_x = 0, head_y = 0, tilt = 0;
@ -23,7 +23,7 @@ void SilencerControl(short itemNum)
if (item->currentAnimState != 12 && item->currentAnimState != 13)
{
item->animNumber = Objects[item->objectNumber].animIndex + 20; // die 21 is for heavy weapon.
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 13;
}
}

View file

@ -30,8 +30,8 @@ void InitialiseSkidman(short itemNum)
skidoo_item = CreateItem();
if (skidoo_item != NO_ITEM)
{
item = &Items[itemNum];
skidoo = &Items[skidoo_item];
item = &g_Level.Items[itemNum];
skidoo = &g_Level.Items[skidoo_item];
skidoo->objectNumber = ID_SNOWMOBILE_GUN;
skidoo->pos.xPos = item->pos.xPos;
skidoo->pos.yPos = item->pos.yPos;
@ -46,7 +46,7 @@ void InitialiseSkidman(short itemNum)
// The skidman remembers his skidoo
item->data = (void*)skidoo_item;
LevelItems++;
g_Level.NumItems++;
}
else
{
@ -58,7 +58,7 @@ void SkidManCollision(short itemNum, ITEM_INFO* laraitem, COLL_INFO* coll)
{
ITEM_INFO* item;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
if (!TestBoundsCollide(item, laraitem, coll->radius))
return;
if (!TestCollision(item, laraitem))
@ -88,7 +88,7 @@ void SkidManControl(short riderNum)
short angle, item_number;
int damage;
rider = &Items[riderNum];
rider = &g_Level.Items[riderNum];
if (rider->data == NULL)
{
printf("FATAL: rider data not contains the skidoo itemNumber !");
@ -96,7 +96,7 @@ void SkidManControl(short riderNum)
}
item_number = (short)rider->data;
item = &Items[item_number];
item = &g_Level.Items[item_number];
/* Need to activate AI for skidoo (it's the skidoo that holds the brain) if not done yet */
if (!item->data)
@ -120,7 +120,7 @@ void SkidManControl(short riderNum)
rider->roomNumber = item->roomNumber;
rider->animNumber = Objects[ID_SNOWMOBILE_DRIVER].animIndex + SMAN_DEATH_ANIM;
rider->frameNumber = Anims[rider->animNumber].frameBase;
rider->frameNumber = g_Level.Anims[rider->animNumber].frameBase;
rider->currentAnimState = SMAN_DEATH;
/* Break Lara's lock */
@ -230,7 +230,7 @@ void SkidManControl(short riderNum)
ItemNewRoom(riderNum, item->roomNumber);
rider->animNumber = item->animNumber + (Objects[ID_SNOWMOBILE_DRIVER].animIndex - Objects[ID_SNOWMOBILE_GUN].animIndex);
rider->frameNumber = item->frameNumber + (Anims[rider->animNumber].frameBase - Anims[item->animNumber].frameBase);
rider->frameNumber = item->frameNumber + (g_Level.Anims[rider->animNumber].frameBase - g_Level.Anims[item->animNumber].frameBase);
}
else if (rider->status == ITEM_DEACTIVATED && item->speed == 0 && item->fallspeed == 0)
{

View file

@ -39,10 +39,10 @@ void InitialiseSpearGuardian(short itemNum)
ClearItem(itemNum);
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
item->animNumber = Objects[item->objectNumber].animIndex + 48;
anim = &Anims[item->animNumber];
anim = &g_Level.Anims[item->animNumber];
item->frameNumber = anim->frameBase;
item->currentAnimState = anim->currentAnimState;
@ -62,7 +62,7 @@ void SpearGuardianControl(short itemNum)
int random, lara_alive;
AI_INFO info;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
xian = (CREATURE_INFO*)item->data;
head = neck = angle = tilt = 0;
lara_alive = (LaraItem->hitPoints > 0);

View file

@ -47,7 +47,7 @@ static void SpiderLeap(short itemNum, ITEM_INFO* item, short angle)
ItemNewRoom(item->roomNumber, vec.roomNumber);
item->animNumber = Objects[item->objectNumber].animIndex + 2;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 5;
CreatureAnimation(itemNum, angle, 0);
@ -63,7 +63,7 @@ void SmallSpiderControl(short itemNum)
AI_INFO info;
short angle;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
spider = (CREATURE_INFO*)item->data;
angle = 0;
@ -168,7 +168,7 @@ void BigSpiderControl(short itemNum)
AI_INFO info;
short angle;
item = &Items[itemNum];
item = &g_Level.Items[itemNum];
spider = (CREATURE_INFO*)item->data;
angle = 0;
@ -177,7 +177,7 @@ void BigSpiderControl(short itemNum)
if (item->currentAnimState != 7)
{
item->animNumber = Objects[item->objectNumber].animIndex + 2;
item->frameNumber = Anims[item->animNumber].frameBase;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 7;
}
}

Some files were not shown because too many files have changed in this diff Show more