mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-28 19:21:04 +00:00
Merge branch 'dagoth_wave' into 'master'
Remove weaponless, non-biped distinction Closes #5054 See merge request OpenMW/openmw!1517
This commit is contained in:
commit
14a9af15ab
@ -19,6 +19,7 @@
|
|||||||
Bug #4700: Editor: Incorrect command implementation
|
Bug #4700: Editor: Incorrect command implementation
|
||||||
Bug #4744: Invisible particles must still be processed
|
Bug #4744: Invisible particles must still be processed
|
||||||
Bug #4949: Incorrect particle lighting
|
Bug #4949: Incorrect particle lighting
|
||||||
|
Bug #5054: Non-biped creatures don't use spellcast equip/unequip animations
|
||||||
Bug #5088: Sky abruptly changes direction during certain weather transitions
|
Bug #5088: Sky abruptly changes direction during certain weather transitions
|
||||||
Bug #5100: Persuasion doesn't always clamp the resulting disposition
|
Bug #5100: Persuasion doesn't always clamp the resulting disposition
|
||||||
Bug #5120: Scripted object spawning updates physics system
|
Bug #5120: Scripted object spawning updates physics system
|
||||||
|
@ -435,6 +435,8 @@ std::string CharacterController::getWeaponAnimation(int weaponType) const
|
|||||||
else if (isRealWeapon)
|
else if (isRealWeapon)
|
||||||
weaponGroup = oneHandFallback;
|
weaponGroup = oneHandFallback;
|
||||||
}
|
}
|
||||||
|
else if (weaponType == ESM::Weapon::HandToHand && !mPtr.getClass().isBipedal(mPtr))
|
||||||
|
return "attack1";
|
||||||
|
|
||||||
return weaponGroup;
|
return weaponGroup;
|
||||||
}
|
}
|
||||||
@ -707,9 +709,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
|
|||||||
if (mPtr.getClass().isActor())
|
if (mPtr.getClass().isActor())
|
||||||
refreshHitRecoilAnims(idle);
|
refreshHitRecoilAnims(idle);
|
||||||
|
|
||||||
std::string weap;
|
std::string weap = getWeaponType(mWeaponType)->mShortGroup;
|
||||||
if (mPtr.getClass().hasInventoryStore(mPtr))
|
|
||||||
weap = getWeaponType(mWeaponType)->mShortGroup;
|
|
||||||
|
|
||||||
refreshJumpAnims(weap, jump, idle, force);
|
refreshJumpAnims(weap, jump, idle, force);
|
||||||
refreshMovementAnims(weap, movement, idle, force);
|
refreshMovementAnims(weap, movement, idle, force);
|
||||||
@ -1119,97 +1119,6 @@ void CharacterController::updateIdleStormState(bool inwater)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CharacterController::updateCreatureState()
|
|
||||||
{
|
|
||||||
const MWWorld::Class &cls = mPtr.getClass();
|
|
||||||
CreatureStats &stats = cls.getCreatureStats(mPtr);
|
|
||||||
|
|
||||||
int weapType = ESM::Weapon::None;
|
|
||||||
if(stats.getDrawState() == DrawState_Weapon)
|
|
||||||
weapType = ESM::Weapon::HandToHand;
|
|
||||||
else if (stats.getDrawState() == DrawState_Spell)
|
|
||||||
weapType = ESM::Weapon::Spell;
|
|
||||||
|
|
||||||
if (weapType != mWeaponType)
|
|
||||||
{
|
|
||||||
mWeaponType = weapType;
|
|
||||||
if (mAnimation->isPlaying(mCurrentWeapon))
|
|
||||||
mAnimation->disable(mCurrentWeapon);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(getAttackingOrSpell())
|
|
||||||
{
|
|
||||||
if(mUpperBodyState == UpperCharState_Nothing && mHitState == CharState_None)
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWorld()->breakInvisibility(mPtr);
|
|
||||||
|
|
||||||
std::string startKey = "start";
|
|
||||||
std::string stopKey = "stop";
|
|
||||||
if (weapType == ESM::Weapon::Spell)
|
|
||||||
{
|
|
||||||
const std::string spellid = stats.getSpells().getSelectedSpell();
|
|
||||||
bool canCast = mCastingManualSpell || MWBase::Environment::get().getWorld()->startSpellCast(mPtr);
|
|
||||||
|
|
||||||
if (!spellid.empty() && canCast)
|
|
||||||
{
|
|
||||||
MWMechanics::CastSpell cast(mPtr, nullptr, false, mCastingManualSpell);
|
|
||||||
cast.playSpellCastingEffects(spellid, false);
|
|
||||||
|
|
||||||
if (!mAnimation->hasAnimation("spellcast"))
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWorld()->castSpell(mPtr, mCastingManualSpell); // No "release" text key to use, so cast immediately
|
|
||||||
mCastingManualSpell = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const ESM::Spell *spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(spellid);
|
|
||||||
const ESM::ENAMstruct &effectentry = spell->mEffects.mList.at(0);
|
|
||||||
|
|
||||||
switch(effectentry.mRange)
|
|
||||||
{
|
|
||||||
case 0: mAttackType = "self"; break;
|
|
||||||
case 1: mAttackType = "touch"; break;
|
|
||||||
case 2: mAttackType = "target"; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
startKey = mAttackType + " " + startKey;
|
|
||||||
stopKey = mAttackType + " " + stopKey;
|
|
||||||
mCurrentWeapon = "spellcast";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mCurrentWeapon = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (weapType != ESM::Weapon::Spell || !mAnimation->hasAnimation("spellcast")) // Not all creatures have a dedicated spellcast animation
|
|
||||||
{
|
|
||||||
mCurrentWeapon = chooseRandomAttackAnimation();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mCurrentWeapon.empty())
|
|
||||||
{
|
|
||||||
mAnimation->play(mCurrentWeapon, Priority_Weapon,
|
|
||||||
MWRender::Animation::BlendMask_All, true,
|
|
||||||
1, startKey, stopKey,
|
|
||||||
0.0f, 0);
|
|
||||||
mUpperBodyState = UpperCharState_StartToMinAttack;
|
|
||||||
|
|
||||||
mAttackStrength = std::min(1.f, 0.1f + Misc::Rng::rollClosedProbability());
|
|
||||||
|
|
||||||
if (weapType == ESM::Weapon::HandToHand)
|
|
||||||
playSwishSound(0.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setAttackingOrSpell(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool animPlaying = mAnimation->getInfo(mCurrentWeapon);
|
|
||||||
if (!animPlaying)
|
|
||||||
mUpperBodyState = UpperCharState_Nothing;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CharacterController::updateCarriedLeftVisible(const int weaptype) const
|
bool CharacterController::updateCarriedLeftVisible(const int weaptype) const
|
||||||
{
|
{
|
||||||
// Shields/torches shouldn't be visible during any operation involving two hands
|
// Shields/torches shouldn't be visible during any operation involving two hands
|
||||||
@ -1218,7 +1127,7 @@ bool CharacterController::updateCarriedLeftVisible(const int weaptype) const
|
|||||||
return mAnimation->updateCarriedLeftVisible(weaptype);
|
return mAnimation->updateCarriedLeftVisible(weaptype);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CharacterController::updateWeaponState(CharacterState& idle)
|
bool CharacterController::updateState(CharacterState& idle)
|
||||||
{
|
{
|
||||||
const MWWorld::Class &cls = mPtr.getClass();
|
const MWWorld::Class &cls = mPtr.getClass();
|
||||||
CreatureStats &stats = cls.getCreatureStats(mPtr);
|
CreatureStats &stats = cls.getCreatureStats(mPtr);
|
||||||
@ -1386,7 +1295,7 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mWeaponType = weaptype;
|
mWeaponType = weaptype;
|
||||||
mCurrentWeapon = getWeaponAnimation(mWeaponType);
|
mCurrentWeapon = weapgroup;
|
||||||
|
|
||||||
if(!upSoundId.empty() && !isStillWeapon)
|
if(!upSoundId.empty() && !isStillWeapon)
|
||||||
{
|
{
|
||||||
@ -1456,15 +1365,13 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
|
|||||||
ESM::WeaponType::Class weapclass = getWeaponType(mWeaponType)->mWeaponClass;
|
ESM::WeaponType::Class weapclass = getWeaponType(mWeaponType)->mWeaponClass;
|
||||||
if(getAttackingOrSpell())
|
if(getAttackingOrSpell())
|
||||||
{
|
{
|
||||||
MWWorld::Ptr player = getPlayer();
|
|
||||||
|
|
||||||
bool resetIdle = ammunition;
|
bool resetIdle = ammunition;
|
||||||
if(mUpperBodyState == UpperCharState_WeapEquiped && (mHitState == CharState_None || mHitState == CharState_Block))
|
if(mUpperBodyState == UpperCharState_WeapEquiped && (mHitState == CharState_None || mHitState == CharState_Block))
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWorld()->breakInvisibility(mPtr);
|
MWBase::Environment::get().getWorld()->breakInvisibility(mPtr);
|
||||||
mAttackStrength = 0;
|
mAttackStrength = 0;
|
||||||
|
|
||||||
// Randomize attacks for non-bipedal creatures with Weapon flag
|
// Randomize attacks for non-bipedal creatures
|
||||||
if (mPtr.getClass().getType() == ESM::Creature::sRecordId &&
|
if (mPtr.getClass().getType() == ESM::Creature::sRecordId &&
|
||||||
!mPtr.getClass().isBipedal(mPtr) &&
|
!mPtr.getClass().isBipedal(mPtr) &&
|
||||||
(!mAnimation->hasAnimation(mCurrentWeapon) || isRandomAttackAnimation(mCurrentWeapon)))
|
(!mAnimation->hasAnimation(mCurrentWeapon) || isRandomAttackAnimation(mCurrentWeapon)))
|
||||||
@ -1477,7 +1384,7 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
|
|||||||
// Unset casting flag, otherwise pressing the mouse button down would
|
// Unset casting flag, otherwise pressing the mouse button down would
|
||||||
// continue casting every frame if there is no animation
|
// continue casting every frame if there is no animation
|
||||||
setAttackingOrSpell(false);
|
setAttackingOrSpell(false);
|
||||||
if (mPtr == player)
|
if (mPtr == getPlayer())
|
||||||
{
|
{
|
||||||
// For the player, set the spell we want to cast
|
// For the player, set the spell we want to cast
|
||||||
// This has to be done at the start of the casting animation,
|
// This has to be done at the start of the casting animation,
|
||||||
@ -1650,7 +1557,14 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
|
|||||||
weapSpeed, startKey, stopKey,
|
weapSpeed, startKey, stopKey,
|
||||||
0.0f, 0);
|
0.0f, 0);
|
||||||
if(mAnimation->getCurrentTime(mCurrentWeapon) != -1.f)
|
if(mAnimation->getCurrentTime(mCurrentWeapon) != -1.f)
|
||||||
|
{
|
||||||
mUpperBodyState = UpperCharState_StartToMinAttack;
|
mUpperBodyState = UpperCharState_StartToMinAttack;
|
||||||
|
if (isRandomAttackAnimation(mCurrentWeapon))
|
||||||
|
{
|
||||||
|
mAttackStrength = std::min(1.f, 0.1f + Misc::Rng::rollClosedProbability());
|
||||||
|
playSwishSound(0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2346,11 +2260,7 @@ void CharacterController::update(float duration)
|
|||||||
|
|
||||||
if (!mSkipAnim)
|
if (!mSkipAnim)
|
||||||
{
|
{
|
||||||
// bipedal means hand-to-hand could be used (which is handled in updateWeaponState). an existing InventoryStore means an actual weapon could be used.
|
forcestateupdate = updateState(idlestate) || forcestateupdate;
|
||||||
if(cls.isBipedal(mPtr) || cls.hasInventoryStore(mPtr))
|
|
||||||
forcestateupdate = updateWeaponState(idlestate) || forcestateupdate;
|
|
||||||
else
|
|
||||||
forcestateupdate = updateCreatureState() || forcestateupdate;
|
|
||||||
|
|
||||||
refreshCurrentAnims(idlestate, movestate, jumpstate, forcestateupdate);
|
refreshCurrentAnims(idlestate, movestate, jumpstate, forcestateupdate);
|
||||||
updateIdleStormState(inwater);
|
updateIdleStormState(inwater);
|
||||||
@ -2879,10 +2789,7 @@ bool CharacterController::readyToStartAttack() const
|
|||||||
if (mHitState != CharState_None && mHitState != CharState_Block)
|
if (mHitState != CharState_None && mHitState != CharState_Block)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mPtr.getClass().hasInventoryStore(mPtr) || mPtr.getClass().isBipedal(mPtr))
|
return mUpperBodyState == UpperCharState_WeapEquiped;
|
||||||
return mUpperBodyState == UpperCharState_WeapEquiped;
|
|
||||||
else
|
|
||||||
return mUpperBodyState == UpperCharState_Nothing;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float CharacterController::getAttackStrength() const
|
float CharacterController::getAttackStrength() const
|
||||||
|
@ -205,8 +205,7 @@ class CharacterController : public MWRender::Animation::TextKeyListener
|
|||||||
|
|
||||||
void clearAnimQueue(bool clearPersistAnims = false);
|
void clearAnimQueue(bool clearPersistAnims = false);
|
||||||
|
|
||||||
bool updateWeaponState(CharacterState& idle);
|
bool updateState(CharacterState& idle);
|
||||||
bool updateCreatureState();
|
|
||||||
void updateIdleStormState(bool inwater);
|
void updateIdleStormState(bool inwater);
|
||||||
|
|
||||||
std::string chooseRandomAttackAnimation() const;
|
std::string chooseRandomAttackAnimation() const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user