Spells pt3
This commit is contained in:
parent
2686764cb3
commit
35dcee85a0
52
Ai.cpp
52
Ai.cpp
@ -1,4 +1,5 @@
|
||||
#include <SDL3/SDL.h>
|
||||
#include "libtcod.hpp"
|
||||
#include "Ai.h"
|
||||
#include "Actor.h"
|
||||
#include "Engine.h"
|
||||
@ -68,6 +69,7 @@ void PlayerAi::update(Actor* owner) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerAi::handleActionKey(Actor* owner, int sdlkey) {
|
||||
switch (sdlkey) {
|
||||
case SDLK_G: // pickup item
|
||||
@ -92,15 +94,29 @@ void PlayerAi::handleActionKey(Actor* owner, int sdlkey) {
|
||||
if (!found) {
|
||||
engine->gui->message(TCOD_ColorRGB(200,200,200), "There's nothing here that you can pick up.");
|
||||
}
|
||||
engine->gameStatus = Engine::NEW_TURN;
|
||||
if (engine->gameStatus != Engine::QUIT)
|
||||
engine->gameStatus = Engine::NEW_TURN;
|
||||
}
|
||||
break;
|
||||
case SDLK_I:
|
||||
{
|
||||
Actor* actor = choseFromInventory(owner);
|
||||
if (actor) {
|
||||
actor->pickable->use(actor, owner);
|
||||
engine->gameStatus = Engine::NEW_TURN;
|
||||
if (engine->gameStatus != Engine::QUIT)
|
||||
engine->gameStatus = Engine::NEW_TURN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDLK_D: // drop item
|
||||
{
|
||||
Actor* actor = choseFromInventory(owner);
|
||||
if (actor) {
|
||||
actor->pickable->drop(actor, owner);
|
||||
if (engine->gameStatus != Engine::QUIT)
|
||||
engine->gameStatus = Engine::NEW_TURN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -156,7 +172,6 @@ Actor* PlayerAi::choseFromInventory(Actor* owner) {
|
||||
engine->context->present(*engine->console);
|
||||
SDL_Event event;
|
||||
while (1) {
|
||||
printf("HERE\n");
|
||||
SDL_WaitEvent(&event);
|
||||
if (event.type == SDL_EVENT_KEY_UP) {
|
||||
if (event.key.key >= SDLK_A && event.key.key < SDLK_A + owner->container->inventory.size()) {
|
||||
@ -213,4 +228,33 @@ void MonsterAi::moveOrAttack(Actor* owner, int targetx, int targety) {
|
||||
else if (owner->attacker) {
|
||||
owner->attacker->attack(owner, engine->player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConfusedMonsterAi::ConfusedMonsterAi(int nbTurns, Ai* oldAi)
|
||||
: nbTurns(nbTurns), oldAi(oldAi) {
|
||||
}
|
||||
|
||||
void ConfusedMonsterAi::update(Actor* owner) {
|
||||
TCODRandom* rng = TCODRandom::getInstance();
|
||||
int dx = rng->getInt(-1, 1);
|
||||
int dy = rng->getInt(-1, 1);
|
||||
if (dx != 0 || dy != 0) {
|
||||
int destx = owner->x + dx;
|
||||
int desty = owner->y + dy;
|
||||
if (engine->map->canWalk(destx, desty)) {
|
||||
owner->x = destx;
|
||||
owner->y = desty;
|
||||
}
|
||||
else {
|
||||
Actor* actor = engine->getActor(destx, desty);
|
||||
if (actor) {
|
||||
owner->attacker->attack(owner, actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
nbTurns--;
|
||||
if (nbTurns == 0) {
|
||||
owner->ai = oldAi;
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
9
Ai.h
9
Ai.h
@ -25,4 +25,13 @@ public:
|
||||
protected:
|
||||
int moveCount;
|
||||
void moveOrAttack(Actor* owner, int targetx, int targety);
|
||||
};
|
||||
|
||||
class ConfusedMonsterAi : public Ai {
|
||||
public:
|
||||
ConfusedMonsterAi(int nbTurns, Ai* oldAi);
|
||||
void update(Actor* owner);
|
||||
protected:
|
||||
int nbTurns;
|
||||
Ai* oldAi;
|
||||
};
|
@ -14,7 +14,7 @@ project ("ADG5")
|
||||
find_package(libtcod CONFIG REQUIRED)
|
||||
|
||||
# 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")
|
||||
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")
|
||||
|
||||
target_link_libraries(ADG5
|
||||
PRIVATE
|
||||
|
28
Confuser.cpp
Normal file
28
Confuser.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
#include "libtcod.hpp"
|
||||
#include "Confuser.h"
|
||||
#include "Engine.h"
|
||||
#include "Gui.h"
|
||||
#include "Ai.h"
|
||||
#include "Actor.h"
|
||||
|
||||
|
||||
Confuser::Confuser(int nbTurns, float range)
|
||||
: nbTurns(nbTurns), range(range) {
|
||||
}
|
||||
bool Confuser::use(Actor* owner, Actor* wearer) {
|
||||
engine->gui->message(TCOD_ColorRGB(0, 255, 255), "Left-click an enemy to confuse it,\nor right-click to cancel.");
|
||||
int x, y;
|
||||
if (!engine->pickATile(&x, &y, range)) {
|
||||
return false;
|
||||
}
|
||||
Actor* actor = engine->getActor(x, y);
|
||||
if (!actor) {
|
||||
return false;
|
||||
}
|
||||
// confuse the monster for <nbTurns> turns
|
||||
Ai* confusedAi = new ConfusedMonsterAi(nbTurns, actor->ai);
|
||||
actor->ai = confusedAi;
|
||||
engine->gui->message(TCOD_ColorRGB(100, 255, 100), "The eyes of the %s look vacant,\nas he starts to stumble around!",
|
||||
actor->name.c_str());
|
||||
return Pickable::use(owner, wearer);
|
||||
}
|
13
Confuser.h
Normal file
13
Confuser.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Pickable.h"
|
||||
|
||||
class Actor;
|
||||
|
||||
class Confuser : public Pickable {
|
||||
public:
|
||||
int nbTurns;
|
||||
float range;
|
||||
Confuser(int nbTurns, float range);
|
||||
bool use(Actor* owner, Actor* wearer);
|
||||
};
|
24
Engine.cpp
24
Engine.cpp
@ -107,7 +107,7 @@ Actor* Engine::getClosestMonster(int x, int y, float range) const {
|
||||
}
|
||||
|
||||
bool Engine::pickATile(int* x, int* y, float maxRange) {
|
||||
while (context->get_sdl_window() != nullptr) {
|
||||
while (true) {
|
||||
render(false);
|
||||
|
||||
// highlight the possible range
|
||||
@ -117,9 +117,9 @@ bool Engine::pickATile(int* x, int* y, float maxRange) {
|
||||
&& (maxRange == 0 || player->getDistance(cx, cy) <= maxRange)) {
|
||||
TCOD_ColorRGBA col = console->at(cx, cy).bg;
|
||||
|
||||
col.r = col.r * 1.2f;
|
||||
col.g = col.g * 1.2f;
|
||||
col.b = col.b * 1.2f;
|
||||
col.r = (int)((float)col.r * 1.2f);
|
||||
col.g = (int)((float)col.g * 1.2f);
|
||||
col.b = (int)((float)col.b * 1.2f);
|
||||
|
||||
console->at(cx, cy).bg = col;
|
||||
}
|
||||
@ -137,6 +137,9 @@ bool Engine::pickATile(int* x, int* y, float maxRange) {
|
||||
engine->mouse.lbutton_pressed = event.button.button == SDL_BUTTON_LEFT;
|
||||
engine->mouse.rbutton_pressed = event.button.button == SDL_BUTTON_RIGHT;
|
||||
break;
|
||||
case SDL_EVENT_QUIT:
|
||||
engine->gameStatus = Engine::QUIT;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,5 +157,16 @@ bool Engine::pickATile(int* x, int* y, float maxRange) {
|
||||
}
|
||||
context->present(*console);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Actor* Engine::getActor(int x, int y) const {
|
||||
for (Actor** iterator = actors.begin();
|
||||
iterator != actors.end(); iterator++) {
|
||||
Actor* actor = *iterator;
|
||||
if (actor->x == x && actor->y == y && actor->destructible
|
||||
&& !actor->destructible->isDead()) {
|
||||
return actor;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
1
Engine.h
1
Engine.h
@ -34,6 +34,7 @@ public:
|
||||
void sendToBack(Actor* actor);
|
||||
Actor* getClosestMonster(int x, int y, float range) const;
|
||||
bool pickATile(int* x, int* y, float maxRange = 0.0f);
|
||||
Actor* getActor(int x, int y) const;
|
||||
private:
|
||||
bool computeFov;
|
||||
};
|
||||
|
9
Map.cpp
9
Map.cpp
@ -8,6 +8,7 @@
|
||||
#include "Healer.h"
|
||||
#include "Lightningbolt.h"
|
||||
#include "Fireball.h"
|
||||
#include "Confuser.h"
|
||||
|
||||
static const int ROOM_MAX_SIZE = 12;
|
||||
static const int ROOM_MIN_SIZE = 6;
|
||||
@ -219,4 +220,12 @@ void Map::addItem(int x, int y) {
|
||||
scrollOfFireball->pickable = new Fireball(3, 12);
|
||||
engine->actors.push(scrollOfFireball);
|
||||
}
|
||||
else {
|
||||
// create a scroll of confusion
|
||||
Actor* scrollOfConfusion = new Actor(x, y, "#", "scroll of confusion",
|
||||
TCOD_ColorRGB(255, 100, 100));
|
||||
scrollOfConfusion->blocks = false;
|
||||
scrollOfConfusion->pickable = new Confuser(10, 8);
|
||||
engine->actors.push(scrollOfConfusion);
|
||||
}
|
||||
}
|
12
Pickable.cpp
12
Pickable.cpp
@ -2,6 +2,7 @@
|
||||
#include "Actor.h"
|
||||
#include "Engine.h"
|
||||
#include "Container.h"
|
||||
#include "Gui.h"
|
||||
|
||||
bool Pickable::pick(Actor* owner, Actor* wearer) {
|
||||
if (wearer->container && wearer->container->add(owner)) {
|
||||
@ -18,4 +19,15 @@ bool Pickable::use(Actor* owner, Actor* wearer) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Pickable::drop(Actor* owner, Actor* wearer) {
|
||||
if (wearer->container) {
|
||||
wearer->container->remove(owner);
|
||||
engine->actors.push(owner);
|
||||
owner->x = wearer->x;
|
||||
owner->y = wearer->y;
|
||||
engine->gui->message(TCOD_ColorRGB(200,200,200), "%s drops a %s.",
|
||||
wearer->name.c_str(), owner->name.c_str());
|
||||
}
|
||||
}
|
@ -6,5 +6,6 @@ class Pickable {
|
||||
public:
|
||||
bool pick(Actor* owner, Actor* wearer);
|
||||
virtual bool use(Actor* owner, Actor* wearer);
|
||||
void drop(Actor* owner, Actor* wearer);
|
||||
virtual ~Pickable() {};
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user