mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 03:53:52 +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;
|
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,
|
boost::shared_ptr<MWWorld::Action> Creature::activate (const MWWorld::Ptr& ptr,
|
||||||
const MWWorld::Ptr& actor) const
|
const MWWorld::Ptr& actor) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,6 +42,10 @@ namespace MWClass
|
||||||
virtual MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const;
|
virtual MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return creature stats
|
///< 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,
|
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
|
||||||
const MWWorld::Ptr& actor) const;
|
const MWWorld::Ptr& actor) const;
|
||||||
///< Generate action for activation
|
///< Generate action for activation
|
||||||
|
|
|
@ -288,6 +288,74 @@ namespace MWClass
|
||||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mNpcStats;
|
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,
|
boost::shared_ptr<MWWorld::Action> Npc::activate (const MWWorld::Ptr& ptr,
|
||||||
const MWWorld::Ptr& actor) const
|
const MWWorld::Ptr& actor) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,6 +68,10 @@ namespace MWClass
|
||||||
virtual MWWorld::InventoryStore& getInventoryStore (const MWWorld::Ptr& ptr) const;
|
virtual MWWorld::InventoryStore& getInventoryStore (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return inventory store
|
///< 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,
|
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
|
||||||
const MWWorld::Ptr& actor) const;
|
const MWWorld::Ptr& actor) const;
|
||||||
///< Generate action for activation
|
///< Generate action for activation
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/character.hpp"
|
#include "../mwmechanics/character.hpp"
|
||||||
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
|
@ -548,6 +549,14 @@ bool Animation::handleTextKey(AnimState &state, const std::string &groupname, co
|
||||||
showWeapons(true);
|
showWeapons(true);
|
||||||
else if(evt.compare(off, len, "unequip detach") == 0)
|
else if(evt.compare(off, len, "unequip detach") == 0)
|
||||||
showWeapons(false);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,16 @@ namespace MWWorld
|
||||||
throw std::runtime_error ("class does not have item health");
|
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
|
boost::shared_ptr<Action> Class::activate (const Ptr& ptr, const Ptr& actor) const
|
||||||
{
|
{
|
||||||
return boost::shared_ptr<Action> (new NullAction);
|
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
|
///< Return item max health or throw an exception, if class does not have item health
|
||||||
/// (default implementation: throw an exceoption)
|
/// (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;
|
virtual boost::shared_ptr<Action> activate (const Ptr& ptr, const Ptr& actor) const;
|
||||||
///< Generate action for activation (default implementation: return a null action).
|
///< Generate action for activation (default implementation: return a null action).
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue