mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-14 00:54:05 +02:00
#22 refactoring
This commit is contained in:
@@ -121,6 +121,7 @@ struct Controller {
|
||||
|
||||
vec3 ambient[6];
|
||||
float specular;
|
||||
float intensity;
|
||||
|
||||
float timer;
|
||||
|
||||
@@ -155,6 +156,7 @@ struct Controller {
|
||||
joints = m ? new Basis[m->mCount] : NULL;
|
||||
frameIndex = -1;
|
||||
specular = 0.0f;
|
||||
intensity = e.intensity == -1 ? -1.0f : intensityf(e.intensity);
|
||||
timer = 0.0f;
|
||||
ambient[0] = ambient[1] = ambient[2] = ambient[3] = ambient[4] = ambient[5] = vec3(intensityf(getRoom().ambient));
|
||||
targetLight = NULL;
|
||||
@@ -406,35 +408,52 @@ struct Controller {
|
||||
virtual void getSaveData(SaveData &data) {
|
||||
const TR::Entity &e = getEntity();
|
||||
const TR::Model *m = getModel();
|
||||
// base
|
||||
data.x = e.x ^ int32(pos.x);
|
||||
data.y = e.y ^ int32(pos.y);
|
||||
data.z = e.z ^ int32(pos.z);
|
||||
data.rotation = e.rotation.value ^ TR::angle(normalizeAngle(angle.y)).value;
|
||||
data.type = entity >= level->entitiesBaseCount ? int16(e.type) : 0;
|
||||
data.flags = e.flags.value ^ flags.value;
|
||||
data.timer = timer == 0.0f ? 0 : (timer < 0.0f ? -1 : int16(timer * 30.0f));
|
||||
if (entity < level->entitiesBaseCount) {
|
||||
data.x = e.x ^ int32(pos.x);
|
||||
data.y = e.y ^ int32(pos.y);
|
||||
data.z = e.z ^ int32(pos.z);
|
||||
data.rotation = e.rotation.value ^ TR::angle(normalizeAngle(angle.y)).value;
|
||||
data.type = 0;
|
||||
data.room = e.room ^ roomIndex;
|
||||
} else {
|
||||
data.x = int32(pos.x);
|
||||
data.y = int32(pos.y);
|
||||
data.z = int32(pos.z);
|
||||
data.rotation = TR::angle(normalizeAngle(angle.y)).value;
|
||||
data.type = int16(e.type);
|
||||
data.room = uint8(roomIndex);
|
||||
}
|
||||
|
||||
data.flags = e.flags.value ^ flags.value;
|
||||
data.timer = timer == 0.0f ? 0 : (timer < 0.0f ? -1 : int16(timer * 30.0f));
|
||||
// animation
|
||||
data.animIndex = m ? (m->animation ^ animation.index) : 0;
|
||||
data.animFrame = m ? animation.frameIndex : 0;
|
||||
// common
|
||||
data.room = e.room ^ roomIndex;
|
||||
data.extraSize = 0;
|
||||
data.animIndex = m ? (m->animation ^ animation.index) : 0;
|
||||
data.animFrame = m ? animation.frameIndex : 0;
|
||||
|
||||
data.extraSize = 0;
|
||||
}
|
||||
|
||||
virtual void setSaveData(const SaveData &data) {
|
||||
const TR::Entity &e = getEntity();
|
||||
const TR::Model *m = getModel();
|
||||
// base
|
||||
pos.x = float(e.x ^ data.x);
|
||||
pos.y = float(e.y ^ data.y);
|
||||
pos.z = float(e.z ^ data.z);
|
||||
angle.y = TR::angle(uint16(e.rotation.value ^ data.rotation));
|
||||
flags.value = e.flags.value ^ data.flags;
|
||||
timer = data.timer == -1 ? -1.0f : (timer / 30.0f);
|
||||
if (entity < level->entitiesBaseCount) {
|
||||
pos.x = float(e.x ^ data.x);
|
||||
pos.y = float(e.y ^ data.y);
|
||||
pos.z = float(e.z ^ data.z);
|
||||
angle.y = TR::angle(uint16(e.rotation.value ^ data.rotation));
|
||||
roomIndex = e.room ^ data.room;
|
||||
} else {
|
||||
pos.x = float(data.x);
|
||||
pos.y = float(data.y);
|
||||
pos.z = float(data.z);
|
||||
angle.y = TR::angle(uint16(data.rotation));
|
||||
flags.value = data.flags;
|
||||
roomIndex = data.room;
|
||||
}
|
||||
flags.value = e.flags.value ^ data.flags;
|
||||
timer = data.timer == -1 ? -1.0f : (timer / 30.0f);
|
||||
// animation
|
||||
if (m) animation.setAnim(m->animation ^ data.animIndex, -data.animFrame);
|
||||
roomIndex = e.room ^ data.room;
|
||||
}
|
||||
|
||||
bool isActive() {
|
||||
@@ -838,10 +857,10 @@ struct Controller {
|
||||
for (int i = 0; i < model->mCount; i++)
|
||||
if (explodeMask & (1 << i)) {
|
||||
ExplodePart &part = explodeParts[i];
|
||||
part.velocity.y += GRAVITY * Core::deltaTime;
|
||||
applyGravity(part.velocity.y);
|
||||
|
||||
quat q = quat(vec3(1, 0, 0), PI * Core::deltaTime) * quat(vec3(0, 0, 1), PI * 2.0f * Core::deltaTime);
|
||||
part.basis = Basis(part.basis.rot * q, part.basis.pos + explodeParts[i].velocity * (Core::deltaTime * 30.0f));
|
||||
part.basis = Basis(part.basis.rot * q, part.basis.pos + part.velocity * (30.0f * Core::deltaTime));
|
||||
|
||||
vec3 p = part.basis.pos;
|
||||
//TR::Room::Sector *s = level->getSector(part.roomIndex, int(p.x), int(p.y), int(p.z));
|
||||
|
@@ -656,9 +656,7 @@ namespace Debug {
|
||||
const char *TR1_TYPE_NAMES[] = { TR1_TYPES(DECL_STR) };
|
||||
|
||||
const char *getEntityName(const TR::Level &level, const TR::Entity &entity) {
|
||||
if (entity.type == TR::Entity::NONE)
|
||||
return "NONE";
|
||||
if (entity.type < 0 || entity.type >= COUNT(TR1_TYPE_NAMES))
|
||||
if (entity.type >= COUNT(TR1_TYPE_NAMES))
|
||||
return "UNKNOWN";
|
||||
return TR1_TYPE_NAMES[entity.type];
|
||||
}
|
||||
|
@@ -96,7 +96,7 @@ struct Enemy : Character {
|
||||
|
||||
virtual void updateVelocity() {
|
||||
if (stand == STAND_AIR && (!flying || health <= 0.0f))
|
||||
velocity.y += GRAVITY * Core::deltaTime;
|
||||
applyGravity(velocity.y);
|
||||
else
|
||||
velocity = getDir() * animation.getSpeed();
|
||||
|
||||
|
35
src/format.h
35
src/format.h
@@ -647,7 +647,7 @@ namespace TR {
|
||||
|
||||
struct Entity {
|
||||
enum ActiveState : uint16 { asNone, asActive, asInactive };
|
||||
enum Type : int16 { NONE = -1, TR1_TYPES(DECL_ENUM) };
|
||||
enum Type : uint16 { TR1_TYPES(DECL_ENUM) };
|
||||
|
||||
Type type;
|
||||
int16 room;
|
||||
@@ -760,16 +760,16 @@ namespace TR {
|
||||
|
||||
static Type getItemForHole(Type hole) {
|
||||
switch (hole) {
|
||||
case PUZZLE_HOLE_1 : return PUZZLE_1; break;
|
||||
case PUZZLE_HOLE_2 : return PUZZLE_2; break;
|
||||
case PUZZLE_HOLE_3 : return PUZZLE_3; break;
|
||||
case PUZZLE_HOLE_4 : return PUZZLE_4; break;
|
||||
case KEY_HOLE_1 : return KEY_ITEM_1; break;
|
||||
case KEY_HOLE_2 : return KEY_ITEM_2; break;
|
||||
case KEY_HOLE_3 : return KEY_ITEM_3; break;
|
||||
case KEY_HOLE_4 : return KEY_ITEM_4; break;
|
||||
case MIDAS_HAND : return LEADBAR; break;
|
||||
default : return NONE;
|
||||
case PUZZLE_HOLE_1 : return PUZZLE_1;
|
||||
case PUZZLE_HOLE_2 : return PUZZLE_2;
|
||||
case PUZZLE_HOLE_3 : return PUZZLE_3;
|
||||
case PUZZLE_HOLE_4 : return PUZZLE_4;
|
||||
case KEY_HOLE_1 : return KEY_ITEM_1;
|
||||
case KEY_HOLE_2 : return KEY_ITEM_2;
|
||||
case KEY_HOLE_3 : return KEY_ITEM_3;
|
||||
case KEY_HOLE_4 : return KEY_ITEM_4;
|
||||
case MIDAS_HAND : return LEADBAR;
|
||||
default : return LARA;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1431,10 +1431,8 @@ namespace TR {
|
||||
if (e.type == Entity::CUT_1)
|
||||
cutEntity = i;
|
||||
}
|
||||
for (int i = entitiesBaseCount; i < entitiesCount; i++) {
|
||||
entities[i].type = Entity::NONE;
|
||||
for (int i = entitiesBaseCount; i < entitiesCount; i++)
|
||||
entities[i].controller = NULL;
|
||||
}
|
||||
|
||||
if (version == VER_TR1_PC) {
|
||||
stream.seek(32 * 256);
|
||||
@@ -2106,9 +2104,9 @@ namespace TR {
|
||||
}
|
||||
|
||||
int entityAdd(Entity::Type type, int16 room, const vec3 &pos, float rotation, int16 intensity) {
|
||||
for (int i = entitiesBaseCount; i < entitiesCount; i++)
|
||||
if (entities[i].type == Entity::NONE) {
|
||||
Entity &e = entities[i];
|
||||
for (int i = entitiesBaseCount; i < entitiesCount; i++) {
|
||||
Entity &e = entities[i];
|
||||
if (!e.controller) {
|
||||
e.type = type;
|
||||
e.room = room;
|
||||
e.x = int(pos.x);
|
||||
@@ -2118,14 +2116,13 @@ namespace TR {
|
||||
e.intensity = intensity;
|
||||
e.flags.value = 0;
|
||||
e.modelIndex = getModelIndex(e.type);
|
||||
e.controller = NULL;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void entityRemove(int entityIndex) {
|
||||
entities[entityIndex].type = Entity::NONE;
|
||||
entities[entityIndex].controller = NULL;
|
||||
}
|
||||
|
||||
|
@@ -313,7 +313,7 @@ struct Inventory {
|
||||
|
||||
bool chooseKey(TR::Entity::Type hole) {
|
||||
TR::Entity::Type type = TR::Entity::getItemForHole(hole);
|
||||
if (type == TR::Entity::NONE)
|
||||
if (type == TR::Entity::LARA)
|
||||
return false;
|
||||
int index = contains(type);
|
||||
if (index < 0)
|
||||
@@ -330,7 +330,7 @@ struct Inventory {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool toggle(Page curPage = PAGE_INVENTORY, TR::Entity::Type type = TR::Entity::NONE) {
|
||||
bool toggle(Page curPage = PAGE_INVENTORY, TR::Entity::Type type = TR::Entity::LARA) {
|
||||
if (phaseRing == 0.0f || phaseRing == 1.0f) {
|
||||
active = !active;
|
||||
vec3 p;
|
||||
@@ -346,7 +346,7 @@ struct Inventory {
|
||||
phaseSelect = 1.0f;
|
||||
page = targetPage = curPage;
|
||||
|
||||
if (type != TR::Entity::NONE) {
|
||||
if (type != TR::Entity::LARA) {
|
||||
int i = contains(type);
|
||||
if (i >= 0)
|
||||
pageItemIndex[page] = getLocalIndex(i);
|
||||
|
25
src/lara.h
25
src/lara.h
@@ -594,7 +594,7 @@ struct Lara : Character {
|
||||
case Weapon::Type::SHOTGUN : return TR::Entity::SHOTGUN;
|
||||
case Weapon::Type::MAGNUMS : return TR::Entity::MAGNUMS;
|
||||
case Weapon::Type::UZIS : return TR::Entity::UZIS;
|
||||
default : return TR::Entity::NONE;
|
||||
default : return TR::Entity::LARA;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1535,15 +1535,17 @@ struct Lara : Character {
|
||||
usedKey = item;
|
||||
break;
|
||||
case TR::Entity::INV_LEADBAR :
|
||||
for (int i = 0; i < level->entitiesCount; i++)
|
||||
if (level->entities[i].type == TR::Entity::MIDAS_HAND) {
|
||||
MidasHand *controller = (MidasHand*)level->entities[i].controller;
|
||||
for (int i = 0; i < level->entitiesCount; i++) {
|
||||
const TR::Entity &e = level->entities[i];
|
||||
if (e.controller && e.type == TR::Entity::MIDAS_HAND) {
|
||||
MidasHand *controller = (MidasHand*)e.controller;
|
||||
if (controller->interaction) {
|
||||
controller->invItem = item;
|
||||
return false; // remove item from inventory
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
default : return false;
|
||||
}
|
||||
@@ -1596,11 +1598,10 @@ struct Lara : Character {
|
||||
|
||||
for (int i = 0; i < level->entitiesCount; i++) {
|
||||
TR::Entity &entity = level->entities[i];
|
||||
if (!entity.isPickup())
|
||||
if (!entity.controller || !entity.isPickup())
|
||||
continue;
|
||||
|
||||
Controller *controller = (Controller*)entity.controller;
|
||||
if (!controller) continue;
|
||||
|
||||
if (controller->getRoomIndex() != room || controller->flags.invisible || !canPickup(controller))
|
||||
continue;
|
||||
@@ -1786,10 +1787,10 @@ struct Lara : Character {
|
||||
return;
|
||||
|
||||
limit = actionState == STATE_USE_PUZZLE ? &TR::Limits::PUZZLE_HOLE : &TR::Limits::KEY_HOLE;
|
||||
if (!checkInteraction(controller, limit, isPressed(ACTION) || usedKey != TR::Entity::NONE))
|
||||
if (!checkInteraction(controller, limit, isPressed(ACTION) || usedKey != TR::Entity::LARA))
|
||||
return;
|
||||
|
||||
if (usedKey == TR::Entity::NONE) {
|
||||
if (usedKey == TR::Entity::LARA) {
|
||||
if (isPressed(ACTION) && !game->invChooseKey(entity.type))
|
||||
game->playSound(TR::SND_NO, pos, Sound::PAN); // no compatible items in inventory
|
||||
return;
|
||||
@@ -2135,7 +2136,7 @@ struct Lara : Character {
|
||||
Block* getBlock() {
|
||||
for (int i = 0; i < level->entitiesCount; i++) {
|
||||
TR::Entity &e = level->entities[i];
|
||||
if (!e.isBlock())
|
||||
if (!e.controller || !e.isBlock())
|
||||
continue;
|
||||
|
||||
Block *block = (Block*)e.controller;
|
||||
@@ -2547,7 +2548,7 @@ struct Lara : Character {
|
||||
if (oxygen < LARA_MAX_OXYGEN)
|
||||
oxygen = min(LARA_MAX_OXYGEN, oxygen += Core::deltaTime * 10.0f);
|
||||
|
||||
usedKey = TR::Entity::NONE;
|
||||
usedKey = TR::Entity::LARA;
|
||||
}
|
||||
|
||||
virtual void updateAnimation(bool commands) {
|
||||
@@ -2747,8 +2748,8 @@ struct Lara : Character {
|
||||
// check enemies & doors
|
||||
for (int i = 0; i < level->entitiesCount; i++) {
|
||||
const TR::Entity &e = level->entities[i];
|
||||
|
||||
if (!e.isCollider()) continue;
|
||||
|
||||
if (!e.controller || !e.isCollider()) continue;
|
||||
|
||||
Controller *controller = (Controller*)e.controller;
|
||||
|
||||
|
69
src/level.h
69
src/level.h
@@ -90,23 +90,34 @@ struct Level : IGame {
|
||||
char *data;
|
||||
stream.read(data, stream.size);
|
||||
char *ptr = data;
|
||||
int32 eCount = *((int32*)ptr);
|
||||
ptr += 4;
|
||||
|
||||
Controller::first = NULL;
|
||||
for (int i = level.entitiesBaseCount; i < level.entitiesCount; i++) {
|
||||
for (int i = 0; i < level.entitiesCount; i++) {
|
||||
TR::Entity &e = level.entities[i];
|
||||
if (e.controller) {
|
||||
delete (Controller*)e.controller;
|
||||
e.controller = NULL;
|
||||
Controller *controller = (Controller*)e.controller;
|
||||
if (controller) {
|
||||
controller->next = NULL;
|
||||
controller->flags.state = TR::Entity::asNone;
|
||||
if (i >= level.entitiesBaseCount) {
|
||||
delete controller;
|
||||
e.controller = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < level.entitiesBaseCount; i++) {
|
||||
ASSERT(int(ptr - data) < stream.size);
|
||||
Controller *controller = (Controller*)level.entities[i].controller;
|
||||
ASSERT(controller);
|
||||
for (int i = 0; i < eCount; i++) {
|
||||
Controller::SaveData *saveData = (Controller::SaveData*)ptr;
|
||||
|
||||
Controller *controller;
|
||||
if (i >= level.entitiesBaseCount)
|
||||
controller = addEntity(TR::Entity::Type(saveData->type), saveData->room, vec3(float(saveData->x), float(saveData->y), float(saveData->z)), TR::angle(saveData->rotation));
|
||||
else
|
||||
controller = (Controller*)level.entities[i].controller;
|
||||
|
||||
controller->setSaveData(*saveData);
|
||||
if (controller->flags.state != TR::Entity::asNone) {
|
||||
if (Controller::first != controller && controller->flags.state != TR::Entity::asNone) {
|
||||
controller->next = Controller::first;
|
||||
Controller::first = controller;
|
||||
}
|
||||
@@ -119,15 +130,19 @@ struct Level : IGame {
|
||||
}
|
||||
|
||||
virtual void saveGame(int slot) {
|
||||
char *data = new char[sizeof(Controller::SaveData) * level.entitiesBaseCount];
|
||||
char *ptr = data;
|
||||
char *data = new char[4 + sizeof(Controller::SaveData) * level.entitiesCount];
|
||||
char *ptr = data;
|
||||
int32 *eCount = (int32*)ptr;
|
||||
ptr += 4;
|
||||
|
||||
for (int i = 0; i < level.entitiesBaseCount; i++) {
|
||||
Controller::SaveData *saveData = (Controller::SaveData*)ptr;
|
||||
*eCount = 0;
|
||||
for (int i = 0; i < level.entitiesCount; i++) {
|
||||
Controller *controller = (Controller*)level.entities[i].controller;
|
||||
ASSERT(controller);
|
||||
if (!controller || (controller->getEntity().isSprite() && !controller->getEntity().isPickup())) continue;
|
||||
Controller::SaveData *saveData = (Controller::SaveData*)ptr;
|
||||
controller->getSaveData(*saveData);
|
||||
ptr += (sizeof(Controller::SaveData) - sizeof(Controller::SaveData::Extra)) + saveData->extraSize;
|
||||
(*eCount)++;
|
||||
}
|
||||
Stream::write("savegame.dat", data, int(ptr - data));
|
||||
delete[] data;
|
||||
@@ -307,14 +322,6 @@ struct Level : IGame {
|
||||
int index = level.entityAdd(type, room, pos, angle, -1);
|
||||
if (index > -1) {
|
||||
TR::Entity &e = level.entities[index];
|
||||
Controller *controller = initController(index);
|
||||
e.controller = controller;
|
||||
|
||||
if (e.isEnemy() || e.isSprite()) {
|
||||
controller->flags.active = TR::ACTIVE;
|
||||
controller->activate();
|
||||
}
|
||||
|
||||
if (e.isPickup())
|
||||
e.intensity = 4096;
|
||||
else
|
||||
@@ -324,7 +331,15 @@ struct Level : IGame {
|
||||
else
|
||||
e.intensity = 0x1FFF - level.rooms[room].ambient;
|
||||
}
|
||||
|
||||
|
||||
Controller *controller = initController(index);
|
||||
e.controller = controller;
|
||||
|
||||
if (e.isEnemy() || e.isSprite()) {
|
||||
controller->flags.active = TR::ACTIVE;
|
||||
controller->activate();
|
||||
}
|
||||
|
||||
return controller;
|
||||
}
|
||||
return NULL;
|
||||
@@ -936,7 +951,7 @@ struct Level : IGame {
|
||||
|
||||
void renderEntity(const TR::Entity &entity) {
|
||||
//if (entity.room != lara->getRoomIndex()) return;
|
||||
if (entity.type == TR::Entity::NONE || !entity.modelIndex) return;
|
||||
if (!entity.controller || !entity.modelIndex) return;
|
||||
if (Core::pass == Core::passShadow && !entity.castShadow()) return;
|
||||
|
||||
ASSERT(entity.controller);
|
||||
@@ -952,7 +967,7 @@ struct Level : IGame {
|
||||
if (!room.flags.visible || controller->flags.invisible || controller->flags.rendered)
|
||||
return;
|
||||
|
||||
int16 lum = entity.intensity == -1 ? room.ambient : entity.intensity;
|
||||
float intensity = controller->intensity < 0.0f ? intensityf(room.ambient) : controller->intensity;
|
||||
|
||||
Shader::Type type = isModel ? Shader::ENTITY : Shader::SPRITE;
|
||||
if (entity.type == TR::Entity::CRYSTAL)
|
||||
@@ -961,9 +976,9 @@ struct Level : IGame {
|
||||
if (type == Shader::SPRITE) {
|
||||
float alpha = (entity.type == TR::Entity::SMOKE || entity.type == TR::Entity::WATER_SPLASH || entity.type == TR::Entity::SPARKLES) ? 0.75f : 1.0f;
|
||||
float diffuse = entity.isPickup() ? 1.0f : 0.5f;
|
||||
setRoomParams(roomIndex, type, diffuse, intensityf(lum), controller->specular, alpha, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true);
|
||||
setRoomParams(roomIndex, type, diffuse, intensity, controller->specular, alpha, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true);
|
||||
} else
|
||||
setRoomParams(roomIndex, type, 1.0f, intensityf(lum), controller->specular, 1.0f, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true);
|
||||
setRoomParams(roomIndex, type, 1.0f, intensity, controller->specular, 1.0f, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true);
|
||||
|
||||
if (isModel) { // model
|
||||
vec3 pos = controller->getPos();
|
||||
|
@@ -206,7 +206,7 @@ struct TrapFlameEmitter : Controller {
|
||||
#define LAVA_EMITTER_RANGE (1024 * 10)
|
||||
|
||||
struct LavaParticle : Sprite {
|
||||
int bounces;
|
||||
int bounces;
|
||||
|
||||
LavaParticle(IGame *game, int entity) : Sprite(game, entity, false, Sprite::FRAME_RANDOM), bounces(0) {
|
||||
float speed = randf() * LAVA_H_SPEED;
|
||||
@@ -235,7 +235,7 @@ struct LavaParticle : Sprite {
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
// getEntity().intensity = bounces * 2048 - 1; // TODO: updateEntity()
|
||||
intensity = max(0.0f, 1.0f - bounces * 0.25f);
|
||||
|
||||
if (pos.y > info.floor) pos.y = info.floor;
|
||||
if (pos.y < info.ceiling) pos.y = info.ceiling;
|
||||
@@ -246,9 +246,7 @@ struct LavaParticle : Sprite {
|
||||
};
|
||||
|
||||
struct TrapLavaEmitter : Controller {
|
||||
float timer;
|
||||
|
||||
TrapLavaEmitter(IGame *game, int entity) : Controller(game, entity), timer(0.0f) {}
|
||||
TrapLavaEmitter(IGame *game, int entity) : Controller(game, entity) {}
|
||||
|
||||
void virtual update() {
|
||||
vec3 d = (game->getLara()->pos - pos).abs();
|
||||
@@ -412,8 +410,9 @@ struct Block : Controller {
|
||||
if (info.roomBelow != TR::NO_ROOM)
|
||||
roomIndex = info.roomBelow;
|
||||
|
||||
velocity += Core::deltaTime * GRAVITY;
|
||||
pos.y += Core::deltaTime * velocity * 30.0f;
|
||||
applyGravity(velocity);
|
||||
pos.y += velocity * (30.0f * Core::deltaTime);
|
||||
|
||||
if (pos.y >= info.floor) {
|
||||
velocity = 0.0f;
|
||||
pos.y = info.floor;
|
||||
@@ -448,6 +447,13 @@ struct MovingBlock : Controller {
|
||||
updateFloor(true);
|
||||
}
|
||||
|
||||
virtual void setSaveData(const SaveData &data) {
|
||||
updateFloor(false);
|
||||
Controller::setSaveData(data);
|
||||
if (flags.state == TR::Entity::asNone)
|
||||
updateFloor(true);
|
||||
}
|
||||
|
||||
void updateFloor(bool rise) {
|
||||
TR::Level::FloorInfo info;
|
||||
getFloorInfo(getRoomIndex(), pos, info);
|
||||
@@ -614,9 +620,10 @@ struct TrapFloor : Controller {
|
||||
STATE_FALL,
|
||||
STATE_DOWN,
|
||||
};
|
||||
float speed;
|
||||
|
||||
TrapFloor(IGame *game, int entity) : Controller(game, entity), speed(0) {
|
||||
float velocity;
|
||||
|
||||
TrapFloor(IGame *game, int entity) : Controller(game, entity), velocity(0) {
|
||||
flags.collision = true;
|
||||
}
|
||||
|
||||
@@ -634,8 +641,9 @@ struct TrapFloor : Controller {
|
||||
updateAnimation(true);
|
||||
if (state == STATE_FALL) {
|
||||
flags.collision = false;
|
||||
speed += GRAVITY * 30 * Core::deltaTime;
|
||||
pos.y += speed * Core::deltaTime;
|
||||
|
||||
applyGravity(velocity);
|
||||
pos.y += velocity * (30.0f * Core::deltaTime);
|
||||
|
||||
TR::Level::FloorInfo info;
|
||||
getFloorInfo(getRoomIndex(), pos, info);
|
||||
@@ -771,9 +779,9 @@ struct TrapCeiling : Controller {
|
||||
STATE_DOWN,
|
||||
};
|
||||
|
||||
float speed;
|
||||
float velocity;
|
||||
|
||||
TrapCeiling(IGame *game, int entity) : Controller(game, entity), speed(0) {}
|
||||
TrapCeiling(IGame *game, int entity) : Controller(game, entity), velocity(0) {}
|
||||
|
||||
virtual void update() {
|
||||
updateAnimation(true);
|
||||
@@ -782,8 +790,8 @@ struct TrapCeiling : Controller {
|
||||
animation.setState(STATE_FALL);
|
||||
|
||||
if (state == STATE_FALL) {
|
||||
speed += GRAVITY * 30 * Core::deltaTime;
|
||||
pos.y += speed * Core::deltaTime;
|
||||
applyGravity(velocity);
|
||||
pos.y += velocity * (30.0f * Core::deltaTime);
|
||||
|
||||
TR::Level::FloorInfo info;
|
||||
getFloorInfo(getRoomIndex(), pos, info);
|
||||
@@ -1079,7 +1087,7 @@ struct MidasHand : Controller {
|
||||
TR::Entity::Type invItem;
|
||||
bool interaction;
|
||||
|
||||
MidasHand(IGame *game, int entity) : Controller(game, entity), invItem(TR::Entity::NONE), interaction(false) {
|
||||
MidasHand(IGame *game, int entity) : Controller(game, entity), invItem(TR::Entity::LARA), interaction(false) {
|
||||
activate();
|
||||
}
|
||||
|
||||
@@ -1100,7 +1108,7 @@ struct MidasHand : Controller {
|
||||
interaction = (d.x < 700.0f && d.z < 700.0f) && lara->state == 2; // 2 = Lara::STATE_STOP
|
||||
|
||||
if (interaction) {
|
||||
if (invItem != TR::Entity::NONE) {
|
||||
if (invItem != TR::Entity::LARA) {
|
||||
if (invItem == TR::Entity::INV_LEADBAR) {
|
||||
lara->angle.y = PI * 0.5f;
|
||||
lara->pos.x = pos.x - 612.0f;
|
||||
@@ -1108,7 +1116,7 @@ struct MidasHand : Controller {
|
||||
game->invAdd(TR::Entity::PUZZLE_1);
|
||||
} else
|
||||
game->playSound(TR::SND_NO, pos, Sound::PAN); // uncompatible item
|
||||
invItem = TR::Entity::NONE;
|
||||
invItem = TR::Entity::LARA;
|
||||
} else if (Input::state[cAction] && !game->invChooseKey(getEntity().type)) // TODO: add callback for useItem
|
||||
game->playSound(TR::SND_NO, pos, Sound::PAN); // no compatible items in inventory
|
||||
}
|
||||
@@ -1289,12 +1297,22 @@ struct KeyHole : Controller {
|
||||
virtual bool activate() {
|
||||
if (!Controller::activate()) return false;
|
||||
flags.active = TR::ACTIVE;
|
||||
swap();
|
||||
deactivate();
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void setSaveData(const SaveData &data) {
|
||||
Controller::setSaveData(data);
|
||||
if (flags.active == TR::ACTIVE)
|
||||
swap();
|
||||
}
|
||||
|
||||
void swap() {
|
||||
if (getEntity().isPuzzleHole()) {
|
||||
int doneIdx = TR::Entity::convToInv(TR::Entity::getItemForHole(getEntity().type)) - TR::Entity::INV_PUZZLE_1;
|
||||
meshSwap(0, level->extra.puzzleDone[doneIdx]);
|
||||
}
|
||||
deactivate();
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void update() {}
|
||||
|
Reference in New Issue
Block a user