scummvm/engines/titanic/pet_control/pet_rooms_glyphs.cpp

262 lines
8.4 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_glyphs.h"
#include "titanic/events.h"
#include "titanic/pet_control/pet_control.h"
#include "titanic/pet_control/pet_section.h"
#include "titanic/room_flags.h"
#include "titanic/support/screen_manager.h"
#include "titanic/support/simple_file.h"
#include "titanic/titanic.h"
#include "titanic/translation.h"
namespace Titanic {
CPetRoomsGlyph::CPetRoomsGlyph() : CPetGlyph(),
_roomFlags(0), _mailFlag(0), _mode(RGM_UNASSIGNED),
_chevLeftOnDim(nullptr), _chevLeftOffDim(nullptr), _chevLeftOnLit(nullptr), _chevLeftOffLit(nullptr),
_chevRightOnDim(nullptr), _chevRightOffDim(nullptr), _chevRightOnLit(nullptr), _chevRightOffLit(nullptr) {
}
CPetRoomsGlyph::CPetRoomsGlyph(uint flags) : CPetGlyph(),
_roomFlags(flags), _mailFlag(0), _mode(RGM_UNASSIGNED),
_chevLeftOnDim(nullptr), _chevLeftOffDim(nullptr), _chevLeftOnLit(nullptr), _chevLeftOffLit(nullptr),
_chevRightOnDim(nullptr), _chevRightOffDim(nullptr), _chevRightOnLit(nullptr), _chevRightOffLit(nullptr) {
}
bool CPetRoomsGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) {
if (!CPetGlyph::setup(petControl, owner))
return false;
CPetSection *section = owner->getOwner();
_chevLeftOnDim = section->getBackground(8);
_chevLeftOffDim = section->getBackground(9);
_chevRightOnDim = section->getBackground(12);
_chevRightOffDim = section->getBackground(13);
_chevLeftOnLit = section->getBackground(10);
_chevLeftOffLit = section->getBackground(11);
_chevRightOnLit = section->getBackground(14);
_chevRightOffLit = section->getBackground(15);
return true;
}
void CPetRoomsGlyph::drawAt(CScreenManager *screenManager, const Point &pt, bool isHighlighted_) {
// Clear background
Rect rect(pt.x, pt.y, pt.x + 52, pt.y + 52);
screenManager->fillRect(SURFACE_BACKBUFFER, &rect, 0, 0, 0);
CRoomFlags roomFlags(_roomFlags);
uint elevBits = roomFlags.getElevatorBits();
uint classBits = roomFlags.getPassengerClassBits();
uint floorBits = roomFlags.getFloorBits();
uint roomBits = roomFlags.getRoomBits();
// Save a copy of object pointers that may be modified
CGameObject *leftOnDim = _chevLeftOnDim;
CGameObject *leftOffDim = _chevLeftOffDim;
CGameObject *rightOnDim = _chevRightOnDim;
CGameObject *rightOffDim = _chevRightOffDim;
if (_mailFlag || isHighlighted_) {
_chevLeftOnDim = _chevLeftOnLit;
_chevLeftOffDim = _chevLeftOffLit;
_chevRightOnDim = _chevRightOnLit;
_chevRightOffDim = _chevRightOffLit;
}
// Draw the chevron fragments for each line
Point destPt = pt;
drawObjects(classBits + elevBits * 4, destPt, screenManager);
destPt.y += 10;
drawObjects((floorBits >> 4) & 15, destPt, screenManager);
destPt.y += 10;
drawObjects(floorBits & 15, destPt, screenManager);
destPt.y += 10;
drawObjects(roomBits >> 3, destPt, screenManager);
destPt.y += 10;
drawObjects(((roomBits & 7) << 1) + (roomFlags.getBit0() ? 1 : 0),
destPt, screenManager);
// Restore original image pointers
_chevLeftOnDim = leftOnDim;
_chevLeftOffDim = leftOffDim;
_chevRightOnDim = rightOnDim;
_chevRightOffDim = rightOffDim;
}
void CPetRoomsGlyph::selectGlyph(const Point &topLeft, const Point &pt) {
if (!isAssigned()) {
bool isShiftPressed = g_vm->_events->getSpecialButtons() & MK_SHIFT;
if (isShiftPressed) {
int selection = getSelection(topLeft, pt);
if (selection >= 0)
_roomFlags ^= 1 << selection;
}
updateTooltip();
}
}
bool CPetRoomsGlyph::dragGlyph(const Point &topLeft, CMouseDragStartMsg *msg) {
bool isShiftPressed = g_vm->_events->getSpecialButtons() & MK_SHIFT;
CPetControl *petControl = getPetControl();
if (!isShiftPressed && petControl) {
CGameObject *chevron = petControl->getHiddenObject("3PetChevron");
if (chevron) {
chevron->_destRoomFlags = _roomFlags;
chevron->_isPendingMail = _mailFlag != 0;
petControl->removeFromInventory(chevron, false, false);
chevron->loadSurface();
chevron->dragMove(msg->_mousePos);
msg->_handled = true;
if (msg->execute(chevron))
return true;
petControl->moveToHiddenRoom(chevron);
}
}
return false;
}
void CPetRoomsGlyph::getTooltip(CTextControl *text) {
CRoomFlags roomFlags(_roomFlags);
CPetRooms *owner = static_cast<CPetRooms *>(getPetSection());
CString prefix;
if (isCurrentlyAssigned()) {
prefix = g_vm->_strings[YOUR_ASSIGNED_ROOM];
} else if (isPreviouslyAssigned()) {
prefix = g_vm->_strings[PREVIOUSLY_ASSIGNED_ROOM];
} else if (!_mailFlag) {
prefix = g_vm->_strings[SAVED_CHEVRON];
} else if (_mailFlag == 1 && owner->getRoomFlags() == _roomFlags) {
prefix = g_vm->_strings[CURRENT_LOCATION];
}
// Get the room description
CString roomStr = roomFlags.getRoomDesc();
if (roomStr == TRANSLATE("The Elevator", "Der Aufzug")) {
int elevNum = owner->getElevatorNum();
roomStr = CString::format(g_vm->_strings[ELEVATOR_NUM].c_str(), elevNum);
}
roomStr += g_vm->_strings[SHIFT_CLICK_TO_EDIT];
text->setText(prefix + roomStr);
}
void CPetRoomsGlyph::saveGlyph(SimpleFile *file, int indent) {
file->writeNumberLine(_roomFlags, indent);
file->writeNumberLine(_mode, indent);
}
bool CPetRoomsGlyph::proc33(CPetGlyph *glyph) {
CPetRoomsGlyph *roomGlyph = static_cast<CPetRoomsGlyph *>(glyph);
return CPetGlyph::proc33(glyph) && _roomFlags == roomGlyph->_roomFlags;
}
void CPetRoomsGlyph::loadFlags(SimpleFile *file, int val) {
if (!val) {
_roomFlags = file->readNumber();
}
}
void CPetRoomsGlyph::changeClass(PassengerClass newClassNum) {
CRoomFlags roomFlags(_roomFlags);
roomFlags.changeClass(newClassNum);
_roomFlags = roomFlags.get();
}
int CPetRoomsGlyph::getSelection(const Point &topLeft, const Point &pt) {
Rect rects[4] = {
Rect(topLeft.x, topLeft.y, topLeft.x + 13, topLeft.y + 10),
Rect(topLeft.x + 13, topLeft.y, topLeft.x + 26, topLeft.y + 10),
Rect(topLeft.x + 26, topLeft.y, topLeft.x + 39, topLeft.y + 10),
Rect(topLeft.x + 39, topLeft.y, topLeft.x + 52, topLeft.y + 10)
};
for (int idx = 0, btnIndex = 19; idx < 5; ++idx, btnIndex -= 4) {
// Iterate through each of the four rects, seeing if there's a match.
// If not, move it down to the next row for the next loop iteration
for (int i = 0; i < 4; ++i) {
if (rects[i].contains(pt))
return btnIndex - i;
rects[i].translate(0, 10);
}
}
return -1;
}
void CPetRoomsGlyph::drawObjects(uint flags, const Point &pt, CScreenManager *screenManager) {
if (_chevLeftOnDim && _chevLeftOffDim && _chevRightOnDim && _chevRightOffDim) {
Point destPos = pt;
((flags & 8) ? _chevLeftOnDim : _chevLeftOffDim)->draw(screenManager, destPos);
destPos.x += 13;
((flags & 4) ? _chevRightOnDim : _chevRightOffDim)->draw(screenManager, destPos);
destPos.x += 13;
((flags & 2) ? _chevLeftOnDim : _chevLeftOffDim)->draw(screenManager, destPos);
destPos.x += 13;
((flags & 1) ? _chevRightOnDim : _chevRightOffDim)->draw(screenManager, destPos);
}
}
/*------------------------------------------------------------------------*/
void CPetRoomsGlyphs::saveGlyphs(SimpleFile *file, int indent) {
file->writeNumberLine(size(), indent);
for (const_iterator i = begin(); i != end(); ++i)
(*i)->saveGlyph(file, indent);
}
CPetRoomsGlyph *CPetRoomsGlyphs::findAssignedRoom() const {
for (const_iterator i = begin(); i != end(); ++i) {
CPetRoomsGlyph *glyph = dynamic_cast<CPetRoomsGlyph *>(*i);
if (glyph->isCurrentlyAssigned())
return glyph;
}
return nullptr;
}
CPetRoomsGlyph *CPetRoomsGlyphs::findGlyphByFlags(uint flags) const {
for (const_iterator i = begin(); i != end(); ++i) {
CPetRoomsGlyph *glyph = static_cast<CPetRoomsGlyph *>(*i);
if (glyph->getRoomFlags() == flags)
return glyph;
}
return nullptr;
}
} // End of namespace Titanic