diff options
author | johndoe123 | 2015-12-15 11:39:21 +0100 |
---|---|---|
committer | Eugene Sandulenko | 2018-07-20 06:43:33 +0000 |
commit | 48011948d60f700676629e157de75475d52c8abc (patch) | |
tree | 7fc6cd14c8e1297bd29261904814dd5ddcf88f57 | |
parent | 4aed366334c4ca2651eef87734f1c4d1d41a1ba2 (diff) | |
download | scummvm-rg350-48011948d60f700676629e157de75475d52c8abc.tar.gz scummvm-rg350-48011948d60f700676629e157de75475d52c8abc.tar.bz2 scummvm-rg350-48011948d60f700676629e157de75475d52c8abc.zip |
ILLUSIONS: BBDOU: Implement food/cafeteria minigame
-rw-r--r-- | engines/illusions/bbdou/bbdou_foodctl.cpp | 149 | ||||
-rw-r--r-- | engines/illusions/bbdou/bbdou_foodctl.h | 71 | ||||
-rw-r--r-- | engines/illusions/bbdou/bbdou_specialcode.cpp | 59 | ||||
-rw-r--r-- | engines/illusions/bbdou/bbdou_specialcode.h | 5 | ||||
-rw-r--r-- | engines/illusions/bbdou/scriptopcodes_bbdou.cpp | 3 | ||||
-rw-r--r-- | engines/illusions/module.mk | 1 |
6 files changed, 285 insertions, 3 deletions
diff --git a/engines/illusions/bbdou/bbdou_foodctl.cpp b/engines/illusions/bbdou/bbdou_foodctl.cpp new file mode 100644 index 0000000000..89c22d385c --- /dev/null +++ b/engines/illusions/bbdou/bbdou_foodctl.cpp @@ -0,0 +1,149 @@ +/* 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. + * + */ + +#include "illusions/bbdou/illusions_bbdou.h" +#include "illusions/bbdou/bbdou_foodctl.h" +#include "illusions/actor.h" +#include "illusions/dictionary.h" +#include "illusions/textdrawer.h" +#include "illusions/time.h" +#include "illusions/resources/scriptresource.h" + +namespace Illusions { + +BbdouFoodCtl::BbdouFoodCtl(IllusionsEngine_BBDOU *vm) + : _vm(vm) { +} + +BbdouFoodCtl::~BbdouFoodCtl() { +} + +void BbdouFoodCtl::placeFood(uint totalRoundsCount, uint maxRequestedFoodCount) { + _totalRoundsCount = totalRoundsCount; + _maxRequestedFoodCount = maxRequestedFoodCount; + _requestedFoodCount = 0; + _requestedFoodIndex = 0; + placeActors(); +} + +void BbdouFoodCtl::addFood(uint32 propertyId) { + _foodPropertyIds[_requestedFoodCount++] = propertyId; +} + +void BbdouFoodCtl::requestFirstFood() { + _requestedFoodIndex = 1; + _vm->_scriptResource->_properties.set(_foodPropertyIds[0], true); +} + +void BbdouFoodCtl::requestNextFood() { + uint32 propertyId = _foodPropertyIds[_requestedFoodIndex++]; + _vm->_scriptResource->_properties.set(propertyId, true); +} + +void BbdouFoodCtl::nextRound() { + --_totalRoundsCount; +} + +bool BbdouFoodCtl::hasReachedRequestedFoodCount() { + return _requestedFoodIndex > _requestedFoodCount; +} + +bool BbdouFoodCtl::hasRoundFinished() { + return _totalRoundsCount == 0 || _requestedFoodCount > _maxRequestedFoodCount; +} + +void BbdouFoodCtl::serveFood() { + uint32 foodSequenceId = getFoodSequenceId(); + uint32 studentObjectId = getCurrentStudentObjectId(); + uint32 foodObjectId = _foodItems[_servedFoodCount++].objectId; + Control *foodControl = _vm->_dict->getObjectControl(foodObjectId); + foodControl->startSequenceActor(foodSequenceId, 2, 0); + foodControl->linkToObject(studentObjectId, _servedFoodCount); +} + +void BbdouFoodCtl::resetFood() { + for (uint i = 0; i < _servedFoodCount; ++i) { + Control *control = _vm->_dict->getObjectControl(_foodItems[i].objectId); + control->unlinkObject(); + _foodItems[i].value = 0; + } + _servedFoodCount = 0; + resetFoodControls(); +} + +void BbdouFoodCtl::placeActors() { + static const uint32 kFoodSequenceIds[] = { + 0x00060932, 0x00060933, 0x00060934, + 0x00060935, 0x00060936, 0x00060937 + }; + for (uint i = 0; i < kFoodCount; ++i) { + uint32 objectId = _vm->_controls->newTempObjectId(); + _vm->_controls->placeActor(0x00050119, Common::Point(0, 0), 0x00060931, objectId, 0); + Control *control = _vm->_dict->getObjectControl(objectId); + control->deactivateObject(); + control->setPriority(i + 10); + control->startSequenceActor(kFoodSequenceIds[(i + 1) % 6], 2, 0); + _foodItems[i].objectId = objectId; + _foodItems[i].value = 0; + } + _servedFoodCount = 0; + resetFoodControls(); +} + +void BbdouFoodCtl::resetFoodControls() { + Common::Point pos(-100, 32); + for (uint i = 0; i < kFoodCount; ++i) { + Control *control = _vm->_dict->getObjectControl(_foodItems[i].objectId); + control->setActorPosition(pos); + pos.y += 20; + } +} + +uint32 BbdouFoodCtl::getFoodSequenceId() { + if (_vm->_scriptResource->_properties.get(0x000E014A)) + return 0x60932; + if (_vm->_scriptResource->_properties.get(0x000E014B)) + return 0x60933; + if (_vm->_scriptResource->_properties.get(0x000E014C)) + return 0x60934; + if (_vm->_scriptResource->_properties.get(0x000E014D)) + return 0x60935; + if (_vm->_scriptResource->_properties.get(0x000E014E)) + return 0x60936; + if (_vm->_scriptResource->_properties.get(0x000E014F)) + return 0x60937; + return 0; +} + +uint32 BbdouFoodCtl::getCurrentStudentObjectId() { + if (_vm->_scriptResource->_properties.get(0x000E0146)) + return 0x40077; + if (_vm->_scriptResource->_properties.get(0x000E0147)) + return 0x40255; + if (_vm->_scriptResource->_properties.get(0x000E0148)) + return 0x40256; + if (_vm->_scriptResource->_properties.get(0x000E0149)) + return 0x40257; + return 0; +} + +} // End of namespace Illusions diff --git a/engines/illusions/bbdou/bbdou_foodctl.h b/engines/illusions/bbdou/bbdou_foodctl.h new file mode 100644 index 0000000000..5a3177765e --- /dev/null +++ b/engines/illusions/bbdou/bbdou_foodctl.h @@ -0,0 +1,71 @@ +/* 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. + * + */ + +#ifndef ILLUSIONS_BBDOU_BBDOU_FOODCTL_H +#define ILLUSIONS_BBDOU_BBDOU_FOODCTL_H + +#include "illusions/specialcode.h" +#include "illusions/thread.h" + +namespace Illusions { + +class IllusionsEngine_BBDOU; + +// TODO Merge counts? +const uint kFoodMaxPropertyIdsCount = 15; +const uint kFoodCount = 16; + +struct FoodItem { + uint32 objectId; + int value; +}; + +class BbdouFoodCtl { +public: + BbdouFoodCtl(IllusionsEngine_BBDOU *vm); + ~BbdouFoodCtl(); + void placeFood(uint totalRoundsCount, uint maxRequestedFoodCount); + void addFood(uint32 propertyId); + void requestFirstFood(); + void requestNextFood(); + void nextRound(); + bool hasReachedRequestedFoodCount(); + bool hasRoundFinished(); + void serveFood(); + void resetFood(); +protected: + IllusionsEngine_BBDOU *_vm; + uint _totalRoundsCount, _maxRequestedFoodCount; + uint32 _foodPropertyIds[kFoodMaxPropertyIdsCount]; + uint _requestedFoodCount; + uint _requestedFoodIndex; + FoodItem _foodItems[kFoodCount]; + uint _servedFoodCount; + void placeActors(); + void resetFoodControls(); + uint32 getFoodSequenceId(); + uint32 getCurrentStudentObjectId(); +}; + +} // End of namespace Illusions + +#endif // ILLUSIONS_BBDOU_BBDOU_FOODCTL_H diff --git a/engines/illusions/bbdou/bbdou_specialcode.cpp b/engines/illusions/bbdou/bbdou_specialcode.cpp index 8bc09fff01..8839e2f8dd 100644 --- a/engines/illusions/bbdou/bbdou_specialcode.cpp +++ b/engines/illusions/bbdou/bbdou_specialcode.cpp @@ -26,6 +26,7 @@ #include "illusions/bbdou/bbdou_inventory.h" #include "illusions/bbdou/bbdou_credits.h" #include "illusions/bbdou/bbdou_cursor.h" +#include "illusions/bbdou/bbdou_foodctl.h" #include "illusions/actor.h" #include "illusions/camera.h" #include "illusions/dictionary.h" @@ -112,9 +113,11 @@ BbdouSpecialCode::BbdouSpecialCode(IllusionsEngine_BBDOU *vm) _bubble = new BbdouBubble(_vm, this); _cursor = new BbdouCursor(_vm, this); _inventory = new BbdouInventory(_vm, this); + _foodCtl = new BbdouFoodCtl(_vm); } BbdouSpecialCode::~BbdouSpecialCode() { + delete _foodCtl; delete _inventory; delete _cursor; delete _bubble; @@ -148,6 +151,8 @@ void BbdouSpecialCode::init() { SPECIAL(0x00160027, spcInitConversation); SPECIAL(0x00160030, spcResetCursor); SPECIAL(0x00160032, spcSetCursorField90); + SPECIAL(0x00160034, spcFoodCtl); + SPECIAL(0x00160035, spcTestFoodCtl); SPECIAL(0x00160036, spcInitMenu); SPECIAL(0x00160037, spcIsCursorHoldingObjectId); SPECIAL(0x00160038, spcInitRadarMicrophone); @@ -309,6 +314,56 @@ void BbdouSpecialCode::spcSetCursorField90(OpCall &opCall) { _vm->notifyThreadId(opCall._threadId); } +void BbdouSpecialCode::spcFoodCtl(OpCall &opCall) { + ARG_UINT32(cmd); + switch (cmd) { + case 1: + { + ARG_UINT32(minCount); + ARG_UINT32(maxCount); + _foodCtl->placeFood(minCount, maxCount); + } + break; + case 2: + { + ARG_UINT32(propertyId); + _foodCtl->addFood(propertyId); + } + break; + case 3: + _foodCtl->requestFirstFood(); + break; + case 4: + _foodCtl->requestNextFood(); + break; + case 5: + _foodCtl->serveFood(); + break; + case 6: + _foodCtl->resetFood(); + break; + case 8: + _foodCtl->nextRound(); + break; + default: + break; + } +} + +void BbdouSpecialCode::spcTestFoodCtl(OpCall &opCall) { + ARG_UINT32(cmd); + switch (cmd) { + case 7: + _vm->_stack->push(_foodCtl->hasReachedRequestedFoodCount() ? 1 : 0); + break; + case 9: + _vm->_stack->push(_foodCtl->hasRoundFinished() ? 1 : 0); + break; + default: + break; + } +} + void BbdouSpecialCode::spcInitMenu(OpCall &opCall) { // Called but not used in the reimplementation } @@ -705,7 +760,7 @@ void BbdouSpecialCode::cursorCrosshairControlRoutine(Control *cursorControl, uin if (cursorData._flags & 1) foundOverlapped = false; - else { + else { foundOverlapped = _vm->_controls->getOverlappedObjectAccurate(cursorControl, cursorPos, &overlappedControl, cursorData._item10._field58); } @@ -818,7 +873,7 @@ void BbdouSpecialCode::cursorCrosshairControlRoutine(Control *cursorControl, uin } } else if (_vm->_input->pollEvent(kEventLeftClick)) { - uint index = (uint)_vm->getRandom(2); + uint index = (uint)_vm->getRandom(2); const ShooterAnim &anim = kShooterAnims[index]; uint32 objectId = anim.objectId; int gridX = _shooterStatus[index].gridX; diff --git a/engines/illusions/bbdou/bbdou_specialcode.h b/engines/illusions/bbdou/bbdou_specialcode.h index 973d4b40f8..f48330784e 100644 --- a/engines/illusions/bbdou/bbdou_specialcode.h +++ b/engines/illusions/bbdou/bbdou_specialcode.h @@ -33,6 +33,7 @@ class IllusionsEngine_BBDOU; class BbdouBubble; class BbdouCredits; class BbdouCursor; +class BbdouFoodCtl; class BbdouInventory; struct CursorData; struct Item10; @@ -113,6 +114,8 @@ public: ShooterStatus _shooterStatus[2]; uint _shooterObjectIdIndex; + BbdouFoodCtl *_foodCtl; + // Special code interface functions void spcInitCursor(OpCall &opCall); void spcEnableCursor(OpCall &opCall); @@ -136,6 +139,8 @@ public: void spcInitConversation(OpCall &opCall); void spcResetCursor(OpCall &opCall); void spcSetCursorField90(OpCall &opCall); + void spcFoodCtl(OpCall &opCall); + void spcTestFoodCtl(OpCall &opCall); void spcInitMenu(OpCall &opCall); void spcIsCursorHoldingObjectId(OpCall &opCall); void spcInitRadarMicrophone(OpCall &opCall); diff --git a/engines/illusions/bbdou/scriptopcodes_bbdou.cpp b/engines/illusions/bbdou/scriptopcodes_bbdou.cpp index d887edddb5..e023fb3eee 100644 --- a/engines/illusions/bbdou/scriptopcodes_bbdou.cpp +++ b/engines/illusions/bbdou/scriptopcodes_bbdou.cpp @@ -288,7 +288,7 @@ void ScriptOpcodes_BBDOU::opUnloadActiveScenes(ScriptThread *scriptThread, OpCal //uint32 dsceneId = 0x00010007, dthreadId = 0x0002000C;//Auditorium //uint32 dsceneId = 0x0001000B, dthreadId = 0x00020010; //uint32 dsceneId = 0x00010013, dthreadId = 0x00020018;//Therapist -uint32 dsceneId = 0x00010016, dthreadId = 0x0002001B;//Dorms ext +//uint32 dsceneId = 0x00010016, dthreadId = 0x0002001B;//Dorms ext //uint32 dsceneId = 0x00010017, dthreadId = 0x0002001C;//Dorms int //uint32 dsceneId = 0x0001000D, dthreadId = 0x00020012;//Food minigame //uint32 dsceneId = 0x00010067, dthreadId = 0x0002022A; @@ -297,6 +297,7 @@ uint32 dsceneId = 0x00010016, dthreadId = 0x0002001B;//Dorms ext //uint32 dsceneId = 0x0001001A, dthreadId = 0x0002001F; //uint32 dsceneId = 0x00010047, dthreadId = 0x0002005F; //uint32 dsceneId = 0x0001007D, dthreadId = 0x000203B9; +uint32 dsceneId = 0x0001000D, dthreadId = 0x00020012; void ScriptOpcodes_BBDOU::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) { ARG_SKIP(2); diff --git a/engines/illusions/module.mk b/engines/illusions/module.mk index 7cbbd7f956..82116960ca 100644 --- a/engines/illusions/module.mk +++ b/engines/illusions/module.mk @@ -6,6 +6,7 @@ MODULE_OBJS := \ bbdou/bbdou_cursor.o \ bbdou/bbdou_credits.o \ bbdou/bbdou_credits_staticdata.o \ + bbdou/bbdou_foodctl.o \ bbdou/bbdou_inventory.o \ bbdou/bbdou_specialcode.o \ bbdou/bbdou_triggerfunctions.o \ |