diff options
Diffstat (limited to 'engines/titanic/pet_control/pet_rooms.cpp')
-rw-r--r-- | engines/titanic/pet_control/pet_rooms.cpp | 380 |
1 files changed, 380 insertions, 0 deletions
diff --git a/engines/titanic/pet_control/pet_rooms.cpp b/engines/titanic/pet_control/pet_rooms.cpp new file mode 100644 index 0000000000..dfaa0405e4 --- /dev/null +++ b/engines/titanic/pet_control/pet_rooms.cpp @@ -0,0 +1,380 @@ +/* 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 "titanic/pet_control/pet_rooms.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +CPetRooms::CPetRooms() : + _chevLeftOnDim(nullptr), _chevLeftOffDim(nullptr), + _chevRightOnDim(nullptr), _chevRightOffDim(nullptr), + _chevLeftOnLit(nullptr), _chevLeftOffLit(nullptr), + _chevRightOnLit(nullptr), _chevRightOffLit(nullptr), + _floorNum(0), _elevatorNum(0), _roomNum(0), _field1CC(0), + _field1D0(0), _field1D4(0) { +} + +bool CPetRooms::setup(CPetControl *petControl) { + if (petControl && setupControl(petControl)) + return reset(); + return false; +} + +bool CPetRooms::reset() { + if (_petControl) { + _plinth.reset("PetChevPlinth", _petControl, MODE_UNSELECTED); + _glyphs.reset(); + + uint col = getColor(0); + _text.setColor(col); + _text.setLineColor(0, col); + } + + return true; +} + +void CPetRooms::draw(CScreenManager *screenManager) { + _petControl->drawSquares(screenManager, 6); + _plinth.draw(screenManager); + _glyphItem.drawAt(screenManager, getGlyphPos(), false); + _text.draw(screenManager); +} + +bool CPetRooms::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + if (_glyphs.MouseButtonDownMsg(msg->_mousePos)) + return true; + + if (!_glyphItem.contains(getGlyphPos(), msg->_mousePos)) + return false; + + _glyphItem.MouseButtonDownMsg(msg->_mousePos); + return true; +} + +bool CPetRooms::MouseDragStartMsg(CMouseDragStartMsg *msg) { + if (_glyphs.MouseDragStartMsg(msg)) + return true; + + Point topLeft = getGlyphPos(); + if (!_glyphItem.contains(topLeft, msg->_mousePos)) + return false; + + _glyphItem.dragGlyph(topLeft, msg); + return true; +} + +bool CPetRooms::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + return false; +} + +bool CPetRooms::MouseDoubleClickMsg(CMouseDoubleClickMsg *msg) { + return !_glyphs.MouseButtonDownMsg(msg->_mousePos); +} + +bool CPetRooms::VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) { + return _glyphs.VirtualKeyCharMsg(msg); +} + +bool CPetRooms::checkDragEnd(CGameObject *item) { + // Ignore any item drops except valid mail items + if (!item->_isMail) + return false; + + uint roomFlags = item->_id; + CPetRoomsGlyph *glyph = _glyphs.findGlyphByFlags(roomFlags); + if (glyph) { + if (_glyphs.findGlyphByFlags(0)) { + _glyphs.highlight(glyph); + return false; + } + + roomFlags = 0; + } + + addRoom(roomFlags, true); + return false; +} + +void CPetRooms::displayMessage(const CString &msg) { + _glyphs.resetHighlight(); + CPetSection::displayMessage(msg); +} + +bool CPetRooms::isValid(CPetControl *petControl) { + return setupControl(petControl); +} + +void CPetRooms::load(SimpleFile *file, int param) { + if (!param) { + int count = file->readNumber(); + + for (int idx = 0; idx < count; ++idx) { + CPetRoomsGlyph *glyph = addGlyph(file->readNumber(), false); + glyph->setMode((RoomGlyphMode)file->readNumber()); + } + + _glyphItem.setMode((RoomGlyphMode)file->readNumber()); + file->readNumber(); + _floorNum = file->readNumber(); + _elevatorNum = file->readNumber(); + _roomNum = file->readNumber(); + _field1CC = file->readNumber(); + _field1D0 = file->readNumber(); + _field1D4 = file->readNumber(); + } +} + +void CPetRooms::postLoad() { + reset(); +} + +void CPetRooms::save(SimpleFile *file, int indent) { + _glyphs.saveGlyphs(file, indent); + _glyphItem.saveGlyph(file, indent); + file->writeNumberLine(_floorNum, indent); + file->writeNumberLine(_elevatorNum, indent); + file->writeNumberLine(_roomNum, indent); + file->writeNumberLine(_field1CC, indent); + file->writeNumberLine(_field1D0, indent); + file->writeNumberLine(_field1D4, indent); +} + +void CPetRooms::enter(PetArea oldArea) { + if (!_glyphs.highlighted14()) + _text.setText(""); +} + +void CPetRooms::enterRoom(CRoomItem *room) { + +} + +CPetText *CPetRooms::getText() { + return &_text; +} + +CGameObject *CPetRooms::getBackground(int index) const { + switch (index) { + case 8: + return _chevLeftOnDim; + case 9: + return _chevLeftOffDim; + case 10: + return _chevLeftOnLit; + case 11: + return _chevLeftOffLit; + case 12: + return _chevRightOnDim; + case 13: + return _chevRightOffDim; + case 14: + return _chevRightOnLit; + case 15: + return _chevRightOffLit; + default: + return nullptr; + } +} + +bool CPetRooms::setupControl(CPetControl *petControl) { + _petControl = petControl; + if (!petControl) + return false; + + Rect rect1(0, 0, 470, 15); + rect1.moveTo(32, 445); + _text.setBounds(rect1); + _text.setHasBorder(false); + + Rect rect2(0, 0, 81, 81); + _plinth.setBounds(rect2); + _plinth.translate(494, 374); + + _chevLeftOnDim = petControl->getHiddenObject("3PetChevLeftOnDim"); + _chevLeftOffDim = petControl->getHiddenObject("3PetChevLeftOffDim"); + _chevRightOnDim = petControl->getHiddenObject("3PetChevRightOnDim"); + _chevRightOffDim = petControl->getHiddenObject("3PetChevRightOffDim"); + _chevLeftOnLit = petControl->getHiddenObject("3PetChevLeftOnLit"); + _chevLeftOffLit = petControl->getHiddenObject("3PetChevLeftOffLit"); + _chevRightOnLit = petControl->getHiddenObject("3PetChevRightOnLit"); + _chevRightOffLit = petControl->getHiddenObject("3PetChevRightOffLit"); + + _glyphs.setup(6, this); + _glyphs.setFlags(GFLAG_16); + _glyphItem.setup(petControl, &_glyphs); + _glyphItem.set38(1); + return true; +} + +void CPetRooms::resetHighlight() { + _glyphItem.setRoomFlags(getRoomFlags()); + _glyphs.resetHighlight(); + _glyphItem.updateTooltip(); + areaChanged(PET_ROOMS); +} + +uint CPetRooms::getRoomFlags() const { + CRoomFlags roomFlags; + CString roomName = _petControl->getRoomName(); + + uint flags = roomFlags.getSpecialRoomFlags(roomName); + if (flags) + return flags; + + int classNum = roomFlags.whatPassengerClass(_floorNum); + roomFlags.setPassengerClassBits(classNum); + roomFlags.setFloorNum(_floorNum); + + switch (classNum) { + case 1: + roomFlags.setElevatorNum(_elevatorNum); + roomFlags.setRoomBits(_roomNum); + break; + + case 2: + if (_roomNum > 0) { + if (_roomNum >= 3) { + roomFlags.setElevatorNum(_elevatorNum == 1 || _elevatorNum == 2 ? 1 : 3); + } else { + roomFlags.setElevatorNum(_elevatorNum == 1 || _elevatorNum == 2 ? 2 : 4); + } + + roomFlags.setRoomBits(((_roomNum - 1) & 1) + (_field1CC > 1 ? 3 : 2)); + } else { + roomFlags.setRoomBits(0); + } + break; + + case 3: + roomFlags.setElevatorNum(_elevatorNum); + roomFlags.setRoomBits(_roomNum + _field1CC * 6 - 6); + break; + + default: + break; + } + + return roomFlags.get(); +} + +void CPetRooms::reassignRoom(int passClassNum) { + CPetRoomsGlyph *glyph = _glyphs.findAssignedRoom(); + if (glyph) + // Flag the old assigned room as no longer assigned + glyph->setMode(RGM_PREV_ASSIGNED_ROOM); + + CRoomFlags roomFlags; + roomFlags.setRandomLocation(passClassNum, _field1D4); + glyph = addRoom(roomFlags, true); + if (glyph) { + // Flag the new room as assigned to the player, and highlight it + glyph->setMode(RGM_ASSIGNED_ROOM); + _glyphs.highlight(glyph); + } +} + +CPetRoomsGlyph *CPetRooms::addRoom(uint roomFlags, bool highlight) { + // Ensure that we don't add room if the room is already present + if (_glyphs.hasFlags(roomFlags)) + return nullptr; + + if (_glyphs.size() >= 32) + // Too many rooms already + return nullptr; + + // Do a preliminary scan of the glyph list for any glyph that is + // no longer valid, and thus can be removed + for (CPetRoomsGlyphs::iterator i = _glyphs.begin(); i != _glyphs.end(); ++i) { + CPetRoomsGlyph *glyph = static_cast<CPetRoomsGlyph *>(*i); + if (!glyph->isAssigned()) { + _glyphs.erase(i); + break; + } + } + + // Add the glyph + return addGlyph(roomFlags, highlight); +} + +CPetRoomsGlyph *CPetRooms::addGlyph(uint roomFlags, bool highlight) { + CPetRoomsGlyph *glyph = new CPetRoomsGlyph(roomFlags); + if (!glyph->setup(_petControl, &_glyphs)) { + delete glyph; + return nullptr; + } else { + _glyphs.push_back(glyph); + if (highlight) + _glyphs.highlight(glyph); + + return glyph; + } +} + +bool CPetRooms::changeLocationClass(int newClassNum) { + CPetRoomsGlyph *glyph = _glyphs.findAssignedRoom(); + if (!glyph) + return 0; + + glyph->changeLocation(newClassNum); + return true; +} + +bool CPetRooms::hasRoomFlags(uint roomFlags) const { + for (CPetRoomsGlyphs::const_iterator i = _glyphs.begin(); i != _glyphs.end(); ++i) { + const CPetRoomsGlyph *glyph = static_cast<const CPetRoomsGlyph *>(*i); + if (glyph->isAssigned() && glyph->getRoomFlags() == roomFlags) + return true; + } + + return false; +} + +uint CPetRooms::getAssignedRoomFlags() const { + CPetRoomsGlyph *glyph = _glyphs.findAssignedRoom(); + return glyph ? glyph->getRoomFlags() : 0; +} + +int CPetRooms::getAssignedRoomNum() const { + uint flags = getAssignedRoomFlags(); + if (!flags) + return 0; + + return CRoomFlags(flags).getRoomNum(); +} + +int CPetRooms::getAssignedFloorNum() const { + uint flags = getAssignedRoomFlags(); + if (!flags) + return 0; + + return CRoomFlags(flags).getFloorNum(); +} + +int CPetRooms::getAssignedElevatorNum() const { + uint flags = getAssignedRoomFlags(); + if (!flags) + return 0; + + return CRoomFlags(flags).getElevatorNum(); +} + +} // End of namespace Titanic |