scummvm/engines/lab/processroom.cpp

781 lines
21 KiB
C++
Raw Normal View History

2014-10-06 14:50:05 +02:00
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
/*
* This code is based on Labyrinth of Time code with assistance of
*
* Copyright (c) 1993 Terra Nova Development
* Copyright (c) 2004 The Wyrmkeep Entertainment Co.
*
*/
#include "gui/message.h"
2014-12-25 19:13:52 +01:00
#include "lab/lab.h"
2014-10-06 14:50:05 +02:00
#include "lab/labfun.h"
#include "lab/parsetypes.h"
#include "lab/parsefun.h"
#include "lab/resource.h"
2015-12-01 20:10:42 +01:00
#include "lab/anim.h"
2014-10-06 14:50:05 +02:00
#include "lab/interface.h"
namespace Lab {
/* Global parser data */
#define NOFILE "no file"
2015-11-28 02:27:02 +01:00
RoomData *_rooms;
2014-10-06 14:50:05 +02:00
InventoryData *Inventory;
2015-11-30 01:42:12 +01:00
uint16 NumInv, ManyRooms, HighestCondition, Direction;
2014-10-06 14:50:05 +02:00
2015-12-03 11:01:50 +01:00
extern bool DoNotDrawMessage, noupdatediff, QuitLab, MusicOn;
2014-10-06 14:50:05 +02:00
/*****************************************************************************/
/* Generates a random number. */
/*****************************************************************************/
uint16 getRandom(uint16 max) {
uint32 secs, micros;
2015-11-20 19:45:07 +01:00
g_lab->getTime(&secs, &micros);
2014-10-06 14:50:05 +02:00
return ((micros + secs) % max);
}
/*****************************************************************************/
/* Checks whether all the conditions in a condition list are met. */
/*****************************************************************************/
static bool checkConditions(int16 *Condition) {
int16 Counter;
bool res;
if (Condition == NULL)
return true;
if (Condition[0] == 0)
return true;
Counter = 1;
2014-12-25 19:13:52 +01:00
res = g_lab->_conditions->in(Condition[0]);
2014-10-06 14:50:05 +02:00
while (Condition[Counter] && res) {
2014-12-25 19:13:52 +01:00
res = g_lab->_conditions->in(Condition[Counter]);
2014-10-06 14:50:05 +02:00
Counter++;
}
return res;
}
/*****************************************************************************/
/* Gets the current ViewDataPointer. */
/*****************************************************************************/
ViewData *getViewData(uint16 roomNum, uint16 direction) {
ViewData *view = NULL;
2015-11-28 02:27:02 +01:00
if (!_rooms[roomNum]._roomMsg)
g_lab->_resource->readViews(roomNum);
2014-10-06 14:50:05 +02:00
if (direction == NORTH)
2015-11-28 02:27:02 +01:00
view = _rooms[roomNum]._northView;
2014-10-06 14:50:05 +02:00
else if (direction == SOUTH)
2015-11-28 02:27:02 +01:00
view = _rooms[roomNum]._southView;
2014-10-06 14:50:05 +02:00
else if (direction == EAST)
2015-11-28 02:27:02 +01:00
view = _rooms[roomNum]._eastView;
2014-10-06 14:50:05 +02:00
else if (direction == WEST)
2015-11-28 02:27:02 +01:00
view = _rooms[roomNum]._westView;
2014-10-06 14:50:05 +02:00
do {
if (checkConditions(view->Condition))
break;
2014-10-06 14:50:05 +02:00
view = view->NextCondition;
} while (true);
2014-10-06 14:50:05 +02:00
return view;
2014-10-06 14:50:05 +02:00
}
/*****************************************************************************/
/* Gets an object, if any, from the user's click on the screen. */
/*****************************************************************************/
2015-12-03 11:01:50 +01:00
static CloseData *getObject(uint16 x, uint16 y, CloseDataPtr lcptr) {
ViewData *VPtr;
2014-10-06 14:50:05 +02:00
2015-12-03 11:01:50 +01:00
if (lcptr == NULL) {
2015-11-30 01:42:12 +01:00
VPtr = getViewData(g_lab->_roomNum, Direction);
2015-12-03 11:01:50 +01:00
lcptr = VPtr->closeUps;
2014-10-06 14:50:05 +02:00
}
else
2015-12-03 11:01:50 +01:00
lcptr = lcptr->SubCloseUps;
2014-10-06 14:50:05 +02:00
2015-12-03 11:01:50 +01:00
while (lcptr != NULL) {
if ((x >= scaleX(lcptr->x1)) && (y >= scaleY(lcptr->y1)) &&
(x <= scaleX(lcptr->x2)) && (y <= scaleY(lcptr->y2)))
return lcptr;
2014-10-06 14:50:05 +02:00
2015-12-03 11:01:50 +01:00
lcptr = lcptr->NextCloseUp;
2014-10-06 14:50:05 +02:00
}
return NULL;
}
/*****************************************************************************/
/* Goes through the list of closeups to find a match. */
/* NYI: Known bug here. If there are two objects that have closeups, and */
/* some of the closeups have the same hit boxes, then this returns the */
/* first occurence of the object with the same hit box. */
/*****************************************************************************/
static CloseDataPtr findCPtrMatch(CloseDataPtr Main, CloseDataPtr List) {
CloseDataPtr cptr;
while (List) {
if ((Main->x1 == List->x1) && (Main->x2 == List->x2) &&
(Main->y1 == List->y1) && (Main->y2 == List->y2) &&
(Main->depth == List->depth))
return List;
cptr = findCPtrMatch(Main, List->SubCloseUps);
if (cptr)
return cptr;
else
List = List->NextCloseUp;
}
return NULL;
}
/*****************************************************************************/
/* Returns the current picture name. */
/*****************************************************************************/
2015-12-03 11:01:50 +01:00
char *getPictName(CloseDataPtr *lcptr) {
2015-11-30 01:42:12 +01:00
ViewData *ViewPtr = getViewData(g_lab->_roomNum, Direction);
2014-10-06 14:50:05 +02:00
2015-12-03 11:01:50 +01:00
if (*lcptr != NULL) {
*lcptr = findCPtrMatch(*lcptr, ViewPtr->closeUps);
2014-10-06 14:50:05 +02:00
2015-12-03 11:01:50 +01:00
if (*lcptr)
return (*lcptr)->GraphicName;
2014-10-06 14:50:05 +02:00
}
return ViewPtr->GraphicName;
}
/*****************************************************************************/
/* Draws the current direction to the screen. */
/*****************************************************************************/
2015-12-03 11:01:50 +01:00
void LabEngine::drawDirection(CloseDataPtr lcptr) {
if (lcptr != NULL && lcptr->Message) {
drawMessage(lcptr->Message);
return;
2014-10-06 14:50:05 +02:00
}
Common::String message;
2014-10-06 14:50:05 +02:00
2015-11-30 01:42:12 +01:00
if (_rooms[_roomNum]._roomMsg) {
message += _rooms[_roomNum]._roomMsg;
message += ", ";
2014-10-06 14:50:05 +02:00
}
if (Direction == NORTH)
message += _resource->getStaticText(kTextFacingNorth);
2014-10-06 14:50:05 +02:00
else if (Direction == EAST)
message += _resource->getStaticText(kTextFacingEast);
2014-10-06 14:50:05 +02:00
else if (Direction == SOUTH)
message += _resource->getStaticText(kTextFacingSouth);
2014-10-06 14:50:05 +02:00
else if (Direction == WEST)
message += _resource->getStaticText(kTextFacingWest);
2014-10-06 14:50:05 +02:00
drawMessage(message.c_str());
2014-10-06 14:50:05 +02:00
}
/*****************************************************************************/
/* process a arrow gadget movement. */
/*****************************************************************************/
bool processArrow(uint16 *direction, uint16 Arrow) {
uint16 room = 1;
if (Arrow == 1) { /* Forward */
if (*direction == NORTH)
2015-11-30 01:42:12 +01:00
room = _rooms[g_lab->_roomNum]._northDoor;
2014-10-06 14:50:05 +02:00
else if (*direction == SOUTH)
2015-11-30 01:42:12 +01:00
room = _rooms[g_lab->_roomNum]._southDoor;
2014-10-06 14:50:05 +02:00
else if (*direction == EAST)
2015-11-30 01:42:12 +01:00
room = _rooms[g_lab->_roomNum]._eastDoor;
2014-10-06 14:50:05 +02:00
else if (*direction == WEST)
2015-11-30 01:42:12 +01:00
room = _rooms[g_lab->_roomNum]._westDoor;
2014-10-06 14:50:05 +02:00
if (room == 0)
return false;
else
2015-11-30 01:42:12 +01:00
g_lab->_roomNum = room;
2014-10-06 14:50:05 +02:00
} else if (Arrow == 0) { /* Left */
if (*direction == NORTH)
*direction = WEST;
else if (*direction == WEST)
*direction = SOUTH;
else if (*direction == SOUTH)
*direction = EAST;
else
*direction = NORTH;
} else if (Arrow == 2) { /* Right */
if (*direction == NORTH)
*direction = EAST;
else if (*direction == EAST)
*direction = SOUTH;
else if (*direction == SOUTH)
*direction = WEST;
else
*direction = NORTH;
}
return true;
}
/*****************************************************************************/
/* Sets the current close up data. */
2014-10-06 14:50:05 +02:00
/*****************************************************************************/
void setCurClose(Common::Point pos, CloseDataPtr *cptr, bool useAbsoluteCoords) {
ViewData *VPtr;
2015-12-03 11:01:50 +01:00
CloseDataPtr lcptr;
uint16 x1, y1, x2, y2;
2014-10-06 14:50:05 +02:00
if (*cptr == NULL) {
2015-11-30 01:42:12 +01:00
VPtr = getViewData(g_lab->_roomNum, Direction);
2015-12-03 11:01:50 +01:00
lcptr = VPtr->closeUps;
2014-10-06 14:50:05 +02:00
} else
2015-12-03 11:01:50 +01:00
lcptr = (*cptr)->SubCloseUps;
2014-10-06 14:50:05 +02:00
2015-12-03 11:01:50 +01:00
while (lcptr != NULL) {
if (!useAbsoluteCoords) {
2015-12-03 11:01:50 +01:00
x1 = lcptr->x1;
y1 = lcptr->y1;
x2 = lcptr->x2;
y2 = lcptr->y2;
} else {
2015-12-03 11:01:50 +01:00
x1 = scaleX(lcptr->x1);
y1 = scaleY(lcptr->y1);
x2 = scaleX(lcptr->x2);
y2 = scaleY(lcptr->y2);
2014-10-06 14:50:05 +02:00
}
2015-12-03 11:01:50 +01:00
if (pos.x >= x1 && pos.y >= y1 && pos.x <= x2 && pos.y <= y2 && lcptr->GraphicName) {
*cptr = lcptr;
2014-10-06 14:50:05 +02:00
return;
}
2015-12-03 11:01:50 +01:00
lcptr = lcptr->NextCloseUp;
2014-10-06 14:50:05 +02:00
}
}
/*****************************************************************************/
/* Takes the currently selected item. */
/*****************************************************************************/
bool takeItem(uint16 x, uint16 y, CloseDataPtr *cptr) {
ViewData *VPtr;
2015-12-03 11:01:50 +01:00
CloseDataPtr lcptr;
2014-10-06 14:50:05 +02:00
if (*cptr == NULL) {
2015-11-30 01:42:12 +01:00
VPtr = getViewData(g_lab->_roomNum, Direction);
2015-12-03 11:01:50 +01:00
lcptr = VPtr->closeUps;
2014-10-06 14:50:05 +02:00
} else if ((*cptr)->CloseUpType < 0) {
2014-12-25 19:13:52 +01:00
g_lab->_conditions->inclElement(abs((*cptr)->CloseUpType));
2014-10-06 14:50:05 +02:00
return true;
} else
2015-12-03 11:01:50 +01:00
lcptr = (*cptr)->SubCloseUps;
2014-10-06 14:50:05 +02:00
2015-12-03 11:01:50 +01:00
while (lcptr != NULL) {
if ((x >= scaleX(lcptr->x1)) && (y >= scaleY(lcptr->y1)) &&
(x <= scaleX(lcptr->x2)) && (y <= scaleY(lcptr->y2)) &&
(lcptr->CloseUpType < 0)) {
g_lab->_conditions->inclElement(abs(lcptr->CloseUpType));
2014-10-06 14:50:05 +02:00
return true;
}
2015-12-03 11:01:50 +01:00
lcptr = lcptr->NextCloseUp;
2014-10-06 14:50:05 +02:00
}
return false;
}
/*****************************************************************************/
/* Processes the action list. */
/*****************************************************************************/
2015-12-03 11:01:50 +01:00
static void doActions(Action *APtr, CloseDataPtr *lcptr) {
CloseDataPtr tlcptr;
2014-10-06 14:50:05 +02:00
bool FirstLoaded = true;
char **str, *Test;
uint32 StartSecs, StartMicros, CurSecs, CurMicros;
while (APtr) {
g_lab->_music->updateMusic();
2014-10-06 14:50:05 +02:00
switch (APtr->ActionType) {
case PLAYSOUND:
g_lab->_music->_loopSoundEffect = false;
g_lab->_music->_waitTillFinished = true;
readMusic((char *)APtr->Data, true);
g_lab->_music->_waitTillFinished = false;
2014-10-06 14:50:05 +02:00
break;
case PLAYSOUNDB:
g_lab->_music->_loopSoundEffect = false;
g_lab->_music->_waitTillFinished = false;
readMusic((char *)APtr->Data, false);
2014-10-06 14:50:05 +02:00
break;
case PLAYSOUNDCONT:
g_lab->_music->_doNotFilestopSoundEffect = true;
g_lab->_music->_loopSoundEffect = true;
readMusic((char *)APtr->Data, g_lab->_music->_waitTillFinished);
2014-10-06 14:50:05 +02:00
break;
case SHOWDIFF:
readPict((char *)APtr->Data, true);
break;
case SHOWDIFFCONT:
readPict((char *)APtr->Data, false);
break;
case LOADDIFF:
if (FirstLoaded) {
resetBuffer();
FirstLoaded = false;
}
if (APtr->Data)
g_lab->_music->newOpen((char *)APtr->Data); /* Puts a file into memory */
2014-10-06 14:50:05 +02:00
break;
case WIPECMD:
2015-12-03 11:01:50 +01:00
g_lab->doWipe(APtr->Param1, lcptr, (char *)APtr->Data);
2014-10-06 14:50:05 +02:00
break;
case NOUPDATE:
noupdatediff = true;
2015-12-02 00:34:51 +01:00
g_lab->_anim->_doBlack = false;
2014-10-06 14:50:05 +02:00
break;
case FORCEUPDATE:
g_lab->_curFileName = " ";
2014-10-06 14:50:05 +02:00
break;
case SHOWCURPICT:
2015-12-03 11:01:50 +01:00
Test = getPictName(lcptr);
2014-10-06 14:50:05 +02:00
if (strcmp(Test, g_lab->_curFileName) != 0) {
g_lab->_curFileName = Test;
readPict(g_lab->_curFileName, true);
2014-10-06 14:50:05 +02:00
}
break;
case SETELEMENT:
2014-12-25 19:13:52 +01:00
g_lab->_conditions->inclElement(APtr->Param1);
2014-10-06 14:50:05 +02:00
break;
case UNSETELEMENT:
2014-12-25 19:13:52 +01:00
g_lab->_conditions->exclElement(APtr->Param1);
2014-10-06 14:50:05 +02:00
break;
case SHOWMESSAGE:
DoNotDrawMessage = false;
2015-12-03 11:01:50 +01:00
if (g_lab->_longWinInFront)
g_lab->longDrawMessage((char *)APtr->Data);
2014-10-06 14:50:05 +02:00
else
g_lab->drawMessage((char *)APtr->Data);
2014-10-06 14:50:05 +02:00
DoNotDrawMessage = true;
break;
case CSHOWMESSAGE:
2015-12-03 11:01:50 +01:00
if (*lcptr == NULL) {
2014-10-06 14:50:05 +02:00
DoNotDrawMessage = false;
g_lab->drawMessage((char *)APtr->Data);
2014-10-06 14:50:05 +02:00
DoNotDrawMessage = true;
}
break;
case SHOWMESSAGES:
str = (char **)APtr->Data;
DoNotDrawMessage = false;
g_lab->drawMessage(str[getRandom(APtr->Param1)]);
2014-10-06 14:50:05 +02:00
DoNotDrawMessage = true;
break;
case SETPOSITION:
if (APtr->Param1 & 0x8000) {
// This is a Wyrmkeep Windows trial version, thus stop at this
// point, since we can't check for game payment status
2015-12-03 11:01:50 +01:00
readPict(getPictName(lcptr), true);
APtr = NULL;
GUI::MessageDialog trialMessage("This is the end of the trial version. You can play the full game using the original interpreter from Wyrmkeep");
trialMessage.runModal();
continue;
2014-10-06 14:50:05 +02:00
}
2015-11-30 01:42:12 +01:00
g_lab->_roomNum = APtr->Param1;
2014-10-06 14:50:05 +02:00
Direction = APtr->Param2 - 1;
2015-12-03 11:01:50 +01:00
*lcptr = NULL;
2015-12-02 00:34:51 +01:00
g_lab->_anim->_doBlack = true;
2014-10-06 14:50:05 +02:00
break;
case SETCLOSEUP:
2015-12-03 11:01:50 +01:00
tlcptr = getObject(scaleX(APtr->Param1), scaleY(APtr->Param2), *lcptr);
2014-10-06 14:50:05 +02:00
2015-12-03 11:01:50 +01:00
if (tlcptr)
*lcptr = tlcptr;
2014-10-06 14:50:05 +02:00
break;
case MAINVIEW:
2015-12-03 11:01:50 +01:00
*lcptr = NULL;
2014-10-06 14:50:05 +02:00
break;
case SUBINV:
if (Inventory[APtr->Param1].Many)
(Inventory[APtr->Param1].Many)--;
if (Inventory[APtr->Param1].Many == 0)
2014-12-25 19:13:52 +01:00
g_lab->_conditions->exclElement(APtr->Param1);
2014-10-06 14:50:05 +02:00
break;
case ADDINV:
(Inventory[APtr->Param1].Many) += APtr->Param2;
2014-12-25 19:13:52 +01:00
g_lab->_conditions->inclElement(APtr->Param1);
2014-10-06 14:50:05 +02:00
break;
case SHOWDIR:
DoNotDrawMessage = false;
break;
case WAITSECS:
2015-11-20 19:45:07 +01:00
g_lab->addCurTime(APtr->Param1, 0, &StartSecs, &StartMicros);
2014-10-06 14:50:05 +02:00
2015-11-30 20:07:23 +01:00
g_lab->screenUpdate();
2014-10-06 14:50:05 +02:00
while (1) {
g_lab->_music->updateMusic();
2015-12-01 20:10:42 +01:00
g_lab->_anim->diffNextFrame();
2015-11-20 19:45:07 +01:00
g_lab->getTime(&CurSecs, &CurMicros);
2014-10-06 14:50:05 +02:00
if ((CurSecs > StartSecs) || ((CurSecs == StartSecs) &&
(CurMicros >= StartMicros)))
break;
}
break;
case STOPMUSIC:
g_lab->_music->setMusic(false);
2014-10-06 14:50:05 +02:00
break;
case STARTMUSIC:
g_lab->_music->setMusic(true);
2014-10-06 14:50:05 +02:00
break;
case CHANGEMUSIC:
g_lab->_music->changeMusic((const char *)APtr->Data);
g_lab->_music->setMusicReset(false);
2014-10-06 14:50:05 +02:00
break;
case RESETMUSIC:
g_lab->_music->resetMusic();
g_lab->_music->setMusicReset(true);
2014-10-06 14:50:05 +02:00
break;
case FILLMUSIC:
g_lab->_music->updateMusic();
2014-10-06 14:50:05 +02:00
break;
case WAITSOUND:
while (g_lab->_music->isSoundEffectActive()) {
g_lab->_music->updateMusic();
2015-12-01 20:10:42 +01:00
g_lab->_anim->diffNextFrame();
2015-11-24 23:59:30 +01:00
g_lab->waitTOF();
2014-10-06 14:50:05 +02:00
}
break;
case CLEARSOUND:
if (g_lab->_music->_loopSoundEffect) {
g_lab->_music->_loopSoundEffect = false;
g_lab->_music->stopSoundEffect();
} else if (g_lab->_music->isSoundEffectActive())
g_lab->_music->stopSoundEffect();
2014-10-06 14:50:05 +02:00
break;
case WINMUSIC:
g_lab->_music->_winmusic = true;
g_lab->_music->freeMusic();
g_lab->_music->initMusic();
2014-10-06 14:50:05 +02:00
break;
case WINGAME:
QuitLab = true;
break;
case LOSTGAME:
QuitLab = true;
break;
case RESETBUFFER:
resetBuffer();
break;
case SPECIALCMD:
if (APtr->Param1 == 0)
2015-12-02 00:34:51 +01:00
g_lab->_anim->_doBlack = true;
2014-10-06 14:50:05 +02:00
else if (APtr->Param1 == 1)
2015-12-03 11:10:58 +01:00
g_lab->_anim->_doBlack = (g_lab->_cptr == NULL);
2014-10-06 14:50:05 +02:00
else if (APtr->Param1 == 2)
2015-12-03 11:10:58 +01:00
g_lab->_anim->_doBlack = (g_lab->_cptr != NULL);
2014-10-06 14:50:05 +02:00
else if (APtr->Param1 == 5) { /* inverse the palette */
for (uint16 idx = (8 * 3); idx < (255 * 3); idx++)
2015-12-02 00:34:51 +01:00
g_lab->_anim->_diffPalette[idx] = 255 - g_lab->_anim->_diffPalette[idx];
2014-10-06 14:50:05 +02:00
2015-11-24 23:59:30 +01:00
g_lab->waitTOF();
2015-12-02 00:34:51 +01:00
g_lab->setPalette(g_lab->_anim->_diffPalette, 256);
2015-11-24 23:59:30 +01:00
g_lab->waitTOF();
g_lab->waitTOF();
2014-10-06 14:50:05 +02:00
} else if (APtr->Param1 == 4) { /* white the palette */
whiteScreen();
2015-11-24 23:59:30 +01:00
g_lab->waitTOF();
g_lab->waitTOF();
2014-10-06 14:50:05 +02:00
} else if (APtr->Param1 == 6) { /* Restore the palette */
2015-11-24 23:59:30 +01:00
g_lab->waitTOF();
2015-12-02 00:34:51 +01:00
g_lab->setPalette(g_lab->_anim->_diffPalette, 256);
2015-11-24 23:59:30 +01:00
g_lab->waitTOF();
g_lab->waitTOF();
2014-10-06 14:50:05 +02:00
} else if (APtr->Param1 == 7) { /* Quick pause */
2015-11-24 23:59:30 +01:00
g_lab->waitTOF();
g_lab->waitTOF();
g_lab->waitTOF();
2014-10-06 14:50:05 +02:00
}
break;
}
APtr = APtr->NextAction;
}
if (g_lab->_music->_loopSoundEffect) {
g_lab->_music->_loopSoundEffect = false;
g_lab->_music->stopSoundEffect();
2014-10-06 14:50:05 +02:00
} else {
while (g_lab->_music->isSoundEffectActive()) {
g_lab->_music->updateMusic();
2015-12-01 20:10:42 +01:00
g_lab->_anim->diffNextFrame();
2015-11-24 23:59:30 +01:00
g_lab->waitTOF();
2014-10-06 14:50:05 +02:00
}
}
g_lab->_music->_doNotFilestopSoundEffect = false;
2014-10-06 14:50:05 +02:00
}
/*****************************************************************************/
/* Does the work for doActionRule. */
/*****************************************************************************/
2015-12-03 11:01:50 +01:00
static bool doActionRuleSub(int16 action, int16 roomNum, CloseDataPtr lcptr, CloseDataPtr *Set, bool AllowDefaults) {
action++;
2014-10-06 14:50:05 +02:00
2015-12-03 11:01:50 +01:00
if (lcptr) {
2015-11-30 01:42:12 +01:00
RuleList *rules = _rooms[g_lab->_roomNum]._rules;
2015-11-20 19:45:07 +01:00
if ((rules == NULL) && (roomNum == 0)) {
g_lab->_resource->readViews(roomNum);
2015-11-28 02:27:02 +01:00
rules = _rooms[roomNum]._rules;
2014-10-06 14:50:05 +02:00
}
2015-11-27 21:52:31 +01:00
for (RuleList::iterator rule = rules->begin(); rule != rules->end(); ++rule) {
if (((*rule)->RuleType == ACTION) &&
(((*rule)->Param1 == action) || (((*rule)->Param1 == 0) && AllowDefaults))) {
2015-12-03 11:01:50 +01:00
if ((((*rule)->Param2 == lcptr->CloseUpType) ||
(((*rule)->Param2 == 0) && AllowDefaults))
2014-10-06 14:50:05 +02:00
||
2015-12-03 11:01:50 +01:00
((action == 1) && ((*rule)->Param2 == (-lcptr->CloseUpType)))) {
if (checkConditions((*rule)->Condition)) {
doActions((*rule)->ActionList, Set);
2014-10-06 14:50:05 +02:00
return true;
}
}
}
}
}
return false;
}
/*****************************************************************************/
/* Goes through the rules if an action is taken. */
/*****************************************************************************/
2015-12-03 11:01:50 +01:00
bool doActionRule(Common::Point pos, int16 action, int16 roomNum, CloseDataPtr *lcptr) {
CloseDataPtr tlcptr;
2014-10-06 14:50:05 +02:00
if (roomNum)
g_lab->_newFileName = NOFILE;
2014-10-06 14:50:05 +02:00
else
g_lab->_newFileName = g_lab->_curFileName;
2014-10-06 14:50:05 +02:00
2015-12-03 11:01:50 +01:00
tlcptr = getObject(pos.x, pos.y, *lcptr);
2014-10-06 14:50:05 +02:00
2015-12-03 11:01:50 +01:00
if (doActionRuleSub(action, roomNum, tlcptr, lcptr, false))
2014-10-06 14:50:05 +02:00
return true;
2015-12-03 11:01:50 +01:00
else if (doActionRuleSub(action, roomNum, *lcptr, lcptr, false))
2014-10-06 14:50:05 +02:00
return true;
2015-12-03 11:01:50 +01:00
else if (doActionRuleSub(action, roomNum, tlcptr, lcptr, true))
2014-10-06 14:50:05 +02:00
return true;
2015-12-03 11:01:50 +01:00
else if (doActionRuleSub(action, roomNum, *lcptr, lcptr, true))
2014-10-06 14:50:05 +02:00
return true;
return false;
}
/*****************************************************************************/
/* Does the work for doActionRule. */
/*****************************************************************************/
2015-12-03 11:01:50 +01:00
static bool doOperateRuleSub(int16 ItemNum, int16 roomNum, CloseDataPtr lcptr, CloseDataPtr *Set, bool AllowDefaults) {
if (lcptr)
if (lcptr->CloseUpType > 0) {
2015-11-28 02:27:02 +01:00
RuleList *rules = _rooms[roomNum]._rules;
2014-10-06 14:50:05 +02:00
if ((rules == NULL) && (roomNum == 0)) {
g_lab->_resource->readViews(roomNum);
2015-11-28 02:27:02 +01:00
rules = _rooms[roomNum]._rules;
2014-10-06 14:50:05 +02:00
}
2015-11-27 21:52:31 +01:00
for (RuleList::iterator rule = rules->begin(); rule != rules->end(); ++rule) {
if (((*rule)->RuleType == OPERATE) &&
(((*rule)->Param1 == ItemNum) || (((*rule)->Param1 == 0) && AllowDefaults)) &&
2015-12-03 11:01:50 +01:00
(((*rule)->Param2 == lcptr->CloseUpType) || (((*rule)->Param2 == 0) && AllowDefaults))) {
if (checkConditions((*rule)->Condition)) {
doActions((*rule)->ActionList, Set);
2014-10-06 14:50:05 +02:00
return true;
}
}
}
}
return false;
}
/*****************************************************************************/
/* Goes thru the rules if the user tries to operate an item on an object. */
/*****************************************************************************/
2015-12-03 11:01:50 +01:00
bool doOperateRule(int16 x, int16 y, int16 ItemNum, CloseDataPtr *lcptr) {
CloseDataPtr tlcptr;
2014-10-06 14:50:05 +02:00
g_lab->_newFileName = NOFILE;
2014-10-06 14:50:05 +02:00
2015-12-03 11:01:50 +01:00
tlcptr = getObject(x, y, *lcptr);
2014-10-06 14:50:05 +02:00
2015-12-03 11:01:50 +01:00
if (doOperateRuleSub(ItemNum, g_lab->_roomNum, tlcptr, lcptr, false))
2014-10-06 14:50:05 +02:00
return true;
2015-12-03 11:01:50 +01:00
else if (doOperateRuleSub(ItemNum, g_lab->_roomNum, *lcptr, lcptr, false))
2014-10-06 14:50:05 +02:00
return true;
2015-12-03 11:01:50 +01:00
else if (doOperateRuleSub(ItemNum, g_lab->_roomNum, tlcptr, lcptr, true))
2014-10-06 14:50:05 +02:00
return true;
2015-12-03 11:01:50 +01:00
else if (doOperateRuleSub(ItemNum, g_lab->_roomNum, *lcptr, lcptr, true))
2014-10-06 14:50:05 +02:00
return true;
else {
g_lab->_newFileName = g_lab->_curFileName;
2014-10-06 14:50:05 +02:00
2015-12-03 11:01:50 +01:00
if (doOperateRuleSub(ItemNum, 0, tlcptr, lcptr, false))
2014-10-06 14:50:05 +02:00
return true;
2015-12-03 11:01:50 +01:00
else if (doOperateRuleSub(ItemNum, 0, *lcptr, lcptr, false))
2014-10-06 14:50:05 +02:00
return true;
2015-12-03 11:01:50 +01:00
else if (doOperateRuleSub(ItemNum, 0, tlcptr, lcptr, true))
2014-10-06 14:50:05 +02:00
return true;
2015-12-03 11:01:50 +01:00
else if (doOperateRuleSub(ItemNum, 0, *lcptr, lcptr, true))
2014-10-06 14:50:05 +02:00
return true;
}
return false;
}
/*****************************************************************************/
/* Goes thru the rules if the user tries to go forward. */
/*****************************************************************************/
2015-12-03 11:01:50 +01:00
bool doGoForward(CloseDataPtr *lcptr) {
2015-11-30 01:42:12 +01:00
RuleList *rules = _rooms[g_lab->_roomNum]._rules;
2014-10-06 14:50:05 +02:00
2015-11-27 21:52:31 +01:00
for (RuleList::iterator rule = rules->begin(); rule != rules->end(); ++rule) {
if (((*rule)->RuleType == GOFORWARD) && ((*rule)->Param1 == (Direction + 1))) {
if (checkConditions((*rule)->Condition)) {
2015-12-03 11:01:50 +01:00
doActions((*rule)->ActionList, lcptr);
2014-10-06 14:50:05 +02:00
return true;
}
}
}
return false;
}
/*****************************************************************************/
/* Goes thru the rules if the user tries to turn. */
/*****************************************************************************/
2015-12-03 11:01:50 +01:00
bool doTurn(uint16 from, uint16 to, CloseDataPtr *lcptr) {
2014-10-06 14:50:05 +02:00
from++;
to++;
2015-11-30 01:42:12 +01:00
RuleList *rules = _rooms[g_lab->_roomNum]._rules;
2014-10-06 14:50:05 +02:00
2015-11-27 21:52:31 +01:00
for (RuleList::iterator rule = rules->begin(); rule != rules->end(); ++rule) {
if (((*rule)->RuleType == TURN) ||
(((*rule)->RuleType == TURNFROMTO) &&
((*rule)->Param1 == from) && ((*rule)->Param2 == to))) {
if (checkConditions((*rule)->Condition)) {
2015-12-03 11:01:50 +01:00
doActions((*rule)->ActionList, lcptr);
2014-10-06 14:50:05 +02:00
return true;
}
}
}
return false;
}
/*****************************************************************************/
/* Goes thru the rules if the user tries to go to the main view */
/*****************************************************************************/
2015-12-03 11:01:50 +01:00
bool doMainView(CloseDataPtr *lcptr) {
2015-11-30 01:42:12 +01:00
RuleList *rules = _rooms[g_lab->_roomNum]._rules;
2015-11-27 21:52:31 +01:00
for (RuleList::iterator rule = rules->begin(); rule != rules->end(); ++rule) {
if ((*rule)->RuleType == GOMAINVIEW) {
if (checkConditions((*rule)->Condition)) {
2015-12-03 11:01:50 +01:00
doActions((*rule)->ActionList, lcptr);
2014-10-06 14:50:05 +02:00
return true;
}
}
}
return false;
}
} // End of namespace Lab