1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-22 17:39:42 +00:00

Merge remote-tracking branch 'scrawl/master'

This commit is contained in:
Marc Zinnschlag 2014-01-05 21:27:06 +01:00
commit e63b4964b2
63 changed files with 346 additions and 191 deletions

View file

@ -263,7 +263,7 @@ namespace
static const char *sCreatureTypes[] = static const char *sCreatureTypes[] =
{ {
"Creature", "Deadra", "Undead", "Humanoid", 0 "Creature", "Daedra", "Undead", "Humanoid", 0
}; };
static const char *sWeaponTypes[] = static const char *sWeaponTypes[] =

View file

@ -309,12 +309,16 @@ std::string OMW::Engine::loadSettings (Settings::Manager & settings)
// load nif overrides // load nif overrides
NifOverrides::Overrides nifOverrides; NifOverrides::Overrides nifOverrides;
if (boost::filesystem::exists(mCfgMgr.getLocalPath().string() + "/transparency-overrides.cfg")) std::string transparencyOverrides = "/transparency-overrides.cfg";
nifOverrides.loadTransparencyOverrides(mCfgMgr.getLocalPath().string() + "/transparency-overrides.cfg"); std::string materialOverrides = "/material-overrides.cfg";
else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg")) if (boost::filesystem::exists(mCfgMgr.getLocalPath().string() + transparencyOverrides))
nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg"); nifOverrides.loadTransparencyOverrides(mCfgMgr.getLocalPath().string() + transparencyOverrides);
else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + transparencyOverrides))
settings.setBool("hardware cursors", "GUI", true); nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + transparencyOverrides);
if (boost::filesystem::exists(mCfgMgr.getLocalPath().string() + materialOverrides))
nifOverrides.loadMaterialOverrides(mCfgMgr.getLocalPath().string() + materialOverrides);
else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + materialOverrides))
nifOverrides.loadMaterialOverrides(mCfgMgr.getGlobalPath().string() + materialOverrides);
return settingspath; return settingspath;
} }

View file

@ -84,10 +84,10 @@ namespace MWClass
data->mCreatureStats.getAiSequence().fill(ref->mBase->mAiPackage); data->mCreatureStats.getAiSequence().fill(ref->mBase->mAiPackage);
data->mCreatureStats.setAiSetting (0, ref->mBase->mAiData.mHello); data->mCreatureStats.setAiSetting (MWMechanics::CreatureStats::AI_Hello, ref->mBase->mAiData.mHello);
data->mCreatureStats.setAiSetting (1, ref->mBase->mAiData.mFight); data->mCreatureStats.setAiSetting (MWMechanics::CreatureStats::AI_Fight, ref->mBase->mAiData.mFight);
data->mCreatureStats.setAiSetting (2, ref->mBase->mAiData.mFlee); data->mCreatureStats.setAiSetting (MWMechanics::CreatureStats::AI_Flee, ref->mBase->mAiData.mFlee);
data->mCreatureStats.setAiSetting (3, ref->mBase->mAiData.mAlarm); data->mCreatureStats.setAiSetting (MWMechanics::CreatureStats::AI_Alarm, ref->mBase->mAiData.mAlarm);
// spells // spells
for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin()); for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin());
@ -413,6 +413,14 @@ namespace MWClass
return MWWorld::Ptr(&cell.mCreatures.insert(*ref), &cell); return MWWorld::Ptr(&cell.mCreatures.insert(*ref), &cell);
} }
bool Creature::isFlying(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
return ref->mBase->mFlags & ESM::Creature::Flies;
}
int Creature::getSndGenTypeFromName(const MWWorld::Ptr &ptr, const std::string &name) int Creature::getSndGenTypeFromName(const MWWorld::Ptr &ptr, const std::string &name)
{ {
if(name == "left") if(name == "left")

View file

@ -99,6 +99,8 @@ namespace MWClass
isActor() const { isActor() const {
return true; return true;
} }
virtual bool isFlying (const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -309,10 +309,10 @@ namespace MWClass
data->mNpcStats.getAiSequence().fill(ref->mBase->mAiPackage); data->mNpcStats.getAiSequence().fill(ref->mBase->mAiPackage);
data->mNpcStats.setAiSetting (0, ref->mBase->mAiData.mHello); data->mNpcStats.setAiSetting (MWMechanics::CreatureStats::AI_Hello, ref->mBase->mAiData.mHello);
data->mNpcStats.setAiSetting (1, ref->mBase->mAiData.mFight); data->mNpcStats.setAiSetting (MWMechanics::CreatureStats::AI_Fight, ref->mBase->mAiData.mFight);
data->mNpcStats.setAiSetting (2, ref->mBase->mAiData.mFlee); data->mNpcStats.setAiSetting (MWMechanics::CreatureStats::AI_Flee, ref->mBase->mAiData.mFlee);
data->mNpcStats.setAiSetting (3, ref->mBase->mAiData.mAlarm); data->mNpcStats.setAiSetting (MWMechanics::CreatureStats::AI_Alarm, ref->mBase->mAiData.mAlarm);
// spells // spells
for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin()); for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin());
@ -613,7 +613,7 @@ namespace MWClass
// 'ptr' is losing health. Play a 'hit' voiced dialog entry if not already saying // 'ptr' is losing health. Play a 'hit' voiced dialog entry if not already saying
// something, alert the character controller, scripts, etc. // something, alert the character controller, scripts, etc.
MWBase::Environment::get().getDialogueManager()->say(ptr, "hit"); MWBase::Environment::get().getDialogueManager()->say(ptr, "thief");
if(object.isEmpty()) if(object.isEmpty())
{ {

View file

@ -279,7 +279,8 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
case SelectWrapper::Function_AiSetting: case SelectWrapper::Function_AiSetting:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAiSetting (select.getArgument()); return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAiSetting (
(MWMechanics::CreatureStats::AiSetting)select.getArgument()).getModified();
case SelectWrapper::Function_PcAttribute: case SelectWrapper::Function_PcAttribute:
@ -514,7 +515,8 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
case SelectWrapper::Function_PcVampire: case SelectWrapper::Function_PcVampire:
return MWWorld::Class::get (player).getNpcStats (player).isVampire(); return MWWorld::Class::get (player).getCreatureStats(player).getMagicEffects().
get(ESM::MagicEffect::Vampirism).mMagnitude > 0;
case SelectWrapper::Function_TalkedToPc: case SelectWrapper::Function_TalkedToPc:

View file

@ -76,10 +76,7 @@ void ContainerItemModel::copyItem (const ItemStack& item, size_t count)
const MWWorld::Ptr& source = mItemSources[mItemSources.size()-1]; const MWWorld::Ptr& source = mItemSources[mItemSources.size()-1];
if (item.mBase.getContainerStore() == &source.getClass().getContainerStore(source)) if (item.mBase.getContainerStore() == &source.getClass().getContainerStore(source))
throw std::runtime_error("Item to copy needs to be from a different container!"); throw std::runtime_error("Item to copy needs to be from a different container!");
int origCount = item.mBase.getRefData().getCount(); source.getClass().getContainerStore(source).add(item.mBase, count, source);
item.mBase.getRefData().setCount(count);
source.getClass().getContainerStore(source).add(item.mBase, source);
item.mBase.getRefData().setCount(origCount);
} }
void ContainerItemModel::removeItem (const ItemStack& item, size_t count) void ContainerItemModel::removeItem (const ItemStack& item, size_t count)

View file

@ -42,10 +42,7 @@ void InventoryItemModel::copyItem (const ItemStack& item, size_t count)
{ {
if (item.mBase.getContainerStore() == &mActor.getClass().getContainerStore(mActor)) if (item.mBase.getContainerStore() == &mActor.getClass().getContainerStore(mActor))
throw std::runtime_error("Item to copy needs to be from a different container!"); throw std::runtime_error("Item to copy needs to be from a different container!");
int origCount = item.mBase.getRefData().getCount(); mActor.getClass().getContainerStore(mActor).add(item.mBase, count, mActor);
item.mBase.getRefData().setCount(count);
mActor.getClass().getContainerStore(mActor).add(item.mBase, mActor);
item.mBase.getRefData().setCount(origCount);
} }

View file

@ -364,10 +364,7 @@ namespace MWGui
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr); MWWorld::ContainerStore& invStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
MWWorld::ContainerStoreIterator it = invStore.begin(); MWWorld::ContainerStoreIterator it = invStore.begin();
int origCount = ptr.getRefData().getCount(); it = invStore.add(ptr, mDragAndDrop->mDraggedCount, mPtr);
ptr.getRefData().setCount(mDragAndDrop->mDraggedCount);
it = invStore.add(ptr, mPtr);
ptr.getRefData().setCount(origCount);
mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount); mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount);
ptr = *it; ptr = *it;
@ -521,7 +518,7 @@ namespace MWGui
// add to player inventory // add to player inventory
// can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object // can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWWorld::Ptr newObject = *MWWorld::Class::get (player).getContainerStore (player).add (object, player); MWWorld::Ptr newObject = *player.getClass().getContainerStore (player).add (object, object.getRefData().getCount(), player);
// remove from world // remove from world
MWBase::Environment::get().getWorld()->deleteObject (object); MWBase::Environment::get().getWorld()->deleteObject (object);

View file

@ -393,7 +393,7 @@ namespace MWGui
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
MWMechanics::Spells& spells = stats.getSpells(); MWMechanics::Spells& spells = stats.getSpells();
if (spells.getSelectedSpell() == mSpellToDelete) if (MWBase::Environment::get().getWindowManager()->getSelectedSpell() == mSpellToDelete)
MWBase::Environment::get().getWindowManager()->unsetSelectedSpell(); MWBase::Environment::get().getWindowManager()->unsetSelectedSpell();
spells.remove(mSpellToDelete); spells.remove(mSpellToDelete);

View file

@ -1,5 +1,5 @@
#ifndef _MWINPUT_MWINPUTMANAGERIMP_H #ifndef MWINPUT_MWINPUTMANAGERIMP_H
#define _MWINPUT_MWINPUTMANAGERIMP_H #define MWINPUT_MWINPUTMANAGERIMP_H
#include "../mwgui/mode.hpp" #include "../mwgui/mode.hpp"

View file

@ -172,7 +172,7 @@ namespace MWMechanics
float d = sqrt((actorpos.pos[0] - playerpos.pos[0])*(actorpos.pos[0] - playerpos.pos[0]) float d = sqrt((actorpos.pos[0] - playerpos.pos[0])*(actorpos.pos[0] - playerpos.pos[0])
+(actorpos.pos[1] - playerpos.pos[1])*(actorpos.pos[1] - playerpos.pos[1]) +(actorpos.pos[1] - playerpos.pos[1])*(actorpos.pos[1] - playerpos.pos[1])
+(actorpos.pos[2] - playerpos.pos[2])*(actorpos.pos[2] - playerpos.pos[2])); +(actorpos.pos[2] - playerpos.pos[2])*(actorpos.pos[2] - playerpos.pos[2]));
float fight = ptr.getClass().getCreatureStats(ptr).getAiSetting(1); float fight = ptr.getClass().getCreatureStats(ptr).getAiSetting(CreatureStats::AI_Fight).getModified();
float disp = 100; //creatures don't have disposition, so set it to 100 by default float disp = 100; //creatures don't have disposition, so set it to 100 by default
if(ptr.getTypeName() == typeid(ESM::NPC).name()) if(ptr.getTypeName() == typeid(ESM::NPC).name())
{ {
@ -228,7 +228,7 @@ namespace MWMechanics
now += creatureStats.getActiveSpells().getMagicEffects(); now += creatureStats.getActiveSpells().getMagicEffects();
MagicEffects diff = MagicEffects::diff (creatureStats.getMagicEffects(), now); //MagicEffects diff = MagicEffects::diff (creatureStats.getMagicEffects(), now);
creatureStats.setMagicEffects(now); creatureStats.setMagicEffects(now);
@ -341,6 +341,30 @@ namespace MWMechanics
creatureStats.setDynamic(i, stat); creatureStats.setDynamic(i, stat);
} }
// AI setting modifiers
int creature = !ptr.getClass().isNpc();
if (creature && ptr.get<ESM::Creature>()->mBase->mData.mType == ESM::Creature::Humanoid)
creature = false;
// Note: the Creature variants only work on normal creatures, not on daedra or undead creatures.
if (!creature || ptr.get<ESM::Creature>()->mBase->mData.mType == ESM::Creature::Creatures)
{
Stat<int> stat = creatureStats.getAiSetting(CreatureStats::AI_Fight);
stat.setModifier(creatureStats.getMagicEffects().get(ESM::MagicEffect::FrenzyHumanoid+creature).mMagnitude
- creatureStats.getMagicEffects().get(ESM::MagicEffect::CalmHumanoid+creature).mMagnitude);
creatureStats.setAiSetting(CreatureStats::AI_Fight, stat);
stat = creatureStats.getAiSetting(CreatureStats::AI_Flee);
stat.setModifier(creatureStats.getMagicEffects().get(ESM::MagicEffect::DemoralizeHumanoid+creature).mMagnitude
- creatureStats.getMagicEffects().get(ESM::MagicEffect::RallyHumanoid+creature).mMagnitude);
creatureStats.setAiSetting(CreatureStats::AI_Flee, stat);
}
if (creature && ptr.get<ESM::Creature>()->mBase->mData.mType == ESM::Creature::Undead)
{
Stat<int> stat = creatureStats.getAiSetting(CreatureStats::AI_Flee);
stat.setModifier(creatureStats.getMagicEffects().get(ESM::MagicEffect::TurnUndead).mMagnitude);
creatureStats.setAiSetting(CreatureStats::AI_Flee, stat);
}
// Apply disintegration (reduces item health) // Apply disintegration (reduces item health)
float disintegrateWeapon = effects.get(ESM::MagicEffect::DisintegrateWeapon).mMagnitude; float disintegrateWeapon = effects.get(ESM::MagicEffect::DisintegrateWeapon).mMagnitude;
if (disintegrateWeapon > 0) if (disintegrateWeapon > 0)

View file

@ -122,7 +122,7 @@ namespace MWMechanics
return mLevel; return mLevel;
} }
int CreatureStats::getAiSetting (int index) const Stat<int> CreatureStats::getAiSetting (AiSetting index) const
{ {
assert (index>=0 && index<4); assert (index>=0 && index<4);
return mAiSettings[index]; return mAiSettings[index];
@ -240,12 +240,18 @@ namespace MWMechanics
mAttackingOrSpell = attackingOrSpell; mAttackingOrSpell = attackingOrSpell;
} }
void CreatureStats::setAiSetting (int index, int value) void CreatureStats::setAiSetting (AiSetting index, Stat<int> value)
{ {
assert (index>=0 && index<4); assert (index>=0 && index<4);
mAiSettings[index] = value; mAiSettings[index] = value;
} }
void CreatureStats::setAiSetting (AiSetting index, int base)
{
Stat<int> stat(base);
setAiSetting(index, stat);
}
bool CreatureStats::isDead() const bool CreatureStats::isDead() const
{ {
return mDead; return mDead;

View file

@ -24,7 +24,7 @@ namespace MWMechanics
Spells mSpells; Spells mSpells;
ActiveSpells mActiveSpells; ActiveSpells mActiveSpells;
MagicEffects mMagicEffects; MagicEffects mMagicEffects;
int mAiSettings[4]; Stat<int> mAiSettings[4];
AiSequence mAiSequence; AiSequence mAiSequence;
float mLevelHealthBonus; float mLevelHealthBonus;
bool mDead; bool mDead;
@ -85,9 +85,6 @@ namespace MWMechanics
int getLevel() const; int getLevel() const;
int getAiSetting (int index) const;
///< 0: hello, 1 fight, 2 flee, 3 alarm
Spells & getSpells(); Spells & getSpells();
ActiveSpells & getActiveSpells(); ActiveSpells & getActiveSpells();
@ -125,8 +122,16 @@ namespace MWMechanics
void setLevel(int level); void setLevel(int level);
void setAiSetting (int index, int value); enum AiSetting
///< 0: hello, 1 fight, 2 flee, 3 alarm {
AI_Hello,
AI_Fight,
AI_Flee,
AI_Alarm
};
void setAiSetting (AiSetting index, Stat<int> value);
void setAiSetting (AiSetting index, int base);
Stat<int> getAiSetting (AiSetting index) const;
const AiSequence& getAiSequence() const; const AiSequence& getAiSequence() const;

View file

@ -90,7 +90,7 @@ namespace MWMechanics
// Add the new item to player inventory and remove the old one // Add the new item to player inventory and remove the old one
store.remove(mOldItemPtr, 1, player); store.remove(mOldItemPtr, 1, player);
store.add(newItemPtr, player); store.add(newItemPtr, 1, player);
if(!mSelfEnchanting) if(!mSelfEnchanting)
payForEnchantment(); payForEnchantment();

View file

@ -481,6 +481,8 @@ namespace MWMechanics
if (playerStats.getDrawState() == MWMechanics::DrawState_Weapon) if (playerStats.getDrawState() == MWMechanics::DrawState_Weapon)
x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispWeaponDrawn")->getFloat(); x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispWeaponDrawn")->getFloat();
x += ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Charm).mMagnitude;
int effective_disposition = std::max(0,std::min(int(x),100));//, normally clamped to [0..100] when used int effective_disposition = std::max(0,std::min(int(x),100));//, normally clamped to [0..100] when used
return effective_disposition; return effective_disposition;
} }
@ -605,8 +607,12 @@ namespace MWMechanics
{ {
float s = int(r * fPerDieRollMult * fPerTempMult); float s = int(r * fPerDieRollMult * fPerTempMult);
npcStats.setAiSetting (2, std::max(0, std::min(100, npcStats.getAiSetting (2) + int(std::max(iPerMinChange, s))))); int flee = npcStats.getAiSetting(MWMechanics::CreatureStats::AI_Flee).getBase();
npcStats.setAiSetting (1, std::max(0, std::min(100, npcStats.getAiSetting (1) + int(std::min(-iPerMinChange, -s))))); int fight = npcStats.getAiSetting(MWMechanics::CreatureStats::AI_Fight).getBase();
npcStats.setAiSetting (MWMechanics::CreatureStats::AI_Flee,
std::max(0, std::min(100, flee + int(std::max(iPerMinChange, s)))));
npcStats.setAiSetting (MWMechanics::CreatureStats::AI_Fight,
std::max(0, std::min(100, fight + int(std::min(-iPerMinChange, -s)))));
} }
float c = -std::abs(int(r * fPerDieRollMult)); float c = -std::abs(int(r * fPerDieRollMult));
@ -640,8 +646,12 @@ namespace MWMechanics
{ {
float s = c * fPerDieRollMult * fPerTempMult; float s = c * fPerDieRollMult * fPerTempMult;
npcStats.setAiSetting (2, std::max(0, std::min(100, npcStats.getAiSetting (2) + std::min(-int(iPerMinChange), int(-s))))); int flee = npcStats.getAiSetting (CreatureStats::AI_Flee).getBase();
npcStats.setAiSetting (1, std::max(0, std::min(100, npcStats.getAiSetting (1) + std::max(int(iPerMinChange), int(s))))); int fight = npcStats.getAiSetting (CreatureStats::AI_Fight).getBase();
npcStats.setAiSetting (CreatureStats::AI_Flee,
std::max(0, std::min(100, flee + std::min(-int(iPerMinChange), int(-s)))));
npcStats.setAiSetting (CreatureStats::AI_Fight,
std::max(0, std::min(100, fight + std::max(int(iPerMinChange), int(s)))));
} }
x = int(-c * fPerDieRollMult); x = int(-c * fPerDieRollMult);

View file

@ -28,7 +28,6 @@ MWMechanics::NpcStats::NpcStats()
, mBounty (0) , mBounty (0)
, mLevelProgress(0) , mLevelProgress(0)
, mDisposition(0) , mDisposition(0)
, mVampire (0)
, mReputation(0) , mReputation(0)
, mWerewolfKills (0) , mWerewolfKills (0)
, mProfit(0) , mProfit(0)
@ -318,16 +317,6 @@ void MWMechanics::NpcStats::setFactionReputation (const std::string& faction, in
mFactionReputation[faction] = value; mFactionReputation[faction] = value;
} }
bool MWMechanics::NpcStats::isVampire() const
{
return mVampire;
}
void MWMechanics::NpcStats::setVampire (bool set)
{
mVampire = set;
}
int MWMechanics::NpcStats::getReputation() const int MWMechanics::NpcStats::getReputation() const
{ {
return mReputation; return mReputation;

View file

@ -50,7 +50,6 @@ namespace MWMechanics
int mBounty; int mBounty;
std::set<std::string> mExpelled; std::set<std::string> mExpelled;
std::map<std::string, int> mFactionReputation; std::map<std::string, int> mFactionReputation;
bool mVampire;
int mReputation; int mReputation;
int mWerewolfKills; int mWerewolfKills;
int mProfit; int mProfit;
@ -135,10 +134,6 @@ namespace MWMechanics
void setFactionReputation (const std::string& faction, int value); void setFactionReputation (const std::string& faction, int value);
bool isVampire() const;
void setVampire (bool set);
bool hasSkillsForRank (const std::string& factionId, int rank) const; bool hasSkillsForRank (const std::string& factionId, int rank) const;
bool isWerewolf() const; bool isWerewolf() const;

View file

@ -1,5 +1,5 @@
#ifndef _GAME_RENDER_ACTIVATORANIMATION_H #ifndef GAME_RENDER_ACTIVATORANIMATION_H
#define _GAME_RENDER_ACTIVATORANIMATION_H #define GAME_RENDER_ACTIVATORANIMATION_H
#include "animation.hpp" #include "animation.hpp"

View file

@ -1,5 +1,5 @@
#ifndef _GAME_RENDER_ACTORS_H #ifndef GAME_RENDER_ACTORS_H
#define _GAME_RENDER_ACTORS_H #define GAME_RENDER_ACTORS_H
#include <openengine/ogre/renderer.hpp> #include <openengine/ogre/renderer.hpp>

View file

@ -185,6 +185,7 @@ public:
for(unsigned int i = 0;i < numsubs;++i) for(unsigned int i = 0;i < numsubs;++i)
{ {
Ogre::SubEntity* subEnt = entity->getSubEntity(i); Ogre::SubEntity* subEnt = entity->getSubEntity(i);
sh::Factory::getInstance()._ensureMaterial(subEnt->getMaterial()->getName(), "Default");
subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? mTransQueue : mSolidQueue); subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? mTransQueue : mSolidQueue);
} }
} }
@ -1188,6 +1189,7 @@ public:
unsigned int numsubs = ent->getNumSubEntities(); unsigned int numsubs = ent->getNumSubEntities();
for(unsigned int i = 0;i < numsubs;++i) for(unsigned int i = 0;i < numsubs;++i)
{ {
sh::Factory::getInstance()._ensureMaterial(ent->getSubEntity(i)->getMaterial()->getName(), "Default");
if(ent->getSubEntity(i)->getMaterial()->isTransparent()) if(ent->getSubEntity(i)->getMaterial()->isTransparent())
return true; return true;
} }

View file

@ -1,5 +1,5 @@
#ifndef _GAME_RENDER_ANIMATION_H #ifndef GAME_RENDER_ANIMATION_H
#define _GAME_RENDER_ANIMATION_H #define GAME_RENDER_ANIMATION_H
#include <OgreController.h> #include <OgreController.h>
#include <OgreVector3.h> #include <OgreVector3.h>

View file

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

View file

@ -1,5 +1,5 @@
#ifndef _GAME_RENDER_CREATUREANIMATION_H #ifndef GAME_RENDER_CREATUREANIMATION_H
#define _GAME_RENDER_CREATUREANIMATION_H #define GAME_RENDER_CREATUREANIMATION_H
#include "animation.hpp" #include "animation.hpp"

View file

@ -1,5 +1,5 @@
#ifndef _GAME_RENDER_MWSCENE_H #ifndef GAME_RENDER_MWSCENE_H
#define _GAME_RENDER_MWSCENE_H #define GAME_RENDER_MWSCENE_H
#include <utility> #include <utility>
#include <openengine/ogre/renderer.hpp> #include <openengine/ogre/renderer.hpp>

View file

@ -1,5 +1,5 @@
#ifndef _GAME_RENDER_GLOBALMAP_H #ifndef GAME_RENDER_GLOBALMAP_H
#define _GAME_RENDER_GLOBALMAP_H #define GAME_RENDER_GLOBALMAP_H
#include <string> #include <string>

View file

@ -1,5 +1,5 @@
#ifndef _GAME_RENDER_LOCALMAP_H #ifndef GAME_RENDER_LOCALMAP_H
#define _GAME_RENDER_LOCALMAP_H #define GAME_RENDER_LOCALMAP_H
#include <openengine/ogre/renderer.hpp> #include <openengine/ogre/renderer.hpp>

View file

@ -119,7 +119,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, int v
mShowWeapons(false), mShowWeapons(false),
mShowCarriedLeft(true), mShowCarriedLeft(true),
mFirstPersonOffset(0.f, 0.f, 0.f), mFirstPersonOffset(0.f, 0.f, 0.f),
mAlpha(1.f) mAlpha(1.f),
mNpcType(Type_Normal)
{ {
mNpc = mPtr.get<ESM::NPC>()->mBase; mNpc = mPtr.get<ESM::NPC>()->mBase;
@ -157,8 +158,8 @@ void NpcAnimation::updateNpcBase()
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const ESM::Race *race = store.get<ESM::Race>().find(mNpc->mRace); const ESM::Race *race = store.get<ESM::Race>().find(mNpc->mRace);
bool isWerewolf = mPtr.getClass().getNpcStats(mPtr).isWerewolf(); bool isWerewolf = (mNpcType == Type_Werewolf);
bool vampire = mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Vampirism).mMagnitude; bool isVampire = (mNpcType == Type_Vampire);
if (isWerewolf) if (isWerewolf)
{ {
@ -167,7 +168,7 @@ void NpcAnimation::updateNpcBase()
} }
else else
{ {
if (vampire) if (isVampire)
mHeadModel = getVampireHead(mNpc->mRace, mNpc->mFlags & ESM::NPC::Female); mHeadModel = getVampireHead(mNpc->mRace, mNpc->mFlags & ESM::NPC::Female);
else else
mHeadModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHead)->mModel; mHeadModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHead)->mModel;
@ -226,6 +227,19 @@ void NpcAnimation::updateParts()
const MWWorld::Class &cls = MWWorld::Class::get(mPtr); const MWWorld::Class &cls = MWWorld::Class::get(mPtr);
MWWorld::InventoryStore &inv = cls.getInventoryStore(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 { static const struct {
int mSlot; int mSlot;
int mBasePriority; int mBasePriority;
@ -329,7 +343,7 @@ void NpcAnimation::updateParts()
static const int Flag_Female = 1<<0; static const int Flag_Female = 1<<0;
static const int Flag_FirstPerson = 1<<1; static const int Flag_FirstPerson = 1<<1;
bool isWerewolf = cls.getNpcStats(mPtr).isWerewolf(); bool isWerewolf = (mNpcType == Type_Werewolf);
int flags = (isWerewolf ? -1 : 0); int flags = (isWerewolf ? -1 : 0);
if(!mNpc->isMale()) if(!mNpc->isMale())
flags |= Flag_Female; flags |= Flag_Female;
@ -736,6 +750,7 @@ void NpcAnimation::preRender(Ogre::Camera *camera)
void NpcAnimation::applyAlpha(float alpha, Ogre::Entity *ent, NifOgre::ObjectScenePtr scene) void NpcAnimation::applyAlpha(float alpha, Ogre::Entity *ent, NifOgre::ObjectScenePtr scene)
{ {
sh::Factory::getInstance()._ensureMaterial(ent->getSubEntity(0)->getMaterial()->getName(), "Default");
ent->getSubEntity(0)->setRenderQueueGroup(alpha != 1.f || ent->getSubEntity(0)->getMaterial()->isTransparent() ent->getSubEntity(0)->setRenderQueueGroup(alpha != 1.f || ent->getSubEntity(0)->getMaterial()->isTransparent()
? RQG_Alpha : RQG_Main); ? RQG_Alpha : RQG_Main);

View file

@ -1,5 +1,5 @@
#ifndef _GAME_RENDER_NPCANIMATION_H #ifndef GAME_RENDER_NPCANIMATION_H
#define _GAME_RENDER_NPCANIMATION_H #define GAME_RENDER_NPCANIMATION_H
#include "animation.hpp" #include "animation.hpp"
@ -55,6 +55,14 @@ private:
bool mShowWeapons; bool mShowWeapons;
bool mShowCarriedLeft; bool mShowCarriedLeft;
enum NpcType
{
Type_Normal,
Type_Werewolf,
Type_Vampire
};
NpcType mNpcType;
int mVisibilityFlags; int mVisibilityFlags;
int mPartslots[ESM::PRT_Count]; //Each part slot is taken by clothing, armor, or is empty int mPartslots[ESM::PRT_Count]; //Each part slot is taken by clothing, armor, or is empty

View file

@ -1,5 +1,5 @@
#ifndef _GAME_RENDER_OBJECTS_H #ifndef GAME_RENDER_OBJECTS_H
#define _GAME_RENDER_OBJECTS_H #define GAME_RENDER_OBJECTS_H
#include <OgreColourValue.h> #include <OgreColourValue.h>
#include <OgreAxisAlignedBox.h> #include <OgreAxisAlignedBox.h>

View file

@ -1,5 +1,5 @@
#ifndef _GAME_OCCLUSION_QUERY_H #ifndef GAME_OCCLUSION_QUERY_H
#define _GAME_OCCLUSION_QUERY_H #define GAME_OCCLUSION_QUERY_H
#include <OgreRenderObjectListener.h> #include <OgreRenderObjectListener.h>
#include <OgreRenderQueueListener.h> #include <OgreRenderQueueListener.h>

View file

@ -1,5 +1,5 @@
#ifndef _GAME_RENDERING_INTERFACE_H #ifndef GAME_RENDERING_INTERFACE_H
#define _GAME_RENDERING_INTERFACE_H #define GAME_RENDERING_INTERFACE_H
namespace MWRender namespace MWRender
{ {

View file

@ -1,5 +1,5 @@
#ifndef _GAME_RENDERING_MANAGER_H #ifndef GAME_RENDERING_MANAGER_H
#define _GAME_RENDERING_MANAGER_H #define GAME_RENDERING_MANAGER_H
#include "sky.hpp" #include "sky.hpp"
#include "debugging.hpp" #include "debugging.hpp"

View file

@ -225,7 +225,8 @@ namespace MWScript
{ {
MWWorld::Ptr ptr = R()(runtime); MWWorld::Ptr ptr = R()(runtime);
runtime.push(MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSetting (mIndex)); runtime.push(MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSetting (
(MWMechanics::CreatureStats::AiSetting)mIndex).getModified());
} }
}; };
template<class R> template<class R>
@ -241,8 +242,11 @@ namespace MWScript
Interpreter::Type_Integer value = runtime[0].mInteger; Interpreter::Type_Integer value = runtime[0].mInteger;
runtime.pop(); runtime.pop();
MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (mIndex, MWMechanics::CreatureStats::AiSetting setting
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSetting (mIndex) + value); = MWMechanics::CreatureStats::AiSetting(mIndex);
MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (setting,
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSetting (setting).getBase() + value);
} }
}; };
template<class R> template<class R>
@ -258,8 +262,11 @@ namespace MWScript
Interpreter::Type_Integer value = runtime[0].mInteger; Interpreter::Type_Integer value = runtime[0].mInteger;
runtime.pop(); runtime.pop();
MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (mIndex, MWMechanics::CreatureStats::AiSetting setting = (MWMechanics::CreatureStats::AiSetting)mIndex;
value);
MWMechanics::Stat<int> stat = ptr.getClass().getCreatureStats(ptr).getAiSetting(setting);
stat.setModified(value, 0);
ptr.getClass().getCreatureStats(ptr).setAiSetting(setting, stat);
} }
}; };

View file

@ -370,4 +370,5 @@ op 0x200022f: Resurrect
op 0x2000230: Resurrect, explicit op 0x2000230: Resurrect, explicit
op 0x2000231: GetSpellReadied op 0x2000231: GetSpellReadied
op 0x2000232: GetSpellReadied, explicit op 0x2000232: GetSpellReadied, explicit
opcodes 0x2000233-0x3ffffff unused op 0x2000233: GetPcJumping
opcodes 0x2000234-0x3ffffff unused

View file

@ -58,6 +58,18 @@ namespace MWScript
} }
}; };
class OpGetPcJumping : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWBase::World* world = MWBase::Environment::get().getWorld();
MWWorld::Ptr player = world->getPlayer().getPlayer();
runtime.push (!world->isOnGround(player) && !world->isFlying(player));
}
};
class OpWakeUpPc : public Interpreter::Opcode0 class OpWakeUpPc : public Interpreter::Opcode0
{ {
public: public:
@ -771,6 +783,7 @@ namespace MWScript
interpreter.installSegment5 (Compiler::Misc::opcodeDontSaveObject, new OpDontSaveObject); interpreter.installSegment5 (Compiler::Misc::opcodeDontSaveObject, new OpDontSaveObject);
interpreter.installSegment5 (Compiler::Misc::opcodeToggleVanityMode, new OpToggleVanityMode); interpreter.installSegment5 (Compiler::Misc::opcodeToggleVanityMode, new OpToggleVanityMode);
interpreter.installSegment5 (Compiler::Misc::opcodeGetPcSleep, new OpGetPcSleep); interpreter.installSegment5 (Compiler::Misc::opcodeGetPcSleep, new OpGetPcSleep);
interpreter.installSegment5 (Compiler::Misc::opcodeGetPcJumping, new OpGetPcJumping);
interpreter.installSegment5 (Compiler::Misc::opcodeWakeUpPc, new OpWakeUpPc); interpreter.installSegment5 (Compiler::Misc::opcodeWakeUpPc, new OpWakeUpPc);
interpreter.installSegment5 (Compiler::Misc::opcodePlayBink, new OpPlayBink); interpreter.installSegment5 (Compiler::Misc::opcodePlayBink, new OpPlayBink);
interpreter.installSegment5 (Compiler::Misc::opcodeGetLocked, new OpGetLocked<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeGetLocked, new OpGetLocked<ImplicitRef>);

View file

@ -14,10 +14,7 @@ namespace MWWorld
void ActionTake::executeImp (const Ptr& actor) void ActionTake::executeImp (const Ptr& actor)
{ {
// insert into player's inventory actor.getClass().getContainerStore (actor).add (getTarget(), getTarget().getRefData().getCount(), actor);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPtr ("player", true);
MWWorld::Class::get (player).getContainerStore (player).add (getTarget(), player);
MWBase::Environment::get().getWorld()->deleteObject (getTarget()); MWBase::Environment::get().getWorld()->deleteObject (getTarget());
} }

View file

@ -372,4 +372,10 @@ namespace MWWorld
return newPtr; return newPtr;
} }
bool Class::isFlying(const Ptr &ptr) const
{
return false;
}
} }

View file

@ -306,6 +306,8 @@ namespace MWWorld
return false; return false;
} }
virtual bool isFlying(const MWWorld::Ptr& ptr) const;
static const Class& get (const std::string& key); static const Class& get (const std::string& key);
///< If there is no class for this \a key, an exception is thrown. ///< If there is no class for this \a key, an exception is thrown.

View file

@ -81,7 +81,7 @@ void MWWorld::ContainerStore::unstack(const Ptr &ptr, const Ptr& container)
{ {
if (ptr.getRefData().getCount() <= 1) if (ptr.getRefData().getCount() <= 1)
return; return;
addNewStack(ptr)->getRefData().setCount(ptr.getRefData().getCount()-1); addNewStack(ptr, ptr.getRefData().getCount()-1);
remove(ptr, ptr.getRefData().getCount()-1, container); remove(ptr, ptr.getRefData().getCount()-1, container);
} }
@ -123,12 +123,12 @@ bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(const std::string &id, int count, const Ptr &actorPtr) MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(const std::string &id, int count, const Ptr &actorPtr)
{ {
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), id, count); MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), id, count);
return add(ref.getPtr(), actorPtr); return add(ref.getPtr(), count, actorPtr);
} }
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr, const Ptr& actorPtr) MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr, int count, const Ptr& actorPtr)
{ {
MWWorld::ContainerStoreIterator it = addImp(itemPtr); MWWorld::ContainerStoreIterator it = addImp(itemPtr, count);
MWWorld::Ptr item = *it; MWWorld::Ptr item = *it;
// we may have copied an item from the world, so reset a few things first // we may have copied an item from the world, so reset a few things first
@ -165,7 +165,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr
return it; return it;
} }
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr) MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr, int count)
{ {
int type = getType(ptr); int type = getType(ptr);
@ -180,20 +180,20 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr)
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_025") || Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_025")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_100")) || Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_100"))
{ {
int count = MWWorld::Class::get(ptr).getValue(ptr) * ptr.getRefData().getCount(); int realCount = MWWorld::Class::get(ptr).getValue(ptr) * ptr.getRefData().getCount();
for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter) for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter)
{ {
if (Misc::StringUtils::ciEqual((*iter).get<ESM::Miscellaneous>()->mRef.mRefID, "gold_001")) if (Misc::StringUtils::ciEqual((*iter).get<ESM::Miscellaneous>()->mRef.mRefID, "gold_001"))
{ {
iter->getRefData().setCount(iter->getRefData().getCount() + count); iter->getRefData().setCount(iter->getRefData().getCount() + realCount);
flagAsModified(); flagAsModified();
return iter; return iter;
} }
} }
MWWorld::ManualRef ref(esmStore, "Gold_001", count); MWWorld::ManualRef ref(esmStore, "Gold_001", count);
return addNewStack(ref.getPtr()); return addNewStack(ref.getPtr(), count);
} }
// determine whether to stack or not // determine whether to stack or not
@ -202,17 +202,17 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr)
if (stacks(*iter, ptr)) if (stacks(*iter, ptr))
{ {
// stack // stack
iter->getRefData().setCount( iter->getRefData().getCount() + ptr.getRefData().getCount() ); iter->getRefData().setCount( iter->getRefData().getCount() + count );
flagAsModified(); flagAsModified();
return iter; return iter;
} }
} }
// if we got here, this means no stacking // if we got here, this means no stacking
return addNewStack(ptr); return addNewStack(ptr, count);
} }
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addNewStack (const Ptr& ptr) MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addNewStack (const Ptr& ptr, int count)
{ {
ContainerStoreIterator it = begin(); ContainerStoreIterator it = begin();
@ -232,6 +232,8 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addNewStack (const Ptr&
case Type_Weapon: weapons.mList.push_back (*ptr.get<ESM::Weapon>()); it = ContainerStoreIterator(this, --weapons.mList.end()); break; case Type_Weapon: weapons.mList.push_back (*ptr.get<ESM::Weapon>()); it = ContainerStoreIterator(this, --weapons.mList.end()); break;
} }
it->getRefData().setCount(count);
flagAsModified(); flagAsModified();
return it; return it;
} }
@ -343,7 +345,7 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::
else else
{ {
ref.getPtr().getCellRef().mOwner = owner; ref.getPtr().getCellRef().mOwner = owner;
addImp (ref.getPtr()); addImp (ref.getPtr(), count);
} }
} }
catch (std::logic_error& e) catch (std::logic_error& e)

View file

@ -51,7 +51,7 @@ namespace MWWorld
MWWorld::CellRefList<ESM::Weapon> weapons; MWWorld::CellRefList<ESM::Weapon> weapons;
mutable float mCachedWeight; mutable float mCachedWeight;
mutable bool mWeightUpToDate; mutable bool mWeightUpToDate;
ContainerStoreIterator addImp (const Ptr& ptr); ContainerStoreIterator addImp (const Ptr& ptr, int count);
void addInitialItem (const std::string& id, const std::string& owner, int count, unsigned char failChance=0, bool topLevel=true); void addInitialItem (const std::string& id, const std::string& owner, int count, unsigned char failChance=0, bool topLevel=true);
public: public:
@ -64,7 +64,7 @@ namespace MWWorld
ContainerStoreIterator end(); ContainerStoreIterator end();
virtual ContainerStoreIterator add (const Ptr& itemPtr, const Ptr& actorPtr); virtual ContainerStoreIterator add (const Ptr& itemPtr, int count, const Ptr& actorPtr);
///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed) ///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed)
/// ///
/// \note The item pointed to is not required to exist beyond this function call. /// \note The item pointed to is not required to exist beyond this function call.
@ -91,7 +91,7 @@ namespace MWWorld
///< Unstack an item in this container. The item's count will be set to 1, then a new stack will be added with (origCount-1). ///< Unstack an item in this container. The item's count will be set to 1, then a new stack will be added with (origCount-1).
protected: protected:
ContainerStoreIterator addNewStack (const Ptr& ptr); ContainerStoreIterator addNewStack (const Ptr& ptr, int count);
///< Add the item to this container (do not try to stack it onto existing items) ///< Add the item to this container (do not try to stack it onto existing items)
virtual void flagAsModified(); virtual void flagAsModified();

View file

@ -75,9 +75,9 @@ MWWorld::InventoryStore& MWWorld::InventoryStore::operator= (const InventoryStor
return *this; return *this;
} }
MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr, const Ptr& actorPtr) MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr, int count, const Ptr& actorPtr)
{ {
const MWWorld::ContainerStoreIterator& retVal = MWWorld::ContainerStore::add(itemPtr, actorPtr); const MWWorld::ContainerStoreIterator& retVal = MWWorld::ContainerStore::add(itemPtr, count, actorPtr);
// Auto-equip items if an armor/clothing item is added, but not for the player nor werewolves // Auto-equip items if an armor/clothing item is added, but not for the player nor werewolves
if ((actorPtr.getRefData().getHandle() != "player") if ((actorPtr.getRefData().getHandle() != "player")
@ -118,11 +118,7 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite
// unstack item pointed to by iterator if required // unstack item pointed to by iterator if required
if (iterator!=end() && !slots_.second && iterator->getRefData().getCount() > 1) // if slots.second is true, item can stay stacked when equipped if (iterator!=end() && !slots_.second && iterator->getRefData().getCount() > 1) // if slots.second is true, item can stay stacked when equipped
{ {
// add the item again with a count of count-1, then set the count of the original (that will be equipped) to 1 unstack(*iterator, actor);
int count = iterator->getRefData().getCount();
iterator->getRefData().setCount(count-1);
addNewStack(*iterator);
iterator->getRefData().setCount(1);
} }
mSlots[slot] = iterator; mSlots[slot] = iterator;
@ -139,8 +135,13 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite
void MWWorld::InventoryStore::unequipAll(const MWWorld::Ptr& actor) 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) for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
unequipSlot(slot, actor); unequipSlot(slot, actor);
mUpdatesEnabled = true;
fireEquipmentChangedEvent();
updateMagicEffects(actor);
} }
MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot) MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot)
@ -269,11 +270,7 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
// unstack item pointed to by iterator if required // unstack item pointed to by iterator if required
if (iter->getRefData().getCount() > 1) if (iter->getRefData().getCount() > 1)
{ {
// add the item again with a count of count-1, then set the count of the original (that will be equipped) to 1 unstack(*iter, actor);
int count = iter->getRefData().getCount();
iter->getRefData().setCount(count-1);
addNewStack(*iter);
iter->getRefData().setCount(1);
} }
} }

View file

@ -113,7 +113,7 @@ namespace MWWorld
InventoryStore& operator= (const InventoryStore& store); InventoryStore& operator= (const InventoryStore& store);
virtual ContainerStoreIterator add (const Ptr& itemPtr, const Ptr& actorPtr); virtual ContainerStoreIterator add (const Ptr& itemPtr, int count, const Ptr& actorPtr);
///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed) ///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed)
/// Auto-equip items if specific conditions are fulfilled (see the implementation). /// Auto-equip items if specific conditions are fulfilled (see the implementation).
/// ///

View file

@ -350,6 +350,7 @@ namespace MWWorld
void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position) void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)
{ {
Nif::NIFFile::CacheLock lock;
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0.5); MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0.5);
mRendering.enableTerrain(false); mRendering.enableTerrain(false);

View file

@ -1605,13 +1605,17 @@ namespace MWWorld
if(!ptr.getClass().isActor()) if(!ptr.getClass().isActor())
return false; return false;
if (ptr.getClass().getCreatureStats(ptr).isDead())
return false;
if (ptr.getClass().isFlying(ptr))
return true;
const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr); const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
if(stats.getMagicEffects().get(ESM::MagicEffect::Levitate).mMagnitude > 0 if(stats.getMagicEffects().get(ESM::MagicEffect::Levitate).mMagnitude > 0
&& isLevitationEnabled()) && isLevitationEnabled())
return true; return true;
// TODO: Check if flying creature
const OEngine::Physic::PhysicActor *actor = mPhysEngine->getCharacter(ptr.getRefData().getHandle()); const OEngine::Physic::PhysicActor *actor = mPhysEngine->getCharacter(ptr.getRefData().getHandle());
if(!actor || !actor->getCollisionMode()) if(!actor || !actor->getCollisionMode())
return true; return true;
@ -1960,6 +1964,10 @@ namespace MWWorld
npcStats.setWerewolf(werewolf); 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); MWWorld::InventoryStore& invStore = MWWorld::Class::get(actor).getInventoryStore(actor);
invStore.unequipAll(actor); invStore.unequipAll(actor);
@ -1974,6 +1982,10 @@ namespace MWWorld
actor.getClass().getContainerStore(actor).remove("werewolfrobe", 1, actor); 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") if(actor.getRefData().getHandle() == "player")
{ {
// Update the GUI only when called on the player // Update the GUI only when called on the player
@ -1991,8 +2003,6 @@ namespace MWWorld
windowManager->unsetForceHide(MWGui::GW_Magic); windowManager->unsetForceHide(MWGui::GW_Magic);
} }
} }
mRendering->rebuildPtr(actor);
} }
void World::applyWerewolfAcrobatics(const Ptr &actor) void World::applyWerewolfAcrobatics(const Ptr &actor)

View file

@ -241,6 +241,7 @@ namespace Compiler
extensions.registerInstruction ("togglevanitymode", "", opcodeToggleVanityMode); extensions.registerInstruction ("togglevanitymode", "", opcodeToggleVanityMode);
extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode); extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode);
extensions.registerFunction ("getpcsleep", 'l', "", opcodeGetPcSleep); extensions.registerFunction ("getpcsleep", 'l', "", opcodeGetPcSleep);
extensions.registerFunction ("getpcjumping", 'l', "", opcodeGetPcJumping);
extensions.registerInstruction ("wakeuppc", "", opcodeWakeUpPc); extensions.registerInstruction ("wakeuppc", "", opcodeWakeUpPc);
extensions.registerInstruction ("playbink", "Sl", opcodePlayBink); extensions.registerInstruction ("playbink", "Sl", opcodePlayBink);
extensions.registerFunction ("getlocked", 'l', "", opcodeGetLocked, opcodeGetLockedExplicit); extensions.registerFunction ("getlocked", 'l', "", opcodeGetLocked, opcodeGetLockedExplicit);

View file

@ -188,6 +188,7 @@ namespace Compiler
const int opcodeDontSaveObject = 0x2000153; const int opcodeDontSaveObject = 0x2000153;
const int opcodeToggleVanityMode = 0x2000174; const int opcodeToggleVanityMode = 0x2000174;
const int opcodeGetPcSleep = 0x200019f; const int opcodeGetPcSleep = 0x200019f;
const int opcodeGetPcJumping = 0x2000233;
const int opcodeWakeUpPc = 0x20001a2; const int opcodeWakeUpPc = 0x20001a2;
const int opcodeGetLocked = 0x20001c7; const int opcodeGetLocked = 0x20001c7;
const int opcodeGetLockedExplicit = 0x20001c8; const int opcodeGetLockedExplicit = 0x20001c8;

View file

@ -40,7 +40,7 @@ struct Creature
enum Type enum Type
{ {
Creatures = 0, Creatures = 0,
Deadra = 1, Daedra = 1,
Undead = 2, Undead = 2,
Humanoid = 3 Humanoid = 3
}; };

View file

@ -157,7 +157,6 @@ Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata,
ctrls = ctrls->next; ctrls = ctrls->next;
} }
} }
needTangents = !texName[Nif::NiTexturingProperty::BumpTexture].empty();
// Alpha modifiers // Alpha modifiers
if(alphaprop) if(alphaprop)
@ -407,6 +406,12 @@ Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata,
instance->setProperty("depth_write", sh::makeProperty(new sh::StringValue(((depthFlags>>1)&1) ? "on" : "off"))); instance->setProperty("depth_write", sh::makeProperty(new sh::StringValue(((depthFlags>>1)&1) ? "on" : "off")));
// depth_func??? // depth_func???
if (!texName[0].empty())
NifOverrides::Overrides::getMaterialOverrides(texName[0], instance);
// Don't use texName, as it may be overridden
needTangents = !sh::retrieveValue<sh::StringValue>(instance->getProperty("normalMap"), instance).get().empty();
return name; return name;
} }

View file

@ -4,14 +4,51 @@
#include <../components/misc/stringops.hpp> #include <../components/misc/stringops.hpp>
#include "../extern/shiny/Main/MaterialInstance.hpp"
#include <stdexcept>
using namespace NifOverrides; using namespace NifOverrides;
Ogre::ConfigFile Overrides::mTransparencyOverrides = Ogre::ConfigFile(); Overrides::TransparencyOverrideMap Overrides::mTransparencyOverrides = Overrides::TransparencyOverrideMap();
Overrides::MaterialOverrideMap Overrides::mMaterialOverrides = Overrides::MaterialOverrideMap();
void Overrides::loadTransparencyOverrides (const std::string& file) void Overrides::loadTransparencyOverrides (const std::string& file)
{ {
mTransparencyOverrides.load(file); Ogre::ConfigFile cf;
cf.load(file);
Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
while (seci.hasMoreElements())
{
Ogre::String sectionName = seci.peekNextKey();
mTransparencyOverrides[sectionName] =
Ogre::StringConverter::parseInt(cf.getSetting("alphaRejectValue", sectionName));
seci.getNext();
}
}
void Overrides::loadMaterialOverrides(const std::string &file)
{
Ogre::ConfigFile cf;
cf.load(file);
Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
while (seci.hasMoreElements())
{
Ogre::String sectionName = seci.peekNextKey();
Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
Ogre::ConfigFile::SettingsMultiMap::iterator i;
std::map<std::string, std::string> overrides;
for (i = settings->begin(); i != settings->end(); ++i)
{
overrides[i->first] = i->second;
}
mMaterialOverrides[sectionName] = overrides;
}
} }
TransparencyResult Overrides::getTransparencyOverride(const std::string& texture) TransparencyResult Overrides::getTransparencyOverride(const std::string& texture)
@ -19,20 +56,25 @@ TransparencyResult Overrides::getTransparencyOverride(const std::string& texture
TransparencyResult result; TransparencyResult result;
result.first = false; result.first = false;
std::string tex = texture; TransparencyOverrideMap::iterator it = mTransparencyOverrides.find(Misc::StringUtils::lowerCase(texture));
Misc::StringUtils::toLower(tex); if (it != mTransparencyOverrides.end())
Ogre::ConfigFile::SectionIterator seci = mTransparencyOverrides.getSectionIterator();
while (seci.hasMoreElements())
{
Ogre::String sectionName = seci.peekNextKey();
if (sectionName == tex)
{ {
result.first = true; result.first = true;
result.second = Ogre::StringConverter::parseInt(mTransparencyOverrides.getSetting("alphaRejectValue", sectionName)); result.second = it->second;
break;
}
seci.getNext();
} }
return result; return result;
} }
void Overrides::getMaterialOverrides(const std::string &texture, sh::MaterialInstance* material)
{
MaterialOverrideMap::iterator it = mMaterialOverrides.find(Misc::StringUtils::lowerCase(texture));
if (it != mMaterialOverrides.end())
{
const std::map<std::string, std::string>& overrides = it->second;
for (std::map<std::string, std::string>::const_iterator it = overrides.begin(); it != overrides.end(); ++it)
{
material->setProperty(it->first, sh::makeProperty(it->second));
}
}
}

View file

@ -3,19 +3,34 @@
#include <OgreConfigFile.h> #include <OgreConfigFile.h>
namespace sh
{
class MaterialInstance;
}
namespace NifOverrides namespace NifOverrides
{ {
typedef std::pair<bool, int> TransparencyResult; typedef std::pair<bool, int> TransparencyResult;
/// \brief provide overrides for some model / texture properties that bethesda has chosen poorly /// Allows to provide overrides for some material properties in NIF files.
/// NIFs are a bit limited in that they don't allow specifying a material externally, which is
/// painful for texture modding.
/// We also use this to patch up transparency settings in certain NIFs that bethesda has chosen poorly.
class Overrides class Overrides
{ {
public: public:
static Ogre::ConfigFile mTransparencyOverrides; typedef std::map<std::string, int> TransparencyOverrideMap;
static TransparencyOverrideMap mTransparencyOverrides;
typedef std::map<std::string, std::map<std::string, std::string> > MaterialOverrideMap;
static MaterialOverrideMap mMaterialOverrides;
void loadTransparencyOverrides (const std::string& file); void loadTransparencyOverrides (const std::string& file);
void loadMaterialOverrides (const std::string& file);
static TransparencyResult getTransparencyOverride(const std::string& texture); static TransparencyResult getTransparencyOverride(const std::string& texture);
static void getMaterialOverrides (const std::string& texture, sh::MaterialInstance* instance);
}; };
} }

View file

@ -1,5 +1,5 @@
#ifndef _COMPONENTS_SETTINGS_H #ifndef COMPONENTS_SETTINGS_H
#define _COMPONENTS_SETTINGS_H #define COMPONENTS_SETTINGS_H
#include <OgreConfigFile.h> #include <OgreConfigFile.h>

View file

@ -24,8 +24,8 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------- */ ------------------------------------------------------- */
#ifndef _Channel_H_ #ifndef OICS_Channel_H_
#define _Channel_H_ #define OICS_Channel_H_
#include "ICSPrerequisites.h" #include "ICSPrerequisites.h"

View file

@ -24,8 +24,8 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------- */ ------------------------------------------------------- */
#ifndef _Control_H_ #ifndef OICS_Control_H_
#define _Control_H_ #define OICS_Control_H_
#include "ICSPrerequisites.h" #include "ICSPrerequisites.h"

View file

@ -24,8 +24,8 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------- */ ------------------------------------------------------- */
#ifndef _InputControlSystem_H_ #ifndef OICS_InputControlSystem_H_
#define _InputControlSystem_H_ #define OICS_InputControlSystem_H_
#include "ICSPrerequisites.h" #include "ICSPrerequisites.h"

View file

@ -1,5 +1,5 @@
#ifndef _OIS_SDL_COMPAT_H #ifndef OIS_SDL_COMPAT_H
#define _OIS_SDL_COMPAT_H #define OIS_SDL_COMPAT_H
#include <SDL_events.h> #include <SDL_events.h>
#include <SDL_types.h> #include <SDL_types.h>

View file

@ -1,5 +1,5 @@
#ifndef _SDL4OGRE_CURSOR_MANAGER_H #ifndef SDL4OGRE_CURSOR_MANAGER_H
#define _SDL4OGRE_CURSOR_MANAGER_H #define SDL4OGRE_CURSOR_MANAGER_H
#include <SDL_types.h> #include <SDL_types.h>
#include <string> #include <string>

View file

@ -1,5 +1,5 @@
#ifndef _SDL4OGRE_CURSORMANAGER_H #ifndef SDL4OGRE_CURSORMANAGER_H
#define _SDL4OGRE_CURSORMANAGER_H #define SDL4OGRE_CURSORMANAGER_H
#include <SDL.h> #include <SDL.h>

View file

@ -1,5 +1,5 @@
#ifndef _SDL4OGRE_SDLINPUTWRAPPER_H #ifndef SDL4OGRE_SDLINPUTWRAPPER_H
#define _SDL4OGRE_SDLINPUTWRAPPER_H #define SDL4OGRE_SDLINPUTWRAPPER_H
#include <SDL_events.h> #include <SDL_events.h>

View file

@ -13,8 +13,8 @@
* ===================================================================================== * =====================================================================================
*/ */
#ifndef _BtOgreShapes_H_ #ifndef BtOgreShapes_H_
#define _BtOgreShapes_H_ #define BtOgreShapes_H_
#include "btBulletDynamicsCommon.h" #include "btBulletDynamicsCommon.h"
#include "OgreSimpleRenderable.h" #include "OgreSimpleRenderable.h"

View file

@ -14,8 +14,8 @@
* ===================================================================================== * =====================================================================================
*/ */
#ifndef _BtOgrePG_H_ #ifndef BtOgrePG_H_
#define _BtOgrePG_H_ #define BtOgrePG_H_
#include "btBulletDynamicsCommon.h" #include "btBulletDynamicsCommon.h"
#include "BtOgreExtras.h" #include "BtOgreExtras.h"

View file

@ -14,8 +14,8 @@
* ===================================================================================== * =====================================================================================
*/ */
#ifndef _BtOgreGP_H_ #ifndef BtOgreGP_H_
#define _BtOgreGP_H_ #define BtOgreGP_H_
#include "btBulletDynamicsCommon.h" #include "btBulletDynamicsCommon.h"
#include "OgreSceneNode.h" #include "OgreSceneNode.h"

View file

@ -1,5 +1,5 @@
#ifndef _BULLET_SHAPE_LOADER_H_ #ifndef OPENMW_BULLET_SHAPE_LOADER_H_
#define _BULLET_SHAPE_LOADER_H_ #define OPENMW_BULLET_SHAPE_LOADER_H_
#include <OgreResource.h> #include <OgreResource.h>
#include <OgreResourceManager.h> #include <OgreResourceManager.h>