feat: Implement switching the party leader
This commit is contained in:
parent
9ca1d7a29a
commit
32d050cd0a
5 changed files with 65 additions and 12 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue