Commit f0cef772 authored by Andrei Kortunov's avatar Andrei Kortunov

Refactor weapon types behaviour

1. Move weapon types behaviour from switches to the table (should allow
us to de-hardcode weapon types later)
2. Gereralize bones injection to actors skeletons (instead of using the
hardcoded xbase_anim_sh.nif)
parent 25dc06db
......@@ -83,7 +83,7 @@ add_openmw_dir (mwmechanics
drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow aiavoiddoor aibreathe
aicast aiescort aiface aiactivate aicombat repair enchanting pathfinding pathgrid security spellsuccess spellcasting
disease pickpocket levelledlist combat steering obstacle autocalcspell difficultyscaling aicombataction actor summoning
character actors objects aistate coordinateconverter trading weaponpriority spellpriority
character actors objects aistate coordinateconverter trading weaponpriority spellpriority weapontype
)
add_openmw_dir (mwstate
......
......@@ -20,6 +20,7 @@
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "../mwmechanics/actorutil.hpp"
#include "../mwmechanics/weapontype.hpp"
#include "../mwgui/tooltips.hpp"
......@@ -332,21 +333,13 @@ namespace MWClass
if(*slot == MWWorld::InventoryStore::Slot_CarriedLeft)
{
MWWorld::ConstContainerStoreIterator weapon = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
if(weapon == invStore.end())
return std::make_pair(1,"");
if(weapon->getTypeName() == typeid(ESM::Weapon).name() &&
(weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::LongBladeTwoHand ||
weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::BluntTwoClose ||
weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::BluntTwoWide ||
weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::SpearTwoWide ||
weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::AxeTwoHand ||
weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanBow ||
weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow))
if(weapon != invStore.end() && weapon->getTypeName() == typeid(ESM::Weapon).name())
{
return std::make_pair(3,"");
const MWWorld::LiveCellRef<ESM::Weapon> *ref = weapon->get<ESM::Weapon>();
if (MWMechanics::getWeaponType(ref->mBase->mData.mType)->mFlags & ESM::WeaponType::TwoHanded)
return std::make_pair(3,"");
}
return std::make_pair(1,"");
}
}
......
......@@ -26,7 +26,7 @@
#include "../mwmechanics/combat.hpp"
#include "../mwmechanics/autocalcspell.hpp"
#include "../mwmechanics/difficultyscaling.hpp"
#include "../mwmechanics/character.hpp"
#include "../mwmechanics/weapontype.hpp"
#include "../mwmechanics/actorutil.hpp"
#include "../mwworld/ptr.hpp"
......@@ -1228,9 +1228,9 @@ namespace MWClass
if (getNpcStats(ptr).isWerewolf()
&& getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run))
{
MWMechanics::WeaponType weaponType = MWMechanics::WeapType_None;
MWMechanics::getActiveWeapon(getCreatureStats(ptr), getInventoryStore(ptr), &weaponType);
if (weaponType == MWMechanics::WeapType_None)
int weaponType = ESM::Weapon::None;
MWMechanics::getActiveWeapon(ptr, &weaponType);
if (weaponType == ESM::Weapon::None)
return std::string();
}
......
......@@ -17,6 +17,8 @@
#include "../mwphysics/physicssystem.hpp"
#include "../mwworld/nullaction.hpp"
#include "../mwmechanics/weapontype.hpp"
#include "../mwgui/tooltips.hpp"
#include "../mwrender/objects.hpp"
......@@ -64,8 +66,9 @@ namespace MWClass
bool Weapon::hasItemHealth (const MWWorld::ConstPtr& ptr) const
{
const MWWorld::LiveCellRef<ESM::Weapon> *ref = ptr.get<ESM::Weapon>();
int type = ref->mBase->mData.mType;
return (ref->mBase->mData.mType < ESM::Weapon::MarksmanThrown); // thrown weapons and arrows/bolts don't have health, only quantity
return MWMechanics::getWeaponType(type)->mFlags & ESM::WeaponType::HasHealth;
}
int Weapon::getItemMaxHealth (const MWWorld::ConstPtr& ptr) const
......@@ -86,16 +89,17 @@ namespace MWClass
std::pair<std::vector<int>, bool> Weapon::getEquipmentSlots (const MWWorld::ConstPtr& ptr) const
{
const MWWorld::LiveCellRef<ESM::Weapon> *ref = ptr.get<ESM::Weapon>();
ESM::WeaponType::Class weapClass = MWMechanics::getWeaponType(ref->mBase->mData.mType)->mWeaponClass;
std::vector<int> slots_;
bool stack = false;
if (ref->mBase->mData.mType==ESM::Weapon::Arrow || ref->mBase->mData.mType==ESM::Weapon::Bolt)
if (weapClass == ESM::WeaponType::Ammo)
{
slots_.push_back (int (MWWorld::InventoryStore::Slot_Ammunition));
stack = true;
}
else if (ref->mBase->mData.mType==ESM::Weapon::MarksmanThrown)
else if (weapClass == ESM::WeaponType::Thrown)
{
slots_.push_back (int (MWWorld::InventoryStore::Slot_CarriedRight));
stack = true;
......@@ -109,30 +113,9 @@ namespace MWClass
int Weapon::getEquipmentSkill (const MWWorld::ConstPtr& ptr) const
{
const MWWorld::LiveCellRef<ESM::Weapon> *ref = ptr.get<ESM::Weapon>();
int type = ref->mBase->mData.mType;
const int size = 12;
static const int sMapping[size][2] =
{
{ ESM::Weapon::ShortBladeOneHand, ESM::Skill::ShortBlade },
{ ESM::Weapon::LongBladeOneHand, ESM::Skill::LongBlade },
{ ESM::Weapon::LongBladeTwoHand, ESM::Skill::LongBlade },
{ ESM::Weapon::BluntOneHand, ESM::Skill::BluntWeapon },
{ ESM::Weapon::BluntTwoClose, ESM::Skill::BluntWeapon },
{ ESM::Weapon::BluntTwoWide, ESM::Skill::BluntWeapon },
{ ESM::Weapon::SpearTwoWide, ESM::Skill::Spear },
{ ESM::Weapon::AxeOneHand, ESM::Skill::Axe },
{ ESM::Weapon::AxeTwoHand, ESM::Skill::Axe },
{ ESM::Weapon::MarksmanBow, ESM::Skill::Marksman },
{ ESM::Weapon::MarksmanCrossbow, ESM::Skill::Marksman },
{ ESM::Weapon::MarksmanThrown, ESM::Skill::Marksman }
};
for (int i=0; i<size; ++i)
if (sMapping[i][0]==ref->mBase->mData.mType)
return sMapping[i][1];
return -1;
return MWMechanics::getWeaponType(type)->mSkill;
}
int Weapon::getValue (const MWWorld::ConstPtr& ptr) const
......@@ -152,89 +135,17 @@ namespace MWClass
std::string Weapon::getUpSoundId (const MWWorld::ConstPtr& ptr) const
{
const MWWorld::LiveCellRef<ESM::Weapon> *ref = ptr.get<ESM::Weapon>();
int type = ref->mBase->mData.mType;
// Ammo
if (type == 12 || type == 13)
{
return std::string("Item Ammo Up");
}
// Bow
if (type == 9)
{
return std::string("Item Weapon Bow Up");
}
// Crossbow
if (type == 10)
{
return std::string("Item Weapon Crossbow Up");
}
// Longblades, One hand and Two
if (type == 1 || type == 2)
{
return std::string("Item Weapon Longblade Up");
}
// Shortblade
if (type == 0)
{
return std::string("Item Weapon Shortblade Up");
}
// Spear
if (type == 6)
{
return std::string("Item Weapon Spear Up");
}
// Blunts, Axes and Thrown weapons
if (type == 3 || type == 4 || type == 5 || type == 7 || type == 8 || type == 11)
{
return std::string("Item Weapon Blunt Up");
}
return std::string("Item Misc Up");
std::string soundId = MWMechanics::getWeaponType(type)->mSoundId;
return soundId + " Up";
}
std::string Weapon::getDownSoundId (const MWWorld::ConstPtr& ptr) const
{
const MWWorld::LiveCellRef<ESM::Weapon> *ref = ptr.get<ESM::Weapon>();
int type = ref->mBase->mData.mType;
// Ammo
if (type == 12 || type == 13)
{
return std::string("Item Ammo Down");
}
// Bow
if (type == 9)
{
return std::string("Item Weapon Bow Down");
}
// Crossbow
if (type == 10)
{
return std::string("Item Weapon Crossbow Down");
}
// Longblades, One hand and Two
if (type == 1 || type == 2)
{
return std::string("Item Weapon Longblade Down");
}
// Shortblade
if (type == 0)
{
return std::string("Item Weapon Shortblade Down");
}
// Spear
if (type == 6)
{
return std::string("Item Weapon Spear Down");
}
// Blunts, Axes and Thrown weapons
if (type == 3 || type == 4 || type == 5 || type == 7 || type == 8 || type == 11)
{
return std::string("Item Weapon Blunt Down");
}
return std::string("Item Misc Down");
std::string soundId = MWMechanics::getWeaponType(type)->mSoundId;
return soundId + " Down";
}
std::string Weapon::getInventoryIcon (const MWWorld::ConstPtr& ptr) const
......@@ -254,6 +165,7 @@ namespace MWClass
MWGui::ToolTipInfo Weapon::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const
{
const MWWorld::LiveCellRef<ESM::Weapon> *ref = ptr.get<ESM::Weapon>();
const ESM::WeaponType* weaponType = MWMechanics::getWeaponType(ref->mBase->mData.mType);
MWGui::ToolTipInfo info;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(count);
......@@ -264,37 +176,26 @@ namespace MWClass
std::string text;
// weapon type & damage
if ((ref->mBase->mData.mType < ESM::Weapon::Arrow || Settings::Manager::getBool("show projectile damage", "Game")) && ref->mBase->mData.mType <= ESM::Weapon::Bolt)
if (weaponType->mWeaponClass != ESM::WeaponType::Ammo || Settings::Manager::getBool("show projectile damage", "Game"))
{
text += "\n#{sType} ";
static std::map <int, std::pair <std::string, std::string> > mapping;
if (mapping.empty())
int skill = MWMechanics::getWeaponType(ref->mBase->mData.mType)->mSkill;
const std::string type = ESM::Skill::sSkillNameIds[skill];
std::string oneOrTwoHanded;
if (weaponType->mWeaponClass == ESM::WeaponType::Melee)
{
mapping[ESM::Weapon::ShortBladeOneHand] = std::make_pair("sSkillShortblade", "sOneHanded");
mapping[ESM::Weapon::LongBladeOneHand] = std::make_pair("sSkillLongblade", "sOneHanded");
mapping[ESM::Weapon::LongBladeTwoHand] = std::make_pair("sSkillLongblade", "sTwoHanded");
mapping[ESM::Weapon::BluntOneHand] = std::make_pair("sSkillBluntweapon", "sOneHanded");
mapping[ESM::Weapon::BluntTwoClose] = std::make_pair("sSkillBluntweapon", "sTwoHanded");
mapping[ESM::Weapon::BluntTwoWide] = std::make_pair("sSkillBluntweapon", "sTwoHanded");
mapping[ESM::Weapon::SpearTwoWide] = std::make_pair("sSkillSpear", "sTwoHanded");
mapping[ESM::Weapon::AxeOneHand] = std::make_pair("sSkillAxe", "sOneHanded");
mapping[ESM::Weapon::AxeTwoHand] = std::make_pair("sSkillAxe", "sTwoHanded");
mapping[ESM::Weapon::MarksmanBow] = std::make_pair("sSkillMarksman", "");
mapping[ESM::Weapon::MarksmanCrossbow] = std::make_pair("sSkillMarksman", "");
mapping[ESM::Weapon::MarksmanThrown] = std::make_pair("sSkillMarksman", "");
mapping[ESM::Weapon::Arrow] = std::make_pair("sSkillMarksman", "");
mapping[ESM::Weapon::Bolt] = std::make_pair("sSkillMarksman", "");
if (weaponType->mFlags & ESM::WeaponType::TwoHanded)
oneOrTwoHanded = "sTwoHanded";
else
oneOrTwoHanded = "sOneHanded";
}
const std::string type = mapping[ref->mBase->mData.mType].first;
const std::string oneOrTwoHanded = mapping[ref->mBase->mData.mType].second;
text += store.get<ESM::GameSetting>().find(type)->mValue.getString() +
((oneOrTwoHanded != "") ? ", " + store.get<ESM::GameSetting>().find(oneOrTwoHanded)->mValue.getString() : "");
// weapon damage
if (ref->mBase->mData.mType == ESM::Weapon::MarksmanThrown)
if (weaponType->mWeaponClass == ESM::WeaponType::Thrown)
{
// Thrown weapons have 2x real damage applied
// as they're both the weapon and the ammo
......@@ -302,14 +203,7 @@ namespace MWClass
+ MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[0] * 2))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[1] * 2));
}
else if (ref->mBase->mData.mType >= ESM::Weapon::MarksmanBow)
{
// marksman
text += "\n#{sAttack}: "
+ MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[1]));
}
else
else if (weaponType->mWeaponClass == ESM::WeaponType::Melee)
{
// Chop
text += "\n#{sChop}: "
......@@ -324,6 +218,13 @@ namespace MWClass
+ MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mThrust[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mThrust[1]));
}
else
{
// marksman
text += "\n#{sAttack}: "
+ MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[1]));
}
}
if (hasItemHealth(ptr))
......@@ -335,7 +236,7 @@ namespace MWClass
const bool verbose = Settings::Manager::getBool("show melee info", "Game");
// add reach for melee weapon
if (ref->mBase->mData.mType < ESM::Weapon::MarksmanBow && verbose)
if (weaponType->mWeaponClass == ESM::WeaponType::Melee && verbose)
{
// display value in feet
const float combatDistance = store.get<ESM::GameSetting>().find("fCombatDistance")->mValue.getFloat() * ref->mBase->mData.mReach;
......@@ -344,7 +245,7 @@ namespace MWClass
}
// add attack speed for any weapon excepts arrows and bolts
if (ref->mBase->mData.mType < ESM::Weapon::Arrow && verbose)
if (weaponType->mWeaponClass != ESM::WeaponType::Ammo && verbose)
{
text += MWGui::ToolTips::getPercentString(ref->mBase->mData.mSpeed, "#{sAttributeSpeed}");
}
......@@ -403,13 +304,8 @@ namespace MWClass
if (slots_.first.empty())
return std::make_pair (0, "");
if(ptr.get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::LongBladeTwoHand ||
ptr.get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::BluntTwoClose ||
ptr.get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::BluntTwoWide ||
ptr.get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::SpearTwoWide ||
ptr.get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::AxeTwoHand ||
ptr.get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanBow ||
ptr.get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow)
int type = ptr.get<ESM::Weapon>()->mBase->mData.mType;
if(MWMechanics::getWeaponType(type)->mFlags & ESM::WeaponType::TwoHanded)
{
return std::make_pair (2, "");
}
......
......@@ -445,10 +445,9 @@ namespace MWMechanics
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)
int weapType = ESM::Weapon::None;
MWWorld::ContainerStoreIterator weaponSlot = MWMechanics::getActiveWeapon(target, &weapType);
if (weapType > ESM::Weapon::None)
targetWeapon = *weaponSlot;
}
......@@ -645,7 +644,7 @@ osg::Vec3f AimDirToMovingTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr& t
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
// get projectile speed (depending on weapon type)
if (weapType == ESM::Weapon::MarksmanThrown)
if (MWMechanics::getWeaponType(weapType)->mWeaponClass == ESM::WeaponType::Thrown)
{
static float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->mValue.getFloat();
static float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->mValue.getFloat();
......
......@@ -18,6 +18,7 @@
#include "combat.hpp"
#include "weaponpriority.hpp"
#include "spellpriority.hpp"
#include "weapontype.hpp"
namespace MWMechanics
{
......@@ -125,8 +126,7 @@ namespace MWMechanics
}
const ESM::Weapon* weapon = mWeapon.get<ESM::Weapon>()->mBase;
if (weapon->mData.mType >= ESM::Weapon::MarksmanBow)
if (MWMechanics::getWeaponType(weapon->mData.mType)->mWeaponClass != ESM::WeaponType::Melee)
{
isRanged = true;
return fProjectileMaxSpeed;
......@@ -194,11 +194,12 @@ namespace MWMechanics
if (rating > bestActionRating)
{
const ESM::Weapon* weapon = it->get<ESM::Weapon>()->mBase;
int ammotype = getWeaponType(weapon->mData.mType)->mAmmoType;
MWWorld::Ptr ammo;
if (weapon->mData.mType == ESM::Weapon::MarksmanBow)
if (ammotype == ESM::Weapon::Arrow)
ammo = bestArrow;
else if (weapon->mData.mType == ESM::Weapon::MarksmanCrossbow)
else if (ammotype == ESM::Weapon::Bolt)
ammo = bestBolt;
bestActionRating = rating;
......@@ -367,7 +368,7 @@ namespace MWMechanics
else if (!activeWeapon.isEmpty())
{
const ESM::Weapon* esmWeap = activeWeapon.get<ESM::Weapon>()->mBase;
if (esmWeap->mData.mType >= ESM::Weapon::MarksmanBow)
if (MWMechanics::getWeaponType(esmWeap->mData.mType)->mWeaponClass != ESM::WeaponType::Melee)
{
static const float fTargetSpellMaxSpeed = gmst.find("fProjectileMaxSpeed")->mValue.getFloat();
dist = fTargetSpellMaxSpeed;
......
This diff is collapsed.
......@@ -10,6 +10,8 @@
#include "../mwrender/animation.hpp"
#include "weapontype.hpp"
namespace MWWorld
{
class InventoryStore;
......@@ -113,21 +115,6 @@ enum CharacterState {
CharState_Block
};
enum WeaponType {
WeapType_None,
WeapType_HandToHand,
WeapType_OneHand,
WeapType_TwoHand,
WeapType_TwoWide,
WeapType_BowAndArrow,
WeapType_Crossbow,
WeapType_Thrown,
WeapType_PickProbe,
WeapType_Spell
};
enum UpperBodyCharacterState {
UpperCharState_Nothing,
UpperCharState_EquipingWeap,
......@@ -186,7 +173,7 @@ class CharacterController : public MWRender::Animation::TextKeyListener
JumpingState mJumpState;
std::string mCurrentJump;
WeaponType mWeaponType;
int mWeaponType;
std::string mCurrentWeapon;
float mAttackStrength;
......@@ -212,9 +199,9 @@ class CharacterController : public MWRender::Animation::TextKeyListener
void refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force=false);
void refreshHitRecoilAnims(CharacterState& idle);
void refreshJumpAnims(const WeaponInfo* weap, JumpingState jump, CharacterState& idle, bool force=false);
void refreshMovementAnims(const WeaponInfo* weap, CharacterState movement, CharacterState& idle, bool force=false);
void refreshIdleAnims(const WeaponInfo* weap, CharacterState idle, bool force=false);
void refreshJumpAnims(const std::string& weapShortGroup, JumpingState jump, CharacterState& idle, bool force=false);
void refreshMovementAnims(const std::string& weapShortGroup, CharacterState movement, CharacterState& idle, bool force=false);
void refreshIdleAnims(const std::string& weapShortGroup, CharacterState idle, bool force=false);
void clearAnimQueue(bool clearPersistAnims = false);
......@@ -241,7 +228,7 @@ class CharacterController : public MWRender::Animation::TextKeyListener
/// @param num if non-nullptr, the chosen animation number will be written here
std::string chooseRandomGroup (const std::string& prefix, int* num = nullptr) const;
bool updateCarriedLeftVisible(WeaponType weaptype) const;
bool updateCarriedLeftVisible(int weaptype) const;
public:
CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim);
......@@ -312,8 +299,6 @@ public:
void playSwishSound(float attackStrength);
};
MWWorld::ContainerStoreIterator getActiveWeapon(CreatureStats &stats, MWWorld::InventoryStore &inv, WeaponType *weaptype);
}
#endif /* GAME_MWMECHANICS_CHARACTER_HPP */
......@@ -26,6 +26,7 @@
#include "npcstats.hpp"
#include "actorutil.hpp"
#include "aifollow.hpp"
#include "weapontype.hpp"
namespace MWMechanics
{
......@@ -826,8 +827,9 @@ namespace MWMechanics
bool isProjectile = false;
if (item.getTypeName() == typeid(ESM::Weapon).name())
{
const ESM::Weapon* ref = item.get<ESM::Weapon>()->mBase;
isProjectile = ref->mData.mType >= ESM::Weapon::MarksmanThrown;
int type = item.get<ESM::Weapon>()->mBase->mData.mType;
ESM::WeaponType::Class weapclass = MWMechanics::getWeaponType(type)->mWeaponClass;
isProjectile = (weapclass == ESM::WeaponType::Thrown || weapclass == ESM::WeaponType::Ranged);
}
int type = enchantment->mData.mType;
......
......@@ -16,6 +16,8 @@
#include "creaturestats.hpp"
#include "spellcasting.hpp"
#include "weapontype.hpp"
#include "combat.hpp"
namespace
{
......@@ -379,7 +381,7 @@ namespace MWMechanics
case ESM::MagicEffect::BoundLongbow:
// AI should not summon the bow if there is no suitable ammo.
if (rateAmmo(actor, enemy, ESM::Weapon::Arrow) <= 0.f)
if (rateAmmo(actor, enemy, getWeaponType(ESM::Weapon::MarksmanBow)->mAmmoType) <= 0.f)
return 0.f;
break;
......
......@@ -14,6 +14,7 @@
#include "aicombataction.hpp"
#include "spellpriority.hpp"
#include "spellcasting.hpp"
#include "weapontype.hpp"
namespace MWMechanics
{
......@@ -34,14 +35,15 @@ namespace MWMechanics
const MWBase::World* world = MWBase::Environment::get().getWorld();
const MWWorld::Store<ESM::GameSetting>& gmst = world->getStore().get<ESM::GameSetting>();
if (type == -1 && (weapon->mData.mType == ESM::Weapon::Arrow || weapon->mData.mType == ESM::Weapon::Bolt))
ESM::WeaponType::Class weapclass = MWMechanics::getWeaponType(weapon->mData.mType)->mWeaponClass;
if (type == -1 && weapclass == ESM::WeaponType::Ammo)
return 0.f;
float rating=0.f;
static const float fAIMeleeWeaponMult = gmst.find("fAIMeleeWeaponMult")->mValue.getFloat();
float ratingMult = fAIMeleeWeaponMult;
if (weapon->mData.mType >= ESM::Weapon::MarksmanBow && weapon->mData.mType <= ESM::Weapon::MarksmanThrown)
if (weapclass != ESM::WeaponType::Melee)
{
// Underwater ranged combat is impossible
if (world->isUnderwater(MWWorld::ConstPtr(actor), 0.75f)
......@@ -59,11 +61,11 @@ namespace MWMechanics
const float chop = (weapon->mData.mChop[0] + weapon->mData.mChop[1]) / 2.f;
// We need to account for the fact that thrown weapons have 2x real damage applied to the target
// as they're both the weapon and the ammo of the hit
if (weapon->mData.mType == ESM::Weapon::MarksmanThrown)
if (weapclass == ESM::WeaponType::Thrown)
{
rating = chop * 2;
}
else if (weapon->mData.mType >= ESM::Weapon::MarksmanBow)
else if (weapclass != ESM::WeaponType::Melee)
{
rating = chop;
}
......@@ -76,24 +78,28 @@ namespace MWMechanics
adjustWeaponDamage(rating, item, actor);
if (weapon->mData.mType != ESM::Weapon::MarksmanBow && weapon->mData.mType != ESM::Weapon::MarksmanCrossbow)
if (weapclass != ESM::WeaponType::Ranged)