mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 22:23:51 +00:00
Add beginnings of melee hits
This commit is contained in:
parent
45302f9e25
commit
0c8d4d9be2
7 changed files with 141 additions and 0 deletions
|
@ -148,6 +148,39 @@ namespace MWClass
|
|||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mCreatureStats;
|
||||
}
|
||||
|
||||
|
||||
void Creature::attack(const MWWorld::Ptr& ptr, int type) const
|
||||
{
|
||||
}
|
||||
|
||||
void Creature::setActorHealth(const MWWorld::Ptr& ptr, float health, const MWWorld::Ptr& attacker) const
|
||||
{
|
||||
MWMechanics::CreatureStats &crstats = getCreatureStats(ptr);
|
||||
float diff = health - crstats.getHealth().getCurrent();
|
||||
|
||||
if(diff < 0.0f)
|
||||
{
|
||||
// actor is losing health. Alert the character controller, scripts, etc.
|
||||
// NOTE: 'attacker' may be empty.
|
||||
}
|
||||
|
||||
bool wasDead = crstats.isDead();
|
||||
|
||||
MWMechanics::DynamicStat<float> stat(crstats.getHealth());
|
||||
stat.setCurrent(health);
|
||||
crstats.setHealth(stat);
|
||||
|
||||
if(!wasDead && crstats.isDead())
|
||||
{
|
||||
// actor was just killed
|
||||
}
|
||||
else if(wasDead && !crstats.isDead())
|
||||
{
|
||||
// actor was just resurrected
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Creature::activate (const MWWorld::Ptr& ptr,
|
||||
const MWWorld::Ptr& actor) const
|
||||
{
|
||||
|
|
|
@ -42,6 +42,10 @@ namespace MWClass
|
|||
virtual MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const;
|
||||
///< Return creature stats
|
||||
|
||||
virtual void attack(const MWWorld::Ptr& ptr, int type) const;
|
||||
|
||||
virtual void setActorHealth(const MWWorld::Ptr& ptr, float health, const MWWorld::Ptr& attacker) const;
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
|
||||
const MWWorld::Ptr& actor) const;
|
||||
///< Generate action for activation
|
||||
|
|
|
@ -288,6 +288,74 @@ namespace MWClass
|
|||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mNpcStats;
|
||||
}
|
||||
|
||||
|
||||
void Npc::attack(const MWWorld::Ptr& ptr, int type) const
|
||||
{
|
||||
// FIXME: Detect what was hit
|
||||
MWWorld::Ptr victim;
|
||||
if(victim.isEmpty()) // Didn't hit anything
|
||||
return;
|
||||
|
||||
const MWWorld::Class &othercls = MWWorld::Class::get(victim);
|
||||
if(!othercls.isActor() || othercls.getCreatureStats(victim).isDead())
|
||||
{
|
||||
// Can't hit non-actors, or dead actors
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the weapon used
|
||||
MWWorld::LiveCellRef<ESM::Weapon> *weapon = NULL;
|
||||
MWWorld::InventoryStore &inv = Npc::getInventoryStore(ptr);
|
||||
MWWorld::ContainerStoreIterator iter = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
||||
if(iter != inv.end() && iter->getTypeName() == typeid(ESM::Weapon).name())
|
||||
weapon = iter->get<ESM::Weapon>();
|
||||
|
||||
// TODO: Check weapon skill against victim's armor skill (if !weapon, attacker is using
|
||||
// hand-to-hand, which damages fatique unless in werewolf form).
|
||||
if(weapon)
|
||||
{
|
||||
float health = othercls.getCreatureStats(victim).getHealth().getCurrent();
|
||||
// FIXME: Modify damage based on strength?
|
||||
if(type == MWMechanics::CreatureStats::AT_Chop)
|
||||
health -= weapon->mBase->mData.mChop[1];
|
||||
else if(type == MWMechanics::CreatureStats::AT_Slash)
|
||||
health -= weapon->mBase->mData.mSlash[1];
|
||||
else if(type == MWMechanics::CreatureStats::AT_Thrust)
|
||||
health -= weapon->mBase->mData.mThrust[1];
|
||||
|
||||
othercls.setActorHealth(victim, std::max(health, 0.0f), ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void Npc::setActorHealth(const MWWorld::Ptr& ptr, float health, const MWWorld::Ptr& attacker) const
|
||||
{
|
||||
MWMechanics::CreatureStats &crstats = getCreatureStats(ptr);
|
||||
float diff = health - crstats.getHealth().getCurrent();
|
||||
|
||||
if(diff < 0.0f)
|
||||
{
|
||||
// 'ptr' is losing health. Play a 'hit' voiced dialog entry if not already saying
|
||||
// something, alert the character controller, scripts, etc.
|
||||
// NOTE: 'attacker' may be empty.
|
||||
}
|
||||
|
||||
bool wasDead = crstats.isDead();
|
||||
|
||||
MWMechanics::DynamicStat<float> stat(crstats.getHealth());
|
||||
stat.setCurrent(health);
|
||||
crstats.setHealth(stat);
|
||||
|
||||
if(!wasDead && crstats.isDead())
|
||||
{
|
||||
// actor was just killed
|
||||
}
|
||||
else if(wasDead && !crstats.isDead())
|
||||
{
|
||||
// actor was just resurrected
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Npc::activate (const MWWorld::Ptr& ptr,
|
||||
const MWWorld::Ptr& actor) const
|
||||
{
|
||||
|
|
|
@ -68,6 +68,10 @@ namespace MWClass
|
|||
virtual MWWorld::InventoryStore& getInventoryStore (const MWWorld::Ptr& ptr) const;
|
||||
///< Return inventory store
|
||||
|
||||
virtual void attack(const MWWorld::Ptr& ptr, int type) const;
|
||||
|
||||
virtual void setActorHealth(const MWWorld::Ptr& ptr, float health, const MWWorld::Ptr& attacker) const;
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
|
||||
const MWWorld::Ptr& actor) const;
|
||||
///< Generate action for activation
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "../mwmechanics/character.hpp"
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
namespace MWRender
|
||||
|
@ -548,6 +549,14 @@ bool Animation::handleTextKey(AnimState &state, const std::string &groupname, co
|
|||
showWeapons(true);
|
||||
else if(evt.compare(off, len, "unequip detach") == 0)
|
||||
showWeapons(false);
|
||||
else if(evt.compare(off, len, "chop hit") == 0)
|
||||
MWWorld::Class::get(mPtr).attack(mPtr, MWMechanics::CreatureStats::AT_Chop);
|
||||
else if(evt.compare(off, len, "slash hit") == 0)
|
||||
MWWorld::Class::get(mPtr).attack(mPtr, MWMechanics::CreatureStats::AT_Slash);
|
||||
else if(evt.compare(off, len, "thrust hit") == 0)
|
||||
MWWorld::Class::get(mPtr).attack(mPtr, MWMechanics::CreatureStats::AT_Thrust);
|
||||
else if(evt.compare(off, len, "hit") == 0)
|
||||
MWWorld::Class::get(mPtr).attack(mPtr, -1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -77,6 +77,16 @@ namespace MWWorld
|
|||
throw std::runtime_error ("class does not have item health");
|
||||
}
|
||||
|
||||
void Class::attack(const Ptr& ptr, int type) const
|
||||
{
|
||||
throw std::runtime_error("class cannot attack");
|
||||
}
|
||||
|
||||
void Class::setActorHealth(const Ptr& ptr, float health, const Ptr& attacker) const
|
||||
{
|
||||
throw std::runtime_error("class does not have actor health");
|
||||
}
|
||||
|
||||
boost::shared_ptr<Action> Class::activate (const Ptr& ptr, const Ptr& actor) const
|
||||
{
|
||||
return boost::shared_ptr<Action> (new NullAction);
|
||||
|
|
|
@ -105,6 +105,19 @@ namespace MWWorld
|
|||
///< Return item max health or throw an exception, if class does not have item health
|
||||
/// (default implementation: throw an exceoption)
|
||||
|
||||
virtual void attack(const Ptr& ptr, int type) const;
|
||||
///< Execute a melee hit, using the current weapon. This will check the relevant skills
|
||||
/// of the given attacker, and whoever is hit.
|
||||
/// \a type - type of attack, one of the MWMechanics::CreatureStats::AttackType enums.
|
||||
/// ignored for creature attacks.
|
||||
/// (default implementation: throw an exceoption)
|
||||
|
||||
virtual void setActorHealth(const Ptr& ptr, float health, const Ptr& attacker=Ptr()) const;
|
||||
///< Sets a new current health value for the actor, optionally specifying the object causing
|
||||
/// the change. Use this instead of using CreatureStats directly as this will make sure the
|
||||
/// correct dialog and actor states are properly handled when being hurt or healed.
|
||||
/// (default implementation: throw an exceoption)
|
||||
|
||||
virtual boost::shared_ptr<Action> activate (const Ptr& ptr, const Ptr& actor) const;
|
||||
///< Generate action for activation (default implementation: return a null action).
|
||||
|
||||
|
|
Loading…
Reference in a new issue