feat: Implement switching the party leader

This commit is contained in:
Vsevolod Kremianskii 2020-10-28 00:00:02 +07:00
parent 9ca1d7a29a
commit 32d050cd0a
5 changed files with 65 additions and 12 deletions

View file

@ -55,7 +55,8 @@ Game::Game(const fs::path &path, const Options &opts) :
_window(opts.graphics, this),
_sceneGraph(opts.graphics),
_worldPipeline(&_sceneGraph, opts.graphics),
_console(opts.graphics) {
_console(opts.graphics),
_party(this) {
initGameVersion();
_objectFactory = make_unique<ObjectFactory>(this, &_sceneGraph);
@ -457,6 +458,9 @@ bool Game::handle(const SDL_Event &event) {
if (_console.handle(event)) {
return true;
}
if (_party.handle(event)) {
return true;
}
if (_module->handle(event)) {
return true;
}

View file

@ -513,13 +513,13 @@ SpatialObject *Area::getObjectAt(int x, int y) const {
glm::vec3 fromWorld(glm::unProject(glm::vec3(x, opts.height - y, 0.0f), sceneNode->view(), sceneNode->projection(), viewport));
glm::vec3 toWorld(glm::unProject(glm::vec3(x, opts.height - y, 1.0f), sceneNode->view(), sceneNode->projection(), viewport));
shared_ptr<Creature> player(_game->party().player());
shared_ptr<Creature> partyLeader(_game->party().leader());
RaycastProperties props;
props.flags = kRaycastObjects | kRaycastAABB;
props.origin = fromWorld;
props.direction = glm::normalize(toWorld - fromWorld);
props.except = player.get();
props.except = partyLeader.get();
RaycastResult result;

View file

@ -17,8 +17,14 @@
#include "party.h"
#include <stdexcept>
#include "../system/log.h"
#include "action/follow.h"
#include "game.h"
#include "object/creature.h"
using namespace std;
namespace reone {
@ -27,6 +33,32 @@ namespace game {
static const int kMaxMemberCount = 3;
Party::Party(Game *game) : _game(game) {
if (!game) {
throw invalid_argument("Game must not be null");
}
}
bool Party::handle(const SDL_Event &event) {
if (event.type == SDL_KEYDOWN) {
return handleKeyDown(event.key);
}
return false;
}
bool Party::handleKeyDown(const SDL_KeyboardEvent &event) {
if (event.repeat) return false;
switch (event.keysym.sym) {
case SDLK_TAB:
switchLeader();
return true;
}
return false;
}
bool Party::addAvailableMember(int npc, const string &blueprint) {
auto maybeMember = _availableMembers.find(npc);
if (maybeMember != _availableMembers.end()) {
@ -71,6 +103,13 @@ void Party::switchLeader() {
break;
}
}
_members[0]->actionQueue().clear();
for (int i = 1; i < count; ++i) {
_members[i]->actionQueue().clear();
_members[i]->actionQueue().add(make_unique<FollowAction>(_members[0], 1.0f));
}
_game->module()->area()->onPartyLeaderMoved();
}
const string &Party::getAvailableMember(int npc) const {

View file

@ -22,17 +22,24 @@
#include <string>
#include <vector>
#include "SDL2/SDL_events.h"
namespace reone {
namespace game {
class Creature;
class Game;
/**
* Encapsulates party management.
*/
class Party {
public:
Party(Game *game);
bool handle(const SDL_Event &event);
bool addAvailableMember(int npc, const std::string &blueprint);
bool addMember(const std::shared_ptr<Creature> &member);
void clear();
@ -50,9 +57,12 @@ public:
void setPlayer(const std::shared_ptr<Creature> &player);
private:
Game *_game { nullptr };
std::shared_ptr<Creature> _player;
std::map<int, std::string> _availableMembers;
std::vector<std::shared_ptr<Creature>> _members;
bool handleKeyDown(const SDL_KeyboardEvent &event);
};
} // namespace game

View file

@ -49,8 +49,8 @@ Player::Player(Module *module, Area *area, Camera *camera, const Party *party) :
}
bool Player::handle(const SDL_Event &event) {
shared_ptr<Creature> player(_party->player());
if (!player) return false;
shared_ptr<Creature> partyLeader(_party->leader());
if (!partyLeader) return false;
switch (event.type) {
case SDL_KEYDOWN:
@ -104,7 +104,7 @@ bool Player::handleKeyUp(const SDL_KeyboardEvent &event) {
return true;
case SDL_SCANCODE_X:
_party->player()->playGreetingAnimation();
_party->leader()->playGreetingAnimation();
return true;
default:
@ -113,8 +113,8 @@ bool Player::handleKeyUp(const SDL_KeyboardEvent &event) {
}
void Player::update(float dt) {
shared_ptr<Creature> player(_party->player());
if (!player) return;
shared_ptr<Creature> partyLeader(_party->leader());
if (!partyLeader) return;
float heading = 0.0f;
bool movement = true;
@ -131,16 +131,16 @@ void Player::update(float dt) {
movement = false;
}
if (movement) {
glm::vec2 dest(player->position());
glm::vec2 dest(partyLeader->position());
dest.x -= 100.0f * glm::sin(heading);
dest.y += 100.0f * glm::cos(heading);
if (_area->moveCreatureTowards(*player, dest, true, dt)) {
player->setMovementType(MovementType::Run);
if (_area->moveCreatureTowards(*partyLeader, dest, true, dt)) {
partyLeader->setMovementType(MovementType::Run);
_area->onPartyLeaderMoved();
}
} else {
player->setMovementType(MovementType::None);
partyLeader->setMovementType(MovementType::None);
}
}