[Client] Make tes3mp combat code work with Creatures, not just NPCs

0.6.1
David Cernat 8 years ago
parent a82646a130
commit ea7c3f2dc7

@ -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
bool healthdmg = true;
if (weapon.isEmpty())
{
MWMechanics::CreatureStats &otherstats = victim.getClass().getCreatureStats(victim);
healthdmg = otherstats.isParalyzed() || otherstats.getKnockedDown();
if (attacker.getClass().isBipedal(attacker))
{
MWMechanics::CreatureStats &otherstats = victim.getClass().getCreatureStats(victim);
healthdmg = otherstats.isParalyzed() || otherstats.getKnockedDown();
}
}
if (!weapon.isEmpty())
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…
Cancel
Save