forked from teamnwah/openmw-tes3coop
[Client] Make tes3mp combat code work with Creatures, not just NPCs
This commit is contained in:
parent
a82646a130
commit
ea7c3f2dc7
5 changed files with 124 additions and 21 deletions
|
@ -5,6 +5,21 @@
|
|||
#include <components/esm/loadcrea.hpp>
|
||||
#include <components/esm/creaturestate.hpp>
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Include additional headers for multiplayer purposes
|
||||
*/
|
||||
#include <components/openmw-mp/Log.hpp>
|
||||
#include "../mwmp/Main.hpp"
|
||||
#include "../mwmp/LocalPlayer.hpp"
|
||||
#include "../mwmp/DedicatedPlayer.hpp"
|
||||
#include "../mwmp/CellController.hpp"
|
||||
#include "../mwmp/MechanicsHelper.hpp"
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/magiceffects.hpp"
|
||||
#include "../mwmechanics/movement.hpp"
|
||||
|
@ -225,6 +240,19 @@ namespace MWClass
|
|||
|
||||
void Creature::hit(const MWWorld::Ptr& ptr, float attackStrength, int type) const
|
||||
{
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Ignore hit calculations on this client from DedicatedPlayers and DedicatedActors
|
||||
*/
|
||||
if (mwmp::PlayerList::isDedicatedPlayer(ptr) || mwmp::Main::get().getCellController()->isDedicatedActor(ptr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
MWWorld::LiveCellRef<ESM::Creature> *ref =
|
||||
ptr.get<ESM::Creature>();
|
||||
const MWWorld::Store<ESM::GameSetting> &gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
|
@ -267,8 +295,41 @@ namespace MWClass
|
|||
|
||||
float hitchance = MWMechanics::getHitChance(ptr, victim, ref->mBase->mData.mCombat);
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
If the attacker is a LocalPlayer or LocalActor, get their Attack and
|
||||
assign data for its target
|
||||
*/
|
||||
mwmp::Attack *localAttack = mwmp::Main::get().getMechanicsHelper()->getLocalAttack(ptr);
|
||||
|
||||
if (localAttack)
|
||||
{
|
||||
localAttack->success = true;
|
||||
mwmp::Main::get().getMechanicsHelper()->assignAttackTarget(localAttack, victim);
|
||||
}
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
if(Misc::Rng::roll0to99() >= hitchance)
|
||||
{
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
If this was a failed attack by the LocalPlayer or LocalActor, send a
|
||||
packet about it
|
||||
*/
|
||||
if (localAttack)
|
||||
{
|
||||
localAttack->pressed = false;
|
||||
localAttack->success = false;
|
||||
localAttack->shouldSend = true;
|
||||
}
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
victim.getClass().onHit(victim, 0.0f, false, MWWorld::Ptr(), ptr, osg::Vec3f(), false);
|
||||
MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr);
|
||||
return;
|
||||
|
@ -403,7 +464,21 @@ namespace MWClass
|
|||
float agilityTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() * getGmst().fKnockDownMult->getFloat();
|
||||
float knockdownTerm = stats.getAttribute(ESM::Attribute::Agility).getModified()
|
||||
* getGmst().iKnockDownOddsMult->getInt() * 0.01f + getGmst().iKnockDownOddsBase->getInt();
|
||||
if (ishealth && agilityTerm <= damage && knockdownTerm <= Misc::Rng::roll0to99())
|
||||
|
||||
/*
|
||||
Start of tes3mp change (major)
|
||||
|
||||
If the attacker is a DedicatedPlayer or DedicatedActor with a successful knockdown, apply the knockdown;
|
||||
otherwise, use default probability roll
|
||||
*/
|
||||
mwmp::Attack *dedicatedAttack = mwmp::Main::get().getMechanicsHelper()->getDedicatedAttack(attacker);
|
||||
|
||||
if (dedicatedAttack && dedicatedAttack->knockdown)
|
||||
stats.setKnockedDown(true);
|
||||
else if (ishealth && agilityTerm <= damage && knockdownTerm <= Misc::Rng::roll0to99())
|
||||
/*
|
||||
End of tes3mp change (major)
|
||||
*/
|
||||
stats.setKnockedDown(true);
|
||||
else
|
||||
stats.setHitRecovery(true); // Is this supposed to always occur?
|
||||
|
@ -432,6 +507,27 @@ namespace MWClass
|
|||
stats.setFatigue(fatigue);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
If the attacker was the LocalPlayer or LocalActor, record their target and send a packet with it
|
||||
*/
|
||||
mwmp::Attack *localAttack = mwmp::Main::get().getMechanicsHelper()->getLocalAttack(attacker);
|
||||
|
||||
if (localAttack)
|
||||
{
|
||||
localAttack->pressed = false;
|
||||
localAttack->damage = damage;
|
||||
localAttack->knockdown = getCreatureStats(ptr).getKnockedDown();
|
||||
|
||||
mwmp::Main::get().getMechanicsHelper()->assignAttackTarget(localAttack, ptr);
|
||||
|
||||
localAttack->shouldSend = true;
|
||||
}
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Creature::activate (const MWWorld::Ptr& ptr,
|
||||
|
|
|
@ -34,6 +34,8 @@ DedicatedActor::DedicatedActor()
|
|||
creatureStats->mDynamic[0].mBase = -1;
|
||||
|
||||
hasChangedCell = true;
|
||||
|
||||
attack.pressed = false;
|
||||
}
|
||||
|
||||
DedicatedActor::~DedicatedActor()
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/movement.hpp"
|
||||
|
||||
#include "../mwrender/animation.hpp"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define OPENMW_LOCALACTOR_HPP
|
||||
|
||||
#include <components/openmw-mp/Base/BaseActor.hpp>
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
|
||||
namespace mwmp
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/combat.hpp"
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
#include "../mwmechanics/spellcasting.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
|
@ -107,7 +107,7 @@ void MechanicsHelper::processAttack(Attack attack, const MWWorld::Ptr& attacker)
|
|||
}
|
||||
}
|
||||
|
||||
MWMechanics::CreatureStats &attackerStats = attacker.getClass().getNpcStats(attacker);
|
||||
MWMechanics::CreatureStats &attackerStats = attacker.getClass().getCreatureStats(attacker);
|
||||
attackerStats.getSpells().setSelectedSpell(attack.spellId);
|
||||
|
||||
MWWorld::Ptr victim;
|
||||
|
@ -143,29 +143,35 @@ void MechanicsHelper::processAttack(Attack attack, const MWWorld::Ptr& attacker)
|
|||
// Get the weapon used (if hand-to-hand, weapon = inv.end())
|
||||
if (attackerStats.getDrawState() == MWMechanics::DrawState_Weapon)
|
||||
{
|
||||
MWWorld::InventoryStore &inv = attacker.getClass().getInventoryStore(attacker);
|
||||
MWWorld::ContainerStoreIterator weaponslot = inv.getSlot(
|
||||
MWWorld::InventoryStore::Slot_CarriedRight);
|
||||
MWWorld::Ptr weapon;
|
||||
|
||||
MWWorld::Ptr weapon = ((weaponslot != inv.end()) ? *weaponslot : MWWorld::Ptr());
|
||||
if (!weapon.isEmpty() && weapon.getTypeName() != typeid(ESM::Weapon).name())
|
||||
weapon = MWWorld::Ptr();
|
||||
if (attacker.getClass().hasInventoryStore(attacker))
|
||||
{
|
||||
MWWorld::InventoryStore &inv = attacker.getClass().getInventoryStore(attacker);
|
||||
MWWorld::ContainerStoreIterator weaponslot = inv.getSlot(
|
||||
MWWorld::InventoryStore::Slot_CarriedRight);
|
||||
|
||||
weapon = ((weaponslot != inv.end()) ? *weaponslot : MWWorld::Ptr());
|
||||
if (!weapon.isEmpty() && weapon.getTypeName() != typeid(ESM::Weapon).name())
|
||||
weapon = MWWorld::Ptr();
|
||||
}
|
||||
|
||||
if (victim.mRef != NULL)
|
||||
{
|
||||
bool healthdmg;
|
||||
if (!weapon.isEmpty())
|
||||
healthdmg = true;
|
||||
else
|
||||
{
|
||||
MWMechanics::CreatureStats &otherstats = victim.getClass().getCreatureStats(victim);
|
||||
healthdmg = otherstats.isParalyzed() || otherstats.getKnockedDown();
|
||||
}
|
||||
bool healthdmg = true;
|
||||
|
||||
if (!weapon.isEmpty())
|
||||
if (weapon.isEmpty())
|
||||
{
|
||||
if (attacker.getClass().isBipedal(attacker))
|
||||
{
|
||||
MWMechanics::CreatureStats &otherstats = victim.getClass().getCreatureStats(victim);
|
||||
healthdmg = otherstats.isParalyzed() || otherstats.getKnockedDown();
|
||||
}
|
||||
}
|
||||
else
|
||||
MWMechanics::blockMeleeAttack(attacker, victim, weapon, attack.damage, 1);
|
||||
|
||||
attacker.getClass().onHit(victim, attack.damage, healthdmg, weapon, attacker, osg::Vec3f(),
|
||||
victim.getClass().onHit(victim, attack.damage, healthdmg, weapon, attacker, osg::Vec3f(),
|
||||
attack.success);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue