scummvm/engines/titanic/pet_control/pet_rooms.cpp

381 lines
9.7 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 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"
#include "titanic/translation.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, TRANSLATE(15, 32));
rect1.moveTo(32, TRANSLATE(445, 439));
_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<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(PassengerClass newClassNum) {
CPetRoomsGlyph *glyph = _glyphs.findAssignedRoom();
if (!glyph)
return 0;
glyph->changeClass(newClassNum);
return true;
}
bool CPetRooms::isAssignedRoom(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