/* 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 3 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, see .
*
*/
#ifndef ALCACHOFA_ROOMS_H
#define ALCACHOFA_ROOMS_H
#include "alcachofa/objects.h"
namespace Alcachofa {
class World;
class Room {
public:
static constexpr const char *kClassName = "CHabitacion";
Room(World *world, Common::SeekableReadStream &stream);
virtual ~Room();
inline World &world() { return *_world; }
inline const Common::String &name() const { return _name; }
inline const PathFindingShape *activeFloor() const {
return _activeFloorI < 0 ? nullptr : &_floors[_activeFloorI];
}
inline int8 orderAt(Common::Point query) const {
return _activeFloorI < 0 ? 49 : activeFloor()->orderAt(query);
}
inline float depthAt(Common::Point query) const {
return _activeFloorI < 0 ? 1 : activeFloor()->depthAt(query);
}
inline uint8 characterAlphaTint() const { return _characterAlphaTint; }
inline uint8 characterAlphaPremultiplier() const { return _characterAlphaPremultiplier; }
inline bool fixedCameraOnEntering() const { return _fixedCameraOnEntering; }
inline int musicID() const { return _musicId; }
using ObjectIterator = Common::Array::const_iterator;
inline ObjectIterator beginObjects() const { return _objects.begin(); }
inline ObjectIterator endObjects() const { return _objects.end(); }
void update();
void draw();
virtual bool updateInput();
virtual void loadResources();
virtual void freeResources();
virtual void syncGame(Common::Serializer &serializer);
ObjectBase *getObjectByName(const char *name) const;
void toggleActiveFloor();
void debugPrint(bool withObjects) const;
protected:
Room(World *world, Common::SeekableReadStream &stream, bool hasUselessByte);
void updateScripts();
void updateRoomBounds();
void updateInteraction();
void updateObjects();
void drawObjects();
void drawDebug();
ShapeObject *getSelectedObject(ShapeObject *best = nullptr) const;
World *_world;
Common::String _name;
PathFindingShape _floors[2];
bool _fixedCameraOnEntering;
int8 _activeFloorI = -1;
int _musicId = -1;
uint8
_characterAlphaTint,
_characterAlphaPremultiplier; ///< for some reason in percent instead of 0-255
Common::Array _objects;
};
class OptionsMenu final : public Room {
public:
static constexpr const char *kClassName = "CHabitacionMenuOpciones";
OptionsMenu(World *world, Common::SeekableReadStream &stream);
bool updateInput() override;
void loadResources() override;
void clearLastSelectedObject(); // to reset arm animation
inline SlideButton *¤tSlideButton() { return _currentSlideButton; }
private:
ShapeObject *_lastSelectedObject = nullptr;
ObjectBase *_idleArm = nullptr;
SlideButton *_currentSlideButton = nullptr;
};
class ConnectMenu final : public Room {
public:
static constexpr const char *kClassName = "CHabitacionConectar";
ConnectMenu(World *world, Common::SeekableReadStream &stream);
};
class ListenMenu final : public Room {
public:
static constexpr const char *kClassName = "CHabitacionEsperar";
ListenMenu(World *world, Common::SeekableReadStream &stream);
};
class Inventory final : public Room {
public:
static constexpr const char *kClassName = "CInventario";
Inventory(World *world, Common::SeekableReadStream &stream);
~Inventory() override;
bool updateInput() override;
void initItems();
void updateItemsByActiveCharacter();
void drawAsOverlay(int32 scrollY);
void open();
void close();
private:
Item *getHoveredItem();
Common::Array- _items;
};
enum class GlobalAnimationKind {
GeneralFont = 0,
DialogFont,
Cursor,
MortadeloIcon,
FilemonIcon,
InventoryIcon,
MortadeloDisabledIcon, // only used for multiplayer
FilemonDisabledIcon,
InventoryDisabledIcon,
Count
};
class World final {
public:
World();
~World();
// reference-returning queries will error if the object does not exist
using RoomIterator = Common::Array::const_iterator;
inline RoomIterator beginRooms() const { return _rooms.begin(); }
inline RoomIterator endRooms() const { return _rooms.end(); }
inline Room &globalRoom() const { assert(_globalRoom != nullptr); return *_globalRoom; }
inline Inventory &inventory() const { assert(_inventory != nullptr); return *_inventory; }
inline MainCharacter &filemon() const { assert(_filemon != nullptr); return *_filemon; }
inline MainCharacter &mortadelo() const { assert(_mortadelo != nullptr); return *_mortadelo; }
inline const Common::String &initScriptName() const { return _initScriptName; }
inline uint8 loadedMapCount() const { return _loadedMapCount; }
inline bool somebodyUsing(ObjectBase *object) const {
return filemon().currentlyUsing() == object ||
mortadelo().currentlyUsing() == object;
}
MainCharacter &getMainCharacterByKind(MainCharacterKind kind) const;
MainCharacter &getOtherMainCharacterByKind(MainCharacterKind kind) const;
Room *getRoomByName(const char *name) const;
ObjectBase *getObjectByName(const char *name) const;
ObjectBase *getObjectByName(MainCharacterKind character, const char *name) const;
ObjectBase *getObjectByNameFromAnyRoom(const char *name) const;
const Common::String &getGlobalAnimationName(GlobalAnimationKind kind) const;
const char *getLocalizedName(const Common::String &name) const;
const char *getDialogLine(int32 dialogId) const;
void toggleObject(MainCharacterKind character, const char *objName, bool isEnabled);
void syncGame(Common::Serializer &s);
private:
bool loadWorldFile(const char *path);
void loadLocalizedNames();
void loadDialogLines();
// the default Hash works on the characters, but the default EqualTo compares pointers...
struct StringEqualTo {
bool operator()(const char *a, const char *b) const { return strcmp(a, b) == 0; }
};
Common::Array _rooms;
Common::String _globalAnimationNames[(int)GlobalAnimationKind::Count];
Common::String _initScriptName;
Room *_globalRoom;
Inventory *_inventory;
MainCharacter *_filemon, *_mortadelo;
uint8 _loadedMapCount = 0;
Common::HashMap,
StringEqualTo> _localizedNames;
Common::Array _dialogLines;
Common::Array _namesChunk, _dialogChunk; ///< holds the memory for localizedNames / dialogLines
};
}
#endif // ALCACHOFA_ROOMS_H