Handle bipedal creatures not using weapons (Fixes #2238)

moveref
scrawl 10 years ago
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))
{
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");
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");
}
}
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…
Cancel
Save