mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-16 14:50:17 +00:00
521 lines
12 KiB
C++
521 lines
12 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "ngi/ngi.h"
|
|
|
|
#include "ngi/objects.h"
|
|
#include "ngi/objectnames.h"
|
|
#include "ngi/constants.h"
|
|
|
|
#include "ngi/scene.h"
|
|
#include "ngi/statics.h"
|
|
#include "ngi/messages.h"
|
|
#include "ngi/gameloader.h"
|
|
#include "ngi/motion.h"
|
|
|
|
namespace NGI {
|
|
|
|
int NGIEngine::lift_getButtonIdP(int objid) {
|
|
switch (objid) {
|
|
case ST_LBN_0N:
|
|
return ST_LBN_0P;
|
|
|
|
case ST_LBN_1N:
|
|
return ST_LBN_1P;
|
|
|
|
case ST_LBN_2N:
|
|
return ST_LBN_2P;
|
|
|
|
case ST_LBN_3N:
|
|
return ST_LBN_3P;
|
|
|
|
case ST_LBN_4N:
|
|
return ST_LBN_4P;
|
|
|
|
case ST_LBN_5N:
|
|
return ST_LBN_5P;
|
|
|
|
case ST_LBN_6N:
|
|
return ST_LBN_6P;
|
|
|
|
case ST_LBN_7N:
|
|
return ST_LBN_7P;
|
|
|
|
case ST_LBN_8N:
|
|
return ST_LBN_8P;
|
|
|
|
case ST_LBN_9N:
|
|
return ST_LBN_9P;
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int NGIEngine::lift_getButtonIdH(int objid) {
|
|
switch (objid) {
|
|
case ST_LBN_0P:
|
|
return ST_LBN_0H;
|
|
|
|
case ST_LBN_1P:
|
|
return ST_LBN_1H;
|
|
|
|
case ST_LBN_2P:
|
|
return ST_LBN_2H;
|
|
|
|
case ST_LBN_3P:
|
|
return ST_LBN_3H;
|
|
|
|
case ST_LBN_4P:
|
|
return ST_LBN_4H;
|
|
|
|
case ST_LBN_5P:
|
|
return ST_LBN_5H;
|
|
|
|
case ST_LBN_6P:
|
|
return ST_LBN_6H;
|
|
|
|
case ST_LBN_7P:
|
|
return ST_LBN_7H;
|
|
|
|
case ST_LBN_8P:
|
|
return ST_LBN_8H;
|
|
|
|
case ST_LBN_9P:
|
|
return ST_LBN_9H;
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int NGIEngine::lift_getButtonIdN(int objid) {
|
|
switch (objid) {
|
|
case ST_LBN_0H:
|
|
case ST_LBN_0N:
|
|
case ST_LBN_0P:
|
|
return ST_LBN_0N;
|
|
|
|
case ST_LBN_1H:
|
|
case ST_LBN_1N:
|
|
case ST_LBN_1P:
|
|
return ST_LBN_1N;
|
|
|
|
case ST_LBN_2H:
|
|
case ST_LBN_2N:
|
|
case ST_LBN_2P:
|
|
return ST_LBN_2N;
|
|
|
|
case ST_LBN_3H:
|
|
case ST_LBN_3N:
|
|
case ST_LBN_3P:
|
|
return ST_LBN_3N;
|
|
|
|
case ST_LBN_4H:
|
|
case ST_LBN_4N:
|
|
case ST_LBN_4P:
|
|
return ST_LBN_4N;
|
|
|
|
case ST_LBN_5H:
|
|
case ST_LBN_5N:
|
|
case ST_LBN_5P:
|
|
return ST_LBN_5N;
|
|
|
|
case ST_LBN_6H:
|
|
case ST_LBN_6N:
|
|
case ST_LBN_6P:
|
|
return ST_LBN_6N;
|
|
|
|
case ST_LBN_7H:
|
|
case ST_LBN_7N:
|
|
case ST_LBN_7P:
|
|
return ST_LBN_7N;
|
|
|
|
case ST_LBN_8H:
|
|
case ST_LBN_8N:
|
|
case ST_LBN_8P:
|
|
return ST_LBN_8N;
|
|
|
|
case ST_LBN_9H:
|
|
case ST_LBN_9N:
|
|
case ST_LBN_9P:
|
|
return ST_LBN_9N;
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void NGIEngine::lift_setButton(const char *name, int state) {
|
|
GameVar *var = g_nmi->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName(sO_LiftButtons);
|
|
|
|
if (var)
|
|
var->setSubVarAsInt(name, state);
|
|
}
|
|
|
|
void NGIEngine::lift_init(Scene *sc, int enterSeq, int exitSeq) {
|
|
_lastLiftButton = nullptr;
|
|
|
|
_liftEnterMQ = sc->getMessageQueueById(enterSeq);
|
|
if (!_liftEnterMQ)
|
|
return;
|
|
|
|
_liftExitMQ = sc->getMessageQueueById(exitSeq);
|
|
|
|
if (!_liftExitMQ)
|
|
return;
|
|
|
|
ExCommand *ex = _liftEnterMQ->getExCommandByIndex(0);
|
|
|
|
if (!ex)
|
|
return;
|
|
|
|
_liftX = ex->_x;
|
|
_liftY = ex->_y;
|
|
|
|
_lift = sc->getStaticANIObject1ById(ANI_LIFT, -1);
|
|
|
|
for (uint i = 0; i < sc->_staticANIObjectList1.size(); i++) {
|
|
StaticANIObject *ani = sc->_staticANIObjectList1[i];
|
|
|
|
if (ani->_id == ANI_LIFTBUTTON)
|
|
ani->_statics = ani->getStaticsById(lift_getButtonIdP(ani->_statics->_staticsId));
|
|
}
|
|
|
|
GameVar *var = getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName(sO_LiftButtons);
|
|
if (var) {
|
|
for (var = var->_subVars; var; var = var->_nextVarObj) {
|
|
for (uint i = 0; i < sc->_staticANIObjectList1.size(); i++) {
|
|
StaticANIObject *ani = sc->_staticANIObjectList1[i];
|
|
|
|
if (ani->_id == ANI_LIFTBUTTON) {
|
|
int id = lift_getButtonIdN(ani->_statics->_staticsId);
|
|
|
|
if (id == var->_value.intValue)
|
|
ani->_statics = ani->getStaticsById(id);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void NGIEngine::lift_exitSeq(ExCommand *cmd) {
|
|
if (cmd) {
|
|
MessageQueue *mq = _globalMessageQueueList->getMessageQueueById(cmd->_parId);
|
|
|
|
if (mq)
|
|
mq->activateExCommandsByKind(34);
|
|
}
|
|
|
|
_lift->changeStatics2(ST_LFT_CLOSED);
|
|
|
|
MessageQueue *mq = new MessageQueue(_globalMessageQueueList->compact());
|
|
|
|
ExCommand *ex = new ExCommand(_aniMan->_id, 34, 256, 0, 0, 0, 1, 0, 0, 0);
|
|
|
|
ex->_z = 256;
|
|
ex->_messageNum = 256;
|
|
ex->_excFlags |= 3;
|
|
mq->addExCommandToEnd(ex);
|
|
|
|
if (!cmd) {
|
|
ex = new ExCommand(_aniMan->_id, 2, 40, 0, 0, 0, 1, 0, 0, 0);
|
|
ex->_param = _aniMan->_odelay;
|
|
ex->_excFlags |= 2;
|
|
mq->addExCommandToEnd(ex);
|
|
}
|
|
|
|
ex = new ExCommand(_lift->_id, 1, MV_LFT_OPEN, 0, 0, 0, 1, 0, 0, 0);
|
|
ex->_param = _lift->_odelay;
|
|
ex->_excFlags |= 2;
|
|
mq->addExCommandToEnd(ex);
|
|
|
|
ex = new ExCommand(_aniMan->_id, 1, MV_MAN_STARTD, 0, 0, 0, 1, 0, 0, 0);
|
|
ex->_param = _aniMan->_odelay;
|
|
ex->_excFlags |= 2;
|
|
mq->addExCommandToEnd(ex);
|
|
|
|
ex = new ExCommand(_aniMan->_id, 5, -1, 0, 0, 0, 1, 0, 0, 0);
|
|
ex->_param = _aniMan->_odelay;
|
|
ex->_z = 10;
|
|
ex->_x = -1;
|
|
ex->_y = -1;
|
|
ex->_excFlags |= 3;
|
|
mq->addExCommandToEnd(ex);
|
|
|
|
ex = new ExCommand(_aniMan->_id, 34, 256, 0, 0, 0, 1, 0, 0, 0);
|
|
ex->_excFlags |= 3;
|
|
ex->_z = 256;
|
|
ex->_messageNum = 0;
|
|
mq->addExCommandToEnd(ex);
|
|
|
|
ex = new ExCommand(0, 17, MSG_LIFT_STARTEXITQUEUE, 0, 0, 0, 1, 0, 0, 0);
|
|
ex->_excFlags |= 3;
|
|
mq->addExCommandToEnd(ex);
|
|
|
|
ex = new ExCommand(_lift->_id, 1, MV_LFT_CLOSE, 0, 0, 0, 1, 0, 0, 0);
|
|
ex->_param = _lift->_odelay;
|
|
ex->_excFlags |= 2;
|
|
|
|
mq->addExCommandToEnd(ex);
|
|
|
|
mq->chain(nullptr);
|
|
}
|
|
|
|
void NGIEngine::lift_closedoorSeq() {
|
|
if (_lift->_movement) {
|
|
if (_lift->_movement->_id == MV_LFT_CLOSE) {
|
|
_lift->queueMessageQueue(nullptr);
|
|
} else if (_lift->_movement->_id == MV_LFT_OPEN) {
|
|
int ph = _lift->_movement->_currDynamicPhaseIndex;
|
|
|
|
_lift->changeStatics2(ST_LFT_OPEN_NEW);
|
|
_lift->startAnim(MV_LFT_CLOSE, 0, -1);
|
|
|
|
if (_lift->_movement->_currMovement)
|
|
_lift->_movement->setDynamicPhaseIndex(_lift->_movement->_currMovement->_dynamicPhases.size() - ph);
|
|
else
|
|
_lift->_movement->setDynamicPhaseIndex(_lift->_movement->_dynamicPhases.size() - ph);
|
|
} else {
|
|
_lift->changeStatics2(ST_LFT_OPEN_NEW);
|
|
|
|
_lift->startAnim(MV_LFT_CLOSE, 0, -1);
|
|
}
|
|
} else {
|
|
if (_lift->_statics->_staticsId == ST_LFT_CLOSED ) {
|
|
_lift->changeStatics2(ST_LFT_CLOSED);
|
|
} else {
|
|
_lift->startAnim(MV_LFT_CLOSE, 0, -1);
|
|
}
|
|
}
|
|
|
|
MessageQueue *mq = new MessageQueue(_globalMessageQueueList->compact());
|
|
ExCommand *ex = new ExCommand(0, 17, MSG_LIFT_GO, 0, 0, 0, 1, 0, 0, 0);
|
|
|
|
ex->_excFlags |= 3;
|
|
mq->addExCommandToEnd(ex);
|
|
|
|
if (!mq->chain(_lift))
|
|
delete mq;
|
|
}
|
|
|
|
void NGIEngine::lift_walkAndGo() {
|
|
MessageQueue *mq;
|
|
ExCommand *ex;
|
|
|
|
if (abs(_liftX - _aniMan->_ox) > 1 || abs(_liftY - _aniMan->_oy) > 1 || _aniMan->_movement || _aniMan->_statics->_staticsId != ST_MAN_UP) {
|
|
mq = getCurrSceneSc2MotionController()->startMove(_aniMan, _liftX, _liftY, 1, ST_MAN_UP);
|
|
|
|
if (mq) {
|
|
ex = new ExCommand(0, 17, MSG_LIFT_CLICKBUTTON, 0, 0, 0, 1, 0, 0, 0);
|
|
ex->_excFlags |= 3;
|
|
|
|
mq->addExCommandToEnd(ex);
|
|
}
|
|
} else {
|
|
lift_openLift();
|
|
|
|
mq = new MessageQueue(_liftEnterMQ, 0, 0);
|
|
|
|
mq->setFlags(mq->getFlags() | 1);
|
|
|
|
ex = new ExCommand(_aniMan->_id, 2, 15, 0, 0, 0, 1, 0, 0, 0);
|
|
ex->_param = _aniMan->_odelay;
|
|
ex->_excFlags |= 2;
|
|
mq->addExCommand(ex);
|
|
|
|
ex = new ExCommand(_aniMan->_id, 5, -1, 0, 0, 0, 1, 0, 0, 0);
|
|
ex->_param = _aniMan->_odelay;
|
|
ex->_z = _lift->_priority + 1;
|
|
ex->_x = -1;
|
|
ex->_y = -1;
|
|
ex->_excFlags |= 3;
|
|
mq->addExCommandToEnd(ex);
|
|
|
|
ex = new ExCommand(0, 17, MSG_LIFT_CLOSEDOOR, 0, 0, 0, 1, 0, 0, 0);
|
|
ex->_excFlags |= 3;
|
|
mq->addExCommandToEnd(ex);
|
|
|
|
mq->chain(nullptr);
|
|
|
|
_aniMan->_flags |= 0x100;
|
|
}
|
|
}
|
|
|
|
void NGIEngine::lift_openLift() {
|
|
if (_lift->_movement) {
|
|
if (_lift->_movement->_id == MV_LFT_OPEN) {
|
|
_lift->queueMessageQueue(nullptr);
|
|
} else if (_lift->_movement->_id == MV_LFT_CLOSE) {
|
|
int idx = _lift->_movement->_currDynamicPhaseIndex;
|
|
|
|
_lift->changeStatics2(ST_LFT_CLOSED);
|
|
_lift->startAnim(MV_LFT_OPEN, 0, -1);
|
|
|
|
if (_lift->_movement->_currMovement)
|
|
_lift->_movement->setDynamicPhaseIndex(_lift->_movement->_currMovement->_dynamicPhases.size() - idx);
|
|
else
|
|
_lift->_movement->setDynamicPhaseIndex(_lift->_movement->_dynamicPhases.size() - idx);
|
|
} else {
|
|
_lift->changeStatics2(ST_LFT_CLOSED);
|
|
_lift->startAnim(MV_LFT_OPEN, 0, -1);
|
|
}
|
|
} else if (_lift->_statics->_staticsId == ST_LFT_OPEN_NEW) {
|
|
_lift->changeStatics2(ST_LFT_OPEN_NEW);
|
|
} else {
|
|
_lift->startAnim(MV_LFT_OPEN, 0, -1);
|
|
}
|
|
}
|
|
|
|
void NGIEngine::lift_clickButton() {
|
|
if (_lastLiftButton)
|
|
lift_walkAndGo();
|
|
}
|
|
|
|
void NGIEngine::lift_goAnimation() {
|
|
if (_lastLiftButton) {
|
|
int parentId = _currentScene->_sceneId;
|
|
int buttonId = lift_getButtonIdN(_lastLiftButton->_statics->_staticsId);
|
|
|
|
if (!buttonId)
|
|
return;
|
|
|
|
int numItems = _gameLoader->_preloadItems.size();
|
|
|
|
for (int i = 0; i < numItems; i++) {
|
|
PreloadItem &pre = _gameLoader->_preloadItems[i];
|
|
|
|
if (pre.preloadId2 == buttonId && pre.preloadId1 == _currentScene->_sceneId) {
|
|
MessageQueue *mq = new MessageQueue(_globalMessageQueueList->compact());
|
|
|
|
ExCommand *ex = new ExCommand(ANI_MAN, 1, (pre.param != LiftDown ? MV_MAN_LIFTDOWN : MV_MAN_LIFTUP), 0, 0, 0, 1, 0, 0, 0);
|
|
|
|
ex->_param = -1;
|
|
ex->_field_24 = 1;
|
|
ex->_excFlags |= 2;
|
|
|
|
mq->addExCommandToEnd(ex);
|
|
|
|
ex = new ExCommand(parentId, 17, 61, 0, 0, 0, 1, 0, 0, 0);
|
|
|
|
ex->_param = buttonId;
|
|
ex->_excFlags |= 3;
|
|
|
|
mq->addExCommandToEnd(ex);
|
|
|
|
_aniMan->_flags &= ~0x100;
|
|
|
|
if (!mq->chain(_aniMan))
|
|
delete mq;
|
|
|
|
_aniMan->_flags |= 0x100;
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
lift_exitSeq(nullptr);
|
|
|
|
if (_lastLiftButton) {
|
|
_lastLiftButton->_statics = _lastLiftButton->getStaticsById(lift_getButtonIdN(_lastLiftButton->_statics->_staticsId));
|
|
_lastLiftButton = nullptr;
|
|
}
|
|
}
|
|
|
|
void NGIEngine::lift_animateButton(StaticANIObject *button) {
|
|
int butId = lift_getButtonIdP(button->_statics->_staticsId);
|
|
|
|
if (butId && butId != button->_statics->_staticsId) {
|
|
if (button == _lastLiftButton) {
|
|
playSound(SND_CMN_032, 0);
|
|
} else {
|
|
if (_lastLiftButton) {
|
|
int id = lift_getButtonIdN(_lastLiftButton->_statics->_staticsId);
|
|
|
|
if (id)
|
|
_lastLiftButton->_statics = _lastLiftButton->getStaticsById(id);
|
|
|
|
_lastLiftButton = nullptr;
|
|
}
|
|
|
|
if (_aniMan->isIdle() && !(_aniMan->_flags & 0x100)) {
|
|
_lastLiftButton = button;
|
|
button->_statics = button->getStaticsById(butId);
|
|
|
|
ExCommand *ex = new ExCommand(0, 35, SND_CMN_032, 0, 0, 0, 1, 0, 0, 0);
|
|
ex->_excFlags |= 3;
|
|
ex->_z = 1;
|
|
ex->postMessage();
|
|
|
|
int id = lift_getButtonIdH(_lastLiftButton->_statics->_staticsId);
|
|
|
|
if (id) {
|
|
_lastLiftButton->_statics = _lastLiftButton->getStaticsById(id);
|
|
|
|
lift_walkAndGo();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void NGIEngine::lift_startExitQueue() {
|
|
MessageQueue *mq = new MessageQueue(_liftExitMQ, 0, 0);
|
|
|
|
mq->chain(nullptr);
|
|
}
|
|
|
|
void NGIEngine::lift_hoverButton(ExCommand *cmd) {
|
|
if (_lastLiftButton) {
|
|
if (!(cmd->_param & 2) || _liftX != cmd->_x || _liftY != cmd->_y) {
|
|
_lastLiftButton->_statics = _lastLiftButton->getStaticsById(lift_getButtonIdN(_lastLiftButton->_statics->_staticsId));
|
|
_lastLiftButton = nullptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool NGIEngine::lift_checkButton(const char *varName) {
|
|
GameVar *var = g_nmi->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName(sO_LiftButtons);
|
|
|
|
if (var)
|
|
return lift_getButtonIdP(var->getSubVarByName(varName)->_value.intValue) > 0;
|
|
|
|
return false;
|
|
}
|
|
|
|
void NGIEngine::lift_setButtonStatics(Scene *sc, int buttonId) {
|
|
for (uint i = 0; i < sc->_staticANIObjectList1.size(); i++) {
|
|
StaticANIObject *ani = sc->_staticANIObjectList1[i];
|
|
|
|
if (ani->_id == ANI_LIFTBUTTON) {
|
|
int id = lift_getButtonIdN(ani->_statics->_staticsId);
|
|
|
|
if (id == buttonId)
|
|
ani->_statics = ani->getStaticsById(id);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
} // End of namespace NGI
|