Merge branch 'master' into characterpreview

actorid
scrawl 12 years ago
commit d90af9c524

@ -51,7 +51,7 @@ add_openmw_dir (mwworld
refdata worldimp physicssystem scene globals class action nullaction actionteleport
containerstore actiontalk actiontake manualref player cellfunctors
cells localscripts customdata weather inventorystore ptr actionopen actionread
actionequip timestamp actionalchemy cellstore actionapply
actionequip timestamp actionalchemy cellstore actionapply actioneat
)
add_openmw_dir (mwclass

@ -162,6 +162,10 @@ void OMW::Engine::loadBSA()
dataDirectory = iter->string();
std::cout << "Data dir " << dataDirectory << std::endl;
Bsa::addDir(dataDirectory, mFSStrict);
// Workaround: Mygui does not find textures in non-BSA subfolders, _unless_ they are explicitely added like this
// For splash screens, this is OK to do, but eventually we will need an investigation why this is necessary
Bsa::addDir(dataDirectory + "/Splash", mFSStrict);
}
}

@ -218,6 +218,7 @@ namespace MWBase
virtual void executeInConsole (const std::string& path) = 0;
virtual void setLoadingProgress (const std::string& stage, int depth, int current, int total) = 0;
virtual void loadingDone() = 0;
};
}

@ -11,6 +11,7 @@
#include "../mwworld/actiontake.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwworld/physicssystem.hpp"
#include "../mwworld/actioneat.hpp"
#include "../mwgui/tooltips.hpp"
@ -19,6 +20,14 @@
namespace MWClass
{
std::string Ingredient::getId (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return ref->base->mId;
}
void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{
const std::string model = getModel(ptr);
@ -84,6 +93,16 @@ namespace MWClass
return ref->base->data.value;
}
boost::shared_ptr<MWWorld::Action> Ingredient::use (const MWWorld::Ptr& ptr) const
{
boost::shared_ptr<MWWorld::Action> action (new MWWorld::ActionEat (ptr));
action->setSound ("Swallow");
return action;
}
void Ingredient::registerSelf()
{
boost::shared_ptr<Class> instance (new Ingredient);

@ -12,6 +12,9 @@ namespace MWClass
public:
virtual std::string getId (const MWWorld::Ptr& ptr) const;
///< Return ID of \a ptr
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
@ -37,6 +40,10 @@ namespace MWClass
virtual int getValue (const MWWorld::Ptr& ptr) const;
///< Return trade value of the object. Throws an exception, if the object can't be traded.
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const;
///< Generate action for using via inventory menu
static void registerSelf();
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;

@ -365,7 +365,7 @@ namespace MWClass
/// \todo consider instant effects
return stats.getActiveSpells().addSpell (id);
return stats.getActiveSpells().addSpell (id, actor);
}
void Npc::skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType) const

@ -11,6 +11,8 @@
#include "../mwbase/environment.hpp"
#include "../mwbase/inputmanager.hpp"
#include "../mwbase/windowmanager.hpp"
namespace MWGui
{
@ -20,6 +22,8 @@ namespace MWGui
, WindowBase("openmw_loading_screen.layout", parWindowManager)
, mLoadingOn(false)
, mLastRenderTime(0.f)
, mLastWallpaperChangeTime(0.f)
, mFirstLoad(true)
{
getWidget(mLoadingText, "LoadingText");
getWidget(mProgressBar, "ProgressBar");
@ -77,11 +81,7 @@ namespace MWGui
mTotalRefsLoading = total;
}
if (mTotalCellsLoading == 0)
{
loadingOff();
return;
}
assert (mTotalCellsLoading != 0);
float refProgress;
if (mTotalRefsLoading <= 1)
@ -98,11 +98,6 @@ namespace MWGui
float progress = (float(mCurrentCellLoading)+refProgress) / float(mTotalCellsLoading);
assert(progress <= 1 && progress >= 0);
if (progress >= 1)
{
loadingOff();
return;
}
mLoadingText->setCaption(stage + "... ");
mProgressBar->setProgressPosition (static_cast<size_t>(progress * 1000));
@ -113,6 +108,11 @@ namespace MWGui
{
mLastRenderTime = mTimer.getMilliseconds ();
if (mFirstLoad && mTimer.getMilliseconds () > mLastWallpaperChangeTime + 3000*1)
{
mLastWallpaperChangeTime = mTimer.getMilliseconds ();
changeWallpaper();
}
// Turn off rendering except the GUI
mSceneMgr->clearSpecialCaseRenderQueues();
@ -139,8 +139,11 @@ namespace MWGui
}
else
{
mBackgroundMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(chain->getCompositor ("gbufferFinalizer")->getTextureInstance ("no_mrt_output", 0)->getName());
mRectangle->setVisible(true);
if (!mFirstLoad)
{
mBackgroundMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(chain->getCompositor ("gbufferFinalizer")->getTextureInstance ("no_mrt_output", 0)->getName());
mRectangle->setVisible(true);
}
for (unsigned int i = 0; i<chain->getNumCompositors(); ++i)
{
@ -158,19 +161,37 @@ namespace MWGui
{
Ogre::CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0), chain->getCompositor(i)->getCompositor()->getName(), true);
}
mRectangle->setVisible(false);
}
mRectangle->setVisible(false);
// resume 3d rendering
mSceneMgr->clearSpecialCaseRenderQueues();
mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE);
}
}
void LoadingScreen::loadingDone()
{
loadingOff();
}
void LoadingScreen::loadingOn()
{
setVisible(true);
mLoadingOn = true;
if (mFirstLoad)
{
changeWallpaper();
mWindowManager.pushGuiMode(GM_LoadingWallpaper);
}
else
{
mBackgroundImage->setImageTexture("");
mWindowManager.pushGuiMode(GM_Loading);
}
}
@ -178,5 +199,28 @@ namespace MWGui
{
setVisible(false);
mLoadingOn = false;
mFirstLoad = false;
mWindowManager.removeGuiMode(GM_Loading);
mWindowManager.removeGuiMode(GM_LoadingWallpaper);
}
void LoadingScreen::changeWallpaper ()
{
/// \todo use a directory listing here
std::vector<std::string> splash;
splash.push_back ("Splash_Bonelord.tga");
splash.push_back ("Splash_ClannDaddy.tga");
splash.push_back ("Splash_Clannfear.tga");
splash.push_back ("Splash_Daedroth.tga");
splash.push_back ("Splash_Hunger.tga");
splash.push_back ("Splash_KwamaWarrior.tga");
splash.push_back ("Splash_Netch.tga");
splash.push_back ("Splash_NixHound.tga");
splash.push_back ("Splash_Siltstriker.tga");
splash.push_back ("Splash_Skeleton.tga");
splash.push_back ("Splash_SphereCenturion.tga");
mBackgroundImage->setImageTexture (splash[rand() % splash.size()]);
}
}

@ -15,13 +15,17 @@ namespace MWGui
virtual ~LoadingScreen();
void setLoadingProgress (const std::string& stage, int depth, int current, int total);
void loadingDone();
void onResChange(int w, int h);
private:
bool mFirstLoad;
Ogre::SceneManager* mSceneMgr;
Ogre::RenderWindow* mWindow;
unsigned long mLastWallpaperChangeTime;
unsigned long mLastRenderTime;
Ogre::Timer mTimer;
@ -43,6 +47,8 @@ namespace MWGui
void loadingOn();
void loadingOff();
void changeWallpaper();
};
}

@ -35,6 +35,9 @@ namespace MWGui
// interactive MessageBox
GM_InterMessageBox,
GM_Loading,
GM_LoadingWallpaper,
GM_QuickKeysMenu
};

@ -248,6 +248,8 @@ void WindowManager::updateVisible()
mSpellWindow->setVisible(false);
mQuickKeysMenu->setVisible(false);
mHud->setVisible(true);
// Mouse is visible whenever we're not in game mode
MyGUI::PointerManager::getInstance().setVisible(isGuiMode());
@ -340,6 +342,13 @@ void WindowManager::updateVisible()
case GM_Journal:
mJournal->setVisible(true);
break;
case GM_LoadingWallpaper:
mHud->setVisible(false);
MyGUI::PointerManager::getInstance().setVisible(false);
break;
case GM_Loading:
MyGUI::PointerManager::getInstance().setVisible(false);
break;
default:
// Unsupported mode, switch back to game
break;
@ -909,3 +918,8 @@ void WindowManager::setLoadingProgress (const std::string& stage, int depth, int
{
mLoadingScreen->setLoadingProgress (stage, depth, current, total);
}
void WindowManager::loadingDone ()
{
mLoadingScreen->loadingDone ();
}

@ -197,6 +197,7 @@ namespace MWGui
virtual void executeInConsole (const std::string& path);
virtual void setLoadingProgress (const std::string& stage, int depth, int current, int total);
virtual void loadingDone();
private:
OEngine::GUI::MyGUIManager *mGuiManager;

@ -5,12 +5,20 @@
#include <components/esm/loadalch.hpp>
#include <components/esm/loadspel.hpp>
#include <components/esm/loadingr.hpp>
#include <components/esm/loadmgef.hpp>
#include <components/esm/loadskil.hpp>
#include <components/esm_store/store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/class.hpp"
#include "creaturestats.hpp"
#include "npcstats.hpp"
namespace MWMechanics
{
void ActiveSpells::update() const
@ -41,47 +49,102 @@ namespace MWMechanics
}
if (rebuild)
{
mEffects = MagicEffects();
rebuildEffects();
}
for (TIterator iter (begin()); iter!=end(); ++iter)
{
const ESM::EffectList& effects = getEffectList (iter->first);
void ActiveSpells::rebuildEffects() const
{
MWWorld::TimeStamp now = MWBase::Environment::get().getWorld()->getTimeStamp();
mEffects = MagicEffects();
for (TIterator iter (begin()); iter!=end(); ++iter)
{
std::pair<ESM::EffectList, bool> effects = getEffectList (iter->first);
const MWWorld::TimeStamp& start = iter->second.first;
float magnitude = iter->second.second;
const MWWorld::TimeStamp& start = iter->second.first;
float magnitude = iter->second.second;
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.list.begin());
iter!=effects.list.end(); ++iter)
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.first.list.begin());
iter!=effects.first.list.end(); ++iter)
{
if (iter->duration)
{
if (iter->duration)
int duration = iter->duration;
if (effects.second)
duration *= magnitude;
MWWorld::TimeStamp end = start;
end += static_cast<double> (duration)*
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);
if (end>now)
{
MWWorld::TimeStamp end = start;
end += static_cast<double> (iter->duration)*
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);
if (end>now)
EffectParam param;
if (effects.second)
{
EffectParam param;
param.mMagnitude = static_cast<int> (
(iter->magnMax-iter->magnMin+1)*magnitude + iter->magnMin);
mEffects.add (*iter, param);
const ESM::MagicEffect *magicEffect =
MWBase::Environment::get().getWorld()->getStore().magicEffects.find (
iter->effectID);
if (iter->duration==0)
{
param.mMagnitude =
static_cast<int> (magnitude / (0.1 * magicEffect->data.baseCost));
}
else
{
param.mMagnitude =
static_cast<int> (0.05*magnitude / (0.1 * magicEffect->data.baseCost));
}
}
else
param.mMagnitude = static_cast<int> (
(iter->magnMax-iter->magnMin)*magnitude + iter->magnMin);
mEffects.add (*iter, param);
}
}
}
}
}
}
const ESM::EffectList& ActiveSpells::getEffectList (const std::string& id) const
std::pair<ESM::EffectList, bool> ActiveSpells::getEffectList (const std::string& id) const
{
if (const ESM::Spell *spell =
MWBase::Environment::get().getWorld()->getStore().spells.search (id))
return spell->effects;
return std::make_pair (spell->effects, false);
if (const ESM::Potion *potion =
MWBase::Environment::get().getWorld()->getStore().potions.search (id))
return potion->effects;
return std::make_pair (potion->effects, false);
if (const ESM::Ingredient *ingredient =
MWBase::Environment::get().getWorld()->getStore().ingreds.search (id))
{
const ESM::MagicEffect *magicEffect =
MWBase::Environment::get().getWorld()->getStore().magicEffects.find (
ingredient->data.effectID[0]);
ESM::ENAMstruct effect;
effect.effectID = ingredient->data.effectID[0];
effect.skill = ingredient->data.skills[0];
effect.attribute = ingredient->data.attributes[0];
effect.range = 0;
effect.area = 0;
effect.duration = magicEffect->data.flags & ESM::MagicEffect::NoDuration ? 0 : 1;
effect.magnMin = 1;
effect.magnMax = 1;
std::pair<ESM::EffectList, bool> result;
result.first.list.push_back (effect);
result.second = true;
return result;
}
throw std::runtime_error ("ID " + id + " can not produce lasting effects");
}
@ -90,14 +153,14 @@ namespace MWMechanics
: mSpellsChanged (false), mLastUpdate (MWBase::Environment::get().getWorld()->getTimeStamp())
{}
bool ActiveSpells::addSpell (const std::string& id)
bool ActiveSpells::addSpell (const std::string& id, const MWWorld::Ptr& actor)
{
const ESM::EffectList& effects = getEffectList (id);
std::pair<ESM::EffectList, bool> effects = getEffectList (id);
bool found = false;
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.list.begin());
iter!=effects.list.end(); ++iter)
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.first.list.begin());
iter!=effects.first.list.end(); ++iter)
{
if (iter->duration)
{
@ -113,6 +176,22 @@ namespace MWMechanics
float random = static_cast<float> (std::rand()) / RAND_MAX;
if (effects.second)
{
// ingredient -> special treatment required.
const CreatureStats& creatureStats = MWWorld::Class::get (actor).getCreatureStats (actor);
const NpcStats& npcStats = MWWorld::Class::get (actor).getNpcStats (actor);
float x =
(npcStats.getSkill (ESM::Skill::Alchemy).getModified() +
0.2 * creatureStats.getAttribute (1).getModified()
+ 0.1 * creatureStats.getAttribute (7).getModified())
* creatureStats.getFatigueTerm();
random *= 100;
random = random / std::min (x, 100.0f);
random *= 0.25 * x;
}
if (iter==mSpells.end())
mSpells.insert (std::make_pair (id,
std::make_pair (MWBase::Environment::get().getWorld()->getTimeStamp(), random)));
@ -155,17 +234,20 @@ namespace MWMechanics
double ActiveSpells::timeToExpire (const TIterator& iterator) const
{
const ESM::EffectList& effects = getEffectList (iterator->first);
std::pair<ESM::EffectList, bool> effects = getEffectList (iterator->first);
int duration = 0;
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.list.begin());
iter!=effects.list.end(); ++iter)
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.first.list.begin());
iter!=effects.first.list.end(); ++iter)
{
if (iter->duration>duration)
duration = iter->duration;
}
if (effects.second)
duration *= iterator->second.second;
double scaledDuration = duration *
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);

@ -15,6 +15,11 @@ namespace ESM
struct EffectList;
}
namespace MWWorld
{
class Ptr;
}
namespace MWMechanics
{
/// \brief Lasting spell effects
@ -36,14 +41,16 @@ namespace MWMechanics
mutable MWWorld::TimeStamp mLastUpdate;
void update() const;
void rebuildEffects() const;
const ESM::EffectList& getEffectList (const std::string& id) const;
std::pair<ESM::EffectList, bool> getEffectList (const std::string& id) const;
public:
ActiveSpells();
bool addSpell (const std::string& id);
bool addSpell (const std::string& id, const MWWorld::Ptr& actor);
///< Overwrites an existing spell with the same ID. If the spell does not have any
/// non-instant effects, it is ignored.
///

@ -1,58 +1,206 @@
#include "creaturestats.hpp"
#include <algorithm>
#include <components/esm_store/store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
namespace MWMechanics
{
CreatureStats::CreatureStats()
{}
{
const AiSequence& CreatureStats::getAiSequence() const
{
return mAiSequence;
}
// Can't use all benefits of members initialization because of
// lack of copy constructors
CreatureStats::CreatureStats(const CreatureStats &orig)
: mLevel(orig.mLevel), mHello(orig.mHello), mFight(orig.mFight),
mFlee(orig.mFlee), mAlarm(orig.mAlarm)
{
for (int i = 0; i < 8; ++i) {
mAttributes[i] = orig.mAttributes[i];
AiSequence& CreatureStats::getAiSequence()
{
return mAiSequence;
}
float CreatureStats::getFatigueTerm() const
{
int max = getFatigue().getModified();
int current = getFatigue().getCurrent();
float normalised = max==0 ? 1 : std::max (0.0f, static_cast<float> (current)/max);
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
return store.gameSettings.find ("fFatigueBase")->getFloat()
- store.gameSettings.find ("fFatigueMult")->getFloat() * (1-normalised);
}
const Stat<int> &CreatureStats::getAttribute(int index) const
{
if (index < 0 || index > 7) {
throw std::runtime_error("attribute index is out of range");
}
for (int i = 0; i < 3; ++i) {
mDynamic[i] = orig.mDynamic[i];
return mAttributes[index];
}
const DynamicStat<int> &CreatureStats::getHealth() const
{
return mDynamic[0];
}
const DynamicStat<int> &CreatureStats::getMagicka() const
{
return mDynamic[1];
}
const DynamicStat<int> &CreatureStats::getFatigue() const
{
return mDynamic[2];
}
const Spells &CreatureStats::getSpells() const
{
return mSpells;
}
const ActiveSpells &CreatureStats::getActiveSpells() const
{
return mActiveSpells;
}
const MagicEffects &CreatureStats::getMagicEffects() const
{
return mMagicEffects;
}
int CreatureStats::getLevel() const
{
return mLevel;
}
int CreatureStats::getHello() const
{
return mHello;
}
int CreatureStats::getFight() const
{
return mFight;
}
int CreatureStats::getFlee() const
{
return mFlee;
}
int CreatureStats::getAlarm() const
{
return mAlarm;
}
Stat<int> &CreatureStats::getAttribute(int index)
{
if (index < 0 || index > 7) {
throw std::runtime_error("attribute index is out of range");
}
mSpells = orig.mSpells;
mActiveSpells = orig.mActiveSpells;
mMagicEffects = orig.mMagicEffects;
return mAttributes[index];
}
CreatureStats::~CreatureStats()
{}
DynamicStat<int> &CreatureStats::getHealth()
{
return mDynamic[0];
}
DynamicStat<int> &CreatureStats::getMagicka()
{
return mDynamic[1];
}
DynamicStat<int> &CreatureStats::getFatigue()
{
return mDynamic[2];
}
const CreatureStats &
CreatureStats::operator=(const CreatureStats &orig)
DynamicStat<int> &CreatureStats::getDynamic(int index)
{
for (int i = 0; i < 8; ++i) {
mAttributes[i] = orig.mAttributes[i];
if (index < 0 || index > 2) {
throw std::runtime_error("dynamic stat index is out of range");
}
for (int i = 0; i < 3; ++i) {
mDynamic[i] = orig.mDynamic[i];
return mDynamic[index];
}
Spells &CreatureStats::getSpells()
{
return mSpells;
}
void CreatureStats::setSpells(const Spells &spells)
{
mSpells = spells;
}
ActiveSpells &CreatureStats::getActiveSpells()
{
return mActiveSpells;
}
MagicEffects &CreatureStats::getMagicEffects()
{
return mMagicEffects;
}
void CreatureStats::setAttribute(int index, const Stat<int> &value)
{
if (index < 0 || index > 7) {
throw std::runtime_error("attribute index is out of range");
}
mLevel = orig.mLevel;
mSpells = orig.mSpells;
mActiveSpells = orig.mActiveSpells;
mMagicEffects = orig.mMagicEffects;
mHello = orig.mHello;
mFight = orig.mFight;
mFlee = orig.mFlee;
mAlarm = orig.mAlarm;
mAttributes[index] = value;
}
return *this;
void CreatureStats::setHealth(const DynamicStat<int> &value)
{
mDynamic[0] = value;
}
const AiSequence& CreatureStats::getAiSequence() const
void CreatureStats::setMagicka(const DynamicStat<int> &value)
{
return mAiSequence;
mDynamic[1] = value;
}
AiSequence& CreatureStats::getAiSequence()
void CreatureStats::setFatigue(const DynamicStat<int> &value)
{
return mAiSequence;
mDynamic[2] = value;
}
void CreatureStats::setLevel(int level)
{
mLevel = level;
}
void CreatureStats::setActiveSpells(const ActiveSpells &active)
{
mActiveSpells = active;
}
void CreatureStats::setMagicEffects(const MagicEffects &effects)
{
mMagicEffects = effects;
}
void CreatureStats::setHello(int value)
{
mHello = value;
}
void CreatureStats::setFight(int value)
{
mFight = value;
}
void CreatureStats::setFlee(int value)
{
mFlee = value;
}
void CreatureStats::setAlarm(int value)
{
mAlarm = value;
}
}

@ -31,11 +31,6 @@ namespace MWMechanics
AiSequence mAiSequence;
public:
CreatureStats();
CreatureStats(const CreatureStats &);
virtual ~CreatureStats();
const CreatureStats & operator=(const CreatureStats &);
const Stat<int> & getAttribute(int index) const;
@ -106,185 +101,10 @@ namespace MWMechanics
const AiSequence& getAiSequence() const;
AiSequence& getAiSequence();
};
// Inline const getters
inline const Stat<int> &
CreatureStats::getAttribute(int index) const {
if (index < 0 || index > 7) {
throw std::runtime_error("attribute index is out of range");
}
return mAttributes[index];
}
inline const DynamicStat<int> &
CreatureStats::getHealth() const {
return mDynamic[0];
}
inline const DynamicStat<int> &
CreatureStats::getMagicka() const {
return mDynamic[1];
}
inline const DynamicStat<int> &
CreatureStats::getFatigue() const {
return mDynamic[2];
}
inline const Spells &
CreatureStats::getSpells() const {
return mSpells;
}
inline const ActiveSpells &
CreatureStats::getActiveSpells() const {
return mActiveSpells;
}
inline const MagicEffects &
CreatureStats::getMagicEffects() const {
return mMagicEffects;
}
inline int
CreatureStats::getLevel() const {
return mLevel;
}
inline int
CreatureStats::getHello() const {
return mHello;
}
inline int
CreatureStats::getFight() const {
return mFight;
}
inline int
CreatureStats::getFlee() const {
return mFlee;
}
inline int
CreatureStats::getAlarm() const {
return mAlarm;
}
// Inline non-const getters
inline Stat<int> &
CreatureStats::getAttribute(int index) {
if (index < 0 || index > 7) {
throw std::runtime_error("attribute index is out of range");
}
return mAttributes[index];
}
inline DynamicStat<int> &
CreatureStats::getHealth() {
return mDynamic[0];
}
inline DynamicStat<int> &
CreatureStats::getMagicka() {
return mDynamic[1];
}
inline DynamicStat<int> &
CreatureStats::getFatigue() {
return mDynamic[2];
}
inline DynamicStat<int> &
CreatureStats::getDynamic(int index) {
if (index < 0 || index > 2) {
throw std::runtime_error("dynamic stat index is out of range");
}
return mDynamic[index];
}
inline Spells &
CreatureStats::getSpells() {
return mSpells;
}
inline void
CreatureStats::setSpells(const Spells &spells) {
mSpells = spells;
}
inline ActiveSpells &
CreatureStats::getActiveSpells() {
return mActiveSpells;
}
inline MagicEffects &
CreatureStats::getMagicEffects() {
return mMagicEffects;
}
// Inline setters
inline void
CreatureStats::setAttribute(int index, const Stat<int> &value) {
if (index < 0 || index > 7) {
throw std::runtime_error("attribute index is out of range");
}
mAttributes[index] = value;
}
inline void
CreatureStats::setHealth(const DynamicStat<int> &value) {
mDynamic[0] = value;
}
inline void
CreatureStats::setMagicka(const DynamicStat<int> &value) {
mDynamic[1] = value;
}
inline void
CreatureStats::setFatigue(const DynamicStat<int> &value) {
mDynamic[2] = value;
}
inline void
CreatureStats::setLevel(int level) {
mLevel = level;
}
inline void
CreatureStats::setActiveSpells(const ActiveSpells &active) {
mActiveSpells = active;
}
inline void
CreatureStats::setMagicEffects(const MagicEffects &effects) {
mMagicEffects = effects;
}
inline void
CreatureStats::setHello(int value) {
mHello = value;
}
inline void
CreatureStats::setFight(int value) {
mFight = value;
}
inline void
CreatureStats::setFlee(int value) {
mFlee = value;
}
inline void
CreatureStats::setAlarm(int value) {
mAlarm = value;
}
float getFatigueTerm() const;
///< Return effective fatigue
};
}
#endif

@ -11,9 +11,6 @@
#include <OgreBillboardSet.h>
#include <OgreEntity.h>
#include <OgreSubEntity.h>
#include <OgreOverlay.h>
#include <OgreOverlayManager.h>
#include <OgreOverlayContainer.h>
#include <boost/lexical_cast.hpp>

@ -24,7 +24,6 @@ namespace Ogre
class Entity;
class BillboardSet;
class TextureUnitState;
class Overlay;
}
namespace MWRender

@ -0,0 +1,49 @@
#include "actioneat.hpp"
#include <cstdlib>
#include <components/esm/loadskil.hpp>
#include <components/esm_store/store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "class.hpp"
namespace MWWorld
{
void ActionEat::executeImp (const Ptr& actor)
{
// remove used item
getTarget().getRefData().setCount (getTarget().getRefData().getCount()-1);
// check for success
const MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (actor).getCreatureStats (actor);
MWMechanics::NpcStats& npcStats = MWWorld::Class::get (actor).getNpcStats (actor);
float x =
(npcStats.getSkill (ESM::Skill::Alchemy).getModified() +
0.2 * creatureStats.getAttribute (1).getModified()
+ 0.1 * creatureStats.getAttribute (7).getModified())
* creatureStats.getFatigueTerm();
if (x>=100*static_cast<float> (std::rand()) / RAND_MAX)
{
// apply to actor
std::string id = Class::get (getTarget()).getId (getTarget());
Class::get (actor).apply (actor, id, actor);
// we ignore the result here. Skill increases no matter if the ingredient did something or not.
// increase skill
Class::get (actor).skillUsageSucceeded (actor, ESM::Skill::Alchemy, 1);
}
}
ActionEat::ActionEat (const MWWorld::Ptr& object) : Action (false, object) {}
}

@ -0,0 +1,19 @@
#ifndef GAME_MWWORLD_ACTIONEAT_H
#define GAME_MWWORLD_ACTIONEAT_H
#include "action.hpp"
#include "ptr.hpp"
namespace MWWorld
{
class ActionEat : public Action
{
virtual void executeImp (const Ptr& actor);
public:
ActionEat (const MWWorld::Ptr& object);
};
}
#endif

@ -290,7 +290,6 @@ namespace MWWorld
mCurrentCell = *iter;
// adjust player
playerCellChange (mCurrentCell, position, adjustPlayerPos);
@ -300,6 +299,8 @@ namespace MWWorld
mRendering.switchToExterior();
mCellChanged = true;
MWBase::Environment::get().getWindowManager ()->loadingDone ();
}
//We need the ogre renderer and a scene node.
@ -369,6 +370,8 @@ namespace MWWorld
MWBase::Environment::get().getWorld()->adjustSky();
mCellChanged = true;
MWBase::Environment::get().getWindowManager ()->loadingDone ();
}
void Scene::changeToExteriorCell (const ESM::Position& position)

@ -1,8 +1,15 @@
#include "loadgmst.hpp"
#include <stdexcept>
#include "defs.hpp"
namespace ESM
{
/// \todo Review GMST "fixing". Probably remove completely or at least make it optional. Its definitely not
/// working properly in its current state and I doubt it can be fixed without breaking other stuff.
// Some handy macros
#define cI(s,x) { if(id == (s)) return (i == (x)); }
#define cF(s,x) { if(id == (s)) return (f == (x)); }
@ -169,4 +176,32 @@ void GameSetting::load(ESMReader &esm)
dirty = true;
}
int GameSetting::getInt() const
{
switch (type)
{
case VT_Float: return static_cast<int> (f);
case VT_Int: return i;
default: throw std::runtime_error ("GMST " + id + " is not of a numeric type");
}
}
int GameSetting::getFloat() const
{
switch (type)
{
case VT_Float: return f;
case VT_Int: return i;
default: throw std::runtime_error ("GMST " + id + " is not of a numeric type");
}
}
std::string GameSetting::getString() const
{
if (type==VT_String)
return str;
throw std::runtime_error ("GMST " + id + " is not a string");
}
}

@ -83,6 +83,15 @@ struct GameSetting
bool isDirtyBloodmoon();
void load(ESMReader &esm);
int getInt() const;
///< Throws an exception if GMST is not of type int or float.
int getFloat() const;
///< Throws an exception if GMST is not of type int or float.
std::string getString() const;
///< Throwns an exception if GMST is not of type string.
};
}
#endif

@ -1,5 +1,30 @@
#include "loadmgef.hpp"
namespace
{
const int NumberOfHardcodedFlags = 143;
const int HardcodedFlags[NumberOfHardcodedFlags] = {
0x11c8, 0x11c0, 0x11c8, 0x11e0, 0x11e0, 0x11e0, 0x11e0, 0x11d0,
0x11c0, 0x11c0, 0x11e0, 0x11c0, 0x11184, 0x11184, 0x1f0, 0x1f0,
0x1f0, 0x11d2, 0x11f0, 0x11d0, 0x11d0, 0x11d1, 0x1d2, 0x1f0,
0x1d0, 0x1d0, 0x1d1, 0x1f0, 0x11d0, 0x11d0, 0x11d0, 0x11d0,
0x11d0, 0x11d0, 0x11d0, 0x11d0, 0x11d0, 0x1d0, 0x1d0, 0x11c8,
0x31c0, 0x11c0, 0x11c0, 0x11c0, 0x1180, 0x11d8, 0x11d8, 0x11d0,
0x11d0, 0x11180, 0x11180, 0x11180, 0x11180, 0x11180, 0x11180, 0x11180,
0x11180, 0x11c4, 0x111b8, 0x1040, 0x104c, 0x104c, 0x104c, 0x104c,
0x1040, 0x1040, 0x1040, 0x11c0, 0x11c0, 0x1cc, 0x1cc, 0x1cc,
0x1cc, 0x1cc, 0x1c2, 0x1c0, 0x1c0, 0x1c0, 0x1c1, 0x11c2,
0x11c0, 0x11c0, 0x11c0, 0x11c1, 0x11c0, 0x21192, 0x20190, 0x20190,
0x20190, 0x21191, 0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x11c0,
0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x1c0, 0x11190, 0x9048, 0x9048,
0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048,
0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x11c0, 0x1180, 0x1180,
0x5048, 0x5048, 0x5048, 0x5048, 0x5048, 0x5048, 0x1188, 0x5048,
0x5048, 0x5048, 0x5048, 0x5048, 0x1048, 0x104c, 0x1048, 0x40,
0x11c8, 0x1048, 0x1048, 0x1048, 0x1048, 0x1048, 0x1048
};
}
namespace ESM
{
@ -8,6 +33,10 @@ void MagicEffect::load(ESMReader &esm)
esm.getHNT(index, "INDX");
esm.getHNT(data, "MEDT", 36);
if (index>=0 && index<NumberOfHardcodedFlags)
data.flags |= HardcodedFlags[index];
icon = esm.getHNOString("ITEX");
particle = esm.getHNOString("PTEX");

@ -10,6 +10,7 @@ struct MagicEffect
{
enum Flags
{
NoDuration = 0x4,
SpellMaking = 0x0200,
Enchanting = 0x0400,
Negative = 0x0800 // A harmful effect. Will determine whether

@ -164,6 +164,13 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
// the flags we currently use, at least.
flags |= node->flags;
// Marker objects: no collision
/// \todo don't do this in the editor
if (node->name.find("marker") != std::string::npos)
{
flags |= 0x800;
}
// Check for extra data
Nif::Extra *e = node;
while (!e->extra.empty())
@ -178,12 +185,10 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
// affecting the entire subtree of this node
Nif::NiStringExtraData *sd = (Nif::NiStringExtraData*)e;
if (sd->string == "NCO" && !raycastingOnly)
if (sd->string == "NCO")
{
// No collision. Use an internal flag setting to mark this.
// We ignor this node!
flags |= 0x800;
return;
}
else if (sd->string == "MRK" && !raycastingOnly)
// Marker objects. These are only visible in the
@ -229,7 +234,7 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
}
else if (node->recType == Nif::RC_NiTriShape && (isCollisionNode || !hasCollisionNode))
{
cShape->collide = true;
cShape->collide = !(flags&0x800);
handleNiTriShape(dynamic_cast<Nif::NiTriShape*>(node), flags,node->trafo.rotation,node->trafo.pos,node->trafo.scale,raycastingOnly);
}
else if(node->recType == Nif::RC_RootCollisionNode)

@ -940,6 +940,11 @@ public:
{
flags |= node->flags;
// Marker objects: just skip the entire node
/// \todo don't do this in the editor
if (node->name.find("marker") != std::string::npos)
return;
Nif::ExtraPtr e = node->extra;
while(!e.empty())
{

Loading…
Cancel
Save