|
|
@ -2,7 +2,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
#include <OgreMath.h>
|
|
|
|
#include <OgreMath.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include <openengine/misc/rng.hpp>
|
|
|
|
#include <components/misc/rng.hpp>
|
|
|
|
|
|
|
|
|
|
|
|
#include <components/esm/aisequence.hpp>
|
|
|
|
#include <components/esm/aisequence.hpp>
|
|
|
|
|
|
|
|
|
|
|
@ -396,7 +396,7 @@ namespace MWMechanics
|
|
|
|
if (!distantCombat) attackType = chooseBestAttack(weapon, movement);
|
|
|
|
if (!distantCombat) attackType = chooseBestAttack(weapon, movement);
|
|
|
|
else attackType = ESM::Weapon::AT_Chop; // cause it's =0
|
|
|
|
else attackType = ESM::Weapon::AT_Chop; // cause it's =0
|
|
|
|
|
|
|
|
|
|
|
|
strength = OEngine::Misc::Rng::rollClosedProbability();
|
|
|
|
strength = Misc::Rng::rollClosedProbability();
|
|
|
|
|
|
|
|
|
|
|
|
// Note: may be 0 for some animations
|
|
|
|
// Note: may be 0 for some animations
|
|
|
|
timerAttack = minMaxAttackDuration[attackType][0] +
|
|
|
|
timerAttack = minMaxAttackDuration[attackType][0] +
|
|
|
@ -407,7 +407,7 @@ namespace MWMechanics
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const MWWorld::ESMStore &store = world->getStore();
|
|
|
|
const MWWorld::ESMStore &store = world->getStore();
|
|
|
|
int chance = store.get<ESM::GameSetting>().find("iVoiceAttackOdds")->getInt();
|
|
|
|
int chance = store.get<ESM::GameSetting>().find("iVoiceAttackOdds")->getInt();
|
|
|
|
if (OEngine::Misc::Rng::roll0to99() < chance)
|
|
|
|
if (Misc::Rng::roll0to99() < chance)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
MWBase::Environment::get().getDialogueManager()->say(actor, "attack");
|
|
|
|
MWBase::Environment::get().getDialogueManager()->say(actor, "attack");
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -514,17 +514,17 @@ namespace MWMechanics
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(movement.mPosition[0] || movement.mPosition[1])
|
|
|
|
if(movement.mPosition[0] || movement.mPosition[1])
|
|
|
|
{
|
|
|
|
{
|
|
|
|
timerCombatMove = 0.1f + 0.1f * OEngine::Misc::Rng::rollClosedProbability();
|
|
|
|
timerCombatMove = 0.1f + 0.1f * Misc::Rng::rollClosedProbability();
|
|
|
|
combatMove = true;
|
|
|
|
combatMove = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// only NPCs are smart enough to use dodge movements
|
|
|
|
// only NPCs are smart enough to use dodge movements
|
|
|
|
else if(actorClass.isNpc() && (!distantCombat || (distantCombat && distToTarget < rangeAttack/2)))
|
|
|
|
else if(actorClass.isNpc() && (!distantCombat || (distantCombat && distToTarget < rangeAttack/2)))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//apply sideway movement (kind of dodging) with some probability
|
|
|
|
//apply sideway movement (kind of dodging) with some probability
|
|
|
|
if (OEngine::Misc::Rng::rollClosedProbability() < 0.25)
|
|
|
|
if (Misc::Rng::rollClosedProbability() < 0.25)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
movement.mPosition[0] = OEngine::Misc::Rng::rollProbability() < 0.5 ? 1.0f : -1.0f;
|
|
|
|
movement.mPosition[0] = Misc::Rng::rollProbability() < 0.5 ? 1.0f : -1.0f;
|
|
|
|
timerCombatMove = 0.05f + 0.15f * OEngine::Misc::Rng::rollClosedProbability();
|
|
|
|
timerCombatMove = 0.05f + 0.15f * Misc::Rng::rollClosedProbability();
|
|
|
|
combatMove = true;
|
|
|
|
combatMove = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -639,7 +639,7 @@ namespace MWMechanics
|
|
|
|
float s2 = speed2 * t;
|
|
|
|
float s2 = speed2 * t;
|
|
|
|
float t_swing =
|
|
|
|
float t_swing =
|
|
|
|
minMaxAttackDuration[ESM::Weapon::AT_Thrust][0] +
|
|
|
|
minMaxAttackDuration[ESM::Weapon::AT_Thrust][0] +
|
|
|
|
(minMaxAttackDuration[ESM::Weapon::AT_Thrust][1] - minMaxAttackDuration[ESM::Weapon::AT_Thrust][0]) * OEngine::Misc::Rng::rollClosedProbability();
|
|
|
|
(minMaxAttackDuration[ESM::Weapon::AT_Thrust][1] - minMaxAttackDuration[ESM::Weapon::AT_Thrust][0]) * Misc::Rng::rollClosedProbability();
|
|
|
|
|
|
|
|
|
|
|
|
if (t + s2/speed1 <= t_swing)
|
|
|
|
if (t + s2/speed1 <= t_swing)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -763,10 +763,10 @@ ESM::Weapon::AttackType chooseBestAttack(const ESM::Weapon* weapon, MWMechanics:
|
|
|
|
if (weapon == NULL)
|
|
|
|
if (weapon == NULL)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//hand-to-hand deal equal damage for each type
|
|
|
|
//hand-to-hand deal equal damage for each type
|
|
|
|
float roll = OEngine::Misc::Rng::rollClosedProbability();
|
|
|
|
float roll = Misc::Rng::rollClosedProbability();
|
|
|
|
if(roll <= 0.333f) //side punch
|
|
|
|
if(roll <= 0.333f) //side punch
|
|
|
|
{
|
|
|
|
{
|
|
|
|
movement.mPosition[0] = OEngine::Misc::Rng::rollClosedProbability() ? 1.0f : -1.0f;
|
|
|
|
movement.mPosition[0] = Misc::Rng::rollClosedProbability() ? 1.0f : -1.0f;
|
|
|
|
movement.mPosition[1] = 0;
|
|
|
|
movement.mPosition[1] = 0;
|
|
|
|
attackType = ESM::Weapon::AT_Slash;
|
|
|
|
attackType = ESM::Weapon::AT_Slash;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -790,10 +790,10 @@ ESM::Weapon::AttackType chooseBestAttack(const ESM::Weapon* weapon, MWMechanics:
|
|
|
|
|
|
|
|
|
|
|
|
float total = static_cast<float>(slash + chop + thrust);
|
|
|
|
float total = static_cast<float>(slash + chop + thrust);
|
|
|
|
|
|
|
|
|
|
|
|
float roll = OEngine::Misc::Rng::rollClosedProbability();
|
|
|
|
float roll = Misc::Rng::rollClosedProbability();
|
|
|
|
if(roll <= (slash/total))
|
|
|
|
if(roll <= (slash/total))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
movement.mPosition[0] = (OEngine::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 = ESM::Weapon::AT_Slash;
|
|
|
|
}
|
|
|
|
}
|
|
|
|