mirror of
https://github.com/XProger/OpenLara.git
synced 2025-02-24 23:42:49 +01:00
#8 add camera interface; #15 fix floating point textures for FireFox and warnings; #22 fix moving block
This commit is contained in:
parent
1c9d0b4199
commit
b4a0c8e68c
@ -643,6 +643,10 @@ struct WaterCache {
|
||||
if (!refract || w != refract->width || h != refract->height) {
|
||||
delete refract;
|
||||
refract = new Texture(w, h, Texture::RGBA, false);
|
||||
Core::setTarget(refract, true);
|
||||
Core::validateRenderState(); // immediate clear
|
||||
Core::invalidateTarget(false, true);
|
||||
Core::setTarget(NULL);
|
||||
}
|
||||
Core::copyTarget(refract, 0, 0, 0, 0, w, h); // copy framebuffer into refraction texture
|
||||
}
|
||||
|
23
src/camera.h
23
src/camera.h
@ -8,7 +8,7 @@
|
||||
|
||||
#define CAMERA_OFFSET (1024.0f + 256.0f)
|
||||
|
||||
struct Camera : Controller {
|
||||
struct Camera : ICamera {
|
||||
|
||||
enum {
|
||||
STATE_FOLLOW,
|
||||
@ -17,13 +17,15 @@ struct Camera : Controller {
|
||||
STATE_COMBAT,
|
||||
STATE_CUTSCENE,
|
||||
STATE_HEAVY
|
||||
};
|
||||
} state;
|
||||
|
||||
IGame *game;
|
||||
TR::Level *level;
|
||||
Character *owner;
|
||||
Frustum *frustum;
|
||||
|
||||
float fov, znear, zfar;
|
||||
vec3 target, destPos, lastDest, advAngle;
|
||||
vec3 target, pos, destPos, lastDest, angle, advAngle;
|
||||
float advTimer;
|
||||
mat4 mViewInv;
|
||||
int room;
|
||||
@ -32,7 +34,6 @@ struct Camera : Controller {
|
||||
float shake;
|
||||
|
||||
Basis prevBasis;
|
||||
vec4 *reflectPlane;
|
||||
|
||||
int viewIndex;
|
||||
int viewIndexLast;
|
||||
@ -42,7 +43,7 @@ struct Camera : Controller {
|
||||
bool firstPerson;
|
||||
bool isVR;
|
||||
|
||||
Camera(IGame *game, Character *owner) : Controller(game, owner ? owner->entity : 0), owner(owner), frustum(new Frustum()), timer(-1.0f), reflectPlane(NULL), viewIndex(-1), viewIndexLast(-1), viewTarget(NULL), isVR(false) {
|
||||
Camera(IGame *game, Character *owner) : ICamera(), game(game), level(game->getLevel()), owner(owner), frustum(new Frustum()), timer(-1.0f), shake(0.0f), viewIndex(-1), viewIndexLast(-1), viewTarget(NULL), isVR(false) {
|
||||
changeView(false);
|
||||
if (owner->getEntity().type != TR::Entity::LARA && level->cameraFrames) {
|
||||
state = STATE_CUTSCENE;
|
||||
@ -63,7 +64,7 @@ struct Camera : Controller {
|
||||
virtual void checkRoom() {
|
||||
if (state == STATE_CUTSCENE) {
|
||||
for (int i = 0; i < level->roomsCount; i++)
|
||||
if (insideRoom(pos, i)) {
|
||||
if (owner->insideRoom(pos, i)) {
|
||||
room = i;
|
||||
break;
|
||||
}
|
||||
@ -105,7 +106,7 @@ struct Camera : Controller {
|
||||
}
|
||||
|
||||
void setView(int viewIndex, float timer, float speed) {
|
||||
if (viewIndex == viewIndexLast) return;
|
||||
// if (viewIndex == viewIndexLast) return;
|
||||
viewIndexLast = viewIndex;
|
||||
|
||||
state = STATE_STATIC;
|
||||
@ -129,7 +130,7 @@ struct Camera : Controller {
|
||||
shake = max(0.0f, shake - Core::deltaTime);
|
||||
|
||||
if (state == STATE_CUTSCENE) {
|
||||
timer += Core::deltaTime * 15.0f;
|
||||
timer += Core::deltaTime * 30.0f;
|
||||
float t = timer - int(timer);
|
||||
int indexA = int(timer) % level->cameraFramesCount;
|
||||
int indexB = (indexA + 1) % level->cameraFramesCount;
|
||||
@ -260,16 +261,16 @@ struct Camera : Controller {
|
||||
if (lookAt) {
|
||||
dir = (lookAt->pos - target).normal();
|
||||
} else
|
||||
dir = getDir();
|
||||
dir = vec3(angle.x, angle.y);
|
||||
|
||||
int destRoom;
|
||||
if ((state == STATE_COMBAT || owner->state != 25) || lookAt) { // TODO: FUUU! 25 == Lara::STATE_BACK_JUMP
|
||||
vec3 eye = target - dir * CAMERA_OFFSET;
|
||||
destPos = trace(owner->getRoomIndex(), target, eye, destRoom, true);
|
||||
destPos = owner->trace(owner->getRoomIndex(), target, eye, destRoom, true);
|
||||
lastDest = destPos;
|
||||
} else {
|
||||
vec3 eye = lastDest + dir.cross(vec3(0, 1, 0)).normal() * 2048.0f - vec3(0.0f, 512.0f, 0.0f);
|
||||
destPos = trace(owner->getRoomIndex(), target, eye, destRoom, true);
|
||||
destPos = owner->trace(owner->getRoomIndex(), target, eye, destRoom, true);
|
||||
}
|
||||
|
||||
room = destRoom;
|
||||
|
@ -16,11 +16,19 @@
|
||||
|
||||
struct Controller;
|
||||
|
||||
struct ICamera {
|
||||
vec4 *reflectPlane;
|
||||
|
||||
ICamera() : reflectPlane(NULL) {}
|
||||
|
||||
virtual void setup(bool calcMatrices) {}
|
||||
};
|
||||
|
||||
struct IGame {
|
||||
virtual ~IGame() {}
|
||||
virtual TR::Level* getLevel() { return NULL; }
|
||||
virtual MeshBuilder* getMesh() { return NULL; }
|
||||
virtual Controller* getCamera() { return NULL; }
|
||||
virtual ICamera* getCamera() { return NULL; }
|
||||
virtual Controller* getLara() { return NULL; }
|
||||
virtual bool isCutscene() { return false; }
|
||||
virtual uint16 getRandomBox(uint16 zone, uint16 *zones) { return 0; }
|
||||
@ -96,7 +104,7 @@ struct Controller {
|
||||
e.flags.once = false;
|
||||
}
|
||||
|
||||
if (e.flags.active == 0x1F) {
|
||||
if (e.flags.active == TR::ACTIVE) {
|
||||
e.flags.active = 0;
|
||||
e.flags.reverse = true;
|
||||
activate();
|
||||
@ -115,7 +123,7 @@ struct Controller {
|
||||
bool isActive() {
|
||||
TR::Entity &e = getEntity();
|
||||
|
||||
if (e.flags.active != 0x1F)
|
||||
if (e.flags.active != TR::ACTIVE)
|
||||
return e.flags.reverse;
|
||||
|
||||
if (timer == 0.0f)
|
||||
@ -603,8 +611,6 @@ struct Controller {
|
||||
Core::setBlending(bmMultiply);
|
||||
mesh->renderShadowBlob();
|
||||
Core::setBlending(bmNone);
|
||||
|
||||
Core::active.shader->setParam(uViewProj, Core::mViewProj);
|
||||
}
|
||||
|
||||
virtual void render(Frustum *frustum, MeshBuilder *mesh, Shader::Type type, bool caustics) { // TODO: animation.calcJoints
|
||||
|
@ -680,8 +680,8 @@ namespace Debug {
|
||||
const char *ent = (cmd.action == TR::Action::ACTIVATE || cmd.action == TR::Action::CAMERA_TARGET) ? getEntityName(level, level.entities[cmd.args]) : "";
|
||||
sprintf(buf, "%s -> %s (%d)", getTriggerAction(level, cmd.action), ent, cmd.args);
|
||||
if (cmd.action == TR::Action::CAMERA_SWITCH) {
|
||||
sprintf(buf, "%s delay: %d speed: %d", buf, int(info.trigCmd[i].timer), int(info.trigCmd[i].speed) * 8 + 1);
|
||||
i++;
|
||||
sprintf(buf, "%s delay: %d speed: %d", buf, int(info.trigCmd[i].timer), int(info.trigCmd[i].speed) * 8 + 1);
|
||||
}
|
||||
|
||||
Debug::Draw::text(vec2(16, y += 16), vec4(0.1f, 0.6f, 0.1f, 1.0f), buf);
|
||||
|
15
src/format.h
15
src/format.h
@ -209,6 +209,7 @@ namespace TR {
|
||||
NO_FLOOR = -127,
|
||||
NO_ROOM = 0xFF,
|
||||
NO_BOX = 0xFFFF,
|
||||
ACTIVE = 0x1F,
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -351,9 +352,11 @@ namespace TR {
|
||||
Limit BLOCK = {
|
||||
0, -612, 30, {{-300, 0, -692}, {300, 0, -512}}, true, false
|
||||
};
|
||||
}
|
||||
|
||||
#pragma pack(push, 1)
|
||||
Limit SCION = {
|
||||
640, 310, 30, {{-256, 540, -350}, {256, 740, -200}}, true, false
|
||||
};
|
||||
}
|
||||
|
||||
struct fixed {
|
||||
uint16 L;
|
||||
@ -557,11 +560,6 @@ namespace TR {
|
||||
uint16 :8, once:1, active:5, :2;
|
||||
};
|
||||
|
||||
//struct Collider {
|
||||
// uint16 radius:10, info:6;
|
||||
// uint16 flags:16;
|
||||
//};
|
||||
|
||||
// internal mesh structure
|
||||
struct Mesh {
|
||||
|
||||
@ -909,8 +907,6 @@ namespace TR {
|
||||
} flags;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
enum Version : uint32 {
|
||||
VER_TR1_PC = 0x00000020,
|
||||
VER_TR1_PSX = 0x56414270,
|
||||
@ -1777,7 +1773,6 @@ namespace TR {
|
||||
t.clut = c;\
|
||||
t.tile = d.tile;\
|
||||
t.attribute = d.attribute;\
|
||||
t.repeat = false;\
|
||||
t.texCoord[0] = { d.x0, d.y0 };\
|
||||
t.texCoord[1] = { d.x1, d.y1 };\
|
||||
t.texCoord[2] = { d.x2, d.y2 };\
|
||||
|
@ -604,6 +604,7 @@ struct Inventory {
|
||||
void render() {
|
||||
// background
|
||||
Core::setDepthTest(false);
|
||||
Core::setBlending(bmNone);
|
||||
|
||||
if (background[0]) {
|
||||
background[0]->bind(sDiffuse); // orignal image
|
||||
|
33
src/lara.h
33
src/lara.h
@ -454,6 +454,7 @@ struct Lara : Character {
|
||||
//reset(51, vec3(41015, 3584, 34494), -PI); // level 3a (t-rex)
|
||||
//reset(5, vec3(38643, -3072, 92370), PI * 0.5f); // level 3a (gears)
|
||||
//reset(43, vec3(64037, 6656, 48229), PI); // level 3b (movingblock)
|
||||
//reset(5, vec3(73394, 3840, 60758), 0); // level 3b (scion)
|
||||
//reset(99, vec3(45562, -3328, 63366), 225 * DEG2RAD); // level 7a (flipmap)
|
||||
//reset(0, vec3(40913, -1012, 42252), PI); // level 8c
|
||||
//reset(10, vec3(90443, 11264 - 256, 114614), PI, STAND_ONWATER); // villa mortal 2
|
||||
@ -1388,6 +1389,9 @@ struct Lara : Character {
|
||||
controller->angle.x = -25 * DEG2RAD;
|
||||
controller->angle.y = angle.y;
|
||||
|
||||
if (item.type == TR::Entity::SCION_1)
|
||||
limit = TR::Limits::SCION;
|
||||
|
||||
if (!checkInteraction(controller, limit, (input & ACTION) != 0))
|
||||
continue;
|
||||
|
||||
@ -1395,6 +1399,15 @@ struct Lara : Character {
|
||||
angle.x = -25 * DEG2RAD;
|
||||
|
||||
pickupEntity = &item;
|
||||
|
||||
if (item.type == TR::Entity::SCION_1) {
|
||||
animation.setAnim(level->models[level->entities[TR::MODEL_LARA_SPEC].modelIndex].animation);
|
||||
((Controller*)level->cameraController)->state = Camera::STATE_CUTSCENE;
|
||||
level->cutMatrix.identity();
|
||||
level->cutMatrix.setPos(pos);
|
||||
} else
|
||||
state = STATE_PICK_UP;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1507,7 +1520,7 @@ struct Lara : Character {
|
||||
KeyHole *controller = (KeyHole*)entity.controller;
|
||||
|
||||
if (controller->activeState == asNone) {
|
||||
if (entity.flags.active == 0x1F || state != STATE_STOP)
|
||||
if (entity.flags.active == TR::ACTIVE || state != STATE_STOP)
|
||||
return;
|
||||
|
||||
actionState = entity.isPuzzleHole() ? STATE_USE_PUZZLE : STATE_USE_KEY;
|
||||
@ -1583,7 +1596,7 @@ struct Lara : Character {
|
||||
else
|
||||
flags.active |= info.trigInfo.mask;
|
||||
|
||||
if (flags.active != 0x1F)
|
||||
if (flags.active != TR::ACTIVE)
|
||||
break;
|
||||
|
||||
flags.once |= info.trigInfo.once;
|
||||
@ -1603,7 +1616,7 @@ struct Lara : Character {
|
||||
if (info.trigger == TR::Level::Trigger::SWITCH && info.trigInfo.timer && switchIsDown)
|
||||
break;
|
||||
|
||||
if (info.trigger == TR::Level::Trigger::SWITCH || cmd.args != camera->viewIndexLast) {
|
||||
{//if (info.trigger == TR::Level::Trigger::SWITCH || cmd.args != camera->viewIndexLast) {
|
||||
level->cameras[cmd.args].flags.once |= cam.once;
|
||||
camera->setView(cmd.args, cam.timer == 1 ? EPS : float(cam.timer), cam.speed * 8.0f);
|
||||
}
|
||||
@ -1623,20 +1636,20 @@ struct Lara : Character {
|
||||
else
|
||||
flip.active |= info.trigInfo.mask;
|
||||
|
||||
if (flip.active == 0x1F)
|
||||
if (flip.active == TR::ACTIVE)
|
||||
flip.once |= info.trigInfo.once;
|
||||
|
||||
if ((flip.active == 0x1F) ^ level->isFlipped)
|
||||
if ((flip.active == TR::ACTIVE) ^ level->isFlipped)
|
||||
needFlip = true;
|
||||
|
||||
break;
|
||||
}
|
||||
case TR::Action::FLIP_ON :
|
||||
if (level->flipmap[cmd.args].active == 0x1F && !level->isFlipped)
|
||||
if (level->flipmap[cmd.args].active == TR::ACTIVE && !level->isFlipped)
|
||||
needFlip = true;
|
||||
break;
|
||||
case TR::Action::FLIP_OFF :
|
||||
if (level->flipmap[cmd.args].active == 0x1F && level->isFlipped)
|
||||
if (level->flipmap[cmd.args].active == TR::ACTIVE && level->isFlipped)
|
||||
needFlip = true;
|
||||
break;
|
||||
case TR::Action::CAMERA_TARGET :
|
||||
@ -1663,7 +1676,7 @@ struct Lara : Character {
|
||||
else
|
||||
flags.active |= info.trigInfo.mask;
|
||||
|
||||
if (flags.active == 0x1F) {
|
||||
if (flags.active == TR::ACTIVE) {
|
||||
flags.once |= info.trigInfo.once;
|
||||
game->playTrack(track);
|
||||
} else
|
||||
@ -1856,7 +1869,7 @@ struct Lara : Character {
|
||||
angle.x = 0.0f;
|
||||
|
||||
if ((state == STATE_STOP || state == STATE_TREAD) && (input & ACTION) && emptyHands() && doPickUp())
|
||||
return STATE_PICK_UP;
|
||||
return state;
|
||||
|
||||
if ((input & (FORTH | ACTION)) == (FORTH | ACTION) && (animation.index == ANIM_STAND || animation.index == ANIM_STAND_NORMAL) && emptyHands() && collision.side == Collision::FRONT) { // TODO: get rid of animation.index
|
||||
int floor = collision.info[Collision::FRONT].floor;
|
||||
@ -2041,7 +2054,7 @@ struct Lara : Character {
|
||||
|
||||
virtual int getStateUnderwater() {
|
||||
if (input == ACTION && doPickUp())
|
||||
return STATE_PICK_UP;
|
||||
return state;
|
||||
|
||||
if (state == STATE_FORWARD_JUMP || state == STATE_UP_JUMP || state == STATE_BACK_JUMP || state == STATE_LEFT_JUMP || state == STATE_RIGHT_JUMP || state == STATE_FALL || state == STATE_REACH || state == STATE_SLIDE || state == STATE_SLIDE_BACK) {
|
||||
game->waterDrop(pos, 256.0f, 0.2f);
|
||||
|
27
src/level.h
27
src/level.h
@ -54,12 +54,12 @@ struct Level : IGame {
|
||||
return &level;
|
||||
}
|
||||
|
||||
virtual MeshBuilder* getMesh() {
|
||||
virtual MeshBuilder* getMesh() {
|
||||
return mesh;
|
||||
}
|
||||
|
||||
virtual Controller* getCamera() {
|
||||
return camera;
|
||||
virtual ICamera* getCamera() {
|
||||
return camera;
|
||||
}
|
||||
|
||||
virtual Controller* getLara() {
|
||||
@ -555,8 +555,8 @@ struct Level : IGame {
|
||||
// repack texture tiles
|
||||
Atlas *tiles = new Atlas(level.objectTexturesCount + level.spriteTexturesCount + 3, &level, fillCallback);
|
||||
// add textures
|
||||
int startIdx = level.version == TR::VER_TR1_PSX ? 256 : 0; // skip palette color for PSX version
|
||||
for (int i = startIdx; i < level.objectTexturesCount; i++) {
|
||||
int texIdx = level.version == TR::VER_TR1_PSX ? 256 : 0; // skip palette color for PSX version
|
||||
for (int i = texIdx; i < level.objectTexturesCount; i++) {
|
||||
TR::ObjectTexture &t = level.objectTextures[i];
|
||||
int16 tx = (t.tile.index % 4) * 256;
|
||||
int16 ty = (t.tile.index / 4) * 256;
|
||||
@ -567,7 +567,7 @@ struct Level : IGame {
|
||||
uv.z = tx + max(max(t.texCoord[0].x, t.texCoord[1].x), t.texCoord[2].x) + 1;
|
||||
uv.w = ty + max(max(t.texCoord[0].y, t.texCoord[1].y), t.texCoord[2].y) + 1;
|
||||
|
||||
tiles->add(uv, i);
|
||||
tiles->add(uv, texIdx++);
|
||||
}
|
||||
// add sprites
|
||||
for (int i = 0; i < level.spriteTexturesCount; i++) {
|
||||
@ -581,14 +581,14 @@ struct Level : IGame {
|
||||
uv.z = tx + t.texCoord[1].x + 1;
|
||||
uv.w = ty + t.texCoord[1].y + 1;
|
||||
|
||||
tiles->add(uv, level.objectTexturesCount + i);
|
||||
tiles->add(uv, texIdx++);
|
||||
}
|
||||
// add white color
|
||||
tiles->add(short4(2048, 2048, 2048, 2048), level.objectTexturesCount + level.spriteTexturesCount);
|
||||
tiles->add(short4(2048, 2048, 2048, 2048), texIdx++);
|
||||
// add health bar
|
||||
tiles->add(short4(2048, 2048, 2048, 2048 + 4), level.objectTexturesCount + level.spriteTexturesCount + 1);
|
||||
tiles->add(short4(2048, 2048, 2048, 2048 + 4), texIdx++);
|
||||
// add oxygen bar
|
||||
tiles->add(short4(4096, 4096, 4096, 4096 + 4), level.objectTexturesCount + level.spriteTexturesCount + 2);
|
||||
tiles->add(short4(4096, 4096, 4096, 4096 + 4), texIdx++);
|
||||
// get result texture
|
||||
atlas = tiles->pack();
|
||||
|
||||
@ -817,6 +817,9 @@ struct Level : IGame {
|
||||
}
|
||||
|
||||
void update() {
|
||||
if (isCutscene() && !sndSoundtrack)
|
||||
return;
|
||||
|
||||
if (Input::state[cInventory] && level.id != TR::TITLE)
|
||||
inventory.toggle();
|
||||
|
||||
@ -839,7 +842,7 @@ struct Level : IGame {
|
||||
c = next;
|
||||
}
|
||||
|
||||
if (camera->state != Camera::STATE_STATIC)
|
||||
if (!isCutscene() && camera->state != Camera::STATE_STATIC)
|
||||
camera->state = lara->emptyHands() ? Camera::STATE_FOLLOW : Camera::STATE_COMBAT;
|
||||
|
||||
camera->update();
|
||||
@ -898,7 +901,7 @@ struct Level : IGame {
|
||||
|
||||
for (int i = 0; i < level.entitiesCount; i++) {
|
||||
TR::Entity &entity = level.entities[i];
|
||||
if (entity.flags.rendered)
|
||||
if (entity.controller && entity.flags.rendered)
|
||||
((Controller*)entity.controller)->renderShadow(mesh);
|
||||
}
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ struct Texture {
|
||||
};
|
||||
|
||||
FormatDesc desc = formats[format];
|
||||
/*
|
||||
if ((format == RGBA_FLOAT && !Core::support.colorFloat) || (format == RGBA_HALF && !Core::support.colorHalf)) {
|
||||
desc.ifmt = GL_RGBA;
|
||||
#ifdef MOBILE
|
||||
@ -92,6 +93,22 @@ struct Texture {
|
||||
desc.type = GL_HALF_FLOAT_OES;
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
#ifdef MOBILE
|
||||
if (format == RGBA_FLOAT) {
|
||||
if (Core::support.texFloat) {
|
||||
desc.ifmt = GL_RGBA;
|
||||
desc.type = GL_FLOAT;
|
||||
}
|
||||
}
|
||||
|
||||
if (format == RGBA_HALF) {
|
||||
if (Core::support.texHalf) {
|
||||
desc.ifmt = GL_RGBA;
|
||||
desc.type = GL_HALF_FLOAT_OES;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
glTexImage2D(cube ? (GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) : GL_TEXTURE_2D, 0, desc.ifmt, width, height, 0, desc.fmt, desc.type, data);
|
||||
|
@ -35,7 +35,7 @@ struct Switch : Controller {
|
||||
|
||||
virtual void update() {
|
||||
updateAnimation(true);
|
||||
getEntity().flags.active = 0x1F;
|
||||
getEntity().flags.active = TR::ACTIVE;
|
||||
if (!isActive())
|
||||
animation.setState(STATE_UP);
|
||||
}
|
||||
@ -141,7 +141,7 @@ struct Boulder : Controller {
|
||||
Boulder(IGame *game, int entity) : Controller(game, entity) {}
|
||||
|
||||
virtual void update() {
|
||||
if (getEntity().flags.active == 0x1F) {
|
||||
if (getEntity().flags.active == TR::ACTIVE) {
|
||||
updateAnimation(true);
|
||||
updateEntity();
|
||||
}
|
||||
@ -226,7 +226,8 @@ struct Block : Controller {
|
||||
|
||||
struct MovingBlock : Controller {
|
||||
enum {
|
||||
STATE_STOP,
|
||||
STATE_BEGIN,
|
||||
STATE_END,
|
||||
STATE_MOVE,
|
||||
};
|
||||
|
||||
@ -236,6 +237,7 @@ struct MovingBlock : Controller {
|
||||
}
|
||||
|
||||
void updateFloor(bool rise) {
|
||||
updateEntity();
|
||||
TR::Entity &e = getEntity();
|
||||
TR::Level::FloorInfo info;
|
||||
level->getFloorInfo(e.room, e.x, e.y, e.z, info);
|
||||
@ -246,22 +248,26 @@ struct MovingBlock : Controller {
|
||||
s.floor += rise ? -8 : 8;
|
||||
}
|
||||
|
||||
virtual bool activate() {
|
||||
if (Controller::activate()) {
|
||||
updateFloor(false);
|
||||
animation.setState(STATE_MOVE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void update() {
|
||||
updateAnimation(true);
|
||||
|
||||
if (isActive()) {
|
||||
if (state == STATE_BEGIN) {
|
||||
updateFloor(false);
|
||||
animation.setState(STATE_END);
|
||||
}
|
||||
} else {
|
||||
if (state == STATE_END) {
|
||||
updateFloor(false);
|
||||
animation.setState(STATE_BEGIN);
|
||||
}
|
||||
}
|
||||
|
||||
if (activeState == asInactive) {
|
||||
if (getEntity().flags.active == TR::ACTIVE)
|
||||
activeState = asActive; // stay in active items list
|
||||
pos.x = int(pos.x / 1024.0f) * 1024.0f + 512.0f;
|
||||
pos.z = int(pos.z / 1024.0f) * 1024.0f + 512.0f;
|
||||
animation.setState(STATE_STOP);
|
||||
updateFloor(true);
|
||||
return;
|
||||
}
|
||||
@ -503,7 +509,7 @@ struct KeyHole : Controller {
|
||||
|
||||
virtual bool activate() {
|
||||
if (!Controller::activate()) return false;
|
||||
getEntity().flags.active = 0x1F;
|
||||
getEntity().flags.active = TR::ACTIVE;
|
||||
if (getEntity().isPuzzleHole()) {
|
||||
int doneIdx = TR::Entity::convToInv(TR::Entity::getItemForHole(getEntity().type)) - TR::Entity::INV_PUZZLE_1;
|
||||
meshSwap(0, level->extra.puzzleDone[doneIdx]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user