381 lines
9.7 KiB
C++
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
|