Text-Adventure/Room.cpp
2023-11-16 00:44:12 +08:00

205 lines
4.8 KiB
C++

#include "Room.h"
#include "wordwrap.h"
#include <algorithm>
/**
* Stores a static list of all rooms.
*/
std::map<int, Room *> Room::room_map;
int Room::room_id_counter = 1;
/**
* Room default constructor.
* @param _name Room's name.
* @param _desc Room's description.
*/
Room::Room(const string *_name, const string *_desc) :
name(_name), description(_desc), north_id(-1), south_id(-1), east_id(-1), west_id(-1),
room_id(room_id_counter++), objects() {};
/**
* Remove destroyed rooms from the static list.
*/
Room::~Room() {
Room::room_map.erase(room_id);
delete name;
delete description;
}
/**
* Prints the description of a room (the name and long description)
*/
void Room::describe() const {
wrapOut(this->name);
wrapEndPara();
wrapOut(this->description);
wrapEndPara();
for (const auto &obj_id: this->objects) {
auto obj = GameObject::getGameObjectById(obj_id);
std::string obj_desc = obj->getInfo();
wrapOut(&obj_desc);
wrapEndPara();
}
}
/**
* Statically creates a room and then adds it to the global list.
* @param _name Name for the new room.
* @param _desc Description for the new room.
* @return A pointer to the newly created room.
*/
Room *Room::addRoom(const string *_name, const string *_desc) {
auto *newRoom = new Room(_name, _desc);
newRoom->setRoomId(room_id_counter++);
Room::room_map.insert({newRoom->getRoomId(), newRoom});
return newRoom;
}
/**
* Adds an existing room to the static list.
* @param room Pointer to the room to add.
* @return
*/
void Room::addRoom(Room *room) {
Room::room_map.insert({room->getRoomId(), room});
}
string Room::ToString() const {
Packer packer;
for (const auto &obj_id: this->objects) {
packer.pack(obj_id);
}
packer.pack(*name)
.pack(*description)
.pack(room_id)
.pack(north_id)
.pack(south_id)
.pack(east_id)
.pack(west_id)
.pack(this->objects.size());
return packer.ToHexStr();
}
void Room::FromString(const string &str) {
std::string *new_name = new std::string();
std::string *new_desc = new std::string();
Packer packer;
packer.FromHexStr(str);
size_t objects_size;
packer.unpack(objects_size)
.unpack(west_id)
.unpack(east_id)
.unpack(south_id)
.unpack(north_id)
.unpack(room_id)
.unpack(*new_desc)
.unpack(*new_name);
for (int i = 0; i < objects_size; i++) {
int id;
packer.unpack(id);
objects.push_back(id);
}
if (name) delete name;
if (description) delete description;
name = new_name;
description = new_desc;
}
int Room::getNorthId() const {
return north_id;
}
void Room::setNorthId(int _north_id) {
north_id = _north_id;
}
int Room::getSouthId() const {
return south_id;
}
void Room::setSouthId(int _south_id) {
south_id = _south_id;
}
int Room::getEastId() const {
return east_id;
}
void Room::setEastId(int _east_id) {
east_id = _east_id;
}
int Room::getWestId() const {
return west_id;
}
void Room::setWestId(int _west_id) {
west_id = _west_id;
}
int Room::getRoomId() const {
return room_id;
}
void Room::setRoomId(int _room_id) {
room_id = _room_id;
}
Room::Room() : Room(nullptr, nullptr) {
}
Room *Room::getNorth() const {
auto iter = Room::room_map.find(north_id);
return iter == Room::room_map.end() ? nullptr : iter->second;
}
Room *Room::getSouth() const {
auto iter = Room::room_map.find(south_id);
return iter == Room::room_map.end() ? nullptr : iter->second;
}
Room *Room::getEast() const {
auto iter = Room::room_map.find(east_id);
return iter == Room::room_map.end() ? nullptr : iter->second;
}
Room *Room::getWest() const {
auto iter = Room::room_map.find(west_id);
return iter == Room::room_map.end() ? nullptr : iter->second;
}
Room *Room::getRoomById(int id) {
auto iter = Room::room_map.find(id);
return iter == Room::room_map.end() ? nullptr : iter->second;
}
void Room::AddGameObject(int object_id) {
objects.push_back(object_id);
objects.sort();
}
void Room::RemoveGameObject(int object_id) {
objects.remove(object_id);
}
int Room::FindGameObject(const string &keyword) const {
for (const auto &obj_id: this->objects) {
auto obj = GameObject::getGameObjectById(obj_id);
if (obj->getKeyword() == keyword) {
return obj_id;
}
}
return -1;
}
bool Room::IsInRoom(int object_id) const {
return std::find(objects.begin(), objects.end(), object_id) != objects.end();
}