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

Loading…
Cancel
Save