From a1d9f11b04dbff794889d816ee4bb31fab05bb32 Mon Sep 17 00:00:00 2001 From: rexelion Date: Tue, 7 Nov 2017 11:43:21 +0000 Subject: [PATCH 1/5] use fProjectileMaxSpeed for ranged weapons distance --- apps/openmw/mwmechanics/aicombataction.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/aicombataction.cpp b/apps/openmw/mwmechanics/aicombataction.cpp index d44498966..df636dd56 100644 --- a/apps/openmw/mwmechanics/aicombataction.cpp +++ b/apps/openmw/mwmechanics/aicombataction.cpp @@ -115,6 +115,7 @@ namespace MWMechanics isRanged = false; static const float fCombatDistance = MWBase::Environment::get().getWorld()->getStore().get().find("fCombatDistance")->getFloat(); + static const float fProjectileMaxSpeed = MWBase::Environment::get().getWorld()->getStore().get().find("fProjectileMaxSpeed")->getFloat(); if (mWeapon.isEmpty()) { @@ -128,7 +129,7 @@ namespace MWMechanics if (weapon->mData.mType >= ESM::Weapon::MarksmanBow) { isRanged = true; - return 1000.f; + return fProjectileMaxSpeed; } else return weapon->mData.mReach * fCombatDistance; From cab00024615730360fba3f66fc2cfb058acabea3 Mon Sep 17 00:00:00 2001 From: rexelion Date: Tue, 7 Nov 2017 17:57:23 +0000 Subject: [PATCH 2/5] Backing up distance is now dependent on opponents's weapon range; don't back up from ranged oponents --- apps/openmw/mwmechanics/aicombat.cpp | 49 ++++++++++++++-------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 68d282d0c..cd9211a3f 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -490,6 +490,28 @@ namespace MWMechanics void AiCombatStorage::startCombatMove(bool isDistantCombat, float distToTarget, float rangeAttack, const MWWorld::Ptr& actor, const MWWorld::Ptr& target) { + // get the range of the target's weapon + float rangeAttackOfTarget = 0.f; + MWWorld::Ptr targetWeapon = MWWorld::Ptr(); + const MWWorld::Class& targetClass = target.getClass(); + + if (targetClass.hasInventoryStore(target)) + { + MWMechanics::WeaponType weapType = WeapType_None; + MWWorld::ContainerStoreIterator weaponSlot = + MWMechanics::getActiveWeapon(targetClass.getCreatureStats(target), targetClass.getInventoryStore(target), &weapType); + if (weapType != WeapType_PickProbe && weapType != WeapType_Spell && weapType != WeapType_None && weapType != WeapType_HandToHand) + targetWeapon = *weaponSlot; + } + + std::shared_ptr targetWeaponAction(new ActionWeapon(targetWeapon)); + + bool isRangedCombat = false; + if (targetWeaponAction.get()) + { + rangeAttackOfTarget = targetWeaponAction->getCombatRange(isRangedCombat); + } + if (mMovement.mPosition[0] || mMovement.mPosition[1]) { mTimerCombatMove = 0.1f + 0.1f * Misc::Rng::rollClosedProbability(); @@ -498,28 +520,6 @@ namespace MWMechanics // dodge movements (for NPCs and bipedal creatures) else if (actor.getClass().isBipedal(actor)) { - // get the range of the target's weapon - float rangeAttackOfTarget = 0.f; - MWWorld::Ptr targetWeapon = MWWorld::Ptr(); - const MWWorld::Class& targetClass = target.getClass(); - - if (targetClass.hasInventoryStore(target)) - { - MWMechanics::WeaponType weapType = WeapType_None; - MWWorld::ContainerStoreIterator weaponSlot = - MWMechanics::getActiveWeapon(targetClass.getCreatureStats(target), targetClass.getInventoryStore(target), &weapType); - if (weapType != WeapType_PickProbe && weapType != WeapType_Spell && weapType != WeapType_None && weapType != WeapType_HandToHand) - targetWeapon = *weaponSlot; - } - - std::shared_ptr targetWeaponAction (new ActionWeapon(targetWeapon)); - - if (targetWeaponAction.get()) - { - bool isRangedCombat = false; - rangeAttackOfTarget = targetWeaponAction->getCombatRange(isRangedCombat); - } - // apply sideway movement (kind of dodging) with some probability // if actor is within range of target's weapon if (distToTarget <= rangeAttackOfTarget && Misc::Rng::rollClosedProbability() < 0.25) @@ -533,13 +533,14 @@ namespace MWMechanics // Below behavior for backing up during ranged combat differs from vanilla. // Vanilla is observed as backing up only as far as fCombatDistance or // opponent's weapon range, or not backing up if opponent is also using a ranged weapon - if (isDistantCombat && distToTarget < rangeAttack / 4) + if (isDistantCombat) { // actor should not back up into water if (MWBase::Environment::get().getWorld()->isUnderwater(MWWorld::ConstPtr(actor), 0.5f)) return; - mMovement.mPosition[1] = -1; + if (!isRangedCombat && distToTarget <= rangeAttackOfTarget*1.5) // Don't back up if the target is wielding ranged weapon + mMovement.mPosition[1] = -1; } } From 983c33c4c89209ef6679743cd9f17654d4265eb4 Mon Sep 17 00:00:00 2001 From: rexelion Date: Thu, 9 Nov 2017 14:23:26 +0000 Subject: [PATCH 3/5] don't use a pointer for ActionWeapon --- apps/openmw/mwmechanics/aicombat.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index cd9211a3f..6e3268831 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -504,13 +504,8 @@ namespace MWMechanics targetWeapon = *weaponSlot; } - std::shared_ptr targetWeaponAction(new ActionWeapon(targetWeapon)); - bool isRangedCombat = false; - if (targetWeaponAction.get()) - { - rangeAttackOfTarget = targetWeaponAction->getCombatRange(isRangedCombat); - } + rangeAttackOfTarget = ActionWeapon(targetWeapon).getCombatRange(isRangedCombat); if (mMovement.mPosition[0] || mMovement.mPosition[1]) { From 69a56eaea3fee303e3ef58d58d5ca6bd43668143 Mon Sep 17 00:00:00 2001 From: rexelion Date: Fri, 10 Nov 2017 10:44:53 +0000 Subject: [PATCH 4/5] don't initialise rangeAttackOfTarget --- apps/openmw/mwmechanics/aicombat.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 6e3268831..07fb455f3 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -491,7 +491,6 @@ namespace MWMechanics void AiCombatStorage::startCombatMove(bool isDistantCombat, float distToTarget, float rangeAttack, const MWWorld::Ptr& actor, const MWWorld::Ptr& target) { // get the range of the target's weapon - float rangeAttackOfTarget = 0.f; MWWorld::Ptr targetWeapon = MWWorld::Ptr(); const MWWorld::Class& targetClass = target.getClass(); @@ -505,7 +504,7 @@ namespace MWMechanics } bool isRangedCombat = false; - rangeAttackOfTarget = ActionWeapon(targetWeapon).getCombatRange(isRangedCombat); + float rangeAttackOfTarget = ActionWeapon(targetWeapon).getCombatRange(isRangedCombat); if (mMovement.mPosition[0] || mMovement.mPosition[1]) { From f0649849b87be452acbab3307a145992c16f0101 Mon Sep 17 00:00:00 2001 From: rexelion Date: Sat, 11 Nov 2017 12:00:23 +0000 Subject: [PATCH 5/5] changed variable name to be more descriptive --- apps/openmw/mwmechanics/aicombat.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 07fb455f3..ee1013fe4 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -503,8 +503,8 @@ namespace MWMechanics targetWeapon = *weaponSlot; } - bool isRangedCombat = false; - float rangeAttackOfTarget = ActionWeapon(targetWeapon).getCombatRange(isRangedCombat); + bool targetUsesRanged = false; + float rangeAttackOfTarget = ActionWeapon(targetWeapon).getCombatRange(targetUsesRanged); if (mMovement.mPosition[0] || mMovement.mPosition[1]) { @@ -524,16 +524,17 @@ namespace MWMechanics } } - // Below behavior for backing up during ranged combat differs from vanilla. - // Vanilla is observed as backing up only as far as fCombatDistance or - // opponent's weapon range, or not backing up if opponent is also using a ranged weapon + // Backing up behaviour + // Actor backs up slightly further away than opponent's weapon range + // (in vanilla - only as far as oponent's weapon range), + // or not at all if opponent is using a ranged weapon if (isDistantCombat) { // actor should not back up into water if (MWBase::Environment::get().getWorld()->isUnderwater(MWWorld::ConstPtr(actor), 0.5f)) return; - if (!isRangedCombat && distToTarget <= rangeAttackOfTarget*1.5) // Don't back up if the target is wielding ranged weapon + if (!targetUsesRanged && distToTarget <= rangeAttackOfTarget*1.5) // Don't back up if the target is wielding ranged weapon mMovement.mPosition[1] = -1; } }