mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 09:35:28 +00:00
Handle bipedal creatures not using weapons (Fixes #2238)
This commit is contained in:
parent
363d1f9207
commit
d1a29300f0
@ -296,7 +296,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
|
||||
}
|
||||
|
||||
const WeaponInfo *weap = std::find_if(sWeaponTypeList, sWeaponTypeListEnd, FindWeaponType(mWeaponType));
|
||||
if (!mPtr.getClass().hasInventoryStore(mPtr))
|
||||
if (!mPtr.getClass().isBipedal(mPtr))
|
||||
weap = sWeaponTypeListEnd;
|
||||
|
||||
if(force || idle != mIdleState)
|
||||
@ -870,10 +870,26 @@ bool CharacterController::updateWeaponState()
|
||||
const MWWorld::Class &cls = mPtr.getClass();
|
||||
CreatureStats &stats = cls.getCreatureStats(mPtr);
|
||||
WeaponType weaptype = WeapType_None;
|
||||
MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr);
|
||||
MWWorld::ContainerStoreIterator weapon = getActiveWeapon(stats, inv, &weaptype);
|
||||
if(stats.getDrawState() == DrawState_Weapon)
|
||||
weaptype = WeapType_HandToHand;
|
||||
else if (stats.getDrawState() == DrawState_Spell)
|
||||
weaptype = WeapType_Spell;
|
||||
|
||||
const bool isWerewolf = cls.isNpc() && cls.getNpcStats(mPtr).isWerewolf();
|
||||
|
||||
std::string soundid;
|
||||
if (mPtr.getClass().hasInventoryStore(mPtr))
|
||||
{
|
||||
MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr);
|
||||
MWWorld::ContainerStoreIterator weapon = getActiveWeapon(stats, inv, &weaptype);
|
||||
if(weapon != inv.end() && !(weaptype == WeapType_None && mWeaponType == WeapType_Spell))
|
||||
{
|
||||
soundid = (weaptype == WeapType_None) ?
|
||||
weapon->getClass().getDownSoundId(*weapon) :
|
||||
weapon->getClass().getUpSoundId(*weapon);
|
||||
}
|
||||
}
|
||||
|
||||
bool forcestateupdate = false;
|
||||
if(weaptype != mWeaponType && mHitState != CharState_KnockDown)
|
||||
{
|
||||
@ -913,16 +929,10 @@ bool CharacterController::updateWeaponState()
|
||||
}
|
||||
}
|
||||
|
||||
if(weapon != inv.end() && !(weaptype == WeapType_None && mWeaponType == WeapType_Spell))
|
||||
if(!soundid.empty())
|
||||
{
|
||||
std::string soundid = (weaptype == WeapType_None) ?
|
||||
weapon->getClass().getDownSoundId(*weapon) :
|
||||
weapon->getClass().getUpSoundId(*weapon);
|
||||
if(!soundid.empty())
|
||||
{
|
||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||
sndMgr->playSound3D(mPtr, soundid, 1.0f, 1.0f);
|
||||
}
|
||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||
sndMgr->playSound3D(mPtr, soundid, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
mWeaponType = weaptype;
|
||||
@ -945,22 +955,28 @@ bool CharacterController::updateWeaponState()
|
||||
sndMgr->stopSound3D(mPtr, "WolfRun");
|
||||
}
|
||||
|
||||
bool isWeapon = (weapon != inv.end() && weapon->getTypeName() == typeid(ESM::Weapon).name());
|
||||
float weapSpeed = 1.0f;
|
||||
if(isWeapon)
|
||||
weapSpeed = weapon->get<ESM::Weapon>()->mBase->mData.mSpeed;
|
||||
|
||||
// Cancel attack if we no longer have ammunition
|
||||
bool ammunition = true;
|
||||
MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition);
|
||||
if (mWeaponType == WeapType_Crossbow)
|
||||
ammunition = (ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::Bolt);
|
||||
else if (mWeaponType == WeapType_BowAndArrow)
|
||||
ammunition = (ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::Arrow);
|
||||
if (!ammunition && mUpperBodyState > UpperCharState_WeapEquiped)
|
||||
bool isWeapon = false;
|
||||
float weapSpeed = 1.f;
|
||||
if (mPtr.getClass().hasInventoryStore(mPtr))
|
||||
{
|
||||
mAnimation->disable(mCurrentWeapon);
|
||||
mUpperBodyState = UpperCharState_WeapEquiped;
|
||||
MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr);
|
||||
MWWorld::ContainerStoreIterator weapon = getActiveWeapon(stats, inv, &weaptype);
|
||||
isWeapon = (weapon != inv.end() && weapon->getTypeName() == typeid(ESM::Weapon).name());
|
||||
if(isWeapon)
|
||||
weapSpeed = weapon->get<ESM::Weapon>()->mBase->mData.mSpeed;
|
||||
|
||||
MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition);
|
||||
if (mWeaponType == WeapType_Crossbow)
|
||||
ammunition = (ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::Bolt);
|
||||
else if (mWeaponType == WeapType_BowAndArrow)
|
||||
ammunition = (ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::Arrow);
|
||||
if (!ammunition && mUpperBodyState > UpperCharState_WeapEquiped)
|
||||
{
|
||||
mAnimation->disable(mCurrentWeapon);
|
||||
mUpperBodyState = UpperCharState_WeapEquiped;
|
||||
}
|
||||
}
|
||||
|
||||
float complete;
|
||||
@ -1001,15 +1017,14 @@ bool CharacterController::updateWeaponState()
|
||||
|
||||
const ESM::Static* castStatic = MWBase::Environment::get().getWorld()->getStore().get<ESM::Static>().find ("VFX_Hands");
|
||||
if (mAnimation->getNode("Left Hand"))
|
||||
{
|
||||
mAnimation->addEffect("meshes\\" + castStatic->mModel, -1, false, "Left Hand", effect->mParticle);
|
||||
mAnimation->addEffect("meshes\\" + castStatic->mModel, -1, false, "Right Hand", effect->mParticle);
|
||||
}
|
||||
else
|
||||
{
|
||||
mAnimation->addEffect("meshes\\" + castStatic->mModel, -1, false, "Bip01 L Hand", effect->mParticle);
|
||||
|
||||
if (mAnimation->getNode("Right Hand"))
|
||||
mAnimation->addEffect("meshes\\" + castStatic->mModel, -1, false, "Right Hand", effect->mParticle);
|
||||
else
|
||||
mAnimation->addEffect("meshes\\" + castStatic->mModel, -1, false, "Bip01 R Hand", effect->mParticle);
|
||||
}
|
||||
|
||||
switch(effectentry.mRange)
|
||||
{
|
||||
@ -1024,14 +1039,20 @@ bool CharacterController::updateWeaponState()
|
||||
0.0f, 0);
|
||||
mUpperBodyState = UpperCharState_CastingSpell;
|
||||
}
|
||||
if (inv.getSelectedEnchantItem() != inv.end())
|
||||
if (mPtr.getClass().hasInventoryStore(mPtr))
|
||||
{
|
||||
// Enchanted items cast immediately (no animation)
|
||||
MWBase::Environment::get().getWorld()->castSpell(mPtr);
|
||||
MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr);
|
||||
if (inv.getSelectedEnchantItem() != inv.end())
|
||||
{
|
||||
// Enchanted items cast immediately (no animation)
|
||||
MWBase::Environment::get().getWorld()->castSpell(mPtr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if(mWeaponType == WeapType_PickProbe)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator weapon = mPtr.getClass().getInventoryStore(mPtr).getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
||||
MWWorld::Ptr item = *weapon;
|
||||
// TODO: this will only work for the player, and needs to be fixed if NPCs should ever use lockpicks/probes.
|
||||
MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getFacedObject();
|
||||
@ -1063,7 +1084,10 @@ bool CharacterController::updateWeaponState()
|
||||
{
|
||||
if(isWeapon && mPtr.getRefData().getHandle() == "player" &&
|
||||
Settings::Manager::getBool("best attack", "Game"))
|
||||
{
|
||||
MWWorld::ContainerStoreIterator weapon = mPtr.getClass().getInventoryStore(mPtr).getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
||||
mAttackType = getBestAttack(weapon->get<ESM::Weapon>()->mBase);
|
||||
}
|
||||
else
|
||||
determineAttackType();
|
||||
}
|
||||
@ -1283,17 +1307,21 @@ bool CharacterController::updateWeaponState()
|
||||
}
|
||||
}
|
||||
|
||||
MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
|
||||
if(torch != inv.end() && torch->getTypeName() == typeid(ESM::Light).name()
|
||||
&& updateCarriedLeftVisible(mWeaponType))
|
||||
if (mPtr.getClass().hasInventoryStore(mPtr))
|
||||
{
|
||||
MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr);
|
||||
MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
|
||||
if(torch != inv.end() && torch->getTypeName() == typeid(ESM::Light).name()
|
||||
&& updateCarriedLeftVisible(mWeaponType))
|
||||
|
||||
{
|
||||
mAnimation->play("torch", Priority_Torch, MWRender::Animation::Group_LeftArm,
|
||||
false, 1.0f, "start", "stop", 0.0f, (~(size_t)0), true);
|
||||
}
|
||||
else if (mAnimation->isPlaying("torch"))
|
||||
{
|
||||
mAnimation->disable("torch");
|
||||
{
|
||||
mAnimation->play("torch", Priority_Torch, MWRender::Animation::Group_LeftArm,
|
||||
false, 1.0f, "start", "stop", 0.0f, (~(size_t)0), true);
|
||||
}
|
||||
else if (mAnimation->isPlaying("torch"))
|
||||
{
|
||||
mAnimation->disable("torch");
|
||||
}
|
||||
}
|
||||
|
||||
return forcestateupdate;
|
||||
@ -1607,7 +1635,7 @@ void CharacterController::update(float duration)
|
||||
}
|
||||
}
|
||||
|
||||
if(cls.hasInventoryStore(mPtr))
|
||||
if(cls.isBipedal(mPtr))
|
||||
forcestateupdate = updateWeaponState() || forcestateupdate;
|
||||
else
|
||||
forcestateupdate = updateCreatureState() || forcestateupdate;
|
||||
@ -1839,15 +1867,12 @@ void CharacterController::determineAttackType()
|
||||
{
|
||||
float *move = mPtr.getClass().getMovementSettings(mPtr).mPosition;
|
||||
|
||||
if(mPtr.getClass().hasInventoryStore(mPtr))
|
||||
{
|
||||
if (move[1] && !move[0]) // forward-backward
|
||||
mAttackType = "thrust";
|
||||
else if (move[0] && !move[1]) //sideway
|
||||
mAttackType = "slash";
|
||||
else
|
||||
mAttackType = "chop";
|
||||
}
|
||||
if (move[1] && !move[0]) // forward-backward
|
||||
mAttackType = "thrust";
|
||||
else if (move[0] && !move[1]) //sideway
|
||||
mAttackType = "slash";
|
||||
else
|
||||
mAttackType = "chop";
|
||||
}
|
||||
|
||||
bool CharacterController::isReadyToBlock() const
|
||||
|
Loading…
x
Reference in New Issue
Block a user