Spells pt3
This commit is contained in:
parent
2686764cb3
commit
35dcee85a0
46
Ai.cpp
46
Ai.cpp
@ -1,4 +1,5 @@
|
|||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
#include "libtcod.hpp"
|
||||||
#include "Ai.h"
|
#include "Ai.h"
|
||||||
#include "Actor.h"
|
#include "Actor.h"
|
||||||
#include "Engine.h"
|
#include "Engine.h"
|
||||||
@ -68,6 +69,7 @@ void PlayerAi::update(Actor* owner) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerAi::handleActionKey(Actor* owner, int sdlkey) {
|
void PlayerAi::handleActionKey(Actor* owner, int sdlkey) {
|
||||||
switch (sdlkey) {
|
switch (sdlkey) {
|
||||||
case SDLK_G: // pickup item
|
case SDLK_G: // pickup item
|
||||||
@ -92,15 +94,29 @@ void PlayerAi::handleActionKey(Actor* owner, int sdlkey) {
|
|||||||
if (!found) {
|
if (!found) {
|
||||||
engine->gui->message(TCOD_ColorRGB(200,200,200), "There's nothing here that you can pick up.");
|
engine->gui->message(TCOD_ColorRGB(200,200,200), "There's nothing here that you can pick up.");
|
||||||
}
|
}
|
||||||
|
if (engine->gameStatus != Engine::QUIT)
|
||||||
engine->gameStatus = Engine::NEW_TURN;
|
engine->gameStatus = Engine::NEW_TURN;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDLK_I:
|
case SDLK_I:
|
||||||
|
{
|
||||||
Actor* actor = choseFromInventory(owner);
|
Actor* actor = choseFromInventory(owner);
|
||||||
if (actor) {
|
if (actor) {
|
||||||
actor->pickable->use(actor, owner);
|
actor->pickable->use(actor, owner);
|
||||||
|
if (engine->gameStatus != Engine::QUIT)
|
||||||
engine->gameStatus = Engine::NEW_TURN;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,7 +172,6 @@ Actor* PlayerAi::choseFromInventory(Actor* owner) {
|
|||||||
engine->context->present(*engine->console);
|
engine->context->present(*engine->console);
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (1) {
|
while (1) {
|
||||||
printf("HERE\n");
|
|
||||||
SDL_WaitEvent(&event);
|
SDL_WaitEvent(&event);
|
||||||
if (event.type == SDL_EVENT_KEY_UP) {
|
if (event.type == SDL_EVENT_KEY_UP) {
|
||||||
if (event.key.key >= SDLK_A && event.key.key < SDLK_A + owner->container->inventory.size()) {
|
if (event.key.key >= SDLK_A && event.key.key < SDLK_A + owner->container->inventory.size()) {
|
||||||
@ -214,3 +229,32 @@ void MonsterAi::moveOrAttack(Actor* owner, int targetx, int targety) {
|
|||||||
owner->attacker->attack(owner, engine->player);
|
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
@ -26,3 +26,12 @@ protected:
|
|||||||
int moveCount;
|
int moveCount;
|
||||||
void moveOrAttack(Actor* owner, int targetx, int targety);
|
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)
|
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")
|
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
|
target_link_libraries(ADG5
|
||||||
PRIVATE
|
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) {
|
bool Engine::pickATile(int* x, int* y, float maxRange) {
|
||||||
while (context->get_sdl_window() != nullptr) {
|
while (true) {
|
||||||
render(false);
|
render(false);
|
||||||
|
|
||||||
// highlight the possible range
|
// highlight the possible range
|
||||||
@ -117,9 +117,9 @@ bool Engine::pickATile(int* x, int* y, float maxRange) {
|
|||||||
&& (maxRange == 0 || player->getDistance(cx, cy) <= maxRange)) {
|
&& (maxRange == 0 || player->getDistance(cx, cy) <= maxRange)) {
|
||||||
TCOD_ColorRGBA col = console->at(cx, cy).bg;
|
TCOD_ColorRGBA col = console->at(cx, cy).bg;
|
||||||
|
|
||||||
col.r = col.r * 1.2f;
|
col.r = (int)((float)col.r * 1.2f);
|
||||||
col.g = col.g * 1.2f;
|
col.g = (int)((float)col.g * 1.2f);
|
||||||
col.b = col.b * 1.2f;
|
col.b = (int)((float)col.b * 1.2f);
|
||||||
|
|
||||||
console->at(cx, cy).bg = col;
|
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.lbutton_pressed = event.button.button == SDL_BUTTON_LEFT;
|
||||||
engine->mouse.rbutton_pressed = event.button.button == SDL_BUTTON_RIGHT;
|
engine->mouse.rbutton_pressed = event.button.button == SDL_BUTTON_RIGHT;
|
||||||
break;
|
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);
|
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);
|
void sendToBack(Actor* actor);
|
||||||
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;
|
||||||
private:
|
private:
|
||||||
bool computeFov;
|
bool computeFov;
|
||||||
};
|
};
|
||||||
|
9
Map.cpp
9
Map.cpp
@ -8,6 +8,7 @@
|
|||||||
#include "Healer.h"
|
#include "Healer.h"
|
||||||
#include "Lightningbolt.h"
|
#include "Lightningbolt.h"
|
||||||
#include "Fireball.h"
|
#include "Fireball.h"
|
||||||
|
#include "Confuser.h"
|
||||||
|
|
||||||
static const int ROOM_MAX_SIZE = 12;
|
static const int ROOM_MAX_SIZE = 12;
|
||||||
static const int ROOM_MIN_SIZE = 6;
|
static const int ROOM_MIN_SIZE = 6;
|
||||||
@ -219,4 +220,12 @@ void Map::addItem(int x, int y) {
|
|||||||
scrollOfFireball->pickable = new Fireball(3, 12);
|
scrollOfFireball->pickable = new Fireball(3, 12);
|
||||||
engine->actors.push(scrollOfFireball);
|
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 "Actor.h"
|
||||||
#include "Engine.h"
|
#include "Engine.h"
|
||||||
#include "Container.h"
|
#include "Container.h"
|
||||||
|
#include "Gui.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)) {
|
||||||
@ -19,3 +20,14 @@ bool Pickable::use(Actor* owner, Actor* wearer) {
|
|||||||
}
|
}
|
||||||
return false;
|
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:
|
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);
|
||||||
virtual ~Pickable() {};
|
virtual ~Pickable() {};
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user