Fix refreshing the combat action queue, deactivate with delay

This commit is contained in:
Vsevolod Kremianskii 2021-03-29 20:03:43 +07:00
parent c94432e1ae
commit 2730abb00b
7 changed files with 36 additions and 17 deletions

View file

@ -34,10 +34,6 @@ bool Timer::advance(float secs) {
return isTimedOut();
}
bool Timer::isTimedOut() const {
return _time == 0.0f;
}
void Timer::cancel() {
_time = 0.0f;
}

View file

@ -41,7 +41,8 @@ public:
*/
void cancel();
bool isTimedOut() const;
bool isSet() const { return _time > 0.0f; }
bool isTimedOut() const { return _time == 0.0f; }
private:
float _time { 0.0f };

View file

@ -186,17 +186,20 @@ void ActionExecutor::executeStartConversation(const shared_ptr<Object> &actor, S
}
void ActionExecutor::executeAttack(const shared_ptr<Object> &actor, shared_ptr<AttackAction> action, float dt) {
// If target is dead, complete the action
shared_ptr<SpatialObject> target(action->target());
if (target->isDead()) {
action->complete();
return;
}
// Otherwise, put the actor in combat state
auto creature = static_pointer_cast<Creature>(actor);
creature->setInCombat(true);
// Make the actor follow its target. When reached, register an attack
if (navigateCreature(creature, target->position(), true, action->range(), dt)) {
_game->combat().addAttack(creature, target, move(action));
_game->combat().addAttack(move(creature), move(target), action);
}
}

View file

@ -33,6 +33,7 @@ namespace game {
static constexpr float kRoundDuration = 3.0f;
static constexpr float kProjectileDelay = 0.5f;
static constexpr float kDeactivateDelay = 8.0f;
Combat::Combat(Game *game) : _game(game) {
if (!game) {
@ -163,7 +164,7 @@ void Combat::startAttack(Attack &attack, bool duel) {
}
static void finishAttack(Combat::Attack &attack) {
attack.attacker->setInCombat(false);
attack.attacker->deactivateCombat(kDeactivateDelay);
attack.attacker->setMovementRestricted(false);
attack.attacker->runEndRoundScript();
if (attack.action) {

View file

@ -291,15 +291,12 @@ void HUD::hideCombatHud() {
}
void HUD::refreshActionQueueItems() const {
int i = 0;
for (auto &action : _game->party().getLeader()->actionQueue().actions()) {
if (action->type() != ActionType::AttackObject) continue;
auto actions = _game->party().getLeader()->actionQueue().actions();
for (int i = 0; i < 4; ++i) {
bool attack = i < static_cast<int>(actions.size()) && actions[i]->type() == ActionType::AttackObject;
Control &item = getControl("LBL_QUEUE" + to_string(i));
item.setBorderFill("i_attack");
if (++i == 4) break;
item.setBorderFill(attack ? "i_attack" : "");
}
}

View file

@ -181,6 +181,7 @@ void Creature::update(float dt) {
SpatialObject::update(dt);
updateModelAnimation();
updateHealth();
updateCombat(dt);
}
void Creature::updateModelAnimation() {
@ -248,6 +249,13 @@ void Creature::updateHealth() {
die();
}
void Creature::updateCombat(float dt) {
if (_combat._deactivationTimer.isSet() && _combat._deactivationTimer.advance(dt)) {
_combat.reset();
_inCombat = false;
}
}
void Creature::clearAllActions() {
SpatialObject::clearAllActions();
setMovementType(MovementType::None);
@ -598,7 +606,7 @@ void Creature::onObjectVanished(const shared_ptr<SpatialObject> &object) {
}
void Creature::onObjectHeard(const shared_ptr<SpatialObject> &object) {
_perception.heard.insert(move(object));
_perception.heard.insert(object);
_perception.lastPerception = PerceptionType::Heard;
_perception.lastPerceived = object;
runOnNoticeScript();
@ -611,6 +619,10 @@ void Creature::onObjectInaudible(const shared_ptr<SpatialObject> &object) {
runOnNoticeScript();
}
void Creature::deactivateCombat(float delay) {
_combat._deactivationTimer.reset(delay);
}
} // namespace game
} // namespace reone

View file

@ -97,6 +97,8 @@ public:
ActionType lastAttackAction { ActionType::Invalid };
bool debilitated { false };
Timer _deactivationTimer;
void reset();
};
@ -153,8 +155,6 @@ public:
// Animation
// END Animation
void playAnimation(AnimationType type, scene::AnimationProperties properties = scene::AnimationProperties(), std::shared_ptr<PlayAnimationAction> actionToComplete = nullptr) override;
void playAnimation(CombatAnimation anim, CreatureWieldType wield, int variant = 1);
@ -163,6 +163,8 @@ public:
void updateModelAnimation();
// END Animation
// Equipment
bool equip(const std::string &resRef);
@ -198,6 +200,12 @@ public:
// END Perception
// Combat
void deactivateCombat(float delay);
// END Combat
// Scripts
void runSpawnScript();
@ -252,6 +260,7 @@ private:
void updateModel();
void updateHealth();
void updateCombat(float dt);
inline void runDeathScript();
inline void runOnNoticeScript();