[Client] Rethink and restructure tes3mp combat code so it works for NPCs

0.6.1
David Cernat 8 years ago
parent 6c2bbd6608
commit 2e8714afaa

@ -13,9 +13,12 @@
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
*/
@ -563,10 +566,12 @@ namespace MWClass
/*
Start of tes3mp addition
Ignore hit calculations on this client from DedicatedPlayers
Ignore hit calculations on this client from DedicatedPlayers and DedicatedActors
*/
if (mwmp::PlayerList::isDedicatedPlayer(ptr))
if (mwmp::PlayerList::isDedicatedPlayer(ptr) || mwmp::Main::get().getCellController()->isDedicatedActor(ptr))
{
return;
}
/*
End of tes3mp addition
*/
@ -620,15 +625,15 @@ namespace MWClass
/*
Start of tes3mp addition
If the attacker is a LocalPlayer and the target is a DedicatedPlayer,
mark that accordingly in the LocalPlayer data
If the attacker is a LocalPlayer or LocalActor, get their Attack and
assign data for its target
*/
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
{
mwmp::Main::get().getLocalPlayer()->attack.success = true;
mwmp::Attack *localAttack = mwmp::Main::get().getMechanicsHelper()->getLocalAttack(ptr);
if (mwmp::PlayerList::isDedicatedPlayer(victim))
mwmp::Main::get().getLocalPlayer()->attack.target.guid = mwmp::PlayerList::getPlayer(victim)->guid;
if (localAttack)
{
localAttack->success = true;
mwmp::Main::get().getMechanicsHelper()->assignAttackTarget(localAttack, victim);
}
/*
End of tes3mp addition
@ -639,13 +644,14 @@ namespace MWClass
/*
Start of tes3mp addition
If this was a failed attack by the LocalPlayer, send a
PlayerAttack packet about it
If this was a failed attack by the LocalPlayer or LocalActor, send a
packet about it
*/
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
if (localAttack)
{
mwmp::Main::get().getLocalPlayer()->attack.success = false;
mwmp::Main::get().getLocalPlayer()->sendAttack(mwmp::Attack::MELEE);
localAttack->pressed = false;
localAttack->success = false;
localAttack->shouldSend = true;
}
/*
End of tes3mp addition
@ -800,10 +806,12 @@ namespace MWClass
/*
Start of tes3mp change (major)
If the attacker is a DedicatedPlayer with a successful knockdown, apply the knockdown;
If the attacker is a DedicatedPlayer or DedicatedActor with a successful knockdown, apply the knockdown;
otherwise, use default probability roll
*/
if (mwmp::PlayerList::isDedicatedPlayer(attacker) && mwmp::PlayerList::getPlayer(attacker)->attack.knockdown)
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())
/*
@ -913,24 +921,24 @@ namespace MWClass
/*
Start of tes3mp addition
If the victim was a DedicatedPlayer, send a PlayerAttack packet from LocalPlayer
If the attacker was the LocalPlayer or LocalActor, record their target and send a packet with it
If the victim was the LocalPlayer, check whether packets should be sent about
their new dynamic stats and position
*/
if (attacker == MWMechanics::getPlayer() && mwmp::PlayerList::isDedicatedPlayer(ptr))
mwmp::Attack *localAttack = mwmp::Main::get().getMechanicsHelper()->getLocalAttack(attacker);
if (localAttack)
{
mwmp::DedicatedPlayer *victimPlayer = mwmp::PlayerList::getPlayer(ptr);
localAttack->pressed = false;
localAttack->damage = damage;
localAttack->knockdown = getCreatureStats(ptr).getKnockedDown();
mwmp::Attack *attack = &mwmp::Main::get().getLocalPlayer()->attack;
attack->damage = damage;
attack->target.guid = victimPlayer->guid;
attack->knockdown = getCreatureStats(ptr).getKnockedDown();
mwmp::Main::get().getMechanicsHelper()->assignAttackTarget(localAttack, ptr);
mwmp::Main::get().getLocalPlayer()->sendAttack(mwmp::Attack::MELEE); // todo: make this sensitive to different weapon types
localAttack->shouldSend = true;
}
if (ptr == MWMechanics::getPlayer())
else if (ptr == MWMechanics::getPlayer())
{
mwmp::Main::get().getLocalPlayer()->updateStatsDynamic(true);
mwmp::Main::get().getLocalPlayer()->updatePosition(true); // fix position after getting damage;

@ -16,10 +16,12 @@
Include additional headers for multiplayer purposes
*/
#include <components/openmw-mp/Log.hpp>
#include "../mwmp/Main.hpp"
#include "../mwmp/CellController.hpp"
#include "../mwmp/DedicatedPlayer.hpp"
#include "../mwmp/LocalPlayer.hpp"
#include "../mwmp/DedicatedPlayer.hpp"
#include "../mwmp/CellController.hpp"
#include "../mwmp/MechanicsHelper.hpp"
/*
End of tes3mp addition
*/
@ -1120,15 +1122,26 @@ namespace MWMechanics
Start of tes3mp change (minor)
Instead of merely updating the player character's mAttackingOrSpell here,
send a PlayerAttack packet from LocalPlayer when applicable
prepare an Attack packet for the LocalPlayer
*/
if (iter->first == player)
{
bool state = MWBase::Environment::get().getWorld()->getPlayer().getAttackingOrSpell();
DrawState_ dstate = player.getClass().getNpcStats(player).getDrawState();
iter->second->getCharacterController()->setAttackingOrSpell(state);
if (dstate == DrawState_Weapon)
mwmp::Main::get().getLocalPlayer()->prepareAttack(mwmp::Attack::MELEE, state);
{
mwmp::Attack *localAttack = mwmp::Main::get().getMechanicsHelper()->getLocalAttack(iter->first);
if (localAttack->pressed != state)
{
mwmp::Main::get().getMechanicsHelper()->resetAttack(localAttack);
localAttack->type = mwmp::Attack::MELEE;
localAttack->pressed = state;
localAttack->shouldSend = true;
}
}
}
/*
End of tes3mp change (minor)
@ -1137,10 +1150,12 @@ namespace MWMechanics
/*
Start of tes3mp addition
If this actor is a DedicatedPlayer, update their mAttackingOrSpell
If this actor is a DedicatedPlayer or DedicatedActor, update their mAttackingOrSpell
*/
if (mwmp::PlayerList::isDedicatedPlayer(iter->first))
mwmp::PlayerList::getPlayer(iter->first)->updateActor(iter->second);
mwmp::Attack *dedicatedAttack = mwmp::Main::get().getMechanicsHelper()->getDedicatedAttack(iter->first);
if (dedicatedAttack)
iter->second->getCharacterController()->setAttackingOrSpell(dedicatedAttack->pressed);
/*
End of tes3mp addition
*/

@ -4,6 +4,18 @@
#include <components/esm/aisequence.hpp>
/*
Start of tes3mp addition
Include additional headers for multiplayer purposes
*/
#include <components/openmw-mp/Log.hpp>
#include "../mwmp/Main.hpp"
#include "../mwmp/MechanicsHelper.hpp"
/*
End of tes3mp addition
*/
#include "../mwworld/class.hpp"
#include "../mwworld/esmstore.hpp"
@ -233,6 +245,25 @@ namespace MWMechanics
{
storage.stopAttack();
characterController.setAttackingOrSpell(false);
/*
Start of tes3mp addition
Record that this actor is stopping an attack so that a packet will be sent about it
*/
mwmp::Attack *localAttack = mwmp::Main::get().getMechanicsHelper()->getLocalAttack(actor);
if (localAttack->pressed != false)
{
mwmp::Main::get().getMechanicsHelper()->resetAttack(localAttack);
localAttack->type = mwmp::Attack::MELEE;
localAttack->pressed = false;
localAttack->shouldSend = true;
}
/*
End of tes3mp addition
*/
storage.mActionCooldown = 0.f;
// Continue combat if target is player or player follower/escorter and an attack has been attempted
const std::list<MWWorld::Ptr>& playerFollowersAndEscorters = MWBase::Environment::get().getMechanicsManager()->getActorsSidingWith(MWMechanics::getPlayer());
@ -566,6 +597,24 @@ namespace MWMechanics
mAttack = true; // attack starts just now
characterController.setAttackingOrSpell(true);
/*
Start of tes3mp addition
Record that this actor is starting an attack so that a packet will be sent about it
*/
mwmp::Attack *localAttack = mwmp::Main::get().getMechanicsHelper()->getLocalAttack(actor);
if (localAttack->pressed != true)
{
mwmp::Main::get().getMechanicsHelper()->resetAttack(localAttack);
localAttack->type = mwmp::Attack::MELEE;
localAttack->pressed = true;
localAttack->shouldSend = true;
}
/*
End of tes3mp addition
*/
if (!distantCombat)
characterController.setAIAttackType(chooseBestAttack(weapon));

@ -34,10 +34,11 @@
*/
#include <components/openmw-mp/Log.hpp>
#include "../mwmp/Main.hpp"
#include "../mwmp/CellController.hpp"
#include "../mwmp/LocalPlayer.hpp"
#include "../mwmp/LocalActor.hpp"
#include "../mwmp/DedicatedPlayer.hpp"
#include "../mwmp/CellController.hpp"
#include "../mwmp/MechanicsHelper.hpp"
/*
End of tes3mp addition
*/
@ -1258,10 +1259,18 @@ bool CharacterController::updateWeaponState()
/*
Start of tes3mp addition
Send PlayerAttack packet for this spell
If this mPtr belongs to a LocalPlayer or LocalActor, get their Attack and prepare
it for sending
*/
if (mPtr == getPlayer())
mwmp::Main::get().getLocalPlayer()->prepareAttack(mwmp::Attack::MAGIC, true);
mwmp::Attack *localAttack = mwmp::Main::get().getMechanicsHelper()->getLocalAttack(mPtr);
if (localAttack)
{
mwmp::Main::get().getMechanicsHelper()->resetAttack(localAttack);
localAttack->type = mwmp::Attack::MAGIC;
localAttack->pressed = true;
localAttack->shouldSend = true;
}
/*
End of tes3mp addition
*/
@ -1349,10 +1358,11 @@ bool CharacterController::updateWeaponState()
/*
Start of tes3mp change (major)
We need player-controlled NPCs to not have their attacks
cancelled here, so a 2nd condition has been added for them
We need DedicatedPlayers and DedicatedActors to not have their attacks
cancelled here, so additional conditions have been added for them
*/
if(mPtr == getPlayer() || mwmp::PlayerList::isDedicatedPlayer(mPtr))
if(mPtr == getPlayer() || mwmp::PlayerList::isDedicatedPlayer(mPtr) ||
mwmp::Main::get().getCellController()->isDedicatedActor(mPtr))
/*
End of tes3mp change (major)
*/

@ -9,9 +9,12 @@
Include additional headers for multiplayer purposes
*/
#include <components/openmw-mp/Log.hpp>
#include "../mwmp/Main.hpp"
#include "../mwmp/DedicatedPlayer.hpp"
#include "../mwmp/LocalPlayer.hpp"
#include "../mwmp/DedicatedPlayer.hpp"
#include "../mwmp/CellController.hpp"
#include "../mwmp/MechanicsHelper.hpp"
/*
End of tes3mp addition
*/
@ -127,19 +130,25 @@ namespace MWMechanics
/*
Start of tes3mp change (major)
Only calculate block chance for blockers who are not DedicatedPlayers
and update block state for LocalPlayer
Only calculate block chance for LocalPlayers and LocalActors; otherwise,
get the block state from the relevant DedicatedPlayer or DedicatedActor
*/
if (attacker == MWMechanics::getPlayer())
mwmp::Main::get().getLocalPlayer()->attack.block = false;
mwmp::Attack *localAttack = mwmp::Main::get().getMechanicsHelper()->getLocalAttack(attacker);
bool isDedicated = mwmp::PlayerList::isDedicatedPlayer(blocker);
if (localAttack)
{
localAttack->block = false;
}
if ((!isDedicated && Misc::Rng::roll0to99() < x) ||
(isDedicated && mwmp::PlayerList::getPlayer(blocker)->attack.block == true))
mwmp::Attack *dedicatedAttack = mwmp::Main::get().getMechanicsHelper()->getDedicatedAttack(blocker);
if ((dedicatedAttack && dedicatedAttack->block == true) ||
Misc::Rng::roll0to99() < x)
{
if (attacker == MWMechanics::getPlayer())
mwmp::Main::get().getLocalPlayer()->attack.block = true;
if (localAttack)
{
localAttack->block = true;
}
/*
End of tes3mp change (major)
*/

@ -13,9 +13,11 @@
Include additional headers for multiplayer purposes
*/
#include <components/openmw-mp/Log.hpp>
#include "../mwmp/Main.hpp"
#include "../mwmp/DedicatedPlayer.hpp"
#include "../mwmp/LocalPlayer.hpp"
#include "../mwmp/MechanicsHelper.hpp"
/*
End of tes3mp addition
*/
@ -856,16 +858,17 @@ namespace MWMechanics
TODO: See if LocalPlayer being the target and having godmode on
can be accounted for like it is in OpenMW's corresponding code
*/
mwmp::DedicatedPlayer *dedicatedPlayer = mwmp::PlayerList::getPlayer(mCaster);
mwmp::Attack *localAttack = NULL;
mwmp::Attack *dedicatedAttack = mwmp::Main::get().getMechanicsHelper()->getDedicatedAttack(mCaster);
bool isDedicated = mwmp::PlayerList::isDedicatedPlayer(mCaster);
if (isDedicated)
dedicatedPlayer->attack.pressed = false;
if (dedicatedAttack)
dedicatedAttack->pressed = false;
else
localAttack = mwmp::Main::get().getMechanicsHelper()->getLocalAttack(mCaster);
// Check success
if ((!isDedicated && !mwmp::Main::get().getLocalPlayer()->attack.success) ||
(isDedicated && dedicatedPlayer->attack.success == false))
if ((localAttack && localAttack->success == false) ||
(dedicatedAttack && dedicatedAttack->success == false))
{
if (mCaster == getPlayer())
{

@ -235,7 +235,7 @@ DedicatedPlayer *PlayerList::getPlayer(const MWWorld::Ptr &ptr)
bool PlayerList::isDedicatedPlayer(const MWWorld::Ptr &ptr)
{
if (ptr.mRef == 0)
if (ptr.mRef == NULL)
return false;
return (getPlayer(ptr) != 0);
@ -420,11 +420,6 @@ void DedicatedPlayer::setMarkerState(bool state)
removeMarker();
}
void DedicatedPlayer::updateActor(MWMechanics::Actor *actor)
{
actor->getCharacterController()->setAttackingOrSpell(attack.pressed);
}
MWWorld::Ptr DedicatedPlayer::getPtr()
{
return ptr;

@ -61,7 +61,6 @@ namespace mwmp
void updateMarker();
void removeMarker();
void setMarkerState(bool state);
void updateActor(MWMechanics::Actor *actor);
MWWorld::Ptr getPtr();
MWWorld::Ptr getLiveCellPtr();

@ -14,6 +14,7 @@
#include "Main.hpp"
#include "Networking.hpp"
#include "ActorList.hpp"
#include "MechanicsHelper.hpp"
using namespace mwmp;
using namespace std;
@ -32,6 +33,9 @@ LocalActor::LocalActor()
statTimer = 0;
attack.type = Attack::MELEE;
attack.shouldSend = false;
creatureStats = new ESM::CreatureStats();
}
@ -47,6 +51,7 @@ void LocalActor::update(bool forceUpdate)
updateAnimPlay();
updateSpeech();
updateStatsDynamic(forceUpdate);
updateAttack();
}
void LocalActor::updatePosition(bool forceUpdate)
@ -168,6 +173,22 @@ void LocalActor::updateStatsDynamic(bool forceUpdate)
}
}
void LocalActor::updateAttack()
{
if (attack.shouldSend)
{
if (attack.type == Attack::MAGIC)
{
MWMechanics::CreatureStats &attackerStats = ptr.getClass().getNpcStats(ptr);
attack.spellId = attackerStats.getSpells().getSelectedSpell();
attack.success = mwmp::Main::get().getMechanicsHelper()->getSpellSuccess(attack.spellId, ptr);
}
mwmp::Main::get().getNetworking()->getActorList()->addAttackActor(*this);
attack.shouldSend = false;
}
}
MWWorld::Ptr LocalActor::getPtr()
{
return ptr;

@ -21,6 +21,7 @@ namespace mwmp
void updateAnimPlay();
void updateSpeech();
void updateStatsDynamic(bool forceUpdate);
void updateAttack();
MWWorld::Ptr getPtr();
void setPtr(const MWWorld::Ptr& newPtr);

@ -2,7 +2,6 @@
// Created by koncord on 14.01.16.
//
#include <components/misc/rng.hpp>
#include <components/esm/esmwriter.hpp>
#include <components/openmw-mp/Log.hpp>
@ -22,7 +21,6 @@
#include "../mwmechanics/aitravel.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/mechanicsmanagerimp.hpp"
#include "../mwmechanics/spellcasting.hpp"
#include "../mwscript/scriptmanagerimp.hpp"
@ -36,9 +34,10 @@
#include "../mwworld/worldimp.hpp"
#include "LocalPlayer.hpp"
#include "Main.hpp"
#include "Networking.hpp"
#include "CellController.hpp"
#include "Main.hpp"
#include "MechanicsHelper.hpp"
using namespace mwmp;
using namespace std;
@ -49,6 +48,8 @@ LocalPlayer::LocalPlayer()
charGenStage.end = 1;
consoleAllowed = true;
ignorePosPacket = false;
attack.shouldSend = false;
}
LocalPlayer::~LocalPlayer()
@ -71,7 +72,7 @@ void LocalPlayer::update()
updateCell();
updatePosition();
updateAnimFlags();
updateAttackState();
updateAttack();
updateDeadState();
updateEquipment();
updateStatsDynamic();
@ -514,32 +515,20 @@ void LocalPlayer::updateInventory(bool forceUpdate)
sendInventory();
}
void LocalPlayer::updateAttackState(bool forceUpdate)
void LocalPlayer::updateAttack()
{
MWBase::World *world = MWBase::Environment::get().getWorld();
MWWorld::Ptr player = getPlayerPtr();
using namespace MWMechanics;
static bool attackPressed = false; // prevent flood
MWMechanics::DrawState_ state = player.getClass().getNpcStats(player).getDrawState();
if (world->getPlayer().getAttackingOrSpell() && !attackPressed)
if (attack.shouldSend)
{
MWWorld::Ptr weapon = MWWorld::Ptr(); // hand-to-hand
if (state == MWMechanics::DrawState_Spell)
if (attack.type == Attack::MAGIC)
{
attack.type = Attack::MAGIC;
attack.pressed = true;
attack.spellId = MWBase::Environment::get().getWindowManager()->getSelectedSpell();
attack.success = mwmp::Main::get().getMechanicsHelper()->getSpellSuccess(attack.spellId, getPlayerPtr());
}
attackPressed = true;
}
else if (!world->getPlayer().getAttackingOrSpell() && attackPressed)
{
attackPressed = false;
getNetworking()->getPlayerPacket(ID_PLAYER_ATTACK)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_ATTACK)->Send();
attack.shouldSend = false;
}
}
@ -1108,17 +1097,6 @@ void LocalPlayer::sendJournalIndex(const std::string& quest, int index)
getNetworking()->getPlayerPacket(ID_PLAYER_JOURNAL)->Send();
}
void LocalPlayer::sendAttack(Attack::TYPE type)
{
MWMechanics::DrawState_ state = getPlayerPtr().getClass().getNpcStats(getPlayerPtr()).getDrawState();
attack.type = type;
attack.pressed = false;
getNetworking()->getPlayerPacket(ID_PLAYER_ATTACK)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_ATTACK)->Send();
}
void LocalPlayer::clearCellStates()
{
cellStateChanges.cellStates.clear();
@ -1161,31 +1139,3 @@ void LocalPlayer::storeCurrentContainer(const MWWorld::Ptr &container, bool loot
currentContainer.mpNum = container.getCellRef().getMpNum();
currentContainer.loot = loot;
}
void LocalPlayer::prepareAttack(Attack::TYPE type, bool state)
{
if (attack.pressed == state && type != Attack::MAGIC)
return;
MWMechanics::DrawState_ dstate = getPlayerPtr().getClass().getNpcStats(getPlayerPtr()).getDrawState();
if (dstate == MWMechanics::DrawState_Spell)
{
attack.spellId = MWBase::Environment::get().getWindowManager()->getSelectedSpell();
attack.success = Misc::Rng::roll0to99() < MWMechanics::getSpellSuccessChance(attack.spellId, getPlayerPtr());
state = true;
}
else
{
attack.success = false;
}
attack.pressed = state;
attack.type = type;
attack.knockdown = false;
attack.block = false;
attack.target.guid = RakNet::RakNetGUID();
getNetworking()->getPlayerPacket(ID_PLAYER_ATTACK)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_ATTACK)->Send();
}

@ -34,7 +34,7 @@ namespace mwmp
void updateChar();
void updateEquipment(bool forceUpdate = false);
void updateInventory(bool forceUpdate = false);
void updateAttackState(bool forceUpdate = false);
void updateAttack();
void updateDeadState(bool forceUpdate = false);
void updateAnimFlags(bool forceUpdate = false);
@ -66,7 +66,6 @@ namespace mwmp
void sendSpellRemoval(const ESM::Spell &spell);
void sendJournalEntry(const std::string& id, int index, const MWWorld::Ptr& actor);
void sendJournalIndex(const std::string& id, int index);
void sendAttack(Attack::TYPE type);
void clearCellStates();
void clearCurrentContainer();
@ -74,8 +73,6 @@ namespace mwmp
void storeCellState(ESM::Cell cell, int stateType);
void storeCurrentContainer(const MWWorld::Ptr& container, bool loot);
void prepareAttack(Attack::TYPE type, bool state);
private:
Networking *getNetworking();
MWWorld::Ptr getPlayerPtr();

@ -97,21 +97,48 @@ void MechanicsHelper::processAttack(Attack attack, const MWWorld::Ptr& attacker)
{
if (attack.pressed == false)
{
LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Attack success: %s", attack.success ? "true" : "false");
LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Processing attack from %s",
attacker.getCellRef().getRefId().c_str());
LOG_APPEND(Log::LOG_VERBOSE, "- success: %s", attack.success ? "true" : "false");
if (attack.success == true)
LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Damage: %f", attack.damage);
{
LOG_APPEND(Log::LOG_VERBOSE, "- damage: %f", attack.damage);
}
}
MWMechanics::CreatureStats &attackerStats = attacker.getClass().getNpcStats(attacker);
attackerStats.getSpells().setSelectedSpell(attack.spellId);
MWWorld::Ptr victim;
if (attack.target.guid == mwmp::Main::get().getLocalPlayer()->guid)
victim = MWBase::Environment::get().getWorld()->getPlayerPtr();
else if (PlayerList::getPlayer(attack.target.guid) != 0)
victim = PlayerList::getPlayer(attack.target.guid)->getPtr();
if (attack.target.refId.empty())
{
if (attack.target.guid == mwmp::Main::get().getLocalPlayer()->guid)
{
victim = MWBase::Environment::get().getWorld()->getPlayerPtr();
}
else if (PlayerList::getPlayer(attack.target.guid) != NULL)
{
victim = PlayerList::getPlayer(attack.target.guid)->getPtr();
}
}
else
{
if (mwmp::Main::get().getCellController()->isLocalActor(attack.target.refId,
attack.target.refNumIndex, attack.target.mpNum))
{
victim = mwmp::Main::get().getCellController()->getLocalActor(attack.target.refId,
attack.target.refNumIndex, attack.target.mpNum)->getPtr();
}
else if (mwmp::Main::get().getCellController()->isDedicatedActor(attack.target.refId,
attack.target.refNumIndex, attack.target.mpNum))
{
victim = mwmp::Main::get().getCellController()->getDedicatedActor(attack.target.refId,
attack.target.refNumIndex, attack.target.mpNum)->getPtr();
}
}
// Get the weapon used (if hand-to-hand, weapon = inv.end())
if (attackerStats.getDrawState() == MWMechanics::DrawState_Weapon)
@ -124,7 +151,7 @@ void MechanicsHelper::processAttack(Attack attack, const MWWorld::Ptr& attacker)
if (!weapon.isEmpty() && weapon.getTypeName() != typeid(ESM::Weapon).name())
weapon = MWWorld::Ptr();
if (victim.mRef != 0)
if (victim.mRef != NULL)
{
bool healthdmg;
if (!weapon.isEmpty())

Loading…
Cancel
Save