adg5/Destructible.cpp
2025-04-22 11:38:20 +10:00

101 lines
2.7 KiB
C++

#include "Destructible.h"
#include "Actor.h"
#include "Engine.h"
#include "Gui.h"
Destructible::Destructible(float maxHp, float defense, std::string corpseName, int xp) :
maxHp(maxHp), hp(maxHp), defense(defense), corpseName(corpseName), xp(xp) {
}
float Destructible::takeDamage(Actor* owner, float damage) {
damage -= defense;
if (damage > 0) {
hp -= damage;
if (hp <= 0) {
die(owner);
}
}
else {
damage = 0;
}
return damage;
}
float Destructible::heal(float amount) {
hp += amount;
if (hp > maxHp) {
amount -= hp - maxHp;
hp = maxHp;
}
return amount;
}
void Destructible::die(Actor* owner) {
// transform the actor into a corpse!
owner->ch = "%";
owner->col = TCOD_ColorRGB(100, 0, 0);
owner->name = corpseName;
owner->blocks = false;
// make sure corpses are drawn before living actors
engine->sendToBack(owner);
}
MonsterDestructible::MonsterDestructible(float maxHp, float defense, std::string corpseName, int xp) :
Destructible(maxHp, defense, corpseName, xp) {
}
PlayerDestructible::PlayerDestructible(float maxHp, float defense, std::string corpseName) :
Destructible(maxHp, defense, corpseName, 1) {
}
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) {
// transform it into a nasty corpse! it doesn't block, can't be
// attacked and doesn't move
engine->gui->message(engine->gui->lightGrey, "%s is dead. You gain %d xp",
owner->name.c_str(), xp);
engine->player->destructible->xp += xp;
Destructible::die(owner);
}
void PlayerDestructible::die(Actor* owner) {
engine->gui->message(engine->gui->red, "You died!\n");
Destructible::die(owner);
engine->gameStatus = Engine::DEFEAT;
}
void Destructible::load(TCODZip& zip) {
maxHp = zip.getFloat();
hp = zip.getFloat();
defense = zip.getFloat();
corpseName = zip.getString();
xp = zip.getInt();
}
void Destructible::save(TCODZip& zip) {
zip.putFloat(maxHp);
zip.putFloat(hp);
zip.putFloat(defense);
zip.putString(corpseName.c_str());
zip.putInt(xp);
}
Destructible* Destructible::create(TCODZip& zip) {
DestructibleType type = (DestructibleType)zip.getInt();
Destructible* destructible = NULL;
switch (type) {
case MONSTER: destructible = new MonsterDestructible(0, 0, "", 0); break;
case PLAYER: destructible = new PlayerDestructible(0, 0, ""); break;
}
destructible->load(zip);
return destructible;
}