From 7313cebdfb58af52fcecd5fb024ddcd233e3a927 Mon Sep 17 00:00:00 2001 From: XProger Date: Mon, 15 Oct 2018 03:24:03 +0300 Subject: [PATCH] fix bridges, fix thor hammer --- src/controller.h | 13 +++++++++++-- src/format.h | 4 +++- src/level.h | 33 +++++++++++++++++++++++--------- src/trigger.h | 49 ++++++++++++++++++++++++++++++++++++------------ 4 files changed, 75 insertions(+), 24 deletions(-) diff --git a/src/controller.h b/src/controller.h index 222990f..0d55128 100644 --- a/src/controller.h +++ b/src/controller.h @@ -270,11 +270,12 @@ struct Controller { TR::Entity &e = level->entities[cmd.args]; Controller *controller = (Controller*)e.controller; if (!controller) continue; // Block UpdateFloor issue while entities initialization - if (!controller->isCollider()) continue; switch (e.type) { case TR::Entity::TRAP_DOOR_1 : case TR::Entity::TRAP_DOOR_2 : { + if (!controller->isCollider()) continue; + int dirX, dirZ; e.getAxis(dirX, dirZ); @@ -293,6 +294,8 @@ struct Controller { break; } case TR::Entity::TRAP_FLOOR : { + if (!controller->isCollider()) continue; + if (sx != int(controller->pos.x) / 1024 || sz != int(controller->pos.z) / 1024) break; int ey = int(controller->pos.y) - 512; @@ -306,6 +309,8 @@ struct Controller { break; } 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; int dirX, dirZ; e.getAxis(dirX, dirZ); @@ -326,10 +331,14 @@ struct Controller { break; } case TR::Entity::HAMMER_HANDLE : { + if (!controller->isCollider()) continue; + int 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.trigCmdCount = 0; + } break; } case TR::Entity::BRIDGE_1 : diff --git a/src/format.h b/src/format.h index 953fed1..1fb1b74 100644 --- a/src/format.h +++ b/src/format.h @@ -2825,7 +2825,9 @@ namespace TR { initRoomMeshes(); initAnimTex(); - memset(&state, 0, sizeof(state)); + memset(&gameStats, 0, sizeof(gameStats)); + memset(&levelStats, 0, sizeof(levelStats)); + memset(&state, 0, sizeof(state)); initExtra(); initCutscene(); diff --git a/src/level.h b/src/level.h index 4807372..ea64f91 100644 --- a/src/level.h +++ b/src/level.h @@ -97,7 +97,7 @@ struct Level : IGame { 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; slot.level = id | (checkpoint ? LVL_FLAG_CHECKPOINT : 0); @@ -117,18 +117,28 @@ struct Level : IGame { ptr += sizeof(*itemsCount); *itemsCount = 0; - for (int i = 0; i < inventory->itemsCount; i++) { - Inventory::Item *invItem = inventory->items[i]; - - if (!TR::Entity::isPickup(TR::Entity::convFromInv(invItem->type))) continue; - + if (dummy) { SaveItem *item = (SaveItem*)ptr; ptr += sizeof(*item); - item->type = invItem->type; - item->count = invItem->count; + item->type = TR::Entity::INV_PISTOLS; + 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) { @@ -262,6 +272,10 @@ struct Level : IGame { 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.sort(); @@ -973,6 +987,7 @@ struct Level : IGame { case TR::Entity::TRAP_SLAM : return new TrapSlam(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_BLOCK : return new ThorHammerBlock(this, index); case TR::Entity::LIGHTNING : return new Lightning(this, index); case TR::Entity::MOVING_OBJECT : return new MovingObject(this, index); case TR::Entity::SWITCH : diff --git a/src/trigger.h b/src/trigger.h index 154c522..65931e0 100644 --- a/src/trigger.h +++ b/src/trigger.h @@ -744,10 +744,6 @@ struct TrapFloor : Controller { struct Bridge : Controller { Bridge(IGame *game, int entity) : Controller(game, entity) {} - - virtual bool isCollider() { - return true; - } }; 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 { enum { STATE_IDLE, @@ -1013,11 +1023,29 @@ struct ThorHammer : Controller { STATE_DOWN, }; - Controller *block; + ThorHammerBlock *block; 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); + 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() { @@ -1025,12 +1053,11 @@ struct ThorHammer : Controller { } virtual void update() { - Character *lara = (Character*)game->getLara(pos); - switch (state) { case STATE_IDLE : if (isActive()) animation.setState(STATE_START); break; case STATE_START : animation.setState(isActive() ? STATE_FALL : STATE_IDLE); break; case STATE_FALL : { + Character *lara = (Character*)game->getLara(pos); if (animation.frameIndex > 30 && lara->health > 0.0f) { vec3 d = pos + getDir() * (3.0f * 1024.0f) - lara->pos; if (fabsf(d.x) < 520.0f && fabsf(d.z) < 520.0f) @@ -1046,13 +1073,11 @@ struct ThorHammer : Controller { } updateAnimation(true); - block->animation.frameA = animation.frameA; - block->animation.frameB = animation.frameB; - block->animation.delta = animation.delta; + if (block) + updateBlock(); } }; - #define LIGHTNING_DAMAGE 400 struct Lightning : Controller {