/* 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(1), _elevatorNum(0), _roomNum(0), _sublevel(1), _wellEntry(0), _elevatorBroken(true) { } 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); _glyphs.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.selectGlyph(getGlyphPos(), 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 onto mail items if (!item->_isPendingMail) return false; uint roomFlags = item->_destRoomFlags; 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.setRoomFlags(file->readNumber()); file->readNumber(); _floorNum = file->readNumber(); _elevatorNum = file->readNumber(); _roomNum = file->readNumber(); _sublevel = file->readNumber(); _wellEntry = file->readNumber(); _elevatorBroken = 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(_sublevel, indent); file->writeNumberLine(_wellEntry, indent); file->writeNumberLine(_elevatorBroken, indent); } void CPetRooms::enter(PetArea oldArea) { if (!_glyphs.highlighted14()) _text.setText(""); } void CPetRooms::enterRoom(CRoomItem *room) { if (room) resetHighlight(); } CTextControl *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.setFlag(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; PassengerClass classNum = roomFlags.whatPassengerClass(_floorNum); roomFlags.setPassengerClassBits(classNum); roomFlags.setFloorNum(_floorNum); switch (classNum) { case FIRST_CLASS: roomFlags.setElevatorNum(_elevatorNum); roomFlags.setRoomBits(_roomNum); break; case SECOND_CLASS: 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) + (_sublevel > 1 ? 3 : 1)); } else { roomFlags.setRoomBits(0); } break; case THIRD_CLASS: roomFlags.setElevatorNum(_elevatorNum); roomFlags.setRoomBits(_roomNum + _sublevel * 6 - 6); break; default: break; } return roomFlags.get(); } void CPetRooms::reassignRoom(PassengerClass 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, _elevatorBroken); 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 room glyphs present. Scan for and remove the first // glyph that isn't for an assigned bedroom for (CPetRoomsGlyphs::iterator i = _glyphs.begin(); i != _glyphs.end(); ++i) { CPetRoomsGlyph *glyph = dynamic_cast(*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(PassengerClass newClassNum) { CPetRoomsGlyph *glyph = _glyphs.findAssignedRoom(); if (!glyph) return 0; glyph->changeClass(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(*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