Let NPCs use attack type regardless of movement

This commit is contained in:
Allofich 2016-09-01 22:43:33 +09:00
parent b92a4f1a32
commit 154dcc942c
3 changed files with 25 additions and 17 deletions

View file

@ -23,7 +23,7 @@ namespace
{ {
//chooses an attack depending on probability to avoid uniformity //chooses an attack depending on probability to avoid uniformity
ESM::Weapon::AttackType chooseBestAttack(const ESM::Weapon* weapon, MWMechanics::Movement &movement); std::string chooseBestAttack(const ESM::Weapon* weapon, MWMechanics::Movement &movement);
osg::Vec3f AimDirToMovingTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, const osg::Vec3f& vLastTargetPos, osg::Vec3f AimDirToMovingTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, const osg::Vec3f& vLastTargetPos,
float duration, int weapType, float strength); float duration, int weapType, float strength);
@ -630,7 +630,7 @@ namespace MWMechanics
characterController.setAttackingOrSpell(true); characterController.setAttackingOrSpell(true);
if (!distantCombat) if (!distantCombat)
chooseBestAttack(weapon, mMovement); characterController.setAIAttackType(chooseBestAttack(weapon, mMovement));
mStrength = Misc::Rng::rollClosedProbability(); mStrength = Misc::Rng::rollClosedProbability();
@ -678,9 +678,9 @@ namespace MWMechanics
namespace namespace
{ {
ESM::Weapon::AttackType chooseBestAttack(const ESM::Weapon* weapon, MWMechanics::Movement &movement) std::string chooseBestAttack(const ESM::Weapon* weapon, MWMechanics::Movement &movement)
{ {
ESM::Weapon::AttackType attackType; std::string attackType;
if (weapon == NULL) if (weapon == NULL)
{ {
@ -690,17 +690,17 @@ ESM::Weapon::AttackType chooseBestAttack(const ESM::Weapon* weapon, MWMechanics:
{ {
movement.mPosition[0] = (Misc::Rng::rollClosedProbability() < 0.5f) ? 1.0f : -1.0f; movement.mPosition[0] = (Misc::Rng::rollClosedProbability() < 0.5f) ? 1.0f : -1.0f;
movement.mPosition[1] = 0; movement.mPosition[1] = 0;
attackType = ESM::Weapon::AT_Slash; attackType = "slash";
} }
else if(roll <= 0.666f) //forward punch else if(roll <= 0.666f) //forward punch
{ {
movement.mPosition[1] = 1; movement.mPosition[1] = 1;
attackType = ESM::Weapon::AT_Thrust; attackType = "thrust";
} }
else else
{ {
movement.mPosition[1] = movement.mPosition[0] = 0; movement.mPosition[1] = movement.mPosition[0] = 0;
attackType = ESM::Weapon::AT_Chop; attackType = "chop";
} }
} }
else else
@ -715,17 +715,17 @@ ESM::Weapon::AttackType chooseBestAttack(const ESM::Weapon* weapon, MWMechanics:
{ {
movement.mPosition[0] = (Misc::Rng::rollClosedProbability() < 0.5f) ? 1.0f : -1.0f; movement.mPosition[0] = (Misc::Rng::rollClosedProbability() < 0.5f) ? 1.0f : -1.0f;
movement.mPosition[1] = 0; movement.mPosition[1] = 0;
attackType = ESM::Weapon::AT_Slash; attackType = "slash";
} }
else if(roll <= (slash + thrust)) else if(roll <= (slash + thrust))
{ {
movement.mPosition[1] = 1; movement.mPosition[1] = 1;
attackType = ESM::Weapon::AT_Thrust; attackType = "thrust";
} }
else else
{ {
movement.mPosition[1] = movement.mPosition[0] = 0; movement.mPosition[1] = movement.mPosition[0] = 0;
attackType = ESM::Weapon::AT_Chop; attackType = "chop";
} }
} }

View file

@ -1208,7 +1208,6 @@ bool CharacterController::updateWeaponState()
if(mUpperBodyState == UpperCharState_WeapEquiped && (mHitState == CharState_None || mHitState == CharState_Block)) if(mUpperBodyState == UpperCharState_WeapEquiped && (mHitState == CharState_None || mHitState == CharState_Block))
{ {
MWBase::Environment::get().getWorld()->breakInvisibility(mPtr); MWBase::Environment::get().getWorld()->breakInvisibility(mPtr);
mAttackType.clear();
if(mWeaponType == WeapType_Spell) if(mWeaponType == WeapType_Spell)
{ {
// Unset casting flag, otherwise pressing the mouse button down would // Unset casting flag, otherwise pressing the mouse button down would
@ -1309,8 +1308,9 @@ bool CharacterController::updateWeaponState()
{ {
if (isWeapon) if (isWeapon)
{ {
if(mPtr == getPlayer() && if(mPtr == getPlayer())
Settings::Manager::getBool("best attack", "Game")) {
if (Settings::Manager::getBool("best attack", "Game"))
{ {
MWWorld::ContainerStoreIterator weapon = mPtr.getClass().getInventoryStore(mPtr).getSlot(MWWorld::InventoryStore::Slot_CarriedRight); MWWorld::ContainerStoreIterator weapon = mPtr.getClass().getInventoryStore(mPtr).getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
mAttackType = getBestAttack(weapon->get<ESM::Weapon>()->mBase); mAttackType = getBestAttack(weapon->get<ESM::Weapon>()->mBase);
@ -1318,6 +1318,8 @@ bool CharacterController::updateWeaponState()
else else
setAttackTypeBasedOnMovement(); setAttackTypeBasedOnMovement();
} }
// else if (mPtr != getPlayer()) use mAttackType already set by AiCombat
}
else else
setAttackTypeRandomly(); setAttackTypeRandomly();
} }
@ -2227,6 +2229,11 @@ void CharacterController::setAttackingOrSpell(bool attackingOrSpell)
mAttackingOrSpell = attackingOrSpell; mAttackingOrSpell = attackingOrSpell;
} }
void CharacterController::setAIAttackType(std::string attackType)
{
mAttackType = attackType;
}
bool CharacterController::readyToPrepareAttack() const bool CharacterController::readyToPrepareAttack() const
{ {
return (mHitState == CharState_None || mHitState == CharState_Block) return (mHitState == CharState_None || mHitState == CharState_Block)

View file

@ -269,6 +269,7 @@ public:
bool isSneaking() const; bool isSneaking() const;
void setAttackingOrSpell(bool attackingOrSpell); void setAttackingOrSpell(bool attackingOrSpell);
void setAIAttackType(std::string attackType); // set and used by AiCombat
bool readyToPrepareAttack() const; bool readyToPrepareAttack() const;
bool readyToStartAttack() const; bool readyToStartAttack() const;