Centralized "fish can't attack non-swimmer" logic.

pull/441/head
dteviot 10 years ago
parent 7aa0f887c0
commit 458b82c308

@ -37,6 +37,7 @@
#include "actor.hpp"
#include "summoning.hpp"
#include "combat.hpp"
namespace
{
@ -309,10 +310,10 @@ namespace MWMechanics
// pure water creatures won't try to fight with the target on the ground
// except that creature is already hostile
if ((againstPlayer || !creatureStats.getAiSequence().isInCombat())
&& ((actor1.getClass().isPureWaterCreature(actor1)
&& !MWBase::Environment::get().getWorld()->isWading(actor2))
|| (!actor1.getClass().canSwim(actor1) && MWBase::Environment::get().getWorld()->isSwimming(actor2)))) // creature can't swim to target
&& !MWMechanics::isEnvironmentCompatible(actor1, actor2)) // creature can't swim to target
{
return;
}
bool aggressive;

@ -23,6 +23,7 @@
#include "character.hpp" // fixme: for getActiveWeapon
#include "aicombataction.hpp"
#include "combat.hpp"
namespace
{
@ -206,12 +207,8 @@ namespace MWMechanics
const MWWorld::Class& actorClass = actor.getClass();
MWBase::World* world = MWBase::Environment::get().getWorld();
if (!actorClass.isNpc() &&
// 1. pure water creature and Player moved out of water
((target == world->getPlayerPtr() &&
actorClass.isPureWaterCreature(actor) && !world->isWading(target))
// 2. creature can't swim to target
|| (!actorClass.canSwim(actor) && world->isSwimming(target))))
// can't fight if attacker can't go where target is. E.g. A fish can't attack person on land.
if (!actorClass.isNpc() && !MWMechanics::isEnvironmentCompatible(actor, target))
{
actorClass.getCreatureStats(actor).setAttackingOrSpell(false);
return true;

@ -367,4 +367,24 @@ namespace MWMechanics
else
sndMgr->playSound3D(victim, "Hand To Hand Hit", 1.0f, 1.0f);
}
bool isEnvironmentCompatible(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim)
{
const MWWorld::Class& attackerClass = attacker.getClass();
MWBase::World* world = MWBase::Environment::get().getWorld();
// If attacker is fish, victim must be in water
if (attackerClass.isPureWaterCreature(attacker))
{
return world->isWading(victim);
}
// If attacker can't swim, victim must not be in water
if (!attackerClass.canSwim(attacker))
{
return !world->isSwimming(victim);
}
return true;
}
}

@ -34,6 +34,10 @@ void adjustWeaponDamage (float& damage, const MWWorld::Ptr& weapon);
void getHandToHandDamage (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, float& damage, bool& healthdmg);
/// Can attacker operate in victim's environment?
/// e.g. If attacker is a fish, is victim in water? Or, if attacker can't swim, is victim on land?
bool isEnvironmentCompatible(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim);
}
#endif

Loading…
Cancel
Save