mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 20:59:55 +00:00
Merge branch 'master' into characterpreview
This commit is contained in:
commit
d90af9c524
26 changed files with 591 additions and 284 deletions
|
@ -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)
|
||||
rebuildEffects();
|
||||
}
|
||||
|
||||
void ActiveSpells::rebuildEffects() const
|
||||
{
|
||||
MWWorld::TimeStamp now = MWBase::Environment::get().getWorld()->getTimeStamp();
|
||||
|
||||
mEffects = MagicEffects();
|
||||
|
||||
for (TIterator iter (begin()); iter!=end(); ++iter)
|
||||
{
|
||||
mEffects = MagicEffects();
|
||||
std::pair<ESM::EffectList, bool> effects = getEffectList (iter->first);
|
||||
|
||||
for (TIterator iter (begin()); iter!=end(); ++iter)
|
||||
const MWWorld::TimeStamp& start = iter->second.first;
|
||||
float magnitude = iter->second.second;
|
||||
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.first.list.begin());
|
||||
iter!=effects.first.list.end(); ++iter)
|
||||
{
|
||||
const ESM::EffectList& effects = getEffectList (iter->first);
|
||||
|
||||
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)
|
||||
if (iter->duration)
|
||||
{
|
||||
if (iter->duration)
|
||||
{
|
||||
MWWorld::TimeStamp end = start;
|
||||
end += static_cast<double> (iter->duration)*
|
||||
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);
|
||||
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)
|
||||
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,51 +1,14 @@
|
|||
#include "creaturestats.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <components/esm_store/store.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
CreatureStats::CreatureStats()
|
||||
{}
|
||||
|
||||
// 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];
|
||||
}
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
mDynamic[i] = orig.mDynamic[i];
|
||||
}
|
||||
mSpells = orig.mSpells;
|
||||
mActiveSpells = orig.mActiveSpells;
|
||||
mMagicEffects = orig.mMagicEffects;
|
||||
}
|
||||
|
||||
CreatureStats::~CreatureStats()
|
||||
{}
|
||||
|
||||
const CreatureStats &
|
||||
CreatureStats::operator=(const CreatureStats &orig)
|
||||
{
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
mAttributes[i] = orig.mAttributes[i];
|
||||
}
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
mDynamic[i] = orig.mDynamic[i];
|
||||
}
|
||||
mLevel = orig.mLevel;
|
||||
mSpells = orig.mSpells;
|
||||
mActiveSpells = orig.mActiveSpells;
|
||||
mMagicEffects = orig.mMagicEffects;
|
||||
mHello = orig.mHello;
|
||||
mFight = orig.mFight;
|
||||
mFlee = orig.mFlee;
|
||||
mAlarm = orig.mAlarm;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
{
|
||||
const AiSequence& CreatureStats::getAiSequence() const
|
||||
{
|
||||
return mAiSequence;
|
||||
|
@ -55,4 +18,189 @@ namespace MWMechanics
|
|||
{
|
||||
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");
|
||||
}
|
||||
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");
|
||||
}
|
||||
return mAttributes[index];
|
||||
}
|
||||
|
||||
DynamicStat<int> &CreatureStats::getHealth()
|
||||
{
|
||||
return mDynamic[0];
|
||||
}
|
||||
|
||||
DynamicStat<int> &CreatureStats::getMagicka()
|
||||
{
|
||||
return mDynamic[1];
|
||||
}
|
||||
|
||||
DynamicStat<int> &CreatureStats::getFatigue()
|
||||
{
|
||||
return mDynamic[2];
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
mAttributes[index] = value;
|
||||
}
|
||||
|
||||
void CreatureStats::setHealth(const DynamicStat<int> &value)
|
||||
{
|
||||
mDynamic[0] = value;
|
||||
}
|
||||
|
||||
void CreatureStats::setMagicka(const DynamicStat<int> &value)
|
||||
{
|
||||
mDynamic[1] = value;
|
||||
}
|
||||
|
||||
void CreatureStats::setFatigue(const DynamicStat<int> &value)
|
||||
{
|
||||
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
|
||||
|
|
49
apps/openmw/mwworld/actioneat.cpp
Normal file
49
apps/openmw/mwworld/actioneat.cpp
Normal file
|
@ -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) {}
|
||||
}
|
19
apps/openmw/mwworld/actioneat.hpp
Normal file
19
apps/openmw/mwworld/actioneat.hpp
Normal file
|
@ -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…
Reference in a new issue