mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-16 01:54:38 +02:00
fix bridges, fix thor hammer
This commit is contained in:
@@ -270,11 +270,12 @@ struct Controller {
|
|||||||
TR::Entity &e = level->entities[cmd.args];
|
TR::Entity &e = level->entities[cmd.args];
|
||||||
Controller *controller = (Controller*)e.controller;
|
Controller *controller = (Controller*)e.controller;
|
||||||
if (!controller) continue; // Block UpdateFloor issue while entities initialization
|
if (!controller) continue; // Block UpdateFloor issue while entities initialization
|
||||||
if (!controller->isCollider()) continue;
|
|
||||||
|
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
case TR::Entity::TRAP_DOOR_1 :
|
case TR::Entity::TRAP_DOOR_1 :
|
||||||
case TR::Entity::TRAP_DOOR_2 : {
|
case TR::Entity::TRAP_DOOR_2 : {
|
||||||
|
if (!controller->isCollider()) continue;
|
||||||
|
|
||||||
int dirX, dirZ;
|
int dirX, dirZ;
|
||||||
e.getAxis(dirX, dirZ);
|
e.getAxis(dirX, dirZ);
|
||||||
|
|
||||||
@@ -293,6 +294,8 @@ struct Controller {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TR::Entity::TRAP_FLOOR : {
|
case TR::Entity::TRAP_FLOOR : {
|
||||||
|
if (!controller->isCollider()) continue;
|
||||||
|
|
||||||
if (sx != int(controller->pos.x) / 1024 || sz != int(controller->pos.z) / 1024)
|
if (sx != int(controller->pos.x) / 1024 || sz != int(controller->pos.z) / 1024)
|
||||||
break;
|
break;
|
||||||
int ey = int(controller->pos.y) - 512;
|
int ey = int(controller->pos.y) - 512;
|
||||||
@@ -306,6 +309,8 @@ struct Controller {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TR::Entity::DRAWBRIDGE : {
|
case TR::Entity::DRAWBRIDGE : {
|
||||||
|
if (controller->isCollider()) continue; // drawbridge is collidable in inactive state, but it works as floor only when active
|
||||||
|
|
||||||
if (controller->flags.active != TR::ACTIVE) continue;
|
if (controller->flags.active != TR::ACTIVE) continue;
|
||||||
int dirX, dirZ;
|
int dirX, dirZ;
|
||||||
e.getAxis(dirX, dirZ);
|
e.getAxis(dirX, dirZ);
|
||||||
@@ -326,10 +331,14 @@ struct Controller {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TR::Entity::HAMMER_HANDLE : {
|
case TR::Entity::HAMMER_HANDLE : {
|
||||||
|
if (!controller->isCollider()) continue;
|
||||||
|
|
||||||
int dirX, dirZ;
|
int dirX, dirZ;
|
||||||
e.getAxis(dirX, dirZ);
|
e.getAxis(dirX, dirZ);
|
||||||
if (abs(int(controller->pos.x) + dirX * 1024 * 3 - x) < 512 && abs(int(controller->pos.z) + dirZ * 1024 * 3 - z) < 512)
|
if (abs(int(controller->pos.x) + dirX * 1024 * 3 - x) < 512 && abs(int(controller->pos.z) + dirZ * 1024 * 3 - z) < 512) {
|
||||||
info.floor -= 1024 * 3;
|
info.floor -= 1024 * 3;
|
||||||
|
info.trigCmdCount = 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TR::Entity::BRIDGE_1 :
|
case TR::Entity::BRIDGE_1 :
|
||||||
|
@@ -2825,7 +2825,9 @@ namespace TR {
|
|||||||
initRoomMeshes();
|
initRoomMeshes();
|
||||||
initAnimTex();
|
initAnimTex();
|
||||||
|
|
||||||
memset(&state, 0, sizeof(state));
|
memset(&gameStats, 0, sizeof(gameStats));
|
||||||
|
memset(&levelStats, 0, sizeof(levelStats));
|
||||||
|
memset(&state, 0, sizeof(state));
|
||||||
|
|
||||||
initExtra();
|
initExtra();
|
||||||
initCutscene();
|
initCutscene();
|
||||||
|
33
src/level.h
33
src/level.h
@@ -97,7 +97,7 @@ struct Level : IGame {
|
|||||||
inventory->toggle(playerIndex, Inventory::Page(page));
|
inventory->toggle(playerIndex, Inventory::Page(page));
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveSlot createSaveSlot(TR::LevelID id, bool checkpoint) {
|
SaveSlot createSaveSlot(TR::LevelID id, bool checkpoint, bool dummy = false) {
|
||||||
SaveSlot slot;
|
SaveSlot slot;
|
||||||
slot.level = id | (checkpoint ? LVL_FLAG_CHECKPOINT : 0);
|
slot.level = id | (checkpoint ? LVL_FLAG_CHECKPOINT : 0);
|
||||||
|
|
||||||
@@ -117,18 +117,28 @@ struct Level : IGame {
|
|||||||
ptr += sizeof(*itemsCount);
|
ptr += sizeof(*itemsCount);
|
||||||
|
|
||||||
*itemsCount = 0;
|
*itemsCount = 0;
|
||||||
for (int i = 0; i < inventory->itemsCount; i++) {
|
if (dummy) {
|
||||||
Inventory::Item *invItem = inventory->items[i];
|
|
||||||
|
|
||||||
if (!TR::Entity::isPickup(TR::Entity::convFromInv(invItem->type))) continue;
|
|
||||||
|
|
||||||
SaveItem *item = (SaveItem*)ptr;
|
SaveItem *item = (SaveItem*)ptr;
|
||||||
ptr += sizeof(*item);
|
ptr += sizeof(*item);
|
||||||
|
|
||||||
item->type = invItem->type;
|
item->type = TR::Entity::INV_PISTOLS;
|
||||||
item->count = invItem->count;
|
item->count = UNLIMITED_AMMO;
|
||||||
|
|
||||||
(*itemsCount)++;
|
*itemsCount = 1;
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < inventory->itemsCount; i++) {
|
||||||
|
Inventory::Item *invItem = inventory->items[i];
|
||||||
|
|
||||||
|
if (!TR::Entity::isPickup(TR::Entity::convFromInv(invItem->type))) continue;
|
||||||
|
|
||||||
|
SaveItem *item = (SaveItem*)ptr;
|
||||||
|
ptr += sizeof(*item);
|
||||||
|
|
||||||
|
item->type = invItem->type;
|
||||||
|
item->count = invItem->count;
|
||||||
|
|
||||||
|
(*itemsCount)++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkpoint) {
|
if (checkpoint) {
|
||||||
@@ -262,6 +272,10 @@ struct Level : IGame {
|
|||||||
|
|
||||||
removeSaveSlot(id, checkpoint);
|
removeSaveSlot(id, checkpoint);
|
||||||
|
|
||||||
|
TR::LevelID startID = TR::getStartId(level.version);
|
||||||
|
if (!checkpoint && getSaveSlot(startID, false) == -1)
|
||||||
|
saveSlots.push(createSaveSlot(startID, false, true)); // add first level save game
|
||||||
|
|
||||||
saveSlots.push(createSaveSlot(id, checkpoint));
|
saveSlots.push(createSaveSlot(id, checkpoint));
|
||||||
saveSlots.sort();
|
saveSlots.sort();
|
||||||
|
|
||||||
@@ -973,6 +987,7 @@ struct Level : IGame {
|
|||||||
case TR::Entity::TRAP_SLAM : return new TrapSlam(this, index);
|
case TR::Entity::TRAP_SLAM : return new TrapSlam(this, index);
|
||||||
case TR::Entity::TRAP_SWORD : return new TrapSword(this, index);
|
case TR::Entity::TRAP_SWORD : return new TrapSword(this, index);
|
||||||
case TR::Entity::HAMMER_HANDLE : return new ThorHammer(this, index);
|
case TR::Entity::HAMMER_HANDLE : return new ThorHammer(this, index);
|
||||||
|
case TR::Entity::HAMMER_BLOCK : return new ThorHammerBlock(this, index);
|
||||||
case TR::Entity::LIGHTNING : return new Lightning(this, index);
|
case TR::Entity::LIGHTNING : return new Lightning(this, index);
|
||||||
case TR::Entity::MOVING_OBJECT : return new MovingObject(this, index);
|
case TR::Entity::MOVING_OBJECT : return new MovingObject(this, index);
|
||||||
case TR::Entity::SWITCH :
|
case TR::Entity::SWITCH :
|
||||||
|
@@ -744,10 +744,6 @@ struct TrapFloor : Controller {
|
|||||||
|
|
||||||
struct Bridge : Controller {
|
struct Bridge : Controller {
|
||||||
Bridge(IGame *game, int entity) : Controller(game, entity) {}
|
Bridge(IGame *game, int entity) : Controller(game, entity) {}
|
||||||
|
|
||||||
virtual bool isCollider() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Drawbridge : Controller {
|
struct Drawbridge : Controller {
|
||||||
@@ -1005,6 +1001,20 @@ struct TrapSword : Controller {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ThorHammerBlock : Controller {
|
||||||
|
Controller *handle;
|
||||||
|
|
||||||
|
ThorHammerBlock(IGame *game, int entity) : Controller(game, entity), handle(NULL) {}
|
||||||
|
|
||||||
|
virtual bool isCollider() {
|
||||||
|
return handle ? handle->isCollider() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool getSaveData(SaveEntity &data) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct ThorHammer : Controller {
|
struct ThorHammer : Controller {
|
||||||
enum {
|
enum {
|
||||||
STATE_IDLE,
|
STATE_IDLE,
|
||||||
@@ -1013,11 +1023,29 @@ struct ThorHammer : Controller {
|
|||||||
STATE_DOWN,
|
STATE_DOWN,
|
||||||
};
|
};
|
||||||
|
|
||||||
Controller *block;
|
ThorHammerBlock *block;
|
||||||
|
|
||||||
ThorHammer(IGame *game, int entity) : Controller(game, entity) {
|
ThorHammer(IGame *game, int entity) : Controller(game, entity) {
|
||||||
block = game->addEntity(TR::Entity::HAMMER_BLOCK, getRoomIndex(), pos, angle.y);
|
initBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void initBlock() {
|
||||||
|
block = (ThorHammerBlock*)game->addEntity(TR::Entity::HAMMER_BLOCK, getRoomIndex(), pos, angle.y);
|
||||||
ASSERT(block);
|
ASSERT(block);
|
||||||
|
if (block)
|
||||||
|
block->handle = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateBlock() {
|
||||||
|
block->animation.frameA = animation.frameA;
|
||||||
|
block->animation.frameB = animation.frameB;
|
||||||
|
block->animation.delta = animation.delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setSaveData(const SaveEntity &data) {
|
||||||
|
Controller::setSaveData(data);
|
||||||
|
initBlock();
|
||||||
|
updateBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isCollider() {
|
virtual bool isCollider() {
|
||||||
@@ -1025,12 +1053,11 @@ struct ThorHammer : Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void update() {
|
virtual void update() {
|
||||||
Character *lara = (Character*)game->getLara(pos);
|
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case STATE_IDLE : if (isActive()) animation.setState(STATE_START); break;
|
case STATE_IDLE : if (isActive()) animation.setState(STATE_START); break;
|
||||||
case STATE_START : animation.setState(isActive() ? STATE_FALL : STATE_IDLE); break;
|
case STATE_START : animation.setState(isActive() ? STATE_FALL : STATE_IDLE); break;
|
||||||
case STATE_FALL : {
|
case STATE_FALL : {
|
||||||
|
Character *lara = (Character*)game->getLara(pos);
|
||||||
if (animation.frameIndex > 30 && lara->health > 0.0f) {
|
if (animation.frameIndex > 30 && lara->health > 0.0f) {
|
||||||
vec3 d = pos + getDir() * (3.0f * 1024.0f) - lara->pos;
|
vec3 d = pos + getDir() * (3.0f * 1024.0f) - lara->pos;
|
||||||
if (fabsf(d.x) < 520.0f && fabsf(d.z) < 520.0f)
|
if (fabsf(d.x) < 520.0f && fabsf(d.z) < 520.0f)
|
||||||
@@ -1046,13 +1073,11 @@ struct ThorHammer : Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateAnimation(true);
|
updateAnimation(true);
|
||||||
block->animation.frameA = animation.frameA;
|
if (block)
|
||||||
block->animation.frameB = animation.frameB;
|
updateBlock();
|
||||||
block->animation.delta = animation.delta;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define LIGHTNING_DAMAGE 400
|
#define LIGHTNING_DAMAGE 400
|
||||||
|
|
||||||
struct Lightning : Controller {
|
struct Lightning : Controller {
|
||||||
|
Reference in New Issue
Block a user