Persistance
This commit is contained in:
parent
35dcee85a0
commit
25ba63cea9
4
ADG5.cpp
4
ADG5.cpp
@ -24,12 +24,14 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
auto context = tcod::Context(params);
|
auto context = tcod::Context(params);
|
||||||
engine = new Engine(80, 50, &context, &console);
|
engine = new Engine(80, 50, &context, &console);
|
||||||
engine->init();
|
engine->load();
|
||||||
|
|
||||||
while (engine->update()) {
|
while (engine->update()) {
|
||||||
engine->render();
|
engine->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
engine->save();
|
||||||
|
|
||||||
delete engine;
|
delete engine;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
52
Actor.cpp
52
Actor.cpp
@ -38,3 +38,55 @@ float Actor::getDistance(int cx, int cy) const {
|
|||||||
int dy = y - cy;
|
int dy = y - cy;
|
||||||
return sqrtf(dx * dx + dy * dy);
|
return sqrtf(dx * dx + dy * dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Actor::save(TCODZip& zip) {
|
||||||
|
zip.putInt(x);
|
||||||
|
zip.putInt(y);
|
||||||
|
zip.putString(std::string(ch).c_str());
|
||||||
|
zip.putInt(col.r);
|
||||||
|
zip.putInt(col.g);
|
||||||
|
zip.putInt(col.b);
|
||||||
|
zip.putString(name.c_str());
|
||||||
|
zip.putInt(blocks);
|
||||||
|
zip.putInt(attacker != NULL);
|
||||||
|
zip.putInt(destructible != NULL);
|
||||||
|
zip.putInt(ai != NULL);
|
||||||
|
zip.putInt(pickable != NULL);
|
||||||
|
zip.putInt(container != NULL);
|
||||||
|
if (attacker) attacker->save(zip);
|
||||||
|
if (destructible) destructible->save(zip);
|
||||||
|
if (ai) ai->save(zip);
|
||||||
|
if (pickable) pickable->save(zip);
|
||||||
|
if (container) container->save(zip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actor::load(TCODZip& zip) {
|
||||||
|
x = zip.getInt();
|
||||||
|
y = zip.getInt();
|
||||||
|
ch = std::string(zip.getString());
|
||||||
|
col = TCOD_ColorRGB(zip.getInt(), zip.getInt(), zip.getInt());
|
||||||
|
name = zip.getString();
|
||||||
|
blocks = zip.getInt();
|
||||||
|
bool hasAttacker = zip.getInt();
|
||||||
|
bool hasDestructible = zip.getInt();
|
||||||
|
bool hasAi = zip.getInt();
|
||||||
|
bool hasPickable = zip.getInt();
|
||||||
|
bool hasContainer = zip.getInt();
|
||||||
|
if (hasAttacker) {
|
||||||
|
attacker = new Attacker(0.0f);
|
||||||
|
attacker->load(zip);
|
||||||
|
}
|
||||||
|
if (hasDestructible) {
|
||||||
|
destructible = Destructible::create(zip);
|
||||||
|
}
|
||||||
|
if (hasAi) {
|
||||||
|
ai = Ai::create(zip);
|
||||||
|
}
|
||||||
|
if (hasPickable) {
|
||||||
|
pickable = Pickable::create(zip);
|
||||||
|
}
|
||||||
|
if (hasContainer) {
|
||||||
|
container = new Container(0);
|
||||||
|
container->load(zip);
|
||||||
|
}
|
||||||
|
}
|
8
Actor.h
8
Actor.h
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "libtcod.hpp"
|
#include "libtcod.hpp"
|
||||||
|
#include "Persistance.h"
|
||||||
|
|
||||||
class Attacker;
|
class Attacker;
|
||||||
class Destructible;
|
class Destructible;
|
||||||
@ -8,11 +9,11 @@ class Ai;
|
|||||||
class Pickable;
|
class Pickable;
|
||||||
class Container;
|
class Container;
|
||||||
|
|
||||||
class Actor {
|
class Actor : public Persistent {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
int x, y; // position on map
|
int x, y; // position on map
|
||||||
std::string_view ch; // ascii code
|
std::string ch; // ascii code
|
||||||
TCOD_ColorRGB col; // color
|
TCOD_ColorRGB col; // color
|
||||||
std::string name;
|
std::string name;
|
||||||
bool blocks;
|
bool blocks;
|
||||||
@ -26,4 +27,7 @@ public:
|
|||||||
~Actor();
|
~Actor();
|
||||||
void render(TCOD_Console& cons) const;
|
void render(TCOD_Console& cons) const;
|
||||||
void update();
|
void update();
|
||||||
|
void load(TCODZip& zip);
|
||||||
|
void save(TCODZip& zip);
|
||||||
|
|
||||||
};
|
};
|
38
Ai.cpp
38
Ai.cpp
@ -258,3 +258,41 @@ void ConfusedMonsterAi::update(Actor* owner) {
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ai* Ai::create(TCODZip& zip) {
|
||||||
|
AiType type = (AiType)zip.getInt();
|
||||||
|
Ai* ai = NULL;
|
||||||
|
switch (type) {
|
||||||
|
case PLAYER: ai = new PlayerAi(); break;
|
||||||
|
case MONSTER: ai = new MonsterAi(); break;
|
||||||
|
case CONFUSED_MONSTER: ai = new ConfusedMonsterAi(0, NULL); break;
|
||||||
|
}
|
||||||
|
ai->load(zip);
|
||||||
|
return ai;
|
||||||
|
}
|
||||||
|
void MonsterAi::load(TCODZip& zip) {
|
||||||
|
moveCount = zip.getInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonsterAi::save(TCODZip& zip) {
|
||||||
|
zip.putInt(MONSTER);
|
||||||
|
zip.putInt(moveCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfusedMonsterAi::load(TCODZip& zip) {
|
||||||
|
nbTurns = zip.getInt();
|
||||||
|
oldAi = Ai::create(zip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfusedMonsterAi::save(TCODZip& zip) {
|
||||||
|
zip.putInt(CONFUSED_MONSTER);
|
||||||
|
zip.putInt(nbTurns);
|
||||||
|
oldAi->save(zip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerAi::load(TCODZip& zip) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerAi::save(TCODZip& zip) {
|
||||||
|
zip.putInt(PLAYER);
|
||||||
|
}
|
17
Ai.h
17
Ai.h
@ -1,17 +1,25 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "libtcod.hpp"
|
||||||
|
#include "Persistance.h"
|
||||||
|
|
||||||
class Actor;
|
class Actor;
|
||||||
|
|
||||||
class Ai {
|
class Ai : public Persistent {
|
||||||
public:
|
public:
|
||||||
virtual void update(Actor* owner) = 0;
|
virtual void update(Actor* owner) = 0;
|
||||||
virtual ~Ai() {};
|
virtual ~Ai() {};
|
||||||
|
static Ai* create(TCODZip& zip);
|
||||||
|
protected:
|
||||||
|
enum AiType {
|
||||||
|
MONSTER, CONFUSED_MONSTER, PLAYER
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlayerAi : public Ai {
|
class PlayerAi : public Ai {
|
||||||
public:
|
public:
|
||||||
void update(Actor* owner);
|
void update(Actor* owner);
|
||||||
|
void load(TCODZip& zip);
|
||||||
|
void save(TCODZip& zip);
|
||||||
protected:
|
protected:
|
||||||
bool moveOrAttack(Actor* owner, int targetx, int targety);
|
bool moveOrAttack(Actor* owner, int targetx, int targety);
|
||||||
void handleActionKey(Actor* owner, int sdlkey);
|
void handleActionKey(Actor* owner, int sdlkey);
|
||||||
@ -21,7 +29,8 @@ protected:
|
|||||||
class MonsterAi : public Ai {
|
class MonsterAi : public Ai {
|
||||||
public:
|
public:
|
||||||
void update(Actor* owner);
|
void update(Actor* owner);
|
||||||
|
void load(TCODZip& zip);
|
||||||
|
void save(TCODZip& zip);
|
||||||
protected:
|
protected:
|
||||||
int moveCount;
|
int moveCount;
|
||||||
void moveOrAttack(Actor* owner, int targetx, int targety);
|
void moveOrAttack(Actor* owner, int targetx, int targety);
|
||||||
@ -31,6 +40,8 @@ class ConfusedMonsterAi : public Ai {
|
|||||||
public:
|
public:
|
||||||
ConfusedMonsterAi(int nbTurns, Ai* oldAi);
|
ConfusedMonsterAi(int nbTurns, Ai* oldAi);
|
||||||
void update(Actor* owner);
|
void update(Actor* owner);
|
||||||
|
void load(TCODZip& zip);
|
||||||
|
void save(TCODZip& zip);
|
||||||
protected:
|
protected:
|
||||||
int nbTurns;
|
int nbTurns;
|
||||||
Ai* oldAi;
|
Ai* oldAi;
|
||||||
|
@ -22,3 +22,11 @@ void Attacker::attack(Actor* owner, Actor* target) {
|
|||||||
engine->gui->message(TCOD_ColorRGB(150, 150, 150), "%s attacks %s in vain.\n", owner->name.c_str(), target->name.c_str());
|
engine->gui->message(TCOD_ColorRGB(150, 150, 150), "%s attacks %s in vain.\n", owner->name.c_str(), target->name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Attacker::load(TCODZip& zip) {
|
||||||
|
power = zip.getFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Attacker::save(TCODZip& zip) {
|
||||||
|
zip.putFloat(power);
|
||||||
|
}
|
@ -1,11 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "libtcod.hpp"
|
||||||
|
#include "Persistance.h"
|
||||||
|
|
||||||
class Actor;
|
class Actor;
|
||||||
|
|
||||||
class Attacker {
|
class Attacker : public Persistent {
|
||||||
public:
|
public:
|
||||||
float power; // hit points given
|
float power; // hit points given
|
||||||
|
|
||||||
Attacker(float power);
|
Attacker(float power);
|
||||||
void attack(Actor* owner, Actor* target);
|
void attack(Actor* owner, Actor* target);
|
||||||
|
void load(TCODZip& zip);
|
||||||
|
void save(TCODZip& zip);
|
||||||
};
|
};
|
@ -14,7 +14,7 @@ project ("ADG5")
|
|||||||
find_package(libtcod CONFIG REQUIRED)
|
find_package(libtcod CONFIG REQUIRED)
|
||||||
|
|
||||||
# Add source to this project's executable.
|
# Add source to this project's executable.
|
||||||
add_executable (ADG5 "ADG5.cpp" "ADG5.h" "Actor.cpp" "Actor.h" "Map.h" "Map.cpp" "Engine.h" "Engine.cpp" "Destructible.h" "Destructible.cpp" "Attacker.h" "Attacker.cpp" "Ai.h" "Ai.cpp" "Gui.h" "Gui.cpp" "Container.h" "Container.cpp" "Pickable.h" "Pickable.cpp" "Healer.h" "Healer.cpp" "Lightningbolt.h" "Lightningbolt.cpp" "Fireball.h" "Fireball.cpp" "Confuser.h" "Confuser.cpp")
|
add_executable (ADG5 "ADG5.cpp" "ADG5.h" "Actor.cpp" "Actor.h" "Map.h" "Map.cpp" "Engine.h" "Engine.cpp" "Destructible.h" "Destructible.cpp" "Attacker.h" "Attacker.cpp" "Ai.h" "Ai.cpp" "Gui.h" "Gui.cpp" "Container.h" "Container.cpp" "Pickable.h" "Pickable.cpp" "Healer.h" "Healer.cpp" "Lightningbolt.h" "Lightningbolt.cpp" "Fireball.h" "Fireball.cpp" "Confuser.h" "Confuser.cpp" "Persistance.h")
|
||||||
|
|
||||||
target_link_libraries(ADG5
|
target_link_libraries(ADG5
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
11
Confuser.cpp
11
Confuser.cpp
@ -26,3 +26,14 @@ bool Confuser::use(Actor* owner, Actor* wearer) {
|
|||||||
actor->name.c_str());
|
actor->name.c_str());
|
||||||
return Pickable::use(owner, wearer);
|
return Pickable::use(owner, wearer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Confuser::load(TCODZip& zip) {
|
||||||
|
nbTurns = zip.getInt();
|
||||||
|
range = zip.getFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Confuser::save(TCODZip& zip) {
|
||||||
|
zip.putInt(CONFUSER);
|
||||||
|
zip.putInt(nbTurns);
|
||||||
|
zip.putFloat(range);
|
||||||
|
}
|
@ -10,4 +10,6 @@ public:
|
|||||||
float range;
|
float range;
|
||||||
Confuser(int nbTurns, float range);
|
Confuser(int nbTurns, float range);
|
||||||
bool use(Actor* owner, Actor* wearer);
|
bool use(Actor* owner, Actor* wearer);
|
||||||
|
void load(TCODZip& zip);
|
||||||
|
void save(TCODZip& zip);
|
||||||
};
|
};
|
@ -1,4 +1,5 @@
|
|||||||
#include "Container.h"
|
#include "Container.h"
|
||||||
|
#include "Actor.h"
|
||||||
|
|
||||||
Container::Container(int size) : size(size) {
|
Container::Container(int size) : size(size) {
|
||||||
}
|
}
|
||||||
@ -19,3 +20,22 @@ bool Container::add(Actor* actor) {
|
|||||||
void Container::remove(Actor* actor) {
|
void Container::remove(Actor* actor) {
|
||||||
inventory.remove(actor);
|
inventory.remove(actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Container::load(TCODZip& zip) {
|
||||||
|
size = zip.getInt();
|
||||||
|
int nbActors = zip.getInt();
|
||||||
|
while (nbActors > 0) {
|
||||||
|
Actor* actor = new Actor(0, 0, "?", "", TCOD_ColorRGB(255, 255, 255));
|
||||||
|
actor->load(zip);
|
||||||
|
inventory.push(actor);
|
||||||
|
nbActors--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Container::save(TCODZip& zip) {
|
||||||
|
zip.putInt(size);
|
||||||
|
zip.putInt(inventory.size());
|
||||||
|
for (Actor** it = inventory.begin(); it != inventory.end(); it++) {
|
||||||
|
(*it)->save(zip);
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "libtcod.hpp"
|
#include "libtcod.hpp"
|
||||||
|
#include "Persistance.h"
|
||||||
class Actor;
|
class Actor;
|
||||||
|
|
||||||
class Container {
|
class Container : public Persistent {
|
||||||
public:
|
public:
|
||||||
int size; // maximum number of actors. 0=unlimited
|
int size; // maximum number of actors. 0=unlimited
|
||||||
TCODList<Actor*> inventory;
|
TCODList<Actor*> inventory;
|
||||||
@ -12,4 +12,6 @@ public:
|
|||||||
~Container();
|
~Container();
|
||||||
bool add(Actor* actor);
|
bool add(Actor* actor);
|
||||||
void remove(Actor* actor);
|
void remove(Actor* actor);
|
||||||
|
void load(TCODZip& zip);
|
||||||
|
void save(TCODZip& zip);
|
||||||
};
|
};
|
@ -47,6 +47,16 @@ PlayerDestructible::PlayerDestructible(float maxHp, float defense, std::string c
|
|||||||
Destructible(maxHp, defense, corpseName) {
|
Destructible(maxHp, defense, corpseName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlayerDestructible::save(TCODZip& zip) {
|
||||||
|
zip.putInt(PLAYER);
|
||||||
|
Destructible::save(zip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonsterDestructible::save(TCODZip& zip) {
|
||||||
|
zip.putInt(MONSTER);
|
||||||
|
Destructible::save(zip);
|
||||||
|
}
|
||||||
|
|
||||||
void MonsterDestructible::die(Actor* owner) {
|
void MonsterDestructible::die(Actor* owner) {
|
||||||
// transform it into a nasty corpse! it doesn't block, can't be
|
// transform it into a nasty corpse! it doesn't block, can't be
|
||||||
// attacked and doesn't move
|
// attacked and doesn't move
|
||||||
@ -59,3 +69,28 @@ void PlayerDestructible::die(Actor* owner) {
|
|||||||
Destructible::die(owner);
|
Destructible::die(owner);
|
||||||
engine->gameStatus = Engine::DEFEAT;
|
engine->gameStatus = Engine::DEFEAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Destructible::load(TCODZip& zip) {
|
||||||
|
maxHp = zip.getFloat();
|
||||||
|
hp = zip.getFloat();
|
||||||
|
defense = zip.getFloat();
|
||||||
|
corpseName = zip.getString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Destructible::save(TCODZip& zip) {
|
||||||
|
zip.putFloat(maxHp);
|
||||||
|
zip.putFloat(hp);
|
||||||
|
zip.putFloat(defense);
|
||||||
|
zip.putString(corpseName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
Destructible* Destructible::create(TCODZip& zip) {
|
||||||
|
DestructibleType type = (DestructibleType)zip.getInt();
|
||||||
|
Destructible* destructible = NULL;
|
||||||
|
switch (type) {
|
||||||
|
case MONSTER: destructible = new MonsterDestructible(0, 0, ""); break;
|
||||||
|
case PLAYER: destructible = new PlayerDestructible(0, 0, ""); break;
|
||||||
|
}
|
||||||
|
destructible->load(zip);
|
||||||
|
return destructible;
|
||||||
|
}
|
@ -1,9 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "libtcod.hpp"
|
||||||
|
#include "Persistance.h"
|
||||||
|
|
||||||
class Actor;
|
class Actor;
|
||||||
|
|
||||||
class Destructible {
|
class Destructible : public Persistent {
|
||||||
public:
|
public:
|
||||||
float maxHp; // maximum health points
|
float maxHp; // maximum health points
|
||||||
float hp; // current health points
|
float hp; // current health points
|
||||||
@ -17,16 +20,25 @@ public:
|
|||||||
virtual void die(Actor* owner);
|
virtual void die(Actor* owner);
|
||||||
|
|
||||||
float heal(float amount);
|
float heal(float amount);
|
||||||
|
void load(TCODZip& zip);
|
||||||
|
void save(TCODZip& zip);
|
||||||
|
static Destructible* create(TCODZip& zip);
|
||||||
|
protected:
|
||||||
|
enum DestructibleType {
|
||||||
|
MONSTER, PLAYER
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class MonsterDestructible : public Destructible {
|
class MonsterDestructible : public Destructible {
|
||||||
public:
|
public:
|
||||||
MonsterDestructible(float maxHp, float defense, std::string corpseName);
|
MonsterDestructible(float maxHp, float defense, std::string corpseName);
|
||||||
|
void save(TCODZip& zip);
|
||||||
void die(Actor* owner);
|
void die(Actor* owner);
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlayerDestructible : public Destructible {
|
class PlayerDestructible : public Destructible {
|
||||||
public:
|
public:
|
||||||
PlayerDestructible(float maxHp, float defense, std::string corpseName);
|
PlayerDestructible(float maxHp, float defense, std::string corpseName);
|
||||||
|
void save(TCODZip& zip);
|
||||||
void die(Actor* owner);
|
void die(Actor* owner);
|
||||||
};
|
};
|
56
Engine.cpp
56
Engine.cpp
@ -35,6 +35,7 @@ void Engine::init() {
|
|||||||
player->container = new Container(26);
|
player->container = new Container(26);
|
||||||
actors.push(player);
|
actors.push(player);
|
||||||
map = new Map(80, 45);
|
map = new Map(80, 45);
|
||||||
|
map->init(true);
|
||||||
gui->message(TCOD_ColorRGB(150,0,0),
|
gui->message(TCOD_ColorRGB(150,0,0),
|
||||||
"Welcome stranger!\nPrepare to perish in the Tombs of Andrew's Dunegon.");
|
"Welcome stranger!\nPrepare to perish in the Tombs of Andrew's Dunegon.");
|
||||||
}
|
}
|
||||||
@ -170,3 +171,58 @@ Actor* Engine::getActor(int x, int y) const {
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Engine::save() {
|
||||||
|
if (player->destructible->isDead()) {
|
||||||
|
TCODSystem::deleteFile("game.sav");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TCODZip zip;
|
||||||
|
// save the map first
|
||||||
|
zip.putInt(map->width);
|
||||||
|
zip.putInt(map->height);
|
||||||
|
map->save(zip);
|
||||||
|
// then the player
|
||||||
|
player->save(zip);
|
||||||
|
// then all the other actors
|
||||||
|
zip.putInt(actors.size() - 1);
|
||||||
|
for (Actor** it = actors.begin(); it != actors.end(); it++) {
|
||||||
|
if (*it != player) {
|
||||||
|
(*it)->save(zip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// finally the message log
|
||||||
|
gui->save(zip);
|
||||||
|
zip.saveToFile("game.sav");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::load() {
|
||||||
|
if (TCODSystem::fileExists("game.sav")) {
|
||||||
|
TCODZip zip;
|
||||||
|
zip.loadFromFile("game.sav");
|
||||||
|
// load the map
|
||||||
|
int width = zip.getInt();
|
||||||
|
int height = zip.getInt();
|
||||||
|
map = new Map(width, height);
|
||||||
|
map->load(zip);
|
||||||
|
// then the player
|
||||||
|
player = new Actor(0, 0, "?", "", TCOD_ColorRGB(255, 255, 255));
|
||||||
|
player->load(zip);
|
||||||
|
actors.push(player);
|
||||||
|
// then all other actors
|
||||||
|
int nbActors = zip.getInt();
|
||||||
|
while (nbActors > 0) {
|
||||||
|
Actor* actor = new Actor(0, 0, "?", "", TCOD_ColorRGB(255, 255, 255));
|
||||||
|
actor->load(zip);
|
||||||
|
actors.push(actor);
|
||||||
|
nbActors--;
|
||||||
|
}
|
||||||
|
// finally the message log
|
||||||
|
gui = new Gui(context, console);
|
||||||
|
gui->load(zip);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
engine->init();
|
||||||
|
}
|
||||||
|
}
|
2
Engine.h
2
Engine.h
@ -35,6 +35,8 @@ public:
|
|||||||
Actor* getClosestMonster(int x, int y, float range) const;
|
Actor* getClosestMonster(int x, int y, float range) const;
|
||||||
bool pickATile(int* x, int* y, float maxRange = 0.0f);
|
bool pickATile(int* x, int* y, float maxRange = 0.0f);
|
||||||
Actor* getActor(int x, int y) const;
|
Actor* getActor(int x, int y) const;
|
||||||
|
void load();
|
||||||
|
void save();
|
||||||
private:
|
private:
|
||||||
bool computeFov;
|
bool computeFov;
|
||||||
};
|
};
|
||||||
|
@ -28,3 +28,9 @@ bool Fireball::use(Actor* owner, Actor* wearer) {
|
|||||||
}
|
}
|
||||||
return Pickable::use(owner, wearer);
|
return Pickable::use(owner, wearer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Fireball::save(TCODZip& zip) {
|
||||||
|
zip.putInt(FIREBALL);
|
||||||
|
zip.putFloat(range);
|
||||||
|
zip.putFloat(damage);
|
||||||
|
}
|
@ -7,4 +7,5 @@ class Fireball : public LightningBolt {
|
|||||||
public:
|
public:
|
||||||
Fireball(float range, float damage);
|
Fireball(float range, float damage);
|
||||||
bool use(Actor* owner, Actor* wearer);
|
bool use(Actor* owner, Actor* wearer);
|
||||||
|
void save(TCODZip& zip);
|
||||||
};
|
};
|
21
Gui.cpp
21
Gui.cpp
@ -116,3 +116,24 @@ void Gui::renderMouseLook() {
|
|||||||
}
|
}
|
||||||
tcod::print(con, { 1, 0 }, buf, TCOD_ColorRGB(200, 200, 200), std::nullopt);
|
tcod::print(con, { 1, 0 }, buf, TCOD_ColorRGB(200, 200, 200), std::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gui::save(TCODZip& zip) {
|
||||||
|
zip.putInt(log.size());
|
||||||
|
for (Message** it = log.begin(); it != log.end(); it++) {
|
||||||
|
zip.putString((*it)->text.c_str());
|
||||||
|
zip.putInt((*it)->col.r);
|
||||||
|
zip.putInt((*it)->col.g);
|
||||||
|
zip.putInt((*it)->col.b);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gui::load(TCODZip& zip) {
|
||||||
|
int nbMessages = zip.getInt();
|
||||||
|
while (nbMessages > 0) {
|
||||||
|
const char* text = zip.getString();
|
||||||
|
TCOD_ColorRGB col(zip.getInt(), zip.getInt(), zip.getInt());
|
||||||
|
message(col, text);
|
||||||
|
nbMessages--;
|
||||||
|
}
|
||||||
|
}
|
6
Gui.h
6
Gui.h
@ -1,13 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "libtcod.hpp"
|
#include "libtcod.hpp"
|
||||||
|
#include "Persistance.h"
|
||||||
class Gui {
|
class Gui : public Persistent {
|
||||||
public:
|
public:
|
||||||
Gui(tcod::Context *ctx, tcod::Console *root);
|
Gui(tcod::Context *ctx, tcod::Console *root);
|
||||||
~Gui();
|
~Gui();
|
||||||
void render();
|
void render();
|
||||||
void message(const TCOD_ColorRGB& col, const char* text, ...);
|
void message(const TCOD_ColorRGB& col, const char* text, ...);
|
||||||
|
void load(TCODZip& zip);
|
||||||
|
void save(TCODZip& zip);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
tcod::Console con;
|
tcod::Console con;
|
||||||
|
@ -14,3 +14,12 @@ bool Healer::use(Actor* owner, Actor* wearer) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Healer::load(TCODZip& zip) {
|
||||||
|
amount = zip.getFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Healer::save(TCODZip& zip) {
|
||||||
|
zip.putInt(HEALER);
|
||||||
|
zip.putFloat(amount);
|
||||||
|
}
|
2
Healer.h
2
Healer.h
@ -9,4 +9,6 @@ public:
|
|||||||
Healer(float amount);
|
Healer(float amount);
|
||||||
bool use(Actor* owner, Actor* wearer);
|
bool use(Actor* owner, Actor* wearer);
|
||||||
~Healer() {};
|
~Healer() {};
|
||||||
|
void load(TCODZip& zip);
|
||||||
|
void save(TCODZip& zip);
|
||||||
};
|
};
|
||||||
|
@ -16,9 +16,20 @@ bool LightningBolt::use(Actor* owner, Actor* wearer) {
|
|||||||
}
|
}
|
||||||
// hit closest monster for <damage> hit points
|
// hit closest monster for <damage> hit points
|
||||||
engine->gui->message(TCOD_ColorRGB(100, 255, 100),
|
engine->gui->message(TCOD_ColorRGB(100, 255, 100),
|
||||||
"A lighting bolt strikes the %s with a loud crack of thunder!\n"
|
"A lighting bolt strikes the %s with a crack of thunder!\n"
|
||||||
"The damage is %g hit points.",
|
"The damage is %g hit points.",
|
||||||
closestMonster->name.c_str(), damage);
|
closestMonster->name.c_str(), damage);
|
||||||
closestMonster->destructible->takeDamage(closestMonster, damage);
|
closestMonster->destructible->takeDamage(closestMonster, damage);
|
||||||
return Pickable::use(owner, wearer);
|
return Pickable::use(owner, wearer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LightningBolt::load(TCODZip& zip) {
|
||||||
|
range = zip.getFloat();
|
||||||
|
damage = zip.getFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LightningBolt::save(TCODZip& zip) {
|
||||||
|
zip.putInt(LIGHTNING_BOLT);
|
||||||
|
zip.putFloat(range);
|
||||||
|
zip.putFloat(damage);
|
||||||
|
}
|
@ -9,4 +9,6 @@ public:
|
|||||||
float range, damage;
|
float range, damage;
|
||||||
LightningBolt(float range, float damage);
|
LightningBolt(float range, float damage);
|
||||||
bool use(Actor* owner, Actor* wearer);
|
bool use(Actor* owner, Actor* wearer);
|
||||||
|
void load(TCODZip& zip);
|
||||||
|
void save(TCODZip& zip);
|
||||||
};
|
};
|
42
Map.cpp
42
Map.cpp
@ -24,15 +24,16 @@ private:
|
|||||||
public:
|
public:
|
||||||
BspListener(Map& map) : map(map), roomNum(0) {}
|
BspListener(Map& map) : map(map), roomNum(0) {}
|
||||||
bool visitNode(TCODBsp* node, void* userData) {
|
bool visitNode(TCODBsp* node, void* userData) {
|
||||||
|
|
||||||
if (node->isLeaf()) {
|
if (node->isLeaf()) {
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
|
bool withActors = (bool)userData;
|
||||||
// dig a room
|
// dig a room
|
||||||
TCODRandom* rng = TCODRandom::getInstance();
|
w = map.rng->getInt(ROOM_MIN_SIZE, node->w - 2);
|
||||||
w = rng->getInt(ROOM_MIN_SIZE, node->w - 2);
|
h = map.rng->getInt(ROOM_MIN_SIZE, node->h - 2);
|
||||||
h = rng->getInt(ROOM_MIN_SIZE, node->h - 2);
|
x = map.rng->getInt(node->x + 1, node->x + node->w - w - 1);
|
||||||
x = rng->getInt(node->x + 1, node->x + node->w - w - 1);
|
y = map.rng->getInt(node->y + 1, node->y + node->h - h - 1);
|
||||||
y = rng->getInt(node->y + 1, node->y + node->h - h - 1);
|
map.createRoom(roomNum == 0, x, y, x + w - 1, y + h - 1, withActors);
|
||||||
map.createRoom(roomNum == 0, x, y, x + w - 1, y + h - 1);
|
|
||||||
if (roomNum != 0) {
|
if (roomNum != 0) {
|
||||||
// dig a corridor from last room
|
// dig a corridor from last room
|
||||||
map.dig(lastx, lasty, x + w / 2, lasty);
|
map.dig(lastx, lasty, x + w / 2, lasty);
|
||||||
@ -47,14 +48,17 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
Map::Map(int width, int height) : width(width), height(height) {
|
Map::Map(int width, int height) : width(width), height(height) {
|
||||||
|
seed = TCODRandom::getInstance()->getInt(0, 0x7FFFFFFF);
|
||||||
|
}
|
||||||
|
void Map::init(bool withActors) {
|
||||||
|
rng = new TCODRandom(seed, TCOD_RNG_CMWC);
|
||||||
tiles = new Tile[width * height];
|
tiles = new Tile[width * height];
|
||||||
map = new TCODMap(width, height);
|
map = new TCODMap(width, height);
|
||||||
TCODBsp bsp(0, 0, width, height);
|
TCODBsp bsp(0, 0, width, height);
|
||||||
bsp.splitRecursive(NULL, 8, ROOM_MAX_SIZE, ROOM_MAX_SIZE, 1.5f, 1.5f);
|
bsp.splitRecursive(rng, 8, ROOM_MAX_SIZE, ROOM_MAX_SIZE, 1.5f, 1.5f);
|
||||||
BspListener listener(*this);
|
BspListener listener(*this);
|
||||||
bsp.traverseInvertedLevelOrder(&listener, NULL);
|
bsp.traverseInvertedLevelOrder(&listener, (void*)withActors);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map::~Map() {
|
Map::~Map() {
|
||||||
delete[] tiles;
|
delete[] tiles;
|
||||||
delete map;
|
delete map;
|
||||||
@ -140,8 +144,11 @@ void Map::dig(int x1, int y1, int x2, int y2) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::createRoom(bool first, int x1, int y1, int x2, int y2) {
|
void Map::createRoom(bool first, int x1, int y1, int x2, int y2, bool withActors) {
|
||||||
dig(x1, y1, x2, y2);
|
dig(x1, y1, x2, y2);
|
||||||
|
if (!withActors) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (first) {
|
if (first) {
|
||||||
// put the player in the first room
|
// put the player in the first room
|
||||||
engine->player->x = (x1 + x2) / 2;
|
engine->player->x = (x1 + x2) / 2;
|
||||||
@ -229,3 +236,18 @@ void Map::addItem(int x, int y) {
|
|||||||
engine->actors.push(scrollOfConfusion);
|
engine->actors.push(scrollOfConfusion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Map::save(TCODZip& zip) {
|
||||||
|
zip.putInt(seed);
|
||||||
|
for (int i = 0; i < width * height; i++) {
|
||||||
|
zip.putInt(tiles[i].explored);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map::load(TCODZip& zip) {
|
||||||
|
seed = zip.getInt();
|
||||||
|
init(false);
|
||||||
|
for (int i = 0; i < width * height; i++) {
|
||||||
|
tiles[i].explored = zip.getInt();
|
||||||
|
}
|
||||||
|
}
|
12
Map.h
12
Map.h
@ -1,16 +1,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "libtcod.hpp"
|
||||||
|
#include "Persistance.h"
|
||||||
|
|
||||||
struct Tile {
|
struct Tile {
|
||||||
bool explored; // has the player already seen this tile ?
|
bool explored; // has the player already seen this tile ?
|
||||||
Tile() : explored(false) {}
|
Tile() : explored(false) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Map {
|
class Map : public Persistent {
|
||||||
public:
|
public:
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
Map(int width, int height);
|
Map(int width, int height);
|
||||||
~Map();
|
~Map();
|
||||||
|
void init(bool withActors);
|
||||||
bool canWalk(int x, int y) const;
|
bool canWalk(int x, int y) const;
|
||||||
bool isWall(int x, int y) const;
|
bool isWall(int x, int y) const;
|
||||||
bool isInFov(int x, int y) const;
|
bool isInFov(int x, int y) const;
|
||||||
@ -18,12 +21,17 @@ public:
|
|||||||
void computeFov();
|
void computeFov();
|
||||||
void render(TCOD_Console& cons) const;
|
void render(TCOD_Console& cons) const;
|
||||||
void addItem(int x, int y);
|
void addItem(int x, int y);
|
||||||
|
long seed;
|
||||||
|
TCODRandom* rng;
|
||||||
|
void load(TCODZip& zip);
|
||||||
|
void save(TCODZip& zip);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Tile* tiles;
|
Tile* tiles;
|
||||||
friend class BspListener;
|
friend class BspListener;
|
||||||
TCODMap* map;
|
TCODMap* map;
|
||||||
void dig(int x1, int y1, int x2, int y2);
|
void dig(int x1, int y1, int x2, int y2);
|
||||||
void createRoom(bool first, int x1, int y1, int x2, int y2);
|
void createRoom(bool first, int x1, int y1, int x2, int y2, bool withActors);
|
||||||
void addMonster(int x, int y);
|
void addMonster(int x, int y);
|
||||||
void setWall(int x, int y);
|
void setWall(int x, int y);
|
||||||
};
|
};
|
7
Persistance.h
Normal file
7
Persistance.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Persistent {
|
||||||
|
public:
|
||||||
|
virtual void load(TCODZip& zip) = 0;
|
||||||
|
virtual void save(TCODZip& zip) = 0;
|
||||||
|
};
|
18
Pickable.cpp
18
Pickable.cpp
@ -3,6 +3,11 @@
|
|||||||
#include "Engine.h"
|
#include "Engine.h"
|
||||||
#include "Container.h"
|
#include "Container.h"
|
||||||
#include "Gui.h"
|
#include "Gui.h"
|
||||||
|
#include "Healer.h"
|
||||||
|
#include "LightningBolt.h"
|
||||||
|
#include "Confuser.h"
|
||||||
|
#include "Fireball.h"
|
||||||
|
|
||||||
|
|
||||||
bool Pickable::pick(Actor* owner, Actor* wearer) {
|
bool Pickable::pick(Actor* owner, Actor* wearer) {
|
||||||
if (wearer->container && wearer->container->add(owner)) {
|
if (wearer->container && wearer->container->add(owner)) {
|
||||||
@ -31,3 +36,16 @@ void Pickable::drop(Actor* owner, Actor* wearer) {
|
|||||||
wearer->name.c_str(), owner->name.c_str());
|
wearer->name.c_str(), owner->name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pickable* Pickable::create(TCODZip& zip) {
|
||||||
|
PickableType type = (PickableType)zip.getInt();
|
||||||
|
Pickable* pickable = NULL;
|
||||||
|
switch (type) {
|
||||||
|
case HEALER: pickable = new Healer(0); break;
|
||||||
|
case LIGHTNING_BOLT: pickable = new LightningBolt(0, 0); break;
|
||||||
|
case CONFUSER: pickable = new Confuser(0, 0); break;
|
||||||
|
case FIREBALL: pickable = new Fireball(0, 0); break;
|
||||||
|
}
|
||||||
|
pickable->load(zip);
|
||||||
|
return pickable;
|
||||||
|
}
|
@ -1,11 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "libtcod.hpp"
|
||||||
|
#include "Persistance.h"
|
||||||
|
|
||||||
class Actor;
|
class Actor;
|
||||||
|
|
||||||
class Pickable {
|
class Pickable : public Persistent {
|
||||||
public:
|
public:
|
||||||
bool pick(Actor* owner, Actor* wearer);
|
bool pick(Actor* owner, Actor* wearer);
|
||||||
virtual bool use(Actor* owner, Actor* wearer);
|
virtual bool use(Actor* owner, Actor* wearer);
|
||||||
void drop(Actor* owner, Actor* wearer);
|
void drop(Actor* owner, Actor* wearer);
|
||||||
virtual ~Pickable() {};
|
virtual ~Pickable() {};
|
||||||
|
static Pickable* create(TCODZip& zip);
|
||||||
|
protected:
|
||||||
|
enum PickableType {
|
||||||
|
HEALER, LIGHTNING_BOLT, CONFUSER, FIREBALL
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user