Combine Object and ActionQueue
This commit is contained in:
parent
6c47a9de8e
commit
e27a77b1e9
15 changed files with 134 additions and 258 deletions
|
@ -403,8 +403,6 @@ set(GAME_HEADERS
|
|||
src/engine/game/action/playanimation.h
|
||||
src/engine/game/action/startconversation.h
|
||||
src/engine/game/action/waitaction.h
|
||||
src/engine/game/actionexecutor.h
|
||||
src/engine/game/actionqueue.h
|
||||
src/engine/game/animationutil.h
|
||||
src/engine/game/camera/animatedcamera.h
|
||||
src/engine/game/camera/camera.h
|
||||
|
@ -501,7 +499,6 @@ set(GAME_HEADERS
|
|||
|
||||
set(GAME_SOURCES
|
||||
src/engine/game/actionexecutor.cpp
|
||||
src/engine/game/actionqueue.cpp
|
||||
src/engine/game/animationutil.cpp
|
||||
src/engine/game/camera/animatedcamera.cpp
|
||||
src/engine/game/camera/camera.cpp
|
||||
|
@ -585,6 +582,7 @@ set(GAME_SOURCES
|
|||
src/engine/game/object/item_blueprint.cpp
|
||||
src/engine/game/object/module.cpp
|
||||
src/engine/game/object/object.cpp
|
||||
src/engine/game/object/object_actions.cpp
|
||||
src/engine/game/object/objectfactory.cpp
|
||||
src/engine/game/object/placeable.cpp
|
||||
src/engine/game/object/placeable_blueprint.cpp
|
||||
|
|
|
@ -55,9 +55,7 @@ ActionExecutor::ActionExecutor(Game *game) : _game(game) {
|
|||
}
|
||||
|
||||
void ActionExecutor::executeActions(const shared_ptr<Object> &object, float dt) {
|
||||
ActionQueue &actionQueue = object->actionQueue();
|
||||
|
||||
shared_ptr<Action> action(actionQueue.getCurrentAction());
|
||||
shared_ptr<Action> action(object->getCurrentAction());
|
||||
if (!action) return;
|
||||
|
||||
ActionType type = action->type();
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2021 The reone project contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
|
||||
#include "../common/timer.h"
|
||||
|
||||
#include "action/action.h"
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
class ActionQueue {
|
||||
public:
|
||||
void clear();
|
||||
|
||||
void add(std::unique_ptr<Action> action);
|
||||
void addToTop(std::unique_ptr<Action> action);
|
||||
void delay(std::unique_ptr<Action> action, float seconds);
|
||||
|
||||
void update(float dt);
|
||||
|
||||
bool isEmpty() const;
|
||||
bool containsUserActions() const;
|
||||
|
||||
int getSize() const;
|
||||
std::shared_ptr<Action> getCurrentAction() const;
|
||||
|
||||
const std::deque<std::shared_ptr<Action>> &actions() const { return _actions; }
|
||||
|
||||
private:
|
||||
struct DelayedAction {
|
||||
std::unique_ptr<Action> action;
|
||||
Timer timer;
|
||||
};
|
||||
|
||||
std::deque<std::shared_ptr<Action>> _actions;
|
||||
std::vector<DelayedAction> _delayed;
|
||||
|
||||
void removeCompletedActions();
|
||||
void updateDelayedActions(float dt);
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
|
@ -288,7 +288,7 @@ void HUD::hideCombatHud() {
|
|||
}
|
||||
|
||||
void HUD::refreshActionQueueItems() const {
|
||||
auto &actions = _game->party().getLeader()->actionQueue().actions();
|
||||
auto &actions = _game->party().getLeader()->actions();
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
bool attack = i < static_cast<int>(actions.size()) && actions[i]->type() == ActionType::AttackObject;
|
||||
|
@ -317,9 +317,9 @@ void HUD::onClick(const string &control) {
|
|||
} else if (control == "BTN_OPT") {
|
||||
_game->openInGameMenu(InGameMenu::Tab::Options);
|
||||
} else if (control == "BTN_CLEARALL") {
|
||||
_game->party().getLeader()->actionQueue().clear();
|
||||
_game->party().getLeader()->clearAllActions();
|
||||
} else if (control == "BTN_CLEARONE" || control == "BTN_CLEARONE2") {
|
||||
for (auto &action : _game->party().getLeader()->actionQueue().actions()) {
|
||||
for (auto &action : _game->party().getLeader()->actions()) {
|
||||
if (action->type() == ActionType::AttackObject) {
|
||||
action->complete();
|
||||
break;
|
||||
|
|
|
@ -118,15 +118,14 @@ bool SelectionOverlay::handleMouseButtonDown(const SDL_MouseButtonEvent &event)
|
|||
|
||||
switch (_actions[_selectedActionIdx]) {
|
||||
case ContextualAction::Unlock: {
|
||||
ActionQueue &actions = _game->party().getLeader()->actionQueue();
|
||||
actions.add(make_unique<ObjectAction>(ActionType::OpenLock, selectedObject));
|
||||
shared_ptr<Creature> partyLeader(_game->party().getLeader());
|
||||
partyLeader->addAction(make_unique<ObjectAction>(ActionType::OpenLock, selectedObject));
|
||||
break;
|
||||
}
|
||||
|
||||
case ContextualAction::Attack: {
|
||||
shared_ptr<Creature> partyLeader(_game->party().getLeader());
|
||||
ActionQueue &actions = partyLeader->actionQueue();
|
||||
actions.add(make_unique<AttackAction>(static_pointer_cast<Creature>(selectedObject), partyLeader->getAttackRange(), true));
|
||||
partyLeader->addAction(make_unique<AttackAction>(static_pointer_cast<Creature>(selectedObject), partyLeader->getAttackRange(), true));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -552,11 +552,9 @@ void Creature::deactivateCombat(float delay) {
|
|||
shared_ptr<SpatialObject> Creature::getAttemptedAttackTarget() const {
|
||||
shared_ptr<SpatialObject> result;
|
||||
|
||||
if (!_actionQueue.isEmpty()) {
|
||||
auto attackAction = dynamic_pointer_cast<AttackAction>(_actionQueue.actions().front());
|
||||
if (attackAction) {
|
||||
result = attackAction->target();
|
||||
}
|
||||
auto attackAction = dynamic_pointer_cast<AttackAction>(getCurrentAction());
|
||||
if (attackAction) {
|
||||
result = attackAction->target();
|
||||
}
|
||||
|
||||
return move(result);
|
||||
|
|
|
@ -216,21 +216,20 @@ void Module::onCreatureClick(const shared_ptr<Creature> &creature) {
|
|||
debug(boost::format("Module: click: creature '%s', faction %d") % creature->tag() % static_cast<int>(creature->faction()));
|
||||
|
||||
shared_ptr<Creature> partyLeader(_game->party().getLeader());
|
||||
ActionQueue &actions = partyLeader->actionQueue();
|
||||
|
||||
if (creature->isDead()) {
|
||||
if (!creature->items().empty()) {
|
||||
actions.clear();
|
||||
actions.add(make_unique<ObjectAction>(ActionType::OpenContainer, creature));
|
||||
partyLeader->clearAllActions();
|
||||
partyLeader->addAction(make_unique<ObjectAction>(ActionType::OpenContainer, creature));
|
||||
}
|
||||
} else {
|
||||
bool isEnemy = Reputes::instance().getIsEnemy(*partyLeader, *creature);
|
||||
if (isEnemy) {
|
||||
actions.clear();
|
||||
actions.add(make_unique<AttackAction>(creature));
|
||||
partyLeader->clearAllActions();
|
||||
partyLeader->addAction(make_unique<AttackAction>(creature));
|
||||
} else if (!creature->conversation().empty()) {
|
||||
actions.clear();
|
||||
actions.add(make_unique<StartConversationAction>(creature, creature->conversation()));
|
||||
partyLeader->clearAllActions();
|
||||
partyLeader->addAction(make_unique<StartConversationAction>(creature, creature->conversation()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -242,22 +241,20 @@ void Module::onDoorClick(const shared_ptr<Door> &door) {
|
|||
}
|
||||
if (!door->isOpen()) {
|
||||
shared_ptr<Creature> partyLeader(_game->party().getLeader());
|
||||
ActionQueue &actions = partyLeader->actionQueue();
|
||||
actions.clear();
|
||||
actions.add(make_unique<ObjectAction>(ActionType::OpenDoor, door));
|
||||
partyLeader->clearAllActions();
|
||||
partyLeader->addAction(make_unique<ObjectAction>(ActionType::OpenDoor, door));
|
||||
}
|
||||
}
|
||||
|
||||
void Module::onPlaceableClick(const shared_ptr<Placeable> &placeable) {
|
||||
shared_ptr<Creature> partyLeader(_game->party().getLeader());
|
||||
ActionQueue &actions = partyLeader->actionQueue();
|
||||
|
||||
if (placeable->hasInventory()) {
|
||||
actions.clear();
|
||||
actions.add(make_unique<ObjectAction>(ActionType::OpenContainer, placeable));
|
||||
partyLeader->clearAllActions();
|
||||
partyLeader->addAction(make_unique<ObjectAction>(ActionType::OpenContainer, placeable));
|
||||
} else if (!placeable->conversation().empty()) {
|
||||
actions.clear();
|
||||
actions.add(make_unique<StartConversationAction>(placeable, placeable->conversation()));
|
||||
partyLeader->clearAllActions();
|
||||
partyLeader->addAction(make_unique<StartConversationAction>(placeable, placeable->conversation()));
|
||||
} else {
|
||||
placeable->runOnUsed(move(partyLeader));
|
||||
}
|
||||
|
|
|
@ -18,12 +18,9 @@
|
|||
#include "object.h"
|
||||
|
||||
#include "../../common/collectionutil.h"
|
||||
#include "../../script/types.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone::script;
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
@ -32,31 +29,7 @@ Object::Object(uint32_t id, ObjectType type) : _id(id), _type(type) {
|
|||
}
|
||||
|
||||
void Object::update(float dt) {
|
||||
_actionQueue.update(dt);
|
||||
}
|
||||
|
||||
void Object::clearAllActions() {
|
||||
_actionQueue.clear();
|
||||
}
|
||||
|
||||
void Object::setTag(string tag) {
|
||||
_tag = move(tag);
|
||||
}
|
||||
|
||||
void Object::setMinOneHP(bool minOneHP) {
|
||||
_minOneHP = minOneHP;
|
||||
}
|
||||
|
||||
void Object::setMaxHitPoints(int maxHitPoints) {
|
||||
_maxHitPoints = maxHitPoints;
|
||||
}
|
||||
|
||||
void Object::setPlotFlag(bool plot) {
|
||||
_plot = plot;
|
||||
}
|
||||
|
||||
void Object::setCommandable(bool value) {
|
||||
_commandable = value;
|
||||
updateActions(dt);
|
||||
}
|
||||
|
||||
bool Object::getLocalBoolean(int index) const {
|
||||
|
|
|
@ -17,13 +17,17 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include "../actionqueue.h"
|
||||
#include "../../common/timer.h"
|
||||
|
||||
#include "../action/action.h"
|
||||
#include "../types.h"
|
||||
|
||||
namespace reone {
|
||||
|
@ -47,12 +51,11 @@ public:
|
|||
const std::string &blueprintResRef() const { return _blueprintResRef; }
|
||||
const std::string &name() const { return _name; }
|
||||
const std::string &conversation() const { return _conversation; }
|
||||
ActionQueue &actionQueue() { return _actionQueue; }
|
||||
bool plotFlag() const { return _plot; }
|
||||
|
||||
void setTag(std::string tag);
|
||||
void setPlotFlag(bool plot);
|
||||
void setCommandable(bool value);
|
||||
void setTag(std::string tag) { _tag = std::move(tag); }
|
||||
void setPlotFlag(bool plot) { _plot = plot; }
|
||||
void setCommandable(bool commandable) { _commandable = commandable; }
|
||||
|
||||
// Hit Points
|
||||
|
||||
|
@ -65,11 +68,25 @@ public:
|
|||
// Current hit points, not counting any bonuses.
|
||||
int currentHitPoints() const { return _currentHitPoints; }
|
||||
|
||||
void setMinOneHP(bool minOneHP);
|
||||
void setMaxHitPoints(int maxHitPoints);
|
||||
void setMinOneHP(bool minOneHP) { _minOneHP = minOneHP; }
|
||||
void setMaxHitPoints(int maxHitPoints) { _maxHitPoints = maxHitPoints; }
|
||||
|
||||
// END Hit Points
|
||||
|
||||
// Actions
|
||||
|
||||
void addAction(std::unique_ptr<Action> action);
|
||||
void addActionOnTop(std::unique_ptr<Action> action);
|
||||
void delayAction(std::unique_ptr<Action> action, float seconds);
|
||||
|
||||
bool hasUserActionsPending() const;
|
||||
|
||||
std::shared_ptr<Action> getCurrentAction() const;
|
||||
|
||||
const std::deque<std::shared_ptr<Action>> &actions() const { return _actions; }
|
||||
|
||||
// END Actions
|
||||
|
||||
// Local variables
|
||||
|
||||
bool getLocalBoolean(int index) const;
|
||||
|
@ -88,13 +105,17 @@ public:
|
|||
// END Scripts
|
||||
|
||||
protected:
|
||||
struct DelayedAction {
|
||||
std::unique_ptr<Action> action;
|
||||
Timer timer;
|
||||
};
|
||||
|
||||
uint32_t _id { 0 };
|
||||
std::string _tag;
|
||||
ObjectType _type { ObjectType::Invalid };
|
||||
std::string _blueprintResRef;
|
||||
std::string _name;
|
||||
std::string _conversation;
|
||||
ActionQueue _actionQueue;
|
||||
bool _minOneHP { false };
|
||||
int _hitPoints { 0 };
|
||||
int _maxHitPoints { 0 };
|
||||
|
@ -105,6 +126,13 @@ protected:
|
|||
bool _autoRemoveKey { false };
|
||||
bool _interruptable { false };
|
||||
|
||||
// Actions
|
||||
|
||||
std::deque<std::shared_ptr<Action>> _actions;
|
||||
std::vector<DelayedAction> _delayed;
|
||||
|
||||
// END Actions
|
||||
|
||||
// Local variables
|
||||
|
||||
std::map<int, bool> _localBooleans;
|
||||
|
@ -121,6 +149,15 @@ protected:
|
|||
// END Scripts
|
||||
|
||||
Object(uint32_t id, ObjectType type);
|
||||
|
||||
// Actions
|
||||
|
||||
void updateActions(float dt);
|
||||
|
||||
void removeCompletedActions();
|
||||
void updateDelayedActions(float dt);
|
||||
|
||||
// END Actions
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "actionqueue.h"
|
||||
#include "object.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -25,33 +25,33 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
void ActionQueue::clear() {
|
||||
void Object::clearAllActions() {
|
||||
while (!_actions.empty()) {
|
||||
_actions.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
void ActionQueue::add(unique_ptr<Action> action) {
|
||||
void Object::addAction(unique_ptr<Action> action) {
|
||||
_actions.push_back(move(action));
|
||||
}
|
||||
|
||||
void ActionQueue::addToTop(unique_ptr<Action> action) {
|
||||
void Object::addActionOnTop(unique_ptr<Action> action) {
|
||||
_actions.push_front(move(action));
|
||||
}
|
||||
|
||||
void ActionQueue::delay(unique_ptr<Action> action, float seconds) {
|
||||
void Object::delayAction(unique_ptr<Action> action, float seconds) {
|
||||
DelayedAction delayed;
|
||||
delayed.action = move(action);
|
||||
delayed.timer.reset(seconds);
|
||||
_delayed.push_back(move(delayed));
|
||||
}
|
||||
|
||||
void ActionQueue::update(float dt) {
|
||||
void Object::updateActions(float dt) {
|
||||
removeCompletedActions();
|
||||
updateDelayedActions(dt);
|
||||
}
|
||||
|
||||
void ActionQueue::removeCompletedActions() {
|
||||
void Object::removeCompletedActions() {
|
||||
while (true) {
|
||||
shared_ptr<Action> action(getCurrentAction());
|
||||
if (!action || !action->isCompleted()) return;
|
||||
|
@ -60,7 +60,7 @@ void ActionQueue::removeCompletedActions() {
|
|||
}
|
||||
}
|
||||
|
||||
void ActionQueue::updateDelayedActions(float dt) {
|
||||
void Object::updateDelayedActions(float dt) {
|
||||
for (auto &delayed : _delayed) {
|
||||
if (delayed.timer.advance(dt)) {
|
||||
_actions.push_back(move(delayed.action));
|
||||
|
@ -74,23 +74,14 @@ void ActionQueue::updateDelayedActions(float dt) {
|
|||
_delayed.erase(delayedToRemove, _delayed.end());
|
||||
}
|
||||
|
||||
bool ActionQueue::isEmpty() const {
|
||||
return _actions.empty();
|
||||
}
|
||||
|
||||
bool ActionQueue::containsUserActions() const {
|
||||
bool Object::hasUserActionsPending() const {
|
||||
for (auto &action : _actions) {
|
||||
if (action->isUserAction()) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int ActionQueue::getSize() const {
|
||||
return static_cast<int>(_actions.size());
|
||||
}
|
||||
|
||||
shared_ptr<Action> ActionQueue::getCurrentAction() const {
|
||||
shared_ptr<Action> Object::getCurrentAction() const {
|
||||
return _actions.empty() ? nullptr : _actions.front();
|
||||
}
|
||||
|
|
@ -125,7 +125,7 @@ void Party::onLeaderChanged() {
|
|||
_members[0].creature->playSound(entry, false);
|
||||
|
||||
for (auto &member : _members) {
|
||||
member.creature->actionQueue().clear();
|
||||
member.creature->clearAllActions();
|
||||
}
|
||||
|
||||
_game->module()->area()->onPartyLeaderMoved(true);
|
||||
|
|
|
@ -156,18 +156,14 @@ void Player::update(float dt) {
|
|||
movement = false;
|
||||
}
|
||||
|
||||
ActionQueue &actions = partyLeader->actionQueue();
|
||||
|
||||
if (movement) {
|
||||
actions.clear();
|
||||
|
||||
partyLeader->clearAllActions();
|
||||
glm::vec2 dir(glm::normalize(glm::vec2(-glm::sin(facing), glm::cos(facing))));
|
||||
|
||||
if (_area->moveCreature(partyLeader, dir, true, dt)) {
|
||||
partyLeader->setMovementType(Creature::MovementType::Run);
|
||||
partyLeader->setAppliedForce(glm::vec3(dir, 0.0f));
|
||||
}
|
||||
} else if (actions.isEmpty()) {
|
||||
} else if (partyLeader->actions().empty()) {
|
||||
partyLeader->setMovementType(Creature::MovementType::None);
|
||||
partyLeader->setAppliedForce(glm::vec3(0.0f));
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ Variable Routines::delayCommand(const VariablesList &args, ExecutionContext &ctx
|
|||
auto action = getAction(args, 1);
|
||||
|
||||
auto objectAction = make_unique<CommandAction>(move(action));
|
||||
getCaller(ctx)->actionQueue().delay(move(objectAction), seconds);
|
||||
getCaller(ctx)->delayAction(move(objectAction), seconds);
|
||||
|
||||
return Variable();
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ Variable Routines::assignCommand(const VariablesList &args, ExecutionContext &ct
|
|||
|
||||
if (subject) {
|
||||
auto objectAction = make_unique<CommandAction>(move(action));
|
||||
subject->actionQueue().add(move(objectAction));
|
||||
subject->addAction(move(objectAction));
|
||||
} else {
|
||||
debug("Script: assignCommand: subject is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ Variable Routines::actionDoCommand(const VariablesList &args, ExecutionContext &
|
|||
auto action = getAction(args, 0);
|
||||
|
||||
auto commandAction = make_unique<CommandAction>(move(action));
|
||||
getCaller(ctx)->actionQueue().add(move(commandAction));
|
||||
getCaller(ctx)->addAction(move(commandAction));
|
||||
|
||||
return Variable();
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ Variable Routines::actionMoveToObject(const VariablesList &args, ExecutionContex
|
|||
|
||||
if (moveTo) {
|
||||
auto action = make_unique<MoveToObjectAction>(move(moveTo), run, range);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionMoveToObject: moveTo is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ Variable Routines::actionStartConversation(const VariablesList &args, ExecutionC
|
|||
dialogResRef = caller->conversation();
|
||||
}
|
||||
auto action = make_unique<StartConversationAction>(move(objectToConverse), move(dialogResRef), ignoreStartRange);
|
||||
caller->actionQueue().add(move(action));
|
||||
caller->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionStartConversation: objectToConverse is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -111,13 +111,13 @@ Variable Routines::actionStartConversation(const VariablesList &args, ExecutionC
|
|||
|
||||
Variable Routines::actionPauseConversation(const VariablesList &args, ExecutionContext &ctx) {
|
||||
auto action = make_unique<Action>(ActionType::PauseConversation);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
return Variable();
|
||||
}
|
||||
|
||||
Variable Routines::actionResumeConversation(const VariablesList &args, ExecutionContext &ctx) {
|
||||
auto action = make_unique<Action>(ActionType::ResumeConversation);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
return Variable();
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ Variable Routines::actionOpenDoor(const VariablesList &args, ExecutionContext &c
|
|||
auto door = getObject(args, 0, ctx);
|
||||
if (door) {
|
||||
auto action = make_unique<ObjectAction>(ActionType::OpenDoor, door);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionOpenDoor: door is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ Variable Routines::actionCloseDoor(const VariablesList &args, ExecutionContext &
|
|||
auto door = getObject(args, 0, ctx);
|
||||
if (door) {
|
||||
auto action = make_unique<ObjectAction>(ActionType::CloseDoor, door);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionCloseDoor: door is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ Variable Routines::actionJumpToObject(const VariablesList &args, ExecutionContex
|
|||
|
||||
if (jumpTo) {
|
||||
auto action = make_unique<ObjectAction>(ActionType::JumpToObject, move(jumpTo));
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionJumpToObject: jumpTo is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ Variable Routines::actionJumpToLocation(const VariablesList &args, ExecutionCont
|
|||
auto location = getLocationEngineType(args, 0);
|
||||
if (location) {
|
||||
auto action = make_unique<LocationAction>(ActionType::JumpToLocation, move(location));
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionJumpToLocation: location is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ Variable Routines::actionForceMoveToObject(const VariablesList &args, ExecutionC
|
|||
|
||||
if (moveTo) {
|
||||
auto action = make_unique<MoveToObjectAction>(move(moveTo), run, range);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionForceMoveToObject: moveTo is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ Variable Routines::actionForceMoveToLocation(const VariablesList &args, Executio
|
|||
|
||||
if (destination) {
|
||||
auto action = make_unique<MoveToLocationAction>(move(destination));
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionForceMoveToLocation: destination is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ Variable Routines::jumpToObject(const VariablesList &args, ExecutionContext &ctx
|
|||
|
||||
if (jumpTo) {
|
||||
auto action = make_unique<ObjectAction>(ActionType::JumpToObject, move(jumpTo));
|
||||
getCaller(ctx)->actionQueue().addToTop(move(action));
|
||||
getCaller(ctx)->addActionOnTop(move(action));
|
||||
} else {
|
||||
debug("Script: jumpToObject: jumpTo is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ Variable Routines::jumpToLocation(const VariablesList &args, ExecutionContext &c
|
|||
auto destination = getLocationEngineType(args, 0);
|
||||
if (destination) {
|
||||
auto action = make_unique<LocationAction>(ActionType::JumpToLocation, move(destination));
|
||||
getCaller(ctx)->actionQueue().addToTop(move(action));
|
||||
getCaller(ctx)->addActionOnTop(move(action));
|
||||
} else {
|
||||
debug("Script: jumpToLocation: destination is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ Variable Routines::jumpToLocation(const VariablesList &args, ExecutionContext &c
|
|||
|
||||
Variable Routines::actionRandomWalk(const VariablesList &args, ExecutionContext &ctx) {
|
||||
auto action = make_unique<Action>(ActionType::RandomWalk);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
return Variable();
|
||||
}
|
||||
|
||||
|
@ -245,7 +245,7 @@ Variable Routines::actionMoveToLocation(const VariablesList &args, ExecutionCont
|
|||
|
||||
if (destination) {
|
||||
auto action = make_unique<MoveToLocationAction>(move(destination), run);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionMoveToLocation: destination is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -261,7 +261,7 @@ Variable Routines::actionMoveAwayFromObject(const VariablesList &args, Execution
|
|||
|
||||
if (fleeFrom) {
|
||||
auto action = make_unique<Action>(ActionType::MoveAwayFromObject);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionMoveAwayFromObject: fleeFrom is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ Variable Routines::actionEquipItem(const VariablesList &args, ExecutionContext &
|
|||
|
||||
if (item) {
|
||||
auto action = make_unique<Action>(ActionType::EquipItem);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionEquipItem: item is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -292,7 +292,7 @@ Variable Routines::actionUnequipItem(const VariablesList &args, ExecutionContext
|
|||
|
||||
if (item) {
|
||||
auto action = make_unique<Action>(ActionType::UnequipItem);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionUnequipItem: item is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ Variable Routines::actionPickUpItem(const VariablesList &args, ExecutionContext
|
|||
auto item = getItem(args, 0, ctx);
|
||||
if (item) {
|
||||
auto action = make_unique<Action>(ActionType::PickUpItem);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionPickUpItem: item is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ Variable Routines::actionPutDownItem(const VariablesList &args, ExecutionContext
|
|||
auto item = getItem(args, 0, ctx);
|
||||
if (item) {
|
||||
auto action = make_unique<Action>(ActionType::DropItem);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionPutDownItem: item is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -332,7 +332,7 @@ Variable Routines::actionAttack(const VariablesList &args, ExecutionContext &ctx
|
|||
|
||||
if (caller && attackee) {
|
||||
auto action = make_unique<AttackAction>(attackee, caller->getAttackRange());
|
||||
caller->actionQueue().add(move(action));
|
||||
caller->addAction(move(action));
|
||||
} else if (!caller) {
|
||||
debug("Script: actionAttack: caller is invalid", 1, DebugChannels::script);
|
||||
} else if (!attackee) {
|
||||
|
@ -348,7 +348,7 @@ Variable Routines::actionSpeakString(const VariablesList &args, ExecutionContext
|
|||
auto talkVolume = getEnum(args, 1, TalkVolume::Talk);
|
||||
|
||||
auto action = make_unique<Action>(ActionType::SpeakString);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
|
||||
return Variable();
|
||||
}
|
||||
|
@ -359,7 +359,7 @@ Variable Routines::actionPlayAnimation(const VariablesList &args, ExecutionConte
|
|||
float duration = getFloat(args, 2, 0.0f);
|
||||
|
||||
auto action = make_unique<PlayAnimationAction>(animation, speed, duration);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
|
||||
return Variable();
|
||||
}
|
||||
|
@ -375,7 +375,7 @@ Variable Routines::actionCastSpellAtObject(const VariablesList &args, ExecutionC
|
|||
bool instantSpell = getBool(args, 6, false);
|
||||
|
||||
auto action = make_unique<Action>(ActionType::CastSpellAtObject);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
|
||||
return Variable();
|
||||
}
|
||||
|
@ -387,7 +387,7 @@ Variable Routines::actionGiveItem(const VariablesList &args, ExecutionContext &c
|
|||
|
||||
if (item && giveTo) {
|
||||
auto action = make_unique<Action>(ActionType::GiveItem);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else if (!item) {
|
||||
debug("Script: actionGiveItem: item is invalid", 1, DebugChannels::script);
|
||||
} else if (!giveTo) {
|
||||
|
@ -404,7 +404,7 @@ Variable Routines::actionTakeItem(const VariablesList &args, ExecutionContext &c
|
|||
|
||||
if (item && takeFrom) {
|
||||
auto action = make_unique<Action>(ActionType::TakeItem);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else if (!item) {
|
||||
debug("Script: actionTakeItem: item is invalid", 1, DebugChannels::script);
|
||||
} else if (!takeFrom) {
|
||||
|
@ -421,7 +421,7 @@ Variable Routines::actionForceFollowObject(const VariablesList &args, ExecutionC
|
|||
|
||||
if (follow) {
|
||||
auto action = make_unique<Action>(ActionType::ForceFollowObject);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionForceFollowObject: follow is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -433,7 +433,7 @@ Variable Routines::actionWait(const VariablesList &args, ExecutionContext &ctx)
|
|||
float seconds = getFloat(args, 0);
|
||||
|
||||
auto action = make_unique<WaitAction>(seconds);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
|
||||
return Variable();
|
||||
}
|
||||
|
@ -449,7 +449,7 @@ Variable Routines::actionCastSpellAtLocation(const VariablesList &args, Executio
|
|||
|
||||
if (targetLocation) {
|
||||
auto action = make_unique<Action>(ActionType::CastSpellAtLocation);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionCastSpellAtLocation: targetLocation is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -463,7 +463,7 @@ Variable Routines::actionSpeakStringByStrRef(const VariablesList &args, Executio
|
|||
auto talkVolume = getEnum(args, 1, TalkVolume::Talk);
|
||||
|
||||
auto action = make_unique<Action>(ActionType::SpeakStringByStrRef);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
|
||||
return Variable();
|
||||
}
|
||||
|
@ -475,7 +475,7 @@ Variable Routines::actionUseFeat(const VariablesList &args, ExecutionContext &ct
|
|||
|
||||
if (target) {
|
||||
auto action = make_unique<Action>(ActionType::UseFeat);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionUseFeat: target is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -492,7 +492,7 @@ Variable Routines::actionUseSkill(const VariablesList &args, ExecutionContext &c
|
|||
|
||||
if (target) {
|
||||
auto action = make_unique<Action>(ActionType::UseSkill);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionUseSkill: target is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -507,7 +507,7 @@ Variable Routines::actionUseTalentOnObject(const VariablesList &args, ExecutionC
|
|||
|
||||
if (target) {
|
||||
auto action = make_unique<Action>(ActionType::UseTalentOnObject);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionUseTalentOnObject: target is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -522,7 +522,7 @@ Variable Routines::actionUseTalentAtLocation(const VariablesList &args, Executio
|
|||
|
||||
if (targetLocation) {
|
||||
auto action = make_unique<Action>(ActionType::UseTalentAtLocation);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
} else {
|
||||
debug("Script: actionUseTalentAtLocation: targetLocation is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
@ -533,70 +533,70 @@ Variable Routines::actionUseTalentAtLocation(const VariablesList &args, Executio
|
|||
Variable Routines::actionInteractObject(const VariablesList &args, ExecutionContext &ctx) {
|
||||
// TODO: extract and pass all arguments to an action
|
||||
auto action = make_unique<Action>(ActionType::InteractObject);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
return Variable();
|
||||
}
|
||||
|
||||
Variable Routines::actionMoveAwayFromLocation(const VariablesList &args, ExecutionContext &ctx) {
|
||||
// TODO: extract and pass all arguments to an action
|
||||
auto action = make_unique<Action>(ActionType::MoveAwayFromLocation);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
return Variable();
|
||||
}
|
||||
|
||||
Variable Routines::actionSurrenderToEnemies(const VariablesList &args, ExecutionContext &ctx) {
|
||||
// TODO: extract and pass all arguments to an action
|
||||
auto action = make_unique<Action>(ActionType::SurrenderToEnemies);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
return Variable();
|
||||
}
|
||||
|
||||
Variable Routines::actionEquipMostDamagingMelee(const VariablesList &args, ExecutionContext &ctx) {
|
||||
// TODO: extract and pass all arguments to an action
|
||||
auto action = make_unique<Action>(ActionType::EquipMostDamagingMelee);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
return Variable();
|
||||
}
|
||||
|
||||
Variable Routines::actionEquipMostDamagingRanged(const VariablesList &args, ExecutionContext &ctx) {
|
||||
// TODO: extract and pass all arguments to an action
|
||||
auto action = make_unique<Action>(ActionType::EquipMostDamagingRanged);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
return Variable();
|
||||
}
|
||||
|
||||
Variable Routines::actionEquipMostEffectiveArmor(const VariablesList &args, ExecutionContext &ctx) {
|
||||
// TODO: extract and pass all arguments to an action
|
||||
auto action = make_unique<Action>(ActionType::EquipMostEffectiveArmor);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
return Variable();
|
||||
}
|
||||
|
||||
Variable Routines::actionUnlockObject(const VariablesList &args, ExecutionContext &ctx) {
|
||||
// TODO: extract and pass all arguments to an action
|
||||
auto action = make_unique<Action>(ActionType::UnlockObject);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
return Variable();
|
||||
}
|
||||
|
||||
Variable Routines::actionLockObject(const VariablesList &args, ExecutionContext &ctx) {
|
||||
// TODO: extract and pass all arguments to an action
|
||||
auto action = make_unique<Action>(ActionType::LockObject);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
return Variable();
|
||||
}
|
||||
|
||||
Variable Routines::actionCastFakeSpellAtObject(const VariablesList &args, ExecutionContext &ctx) {
|
||||
// TODO: extract and pass all arguments to an action
|
||||
auto action = make_unique<Action>(ActionType::CastFakeSpellAtObject);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
return Variable();
|
||||
}
|
||||
|
||||
Variable Routines::actionCastFakeSpellAtLocation(const VariablesList &args, ExecutionContext &ctx) {
|
||||
// TODO: extract and pass all arguments to an action
|
||||
auto action = make_unique<Action>(ActionType::CastFakeSpellAtLocation);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
return Variable();
|
||||
}
|
||||
|
||||
|
@ -605,14 +605,14 @@ Variable Routines::actionBarkString(const VariablesList &args, ExecutionContext
|
|||
int strRef = getInt(args, 0);
|
||||
|
||||
auto action = make_unique<Action>(ActionType::BarkString);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
|
||||
return Variable();
|
||||
}
|
||||
|
||||
Variable Routines::actionFollowLeader(const VariablesList &args, ExecutionContext &ctx) {
|
||||
auto action = make_unique<Action>(ActionType::FollowLeader);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
return Variable();
|
||||
}
|
||||
|
||||
|
@ -621,20 +621,20 @@ Variable Routines::actionFollowOwner(const VariablesList &args, ExecutionContext
|
|||
float range = getFloat(args, 0, 2.5f);
|
||||
|
||||
auto action = make_unique<Action>(ActionType::FollowOwner);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
|
||||
return Variable();
|
||||
}
|
||||
|
||||
Variable Routines::actionSwitchWeapons(const VariablesList &args, ExecutionContext &ctx) {
|
||||
auto action = make_unique<Action>(ActionType::SwitchWeapons);
|
||||
getCaller(ctx)->actionQueue().add(move(action));
|
||||
getCaller(ctx)->addAction(move(action));
|
||||
return Variable();
|
||||
}
|
||||
|
||||
Variable Routines::getCurrentAction(const VariablesList &args, ExecutionContext &ctx) {
|
||||
auto object = getObjectOrCaller(args, 0, ctx);
|
||||
shared_ptr<Action> action(object->actionQueue().getCurrentAction());
|
||||
shared_ptr<Action> action(object->getCurrentAction());
|
||||
return Variable::ofInt(static_cast<int>(action ? action->type() : ActionType::QueueEmpty));
|
||||
}
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ Variable Routines::getUserActionsPending(const VariablesList &args, ExecutionCon
|
|||
|
||||
auto caller = getCallerAsCreature(ctx);
|
||||
if (caller) {
|
||||
result = caller->actionQueue().containsUserActions();
|
||||
result = caller->hasUserActionsPending();
|
||||
} else {
|
||||
debug("Script: getUserActionsPending: caller is invalid", 1, DebugChannels::script);
|
||||
}
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2021 The reone project contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE actionqueue
|
||||
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
|
||||
#include "../engine/game/actionqueue.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone::game;
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_action_completion) {
|
||||
ActionQueue actionQueue;
|
||||
actionQueue.add(make_unique<Action>(ActionType::PauseConversation));
|
||||
actionQueue.add(make_unique<Action>(ActionType::ResumeConversation));
|
||||
|
||||
shared_ptr<Action> currentAction(actionQueue.getCurrentAction());
|
||||
BOOST_TEST((currentAction && currentAction->type() == ActionType::PauseConversation));
|
||||
|
||||
currentAction->complete();
|
||||
actionQueue.update(0.0f);
|
||||
|
||||
currentAction = actionQueue.getCurrentAction();
|
||||
BOOST_TEST((currentAction && currentAction->type() == ActionType::ResumeConversation));
|
||||
|
||||
currentAction->complete();
|
||||
actionQueue.update(0.0f);
|
||||
|
||||
currentAction = actionQueue.getCurrentAction();
|
||||
BOOST_TEST(!currentAction);
|
||||
}
|
Loading…
Reference in a new issue