refactor: Extract creature animation handling into a separate class
This commit is contained in:
parent
798eb3f809
commit
0fcb37f45f
12 changed files with 377 additions and 196 deletions
|
@ -404,6 +404,8 @@ set(GAME_HEADERS
|
|||
src/game/object/area.h
|
||||
src/game/object/camera.h
|
||||
src/game/object/creature.h
|
||||
src/game/object/creatureanimresolver.h
|
||||
src/game/object/creaturemodelbuilder.h
|
||||
src/game/object/door.h
|
||||
src/game/object/item.h
|
||||
src/game/object/module.h
|
||||
|
@ -492,6 +494,8 @@ set(GAME_SOURCES
|
|||
src/game/object/area.cpp
|
||||
src/game/object/camera.cpp
|
||||
src/game/object/creature.cpp
|
||||
src/game/object/creatureanimresolver.cpp
|
||||
src/game/object/creaturemodelbuilder.cpp
|
||||
src/game/object/door.cpp
|
||||
src/game/object/item.cpp
|
||||
src/game/object/module.cpp
|
||||
|
|
|
@ -105,7 +105,7 @@ void Combat::updateCombatantAI(Combatant &combatant) {
|
|||
|
||||
ActionQueue &actions = creature->actionQueue();
|
||||
actions.clear();
|
||||
actions.add(make_unique<AttackAction>(enemy, creature->attackRange()));
|
||||
actions.add(make_unique<AttackAction>(enemy, creature->getAttackRange()));
|
||||
|
||||
debug(boost::format("Combat: attack action added: '%s' -> '%s'") % creature->tag() % enemy->tag(), 2);
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ bool SelectionOverlay::handleMouseButtonDown(const SDL_MouseButtonEvent &event)
|
|||
shared_ptr<Creature> partyLeader(_game->party().leader());
|
||||
ActionQueue &actions = partyLeader->actionQueue();
|
||||
actions.add(make_unique<AttackAction>(static_pointer_cast<Creature>(object),
|
||||
partyLeader->attackRange()));
|
||||
partyLeader->getAttackRange()));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -648,7 +648,7 @@ void Area::fill(SceneGraph &sceneGraph) {
|
|||
glm::vec3 Area::getSelectableScreenCoords(const shared_ptr<SpatialObject> &object, const glm::mat4 &projection, const glm::mat4 &view) const {
|
||||
static glm::vec4 viewport(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
|
||||
glm::vec3 position(object->selectablePosition());
|
||||
glm::vec3 position(object->getSelectablePosition());
|
||||
|
||||
return glm::project(position, view, projection, viewport);
|
||||
}
|
||||
|
|
|
@ -49,30 +49,24 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
static string g_animPauseCreature("cpause1");
|
||||
static string g_animPauseCharacter("pause1");
|
||||
static string g_animWalkCreature("cwalk");
|
||||
static string g_animWalkCharacter("walk");
|
||||
static string g_animRunCreature("crun");
|
||||
static string g_animRunCharacter("run");
|
||||
static string g_animTalkHead("talk");
|
||||
static string g_animTalkBody("tlknorm");
|
||||
static string g_animGreeting("greeting");
|
||||
static string g_animUnlockDoor("unlockdr");
|
||||
|
||||
static string g_headHookNode("headhook");
|
||||
static string g_talkDummyNode("talkdummy");
|
||||
|
||||
Creature::Creature(uint32_t id, ObjectFactory *objectFactory, SceneGraph *sceneGraph) :
|
||||
SpatialObject(id, ObjectType::Creature, sceneGraph), _objectFactory(objectFactory) {
|
||||
SpatialObject(id, ObjectType::Creature, sceneGraph),
|
||||
_objectFactory(objectFactory),
|
||||
_animResolver(this) {
|
||||
|
||||
_drawDistance = 2048.0f;
|
||||
_selectable = true;
|
||||
}
|
||||
|
||||
void Creature::load(const GffStruct &gffs) {
|
||||
loadTransform(gffs);
|
||||
loadBlueprint(gffs);
|
||||
}
|
||||
|
||||
void Creature::loadTransform(const GffStruct &gffs) {
|
||||
_position[0] = gffs.getFloat("XPosition");
|
||||
_position[1] = gffs.getFloat("YPosition");
|
||||
_position[2] = gffs.getFloat("ZPosition");
|
||||
|
@ -310,19 +304,19 @@ void Creature::updateModelAnimation() {
|
|||
|
||||
switch (_movementType) {
|
||||
case MovementType::Run:
|
||||
_model->playAnimation(getRunAnimation(), kAnimationLoop | kAnimationPropagate | kAnimationBlend);
|
||||
_model->playAnimation(_animResolver.getRunAnimation(), kAnimationLoop | kAnimationPropagate | kAnimationBlend);
|
||||
break;
|
||||
case MovementType::Walk:
|
||||
_model->playAnimation(getWalkAnimation(), kAnimationLoop | kAnimationPropagate | kAnimationBlend);
|
||||
_model->playAnimation(_animResolver.getWalkAnimation(), kAnimationLoop | kAnimationPropagate | kAnimationBlend);
|
||||
break;
|
||||
default:
|
||||
if (_talking) {
|
||||
_model->playAnimation(g_animTalkBody, kAnimationLoop | kAnimationPropagate);
|
||||
_model->playAnimation(_animResolver.getTalkAnimation(), kAnimationLoop | kAnimationPropagate);
|
||||
if (_headModel) {
|
||||
_headModel->playAnimation(g_animTalkHead, kAnimationLoop | kAnimationOverlay, 0.25f);
|
||||
_headModel->playAnimation(_animResolver.getHeadTalkAnimation(), kAnimationLoop | kAnimationOverlay, 0.25f);
|
||||
}
|
||||
} else {
|
||||
_model->playAnimation(getPauseAnimation(), kAnimationLoop | kAnimationPropagate | kAnimationBlend);
|
||||
_model->playAnimation(_animResolver.getPauseAnimation(), kAnimationLoop | kAnimationPropagate | kAnimationBlend);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -341,19 +335,19 @@ void Creature::playAnimation(Animation anim) {
|
|||
string animName;
|
||||
switch (anim) {
|
||||
case Animation::UnlockDoor:
|
||||
animName = g_animUnlockDoor;
|
||||
animName = _animResolver.getUnlockDoorAnimation();
|
||||
break;
|
||||
case Animation::DuelAttack:
|
||||
animName = getDuelAttackAnimation();
|
||||
animName = _animResolver.getDuelAttackAnimation();
|
||||
break;
|
||||
case Animation::BashAttack:
|
||||
animName = getBashAttackAnimation();
|
||||
animName = _animResolver.getBashAttackAnimation();
|
||||
break;
|
||||
case Animation::Dodge:
|
||||
animName = getDodgeAnimation();
|
||||
animName = _animResolver.getDodgeAnimation();
|
||||
break;
|
||||
case Animation::Knockdown:
|
||||
animName = getKnockdownAnimation();
|
||||
animName = _animResolver.getKnockdownAnimation();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -424,146 +418,6 @@ void Creature::setTalking(bool talking) {
|
|||
_animDirty = true;
|
||||
}
|
||||
|
||||
string Creature::getPauseAnimation() const {
|
||||
if (_modelType == ModelType::Creature) {
|
||||
return g_animPauseCreature;
|
||||
}
|
||||
|
||||
// TODO: if (_lowHP) return "pauseinj"
|
||||
|
||||
if (_inCombat) {
|
||||
WeaponType type = WeaponType::None;
|
||||
WeaponWield wield = WeaponWield::None;
|
||||
getWeaponInfo(type, wield);
|
||||
|
||||
int wieldNumber = getWeaponWieldNumber(wield);
|
||||
return str(boost::format("g%dr1") % wieldNumber);
|
||||
}
|
||||
|
||||
return g_animPauseCharacter;
|
||||
}
|
||||
|
||||
const string &Creature::getWalkAnimation() const {
|
||||
switch (_modelType) {
|
||||
case ModelType::Creature:
|
||||
return g_animWalkCreature;
|
||||
default:
|
||||
return g_animWalkCharacter;
|
||||
}
|
||||
}
|
||||
|
||||
string Creature::getRunAnimation() const {
|
||||
if (_modelType == ModelType::Creature) {
|
||||
return g_animRunCreature;
|
||||
}
|
||||
|
||||
// TODO: if (_lowHP) return "runinj"
|
||||
|
||||
if (_inCombat) {
|
||||
WeaponType type = WeaponType::None;
|
||||
WeaponWield wield = WeaponWield::None;
|
||||
getWeaponInfo(type, wield);
|
||||
|
||||
switch (wield) {
|
||||
case WeaponWield::SingleSaber:
|
||||
return isSlotEquipped(kInventorySlotLeftWeapon) ? "runds" : "runss";
|
||||
case WeaponWield::TwoHandedSaber:
|
||||
return "runst";
|
||||
case WeaponWield::Rifle:
|
||||
case WeaponWield::HeavyCarbine:
|
||||
return "runrf";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return g_animRunCharacter;
|
||||
}
|
||||
|
||||
string Creature::getDuelAttackAnimation() const {
|
||||
if (_modelType == ModelType::Creature) return "g0a1";
|
||||
|
||||
WeaponType type = WeaponType::None;
|
||||
WeaponWield wield = WeaponWield::None;
|
||||
getWeaponInfo(type, wield);
|
||||
|
||||
int wieldNumber = getWeaponWieldNumber(wield);
|
||||
|
||||
switch (type) {
|
||||
case WeaponType::Melee:
|
||||
return str(boost::format("c%da1") % wieldNumber);
|
||||
case WeaponType::Ranged:
|
||||
return str(boost::format("b%da1") % wieldNumber);
|
||||
default:
|
||||
return str(boost::format("g%da1") % wieldNumber);
|
||||
}
|
||||
}
|
||||
|
||||
bool Creature::getWeaponInfo(WeaponType &type, WeaponWield &wield) const {
|
||||
shared_ptr<Item> item(getEquippedItem(kInventorySlotRightWeapon));
|
||||
if (item) {
|
||||
type = item->weaponType();
|
||||
wield = item->weaponWield();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int Creature::getWeaponWieldNumber(WeaponWield wield) const {
|
||||
switch (wield) {
|
||||
case WeaponWield::StunBaton:
|
||||
return 1;
|
||||
case WeaponWield::SingleSaber:
|
||||
return isSlotEquipped(kInventorySlotLeftWeapon) ? 4 : 2;
|
||||
case WeaponWield::TwoHandedSaber:
|
||||
return 3;
|
||||
case WeaponWield::SingleBlaster:
|
||||
return isSlotEquipped(kInventorySlotLeftWeapon) ? 6 : 5;
|
||||
case WeaponWield::Rifle:
|
||||
return 7;
|
||||
case WeaponWield::HeavyCarbine:
|
||||
return 9;
|
||||
default:
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
|
||||
string Creature::getBashAttackAnimation() const {
|
||||
if (_modelType == ModelType::Creature) return "g0a2";
|
||||
|
||||
WeaponType type = WeaponType::None;
|
||||
WeaponWield wield = WeaponWield::None;
|
||||
getWeaponInfo(type, wield);
|
||||
|
||||
int wieldNumber = getWeaponWieldNumber(wield);
|
||||
|
||||
switch (type) {
|
||||
case WeaponType::Melee:
|
||||
return str(boost::format("c%da2") % wieldNumber);
|
||||
case WeaponType::Ranged:
|
||||
return str(boost::format("b%da2") % wieldNumber);
|
||||
default:
|
||||
return str(boost::format("g%da2") % wieldNumber);
|
||||
}
|
||||
}
|
||||
|
||||
string Creature::getDodgeAnimation() const {
|
||||
if (_modelType == ModelType::Creature) return "cdodgeg";
|
||||
|
||||
WeaponType type = WeaponType::None;
|
||||
WeaponWield wield = WeaponWield::None;
|
||||
getWeaponInfo(type, wield);
|
||||
|
||||
int wieldNumber = getWeaponWieldNumber(wield);
|
||||
|
||||
return str(boost::format("g%dg1") % wieldNumber);
|
||||
}
|
||||
|
||||
string Creature::getKnockdownAnimation() const {
|
||||
return _modelType == ModelType::Creature ? "ckdbck" : "g1y1";
|
||||
}
|
||||
|
||||
void Creature::setPath(const glm::vec3 &dest, vector<glm::vec3> &&points, uint32_t timeFound) {
|
||||
int pointIdx = 0;
|
||||
if (_path) {
|
||||
|
@ -612,6 +466,10 @@ Gender Creature::gender() const {
|
|||
return _config.gender;
|
||||
}
|
||||
|
||||
Creature::ModelType Creature::modelType() const {
|
||||
return _modelType;
|
||||
}
|
||||
|
||||
int Creature::appearance() const {
|
||||
return _config.appearance;
|
||||
}
|
||||
|
@ -640,7 +498,7 @@ CreatureAttributes &Creature::attributes() {
|
|||
return _attributes;
|
||||
}
|
||||
|
||||
glm::vec3 Creature::selectablePosition() const {
|
||||
glm::vec3 Creature::getSelectablePosition() const {
|
||||
glm::vec3 position;
|
||||
|
||||
if (_model->getNodeAbsolutePosition(g_talkDummyNode, position)) {
|
||||
|
@ -654,7 +512,7 @@ Faction Creature::faction() const {
|
|||
return _faction;
|
||||
}
|
||||
|
||||
float Creature::attackRange() const {
|
||||
float Creature::getAttackRange() const {
|
||||
float result = kDefaultAttackRange;
|
||||
|
||||
shared_ptr<Item> item(getEquippedItem(kInventorySlotRightWeapon));
|
||||
|
@ -673,10 +531,18 @@ bool Creature::isMovementRestricted() const {
|
|||
return _movementRestricted;
|
||||
}
|
||||
|
||||
bool Creature::isInCombat() const {
|
||||
return _inCombat;
|
||||
}
|
||||
|
||||
void Creature::setMovementRestricted(bool restricted) {
|
||||
_movementRestricted = restricted;
|
||||
}
|
||||
|
||||
void Creature::setInCombat(bool active) {
|
||||
_inCombat = active;
|
||||
}
|
||||
|
||||
void Creature::setOnSpawn(const string &onSpawn) {
|
||||
_onSpawn = onSpawn;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "../enginetype/effect.h"
|
||||
#include "../rp/attributes.h"
|
||||
|
||||
#include "creatureanimresolver.h"
|
||||
#include "item.h"
|
||||
#include "spatial.h"
|
||||
|
||||
|
@ -51,6 +52,12 @@ enum class CombatState {
|
|||
|
||||
class Creature : public SpatialObject {
|
||||
public:
|
||||
enum class ModelType {
|
||||
Creature,
|
||||
Droid,
|
||||
Character
|
||||
};
|
||||
|
||||
enum class MovementType {
|
||||
None,
|
||||
Walk,
|
||||
|
@ -77,7 +84,7 @@ public:
|
|||
void update(float dt) override;
|
||||
void clearAllActions() override;
|
||||
|
||||
glm::vec3 selectablePosition() const override;
|
||||
glm::vec3 getSelectablePosition() const override;
|
||||
|
||||
void load(const resource::GffStruct &gffs);
|
||||
void load(const std::shared_ptr<CreatureBlueprint> &blueprint);
|
||||
|
@ -85,26 +92,28 @@ public:
|
|||
|
||||
void playAnimation(Animation anim);
|
||||
void updateModelAnimation();
|
||||
|
||||
void applyEffect(std::unique_ptr<Effect> &&eff);
|
||||
|
||||
bool isMovementRestricted() const;
|
||||
bool isInCombat() const;
|
||||
|
||||
float getAttackRange() const;
|
||||
|
||||
const std::string &blueprintResRef() const;
|
||||
Gender gender() const;
|
||||
ModelType modelType() const;
|
||||
int appearance() const;
|
||||
std::shared_ptr<render::Texture> portrait() const;
|
||||
float walkSpeed() const;
|
||||
float runSpeed() const;
|
||||
CreatureAttributes &attributes();
|
||||
Faction faction() const;
|
||||
float attackRange() const;
|
||||
|
||||
void setMovementType(MovementType type);
|
||||
void setTalking(bool talking);
|
||||
void setFaction(Faction faction);
|
||||
void setMovementRestricted(bool restricted);
|
||||
void setInCombat(bool active) { _inCombat = active; }
|
||||
void setInCombat(bool active);
|
||||
void setOnSpawn(const std::string &onSpawn);
|
||||
void setOnUserDefined(const std::string &onUserDefined);
|
||||
|
||||
|
@ -114,29 +123,24 @@ public:
|
|||
void equip(InventorySlot slot, const std::shared_ptr<Item> &item);
|
||||
void unequip(const std::shared_ptr<Item> &item);
|
||||
|
||||
std::shared_ptr<Item> getEquippedItem(InventorySlot slot) const;
|
||||
bool isSlotEquipped(InventorySlot slot) const;
|
||||
|
||||
std::shared_ptr<Item> getEquippedItem(InventorySlot slot) const;
|
||||
|
||||
const std::map<InventorySlot, std::shared_ptr<Item>> &equipment() const;
|
||||
|
||||
// END Equipment
|
||||
|
||||
// Pathfinding
|
||||
|
||||
std::shared_ptr<Path> &path();
|
||||
|
||||
void setPath(const glm::vec3 &dest, std::vector<glm::vec3> &&points, uint32_t timeFound);
|
||||
void clearPath();
|
||||
|
||||
std::shared_ptr<Path> &path();
|
||||
|
||||
// END Pathfinding
|
||||
|
||||
private:
|
||||
enum class ModelType {
|
||||
Creature,
|
||||
Droid,
|
||||
Character
|
||||
};
|
||||
|
||||
ObjectFactory *_objectFactory { nullptr };
|
||||
CreatureConfiguration _config;
|
||||
std::string _blueprintResRef;
|
||||
|
@ -158,6 +162,7 @@ private:
|
|||
bool _movementRestricted { false };
|
||||
bool _inCombat { false };
|
||||
int _portraitId { 0 };
|
||||
CreatureAnimationResolver _animResolver;
|
||||
|
||||
// Scripts
|
||||
|
||||
|
@ -165,29 +170,19 @@ private:
|
|||
|
||||
// END Scripts
|
||||
|
||||
void loadTransform(const resource::GffStruct &gffs);
|
||||
void loadBlueprint(const resource::GffStruct &gffs);
|
||||
void loadAppearance(const resource::TwoDaTable &table, int row);
|
||||
void loadPortrait(int appearance);
|
||||
void updateModel();
|
||||
|
||||
ModelType parseModelType(const std::string &s) const;
|
||||
bool getWeaponInfo(WeaponType &type, WeaponWield &wield) const;
|
||||
int getWeaponWieldNumber(WeaponWield wield) const;
|
||||
|
||||
std::string getBodyModelName() const;
|
||||
std::string getBodyTextureName() const;
|
||||
std::string getHeadModelName() const;
|
||||
std::string getWeaponModelName(InventorySlot slot) const;
|
||||
|
||||
std::string getPauseAnimation() const;
|
||||
std::string getRunAnimation() const;
|
||||
const std::string &getWalkAnimation() const;
|
||||
|
||||
std::string getDuelAttackAnimation() const;
|
||||
std::string getBashAttackAnimation() const;
|
||||
std::string getDodgeAnimation() const;
|
||||
std::string getKnockdownAnimation() const;
|
||||
|
||||
friend class CreatureBlueprint;
|
||||
};
|
||||
|
||||
|
|
203
src/game/object/creatureanimresolver.cpp
Normal file
203
src/game/object/creatureanimresolver.cpp
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* Copyright (c) 2020 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/>.
|
||||
*/
|
||||
|
||||
#include "creatureanimresolver.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include "creature.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
static string g_animPauseCreature("cpause1");
|
||||
static string g_animPauseCharacter("pause1");
|
||||
static string g_animWalkCreature("cwalk");
|
||||
static string g_animWalkCharacter("walk");
|
||||
static string g_animRunCreature("crun");
|
||||
static string g_animRunCharacter("run");
|
||||
static string g_animTalkHead("talk");
|
||||
static string g_animTalkBody("tlknorm");
|
||||
static string g_animGreeting("greeting");
|
||||
static string g_animUnlockDoor("unlockdr");
|
||||
|
||||
CreatureAnimationResolver::CreatureAnimationResolver(const Creature *creature) : _creature(creature) {
|
||||
if (!creature) {
|
||||
throw invalid_argument("creature must not be null");
|
||||
}
|
||||
}
|
||||
|
||||
string CreatureAnimationResolver::getPauseAnimation() const {
|
||||
if (_creature->modelType() == Creature::ModelType::Creature) {
|
||||
return g_animPauseCreature;
|
||||
}
|
||||
|
||||
// TODO: if (_lowHP) return "pauseinj"
|
||||
|
||||
if (_creature->isInCombat()) {
|
||||
WeaponType type = WeaponType::None;
|
||||
WeaponWield wield = WeaponWield::None;
|
||||
getWeaponInfo(type, wield);
|
||||
|
||||
int wieldNumber = getWeaponWieldNumber(wield);
|
||||
return str(boost::format("g%dr1") % wieldNumber);
|
||||
}
|
||||
|
||||
return g_animPauseCharacter;
|
||||
}
|
||||
|
||||
bool CreatureAnimationResolver::getWeaponInfo(WeaponType &type, WeaponWield &wield) const {
|
||||
shared_ptr<Item> item(_creature->getEquippedItem(kInventorySlotRightWeapon));
|
||||
if (item) {
|
||||
type = item->weaponType();
|
||||
wield = item->weaponWield();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int CreatureAnimationResolver::getWeaponWieldNumber(WeaponWield wield) const {
|
||||
switch (wield) {
|
||||
case WeaponWield::StunBaton:
|
||||
return 1;
|
||||
case WeaponWield::SingleSaber:
|
||||
return _creature->isSlotEquipped(kInventorySlotLeftWeapon) ? 4 : 2;
|
||||
case WeaponWield::TwoHandedSaber:
|
||||
return 3;
|
||||
case WeaponWield::SingleBlaster:
|
||||
return _creature->isSlotEquipped(kInventorySlotLeftWeapon) ? 6 : 5;
|
||||
case WeaponWield::Rifle:
|
||||
return 7;
|
||||
case WeaponWield::HeavyCarbine:
|
||||
return 9;
|
||||
default:
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
|
||||
string CreatureAnimationResolver::getWalkAnimation() const {
|
||||
switch (_creature->modelType()) {
|
||||
case Creature::ModelType::Creature:
|
||||
return g_animWalkCreature;
|
||||
default:
|
||||
return g_animWalkCharacter;
|
||||
}
|
||||
}
|
||||
|
||||
string CreatureAnimationResolver::getRunAnimation() const {
|
||||
if (_creature->modelType() == Creature::ModelType::Creature) {
|
||||
return g_animRunCreature;
|
||||
}
|
||||
|
||||
// TODO: if (_lowHP) return "runinj"
|
||||
|
||||
if (_creature->isInCombat()) {
|
||||
WeaponType type = WeaponType::None;
|
||||
WeaponWield wield = WeaponWield::None;
|
||||
getWeaponInfo(type, wield);
|
||||
|
||||
switch (wield) {
|
||||
case WeaponWield::SingleSaber:
|
||||
return _creature->isSlotEquipped(kInventorySlotLeftWeapon) ? "runds" : "runss";
|
||||
case WeaponWield::TwoHandedSaber:
|
||||
return "runst";
|
||||
case WeaponWield::Rifle:
|
||||
case WeaponWield::HeavyCarbine:
|
||||
return "runrf";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return g_animRunCharacter;
|
||||
}
|
||||
|
||||
string CreatureAnimationResolver::getUnlockDoorAnimation() const {
|
||||
return g_animUnlockDoor;
|
||||
}
|
||||
|
||||
string CreatureAnimationResolver::getTalkAnimation() const {
|
||||
return g_animTalkBody;
|
||||
}
|
||||
|
||||
string CreatureAnimationResolver::getHeadTalkAnimation() const {
|
||||
return g_animTalkHead;
|
||||
}
|
||||
|
||||
string CreatureAnimationResolver::getDuelAttackAnimation() const {
|
||||
if (_creature->modelType() == Creature::ModelType::Creature) return "g0a1";
|
||||
|
||||
WeaponType type = WeaponType::None;
|
||||
WeaponWield wield = WeaponWield::None;
|
||||
getWeaponInfo(type, wield);
|
||||
|
||||
int wieldNumber = getWeaponWieldNumber(wield);
|
||||
|
||||
switch (type) {
|
||||
case WeaponType::Melee:
|
||||
return str(boost::format("c%da1") % wieldNumber);
|
||||
case WeaponType::Ranged:
|
||||
return str(boost::format("b%da1") % wieldNumber);
|
||||
default:
|
||||
return str(boost::format("g%da1") % wieldNumber);
|
||||
}
|
||||
}
|
||||
|
||||
string CreatureAnimationResolver::getBashAttackAnimation() const {
|
||||
if (_creature->modelType() == Creature::ModelType::Creature) return "g0a2";
|
||||
|
||||
WeaponType type = WeaponType::None;
|
||||
WeaponWield wield = WeaponWield::None;
|
||||
getWeaponInfo(type, wield);
|
||||
|
||||
int wieldNumber = getWeaponWieldNumber(wield);
|
||||
|
||||
switch (type) {
|
||||
case WeaponType::Melee:
|
||||
return str(boost::format("c%da2") % wieldNumber);
|
||||
case WeaponType::Ranged:
|
||||
return str(boost::format("b%da2") % wieldNumber);
|
||||
default:
|
||||
return str(boost::format("g%da2") % wieldNumber);
|
||||
}
|
||||
}
|
||||
|
||||
string CreatureAnimationResolver::getDodgeAnimation() const {
|
||||
if (_creature->modelType() == Creature::ModelType::Creature) return "cdodgeg";
|
||||
|
||||
WeaponType type = WeaponType::None;
|
||||
WeaponWield wield = WeaponWield::None;
|
||||
getWeaponInfo(type, wield);
|
||||
|
||||
int wieldNumber = getWeaponWieldNumber(wield);
|
||||
|
||||
return str(boost::format("g%dg1") % wieldNumber);
|
||||
}
|
||||
|
||||
string CreatureAnimationResolver::getKnockdownAnimation() const {
|
||||
return _creature->modelType() == Creature::ModelType::Creature ? "ckdbck" : "g1y1";
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
60
src/game/object/creatureanimresolver.h
Normal file
60
src/game/object/creatureanimresolver.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2020 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 <string>
|
||||
|
||||
#include "../types.h"
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
class Creature;
|
||||
|
||||
class CreatureAnimationResolver {
|
||||
public:
|
||||
CreatureAnimationResolver(const Creature *creature);
|
||||
|
||||
std::string getPauseAnimation() const;
|
||||
std::string getRunAnimation() const;
|
||||
std::string getWalkAnimation() const;
|
||||
|
||||
std::string getUnlockDoorAnimation() const;
|
||||
std::string getTalkAnimation() const;
|
||||
std::string getHeadTalkAnimation() const;
|
||||
|
||||
// Attack animations
|
||||
|
||||
std::string getDuelAttackAnimation() const;
|
||||
std::string getBashAttackAnimation() const;
|
||||
std::string getDodgeAnimation() const;
|
||||
std::string getKnockdownAnimation() const;
|
||||
|
||||
// END Attack animations
|
||||
|
||||
private:
|
||||
const Creature *_creature { nullptr };
|
||||
|
||||
bool getWeaponInfo(WeaponType &type, WeaponWield &wield) const;
|
||||
int getWeaponWieldNumber(WeaponWield wield) const;
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
26
src/game/object/creaturemodelbuilder.cpp
Normal file
26
src/game/object/creaturemodelbuilder.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2020 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/>.
|
||||
*/
|
||||
|
||||
#include "creaturemodelbuilder.h"
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
26
src/game/object/creaturemodelbuilder.h
Normal file
26
src/game/object/creaturemodelbuilder.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2020 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
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
|
@ -118,7 +118,7 @@ const vector<shared_ptr<Item>> &SpatialObject::items() const {
|
|||
return _items;
|
||||
}
|
||||
|
||||
glm::vec3 SpatialObject::selectablePosition() const {
|
||||
glm::vec3 SpatialObject::getSelectablePosition() const {
|
||||
return _model->getCenterOfAABB();
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,10 @@ class SpatialObject : public Object {
|
|||
public:
|
||||
void update(float dt) override;
|
||||
|
||||
void face(const SpatialObject &other);
|
||||
|
||||
void addItem(const std::shared_ptr<Item> &item);
|
||||
void moveItemsTo(SpatialObject &other);
|
||||
|
||||
float distanceTo(const glm::vec2 &point) const;
|
||||
float distanceTo(const glm::vec3 &point) const;
|
||||
|
@ -49,11 +52,10 @@ public:
|
|||
|
||||
bool contains(const glm::vec3 &point) const;
|
||||
|
||||
void face(const SpatialObject &other);
|
||||
void moveItemsTo(SpatialObject &other);
|
||||
|
||||
bool isSelectable() const;
|
||||
|
||||
virtual glm::vec3 getSelectablePosition() const;
|
||||
|
||||
Room *room() const;
|
||||
const glm::vec3 &position() const;
|
||||
float heading() const;
|
||||
|
@ -62,7 +64,6 @@ public:
|
|||
std::shared_ptr<scene::ModelSceneNode> model() const;
|
||||
std::shared_ptr<render::Walkmesh> walkmesh() const;
|
||||
const std::vector<std::shared_ptr<Item>> &items() const;
|
||||
virtual glm::vec3 selectablePosition() const;
|
||||
float drawDistance() const;
|
||||
|
||||
void setRoom(Room *room);
|
||||
|
|
Loading…
Reference in a new issue