mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 06:53:52 +00:00
[Client] Delimit and clarify combat changes made by tes3mp
Additionally, revert unneeded small changes to the formatting of OpenMW code
This commit is contained in:
parent
9f226253d4
commit
2565816b22
5 changed files with 154 additions and 25 deletions
|
@ -8,10 +8,18 @@
|
||||||
#include <components/esm/loadnpc.hpp>
|
#include <components/esm/loadnpc.hpp>
|
||||||
#include <components/esm/npcstate.hpp>
|
#include <components/esm/npcstate.hpp>
|
||||||
|
|
||||||
#include "../mwmp/DedicatedPlayer.hpp"
|
/*
|
||||||
#include "../mwmp/Networking.hpp"
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
Include additional headers for multiplayer purposes
|
||||||
|
*/
|
||||||
#include "../mwmp/Main.hpp"
|
#include "../mwmp/Main.hpp"
|
||||||
|
#include "../mwmp/Networking.hpp"
|
||||||
#include "../mwmp/LocalPlayer.hpp"
|
#include "../mwmp/LocalPlayer.hpp"
|
||||||
|
#include "../mwmp/DedicatedPlayer.hpp"
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
@ -553,8 +561,16 @@ namespace MWClass
|
||||||
|
|
||||||
void Npc::hit(const MWWorld::Ptr& ptr, float attackStrength, int type) const
|
void Npc::hit(const MWWorld::Ptr& ptr, float attackStrength, int type) const
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
Ignore hits from DedicatedPlayers
|
||||||
|
*/
|
||||||
if (mwmp::Main::get().getNetworking()->isDedicatedPlayer(ptr))
|
if (mwmp::Main::get().getNetworking()->isDedicatedPlayer(ptr))
|
||||||
return;
|
return;
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
|
|
||||||
|
@ -564,15 +580,15 @@ namespace MWClass
|
||||||
MWWorld::InventoryStore &inv = getInventoryStore(ptr);
|
MWWorld::InventoryStore &inv = getInventoryStore(ptr);
|
||||||
MWWorld::ContainerStoreIterator weaponslot = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
MWWorld::ContainerStoreIterator weaponslot = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
||||||
MWWorld::Ptr weapon = ((weaponslot != inv.end()) ? *weaponslot : MWWorld::Ptr());
|
MWWorld::Ptr weapon = ((weaponslot != inv.end()) ? *weaponslot : MWWorld::Ptr());
|
||||||
if (!weapon.isEmpty() && weapon.getTypeName() != typeid(ESM::Weapon).name())
|
if(!weapon.isEmpty() && weapon.getTypeName() != typeid(ESM::Weapon).name())
|
||||||
weapon = MWWorld::Ptr();
|
weapon = MWWorld::Ptr();
|
||||||
|
|
||||||
MWMechanics::applyFatigueLoss(ptr, weapon, attackStrength);
|
MWMechanics::applyFatigueLoss(ptr, weapon, attackStrength);
|
||||||
|
|
||||||
const float fCombatDistance = store.find("fCombatDistance")->getFloat();
|
const float fCombatDistance = store.find("fCombatDistance")->getFloat();
|
||||||
float dist = fCombatDistance * (!weapon.isEmpty() ?
|
float dist = fCombatDistance * (!weapon.isEmpty() ?
|
||||||
weapon.get<ESM::Weapon>()->mBase->mData.mReach :
|
weapon.get<ESM::Weapon>()->mBase->mData.mReach :
|
||||||
store.find("fHandToHandReach")->getFloat());
|
store.find("fHandToHandReach")->getFloat());
|
||||||
|
|
||||||
// For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit result.
|
// For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit result.
|
||||||
std::vector<MWWorld::Ptr> targetActors;
|
std::vector<MWWorld::Ptr> targetActors;
|
||||||
|
@ -582,16 +598,17 @@ namespace MWClass
|
||||||
// TODO: Use second to work out the hit angle
|
// TODO: Use second to work out the hit angle
|
||||||
std::pair<MWWorld::Ptr, osg::Vec3f> result = world->getHitContact(ptr, dist, targetActors);
|
std::pair<MWWorld::Ptr, osg::Vec3f> result = world->getHitContact(ptr, dist, targetActors);
|
||||||
MWWorld::Ptr victim = result.first;
|
MWWorld::Ptr victim = result.first;
|
||||||
osg::Vec3f hitPosition(result.second);
|
osg::Vec3f hitPosition (result.second);
|
||||||
if (victim.isEmpty()) // Didn't hit anything
|
if(victim.isEmpty()) // Didn't hit anything
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const MWWorld::Class &othercls = victim.getClass();
|
const MWWorld::Class &othercls = victim.getClass();
|
||||||
if (!othercls.isActor()) // Can't hit non-actors
|
if(!othercls.isActor()) // Can't hit non-actors
|
||||||
return;
|
return;
|
||||||
MWMechanics::CreatureStats &otherstats = othercls.getCreatureStats(victim);
|
MWMechanics::CreatureStats &otherstats = othercls.getCreatureStats(victim);
|
||||||
if (otherstats.isDead()) // Can't hit dead actors
|
if(otherstats.isDead()) // Can't hit dead actors
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(ptr == MWMechanics::getPlayer())
|
if(ptr == MWMechanics::getPlayer())
|
||||||
MWBase::Environment::get().getWindowManager()->setEnemy(victim);
|
MWBase::Environment::get().getWindowManager()->setEnemy(victim);
|
||||||
|
|
||||||
|
@ -601,6 +618,12 @@ namespace MWClass
|
||||||
|
|
||||||
float hitchance = MWMechanics::getHitChance(ptr, victim, ptr.getClass().getSkill(ptr, weapskill));
|
float hitchance = MWMechanics::getHitChance(ptr, victim, ptr.getClass().getSkill(ptr, weapskill));
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
If the attacker is a LocalPlayer and the target is a DedicatedPlayer,
|
||||||
|
mark that accordingly in the LocalPlayer data
|
||||||
|
*/
|
||||||
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||||
{
|
{
|
||||||
mwmp::Main::get().getLocalPlayer()->attack.success = true;
|
mwmp::Main::get().getLocalPlayer()->attack.success = true;
|
||||||
|
@ -608,14 +631,26 @@ namespace MWClass
|
||||||
if (dedicatedPlayer != nullptr)
|
if (dedicatedPlayer != nullptr)
|
||||||
mwmp::Main::get().getLocalPlayer()->attack.target = dedicatedPlayer->guid;
|
mwmp::Main::get().getLocalPlayer()->attack.target = dedicatedPlayer->guid;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
if(Misc::Rng::roll0to99() >= hitchance)
|
if (Misc::Rng::roll0to99() >= hitchance)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
If this was a failed attack by the LocalPlayer, send a
|
||||||
|
PlayerAttack packet about it
|
||||||
|
*/
|
||||||
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||||
{
|
{
|
||||||
mwmp::Main::get().getLocalPlayer()->attack.success = false;
|
mwmp::Main::get().getLocalPlayer()->attack.success = false;
|
||||||
mwmp::Main::get().getLocalPlayer()->sendAttack(mwmp::Attack::MELEE);
|
mwmp::Main::get().getLocalPlayer()->sendAttack(mwmp::Attack::MELEE);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
othercls.onHit(victim, 0.0f, false, weapon, ptr, osg::Vec3f(), false);
|
othercls.onHit(victim, 0.0f, false, weapon, ptr, osg::Vec3f(), false);
|
||||||
MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr);
|
MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr);
|
||||||
|
@ -763,13 +798,24 @@ namespace MWClass
|
||||||
float knockdownTerm = stats.getAttribute(ESM::Attribute::Agility).getModified()
|
float knockdownTerm = stats.getAttribute(ESM::Attribute::Agility).getModified()
|
||||||
* gmst.iKnockDownOddsMult->getInt() * 0.01f + gmst.iKnockDownOddsBase->getInt();
|
* gmst.iKnockDownOddsMult->getInt() * 0.01f + gmst.iKnockDownOddsBase->getInt();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp change (major)
|
||||||
|
|
||||||
|
If the attacker is a DedicatedPlayer with a successful knockdown, apply the knockdown;
|
||||||
|
otherwise, use default probability roll
|
||||||
|
*/
|
||||||
mwmp::DedicatedPlayer *dedicatedPlayer = mwmp::Players::getPlayer(attacker);
|
mwmp::DedicatedPlayer *dedicatedPlayer = mwmp::Players::getPlayer(attacker);
|
||||||
bool isDedicated = dedicatedPlayer != nullptr;
|
bool isDedicated = dedicatedPlayer != nullptr;
|
||||||
bool _knockdown = false;
|
bool isDedicatedKnockdown = false;
|
||||||
if(isDedicated)
|
if (isDedicated)
|
||||||
_knockdown = dedicatedPlayer->attack.knockdown;
|
isDedicatedKnockdown = dedicatedPlayer->attack.knockdown;
|
||||||
|
|
||||||
if ((!isDedicated && ishealth && agilityTerm <= damage && knockdownTerm <= Misc::Rng::roll0to99()) || _knockdown)
|
if (isDedicatedKnockdown)
|
||||||
|
stats.setKnockedDown(true);
|
||||||
|
else if (ishealth && agilityTerm <= damage && knockdownTerm <= Misc::Rng::roll0to99())
|
||||||
|
/*
|
||||||
|
End of tes3mp change (major)
|
||||||
|
*/
|
||||||
stats.setKnockedDown(true);
|
stats.setKnockedDown(true);
|
||||||
else
|
else
|
||||||
stats.setHitRecovery(true); // Is this supposed to always occur?
|
stats.setHitRecovery(true); // Is this supposed to always occur?
|
||||||
|
@ -871,7 +917,14 @@ namespace MWClass
|
||||||
MWBase::Environment::get().getMechanicsManager()->actorKilled(ptr, attacker);
|
MWBase::Environment::get().getMechanicsManager()->actorKilled(ptr, attacker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
If the victim was a DedicatedPlayer, send a PlayerAttack packet from LocalPlayer
|
||||||
|
|
||||||
|
If the victim was the LocalPlayer, check whether packets should be sent about
|
||||||
|
their new dynamic stats and position
|
||||||
|
*/
|
||||||
mwmp::DedicatedPlayer *victimPlayer = mwmp::Players::getPlayer(ptr);
|
mwmp::DedicatedPlayer *victimPlayer = mwmp::Players::getPlayer(ptr);
|
||||||
if (attacker == MWMechanics::getPlayer() && victimPlayer != nullptr)
|
if (attacker == MWMechanics::getPlayer() && victimPlayer != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -888,13 +941,25 @@ namespace MWClass
|
||||||
mwmp::Main::get().getLocalPlayer()->updateStatsDynamic(true);
|
mwmp::Main::get().getLocalPlayer()->updateStatsDynamic(true);
|
||||||
mwmp::Main::get().getLocalPlayer()->updatePosition(true); // fix position after getting damage;
|
mwmp::Main::get().getLocalPlayer()->updatePosition(true); // fix position after getting damage;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
Don't display a dialogue screen for two players interacting with each other
|
||||||
|
*/
|
||||||
if (actor == MWMechanics::getPlayer() && mwmp::Main::get().getNetworking()->isDedicatedPlayer(ptr))
|
if (actor == MWMechanics::getPlayer() && mwmp::Main::get().getNetworking()->isDedicatedPlayer(ptr))
|
||||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::FailedAction("Not implemented."));
|
return boost::shared_ptr<MWWorld::Action>(new MWWorld::FailedAction("Not implemented."));
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
// player got activated by another NPC
|
// player got activated by another NPC
|
||||||
if(ptr == MWMechanics::getPlayer())
|
if(ptr == MWMechanics::getPlayer())
|
||||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionTalk(actor));
|
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionTalk(actor));
|
||||||
|
|
|
@ -1109,6 +1109,12 @@ namespace MWMechanics
|
||||||
|
|
||||||
iter->second->getCharacterController()->setActive(inProcessingRange);
|
iter->second->getCharacterController()->setActive(inProcessingRange);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp change (minor)
|
||||||
|
|
||||||
|
Instead of merely updating the player character's mAttackingOrSpell here,
|
||||||
|
send a PlayerAttack packet from LocalPlayer when applicable
|
||||||
|
*/
|
||||||
if (iter->first == player)
|
if (iter->first == player)
|
||||||
{
|
{
|
||||||
bool state = MWBase::Environment::get().getWorld()->getPlayer().getAttackingOrSpell();
|
bool state = MWBase::Environment::get().getWorld()->getPlayer().getAttackingOrSpell();
|
||||||
|
@ -1117,10 +1123,21 @@ namespace MWMechanics
|
||||||
if (dstate == DrawState_Weapon)
|
if (dstate == DrawState_Weapon)
|
||||||
mwmp::Main::get().getLocalPlayer()->prepareAttack(mwmp::Attack::MELEE, state);
|
mwmp::Main::get().getLocalPlayer()->prepareAttack(mwmp::Attack::MELEE, state);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
End of tes3mp change (minor)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
If this actor is a DedicatedPlayer, update their mAttackingOrSpell
|
||||||
|
*/
|
||||||
mwmp::DedicatedPlayer *dedicatedPlayer = mwmp::Players::getPlayer(iter->first);
|
mwmp::DedicatedPlayer *dedicatedPlayer = mwmp::Players::getPlayer(iter->first);
|
||||||
if (dedicatedPlayer != NULL)
|
if (dedicatedPlayer != NULL)
|
||||||
dedicatedPlayer->updateActor(iter->second);
|
dedicatedPlayer->updateActor(iter->second);
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
// If dead or no longer in combat, no longer store any actors who attempted to hit us. Also remove for the player.
|
// If dead or no longer in combat, no longer store any actors who attempted to hit us. Also remove for the player.
|
||||||
|
|
|
@ -1254,8 +1254,16 @@ bool CharacterController::updateWeaponState()
|
||||||
|
|
||||||
if(!spellid.empty() && MWBase::Environment::get().getWorld()->startSpellCast(mPtr))
|
if(!spellid.empty() && MWBase::Environment::get().getWorld()->startSpellCast(mPtr))
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
Send PlayerAttack packet for this spell
|
||||||
|
*/
|
||||||
if (mPtr == getPlayer())
|
if (mPtr == getPlayer())
|
||||||
mwmp::Main::get().getLocalPlayer()->prepareAttack(mwmp::Attack::MAGIC, true);
|
mwmp::Main::get().getLocalPlayer()->prepareAttack(mwmp::Attack::MAGIC, true);
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
MWMechanics::CastSpell cast(mPtr, NULL);
|
MWMechanics::CastSpell cast(mPtr, NULL);
|
||||||
cast.playSpellCastingEffects(spellid);
|
cast.playSpellCastingEffects(spellid);
|
||||||
|
|
|
@ -117,7 +117,12 @@ namespace MWMechanics
|
||||||
int iBlockMinChance = gmst.find("iBlockMinChance")->getInt();
|
int iBlockMinChance = gmst.find("iBlockMinChance")->getInt();
|
||||||
x = std::min(iBlockMaxChance, std::max(iBlockMinChance, x));
|
x = std::min(iBlockMaxChance, std::max(iBlockMinChance, x));
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp change (major)
|
||||||
|
|
||||||
|
Only calculate block chance for blockers who are not DedicatedPlayers
|
||||||
|
and update block state for LocalPlayer
|
||||||
|
*/
|
||||||
mwmp::DedicatedPlayer *dedicatedPlayer = mwmp::Players::getPlayer(blocker);
|
mwmp::DedicatedPlayer *dedicatedPlayer = mwmp::Players::getPlayer(blocker);
|
||||||
bool isDedicated = dedicatedPlayer != NULL;
|
bool isDedicated = dedicatedPlayer != NULL;
|
||||||
if (attacker == MWMechanics::getPlayer())
|
if (attacker == MWMechanics::getPlayer())
|
||||||
|
@ -128,6 +133,9 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
if (attacker == MWMechanics::getPlayer())
|
if (attacker == MWMechanics::getPlayer())
|
||||||
mwmp::Main::get().getLocalPlayer()->attack.block = true;
|
mwmp::Main::get().getLocalPlayer()->attack.block = true;
|
||||||
|
/*
|
||||||
|
End of tes3mp change (major)
|
||||||
|
*/
|
||||||
|
|
||||||
// Reduce shield durability by incoming damage
|
// Reduce shield durability by incoming damage
|
||||||
int shieldhealth = shield->getClass().getItemHealth(*shield);
|
int shieldhealth = shield->getClass().getItemHealth(*shield);
|
||||||
|
@ -183,8 +191,17 @@ namespace MWMechanics
|
||||||
void projectileHit(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, MWWorld::Ptr weapon, const MWWorld::Ptr& projectile,
|
void projectileHit(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, MWWorld::Ptr weapon, const MWWorld::Ptr& projectile,
|
||||||
const osg::Vec3f& hitPosition, float attackStrength)
|
const osg::Vec3f& hitPosition, float attackStrength)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
Ignore projectiles fired by DedicatedPlayers
|
||||||
|
*/
|
||||||
if (mwmp::Main::get().getNetworking()->isDedicatedPlayer(attacker))
|
if (mwmp::Main::get().getNetworking()->isDedicatedPlayer(attacker))
|
||||||
return;
|
return;
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
|
@ -202,13 +219,31 @@ namespace MWMechanics
|
||||||
|
|
||||||
int skillValue = attacker.getClass().getSkill(attacker, weapon.getClass().getEquipmentSkill(weapon));
|
int skillValue = attacker.getClass().getSkill(attacker, weapon.getClass().getEquipmentSkill(weapon));
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
Mark this as a successful attack for LocalPlayer unless proven otherwise
|
||||||
|
*/
|
||||||
if (attacker == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
if (attacker == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||||
mwmp::Main::get().getLocalPlayer()->attack.success = true;
|
mwmp::Main::get().getLocalPlayer()->attack.success = true;
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
if (Misc::Rng::roll0to99() >= getHitChance(attacker, victim, skillValue))
|
if (Misc::Rng::roll0to99() >= getHitChance(attacker, victim, skillValue))
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
Mark this as a failed attack for LocalPlayer now that the hit roll
|
||||||
|
has failed
|
||||||
|
*/
|
||||||
if (attacker == getPlayer())
|
if (attacker == getPlayer())
|
||||||
mwmp::Main::get().getLocalPlayer()->attack.success = false;
|
mwmp::Main::get().getLocalPlayer()->attack.success = false;
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
victim.getClass().onHit(victim, damage, false, projectile, attacker, osg::Vec3f(), false);
|
victim.getClass().onHit(victim, damage, false, projectile, attacker, osg::Vec3f(), false);
|
||||||
MWMechanics::reduceWeaponCondition(damage, false, weapon, attacker);
|
MWMechanics::reduceWeaponCondition(damage, false, weapon, attacker);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -836,17 +836,18 @@ namespace MWMechanics
|
||||||
|
|
||||||
bool fail = false;
|
bool fail = false;
|
||||||
|
|
||||||
// Major change done by tes3mp:
|
/*
|
||||||
//
|
Start of tes3mp change (major)
|
||||||
// Instead of checking whether the caster is a player or an NPC,
|
|
||||||
// first check whether it's the LocalPlayer or a DedicatedPlayer and calculate
|
|
||||||
// calculate the success chance in clients' LocalPlayer::prepareAttack()
|
|
||||||
//
|
|
||||||
// TODO: Make this make sense for NPCs too
|
|
||||||
//
|
|
||||||
// TODO: See if LocalPlayer being the target and having godmode on
|
|
||||||
// can be accounted for like it is in OpenMW's corresponding code
|
|
||||||
|
|
||||||
|
Instead of checking whether the caster is a player or an NPC,
|
||||||
|
first check whether it's the LocalPlayer or a DedicatedPlayer and calculate
|
||||||
|
calculate the success chance in clients' LocalPlayer::prepareAttack()
|
||||||
|
|
||||||
|
TODO: Make this make sense for NPCs too
|
||||||
|
|
||||||
|
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::Players::getPlayer(mCaster);
|
mwmp::DedicatedPlayer *dedicatedPlayer = mwmp::Players::getPlayer(mCaster);
|
||||||
bool isDedicated = dedicatedPlayer != NULL;
|
bool isDedicated = dedicatedPlayer != NULL;
|
||||||
|
|
||||||
|
@ -864,6 +865,9 @@ namespace MWMechanics
|
||||||
fail = true;
|
fail = true;
|
||||||
}
|
}
|
||||||
else if (!(mCaster == getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState()))
|
else if (!(mCaster == getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState()))
|
||||||
|
/*
|
||||||
|
End of tes3mp change (major)
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
float successChance = getSpellSuccessChance(spell, mCaster);
|
float successChance = getSpellSuccessChance(spell, mCaster);
|
||||||
if (Misc::Rng::roll0to99() >= successChance)
|
if (Misc::Rng::roll0to99() >= successChance)
|
||||||
|
|
Loading…
Reference in a new issue