Closes #1083: Fix werewolf change handling

actorid
scrawl 11 years ago
parent f4517c8221
commit c4e4a8fb57

@ -140,8 +140,7 @@ namespace MWRender
void InventoryPreview::update(int sizeX, int sizeY)
{
// TODO: can we avoid this. Vampire state needs to be updated.
mAnimation->rebuild();
mAnimation->updateParts();
MWWorld::InventoryStore &inv = MWWorld::Class::get(mCharacter).getInventoryStore(mCharacter);
MWWorld::ContainerStoreIterator iter = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
@ -177,12 +176,8 @@ namespace MWRender
groupname = "inventoryhandtohand";
}
// TODO see above
//if(groupname != mCurrentAnimGroup)
//{
mCurrentAnimGroup = groupname;
mAnimation->play(mCurrentAnimGroup, 1, Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0);
//}
mCurrentAnimGroup = groupname;
mAnimation->play(mCurrentAnimGroup, 1, Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0);
MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
if(torch != inv.end() && torch->getTypeName() == typeid(ESM::Light).name())
@ -194,7 +189,6 @@ namespace MWRender
else if(mAnimation->getInfo("torch"))
mAnimation->disable("torch");
mAnimation->updateParts();
mAnimation->runAnimation(0.0f);
mViewport->setDimensions (0, 0, std::min(1.f, float(sizeX) / float(512)), std::min(1.f, float(sizeY) / float(1024)));

@ -119,7 +119,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, int v
mShowWeapons(false),
mShowCarriedLeft(true),
mFirstPersonOffset(0.f, 0.f, 0.f),
mAlpha(1.f)
mAlpha(1.f),
mNpcType(Type_Normal)
{
mNpc = mPtr.get<ESM::NPC>()->mBase;
@ -157,8 +158,8 @@ void NpcAnimation::updateNpcBase()
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const ESM::Race *race = store.get<ESM::Race>().find(mNpc->mRace);
bool isWerewolf = mPtr.getClass().getNpcStats(mPtr).isWerewolf();
bool vampire = mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Vampirism).mMagnitude;
bool isWerewolf = (mNpcType == Type_Werewolf);
bool isVampire = (mNpcType == Type_Vampire);
if (isWerewolf)
{
@ -167,7 +168,7 @@ void NpcAnimation::updateNpcBase()
}
else
{
if (vampire)
if (isVampire)
mHeadModel = getVampireHead(mNpc->mRace, mNpc->mFlags & ESM::NPC::Female);
else
mHeadModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHead)->mModel;
@ -221,11 +222,24 @@ void NpcAnimation::updateNpcBase()
}
void NpcAnimation::updateParts()
{
{
mAlpha = 1.f;
const MWWorld::Class &cls = MWWorld::Class::get(mPtr);
MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr);
NpcType curType = Type_Normal;
if (cls.getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Vampirism).mMagnitude > 0)
curType = Type_Vampire;
if (cls.getNpcStats(mPtr).isWerewolf())
curType = Type_Werewolf;
if (curType != mNpcType)
{
mNpcType = curType;
rebuild();
return;
}
static const struct {
int mSlot;
int mBasePriority;
@ -329,7 +343,7 @@ void NpcAnimation::updateParts()
static const int Flag_Female = 1<<0;
static const int Flag_FirstPerson = 1<<1;
bool isWerewolf = cls.getNpcStats(mPtr).isWerewolf();
bool isWerewolf = (mNpcType == Type_Werewolf);
int flags = (isWerewolf ? -1 : 0);
if(!mNpc->isMale())
flags |= Flag_Female;

@ -55,6 +55,14 @@ private:
bool mShowWeapons;
bool mShowCarriedLeft;
enum NpcType
{
Type_Normal,
Type_Werewolf,
Type_Vampire
};
NpcType mNpcType;
int mVisibilityFlags;
int mPartslots[ESM::PRT_Count]; //Each part slot is taken by clothing, armor, or is empty

@ -139,8 +139,13 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite
void MWWorld::InventoryStore::unequipAll(const MWWorld::Ptr& actor)
{
// Only *one* change event should be fired
mUpdatesEnabled = false;
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
unequipSlot(slot, actor);
mUpdatesEnabled = true;
fireEquipmentChangedEvent();
updateMagicEffects(actor);
}
MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot)

@ -1960,6 +1960,10 @@ namespace MWWorld
npcStats.setWerewolf(werewolf);
// This is a bit dangerous. Equipped items other than WerewolfRobe may reference
// bones that do not even exist with the werewolf object root.
// Therefore, make sure to unequip everything at once, and only fire the change event
// (which will rebuild the animation parts) afterwards. unequipAll will do this for us.
MWWorld::InventoryStore& invStore = MWWorld::Class::get(actor).getInventoryStore(actor);
invStore.unequipAll(actor);
@ -1974,6 +1978,10 @@ namespace MWWorld
actor.getClass().getContainerStore(actor).remove("werewolfrobe", 1, actor);
}
// NpcAnimation::updateParts will already rebuild the animation when it detects change of Npc type.
// the following is just for reattaching the camera properly.
mRendering->rebuildPtr(actor);
if(actor.getRefData().getHandle() == "player")
{
// Update the GUI only when called on the player
@ -1991,8 +1999,6 @@ namespace MWWorld
windowManager->unsetForceHide(MWGui::GW_Magic);
}
}
mRendering->rebuildPtr(actor);
}
void World::applyWerewolfAcrobatics(const Ptr &actor)

Loading…
Cancel
Save