mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-06 03:45:35 +00:00
Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
commit
6c4920c58e
82 changed files with 683 additions and 404 deletions
|
@ -1,7 +1,7 @@
|
||||||
OpenMW
|
OpenMW
|
||||||
======
|
======
|
||||||
|
|
||||||
[![Build Status](https://img.shields.io/travis/OpenMW/openmw.svg)](https://travis-ci.org/OpenMW/openmw) [![Coverity Scan Build Status](https://scan.coverity.com/projects/3740/badge.svg)](https://scan.coverity.com/projects/3740)
|
[![Build Status](https://img.shields.io/travis/OpenMW/openmw.svg?style=plastic)](https://travis-ci.org/OpenMW/openmw) [![Coverity Scan Build Status](https://scan.coverity.com/projects/3740/badge.svg)](https://scan.coverity.com/projects/3740)
|
||||||
|
|
||||||
OpenMW is an attempt at recreating the engine for the popular role-playing game
|
OpenMW is an attempt at recreating the engine for the popular role-playing game
|
||||||
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
|
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
|
||||||
|
@ -68,7 +68,10 @@ Command line options
|
||||||
of the blacklist is enabled)
|
of the blacklist is enabled)
|
||||||
--script-blacklist-use [=arg(=1)] (=1)
|
--script-blacklist-use [=arg(=1)] (=1)
|
||||||
enable script blacklisting
|
enable script blacklisting
|
||||||
--load-savegame arg load a save game file on game startup
|
--load-savegame arg load a save game file on game startup
|
||||||
|
(specify an absolute filename or a
|
||||||
|
filename relative to the current
|
||||||
|
working directory)
|
||||||
--skip-menu [=arg(=1)] (=0) skip main menu on game startup
|
--skip-menu [=arg(=1)] (=0) skip main menu on game startup
|
||||||
--new-game [=arg(=1)] (=0) run new game sequence (ignored if
|
--new-game [=arg(=1)] (=0) run new game sequence (ignored if
|
||||||
skip-menu=0)
|
skip-menu=0)
|
||||||
|
|
|
@ -535,10 +535,10 @@ void Record<ESM::Class>::print()
|
||||||
std::cout << " Specialization: " << specializationLabel(mData.mData.mSpecialization)
|
std::cout << " Specialization: " << specializationLabel(mData.mData.mSpecialization)
|
||||||
<< " (" << mData.mData.mSpecialization << ")" << std::endl;
|
<< " (" << mData.mData.mSpecialization << ")" << std::endl;
|
||||||
for (int i = 0; i != 5; i++)
|
for (int i = 0; i != 5; i++)
|
||||||
std::cout << " Major Skill: " << skillLabel(mData.mData.mSkills[i][0])
|
std::cout << " Minor Skill: " << skillLabel(mData.mData.mSkills[i][0])
|
||||||
<< " (" << mData.mData.mSkills[i][0] << ")" << std::endl;
|
<< " (" << mData.mData.mSkills[i][0] << ")" << std::endl;
|
||||||
for (int i = 0; i != 5; i++)
|
for (int i = 0; i != 5; i++)
|
||||||
std::cout << " Minor Skill: " << skillLabel(mData.mData.mSkills[i][1])
|
std::cout << " Major Skill: " << skillLabel(mData.mData.mSkills[i][1])
|
||||||
<< " (" << mData.mData.mSkills[i][1] << ")" << std::endl;
|
<< " (" << mData.mData.mSkills[i][1] << ")" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,7 +837,7 @@ void Record<ESM::CreatureLevList>::print()
|
||||||
std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl;
|
std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl;
|
||||||
std::cout << " Flags: " << creatureListFlags(mData.mFlags) << std::endl;
|
std::cout << " Flags: " << creatureListFlags(mData.mFlags) << std::endl;
|
||||||
std::cout << " Number of items: " << mData.mList.size() << std::endl;
|
std::cout << " Number of items: " << mData.mList.size() << std::endl;
|
||||||
std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
|
std::vector<ESM::LevelledListBase::LevelItem>::iterator iit;
|
||||||
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
|
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
|
||||||
std::cout << " Creature: Level: " << iit->mLevel
|
std::cout << " Creature: Level: " << iit->mLevel
|
||||||
<< " Creature: " << iit->mId << std::endl;
|
<< " Creature: " << iit->mId << std::endl;
|
||||||
|
@ -849,7 +849,7 @@ void Record<ESM::ItemLevList>::print()
|
||||||
std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl;
|
std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl;
|
||||||
std::cout << " Flags: " << itemListFlags(mData.mFlags) << std::endl;
|
std::cout << " Flags: " << itemListFlags(mData.mFlags) << std::endl;
|
||||||
std::cout << " Number of items: " << mData.mList.size() << std::endl;
|
std::cout << " Number of items: " << mData.mList.size() << std::endl;
|
||||||
std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
|
std::vector<ESM::LevelledListBase::LevelItem>::iterator iit;
|
||||||
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
|
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
|
||||||
std::cout << " Inventory: Level: " << iit->mLevel
|
std::cout << " Inventory: Level: " << iit->mLevel
|
||||||
<< " Item: " << iit->mId << std::endl;
|
<< " Item: " << iit->mId << std::endl;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <components/esm/weatherstate.hpp>
|
#include <components/esm/weatherstate.hpp>
|
||||||
#include <components/esm/globalscript.hpp>
|
#include <components/esm/globalscript.hpp>
|
||||||
#include <components/esm/queststate.hpp>
|
#include <components/esm/queststate.hpp>
|
||||||
|
#include <components/esm/stolenitems.hpp>
|
||||||
|
|
||||||
#include "importcrec.hpp"
|
#include "importcrec.hpp"
|
||||||
#include "importcntc.hpp"
|
#include "importcntc.hpp"
|
||||||
|
@ -387,24 +388,50 @@ public:
|
||||||
virtual void read(ESM::ESMReader &esm)
|
virtual void read(ESM::ESMReader &esm)
|
||||||
{
|
{
|
||||||
std::string itemid = esm.getHNString("NAME");
|
std::string itemid = esm.getHNString("NAME");
|
||||||
|
Misc::StringUtils::toLower(itemid);
|
||||||
|
|
||||||
while (esm.isNextSub("FNAM") || esm.isNextSub("ONAM"))
|
while (esm.isNextSub("FNAM") || esm.isNextSub("ONAM"))
|
||||||
{
|
{
|
||||||
if (esm.retSubName().toString() == "FNAM")
|
if (esm.retSubName().toString() == "FNAM")
|
||||||
{
|
{
|
||||||
std::string factionid = esm.getHString();
|
std::string factionid = esm.getHString();
|
||||||
mFactionStolenItems.insert(std::make_pair(itemid, factionid));
|
mStolenItems[itemid].insert(std::make_pair(Misc::StringUtils::lowerCase(factionid), true));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::string ownerid = esm.getHString();
|
std::string ownerid = esm.getHString();
|
||||||
mStolenItems.insert(std::make_pair(itemid, ownerid));
|
mStolenItems[itemid].insert(std::make_pair(Misc::StringUtils::lowerCase(ownerid), false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
virtual void write(ESM::ESMWriter &esm)
|
||||||
|
{
|
||||||
|
ESM::StolenItems items;
|
||||||
|
for (std::map<std::string, std::set<Owner> >::const_iterator it = mStolenItems.begin(); it != mStolenItems.end(); ++it)
|
||||||
|
{
|
||||||
|
std::map<std::pair<std::string, bool>, int> owners;
|
||||||
|
for (std::set<Owner>::const_iterator ownerIt = it->second.begin(); ownerIt != it->second.end(); ++ownerIt)
|
||||||
|
{
|
||||||
|
owners.insert(std::make_pair(std::make_pair(ownerIt->first, ownerIt->second)
|
||||||
|
// Since OpenMW doesn't suffer from the owner contamination bug,
|
||||||
|
// it needs a count argument. But for legacy savegames, we don't know
|
||||||
|
// this count, so must assume all items of that ID are stolen,
|
||||||
|
// like vanilla MW did.
|
||||||
|
,std::numeric_limits<int>::max()));
|
||||||
|
}
|
||||||
|
|
||||||
|
items.mStolenItems.insert(std::make_pair(it->first, owners));
|
||||||
|
}
|
||||||
|
|
||||||
|
esm.startRecord(ESM::REC_STLN);
|
||||||
|
items.write(esm);
|
||||||
|
esm.endRecord(ESM::REC_STLN);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::multimap<std::string, std::string> mStolenItems;
|
typedef std::pair<std::string, bool> Owner; // <owner id, bool isFaction>
|
||||||
std::multimap<std::string, std::string> mFactionStolenItems;
|
|
||||||
|
std::map<std::string, std::set<Owner> > mStolenItems;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Seen responses for a dialogue topic?
|
/// Seen responses for a dialogue topic?
|
||||||
|
|
|
@ -17,6 +17,8 @@ namespace ESSImport
|
||||||
}
|
}
|
||||||
for (int i=0; i<8; ++i)
|
for (int i=0; i<8; ++i)
|
||||||
out.mObject.mNpcStats.mSkillIncrease[i] = pcdt.mPNAM.mSkillIncreases[i];
|
out.mObject.mNpcStats.mSkillIncrease[i] = pcdt.mPNAM.mSkillIncreases[i];
|
||||||
|
for (int i=0; i<27; ++i)
|
||||||
|
out.mObject.mNpcStats.mSkills[i].mRegular.mProgress = pcdt.mPNAM.mSkillProgress[i];
|
||||||
out.mObject.mNpcStats.mLevelProgress = pcdt.mPNAM.mLevelProgress;
|
out.mObject.mNpcStats.mLevelProgress = pcdt.mPNAM.mLevelProgress;
|
||||||
|
|
||||||
if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Weapon)
|
if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Weapon)
|
||||||
|
@ -24,9 +26,6 @@ namespace ESSImport
|
||||||
if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Spell)
|
if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Spell)
|
||||||
out.mObject.mCreatureStats.mDrawState = 2;
|
out.mObject.mCreatureStats.mDrawState = 2;
|
||||||
|
|
||||||
// TODO: convert PNAM.mSkillProgress, needs to be converted to uniform scale
|
|
||||||
// (or change openmw to accept non-uniform skill progress)
|
|
||||||
|
|
||||||
firstPersonCam = (pcdt.mPNAM.mCameraState == PCDT::CameraState_FirstPerson);
|
firstPersonCam = (pcdt.mPNAM.mCameraState == PCDT::CameraState_FirstPerson);
|
||||||
|
|
||||||
for (std::vector<std::string>::const_iterator it = pcdt.mKnownDialogueTopics.begin();
|
for (std::vector<std::string>::const_iterator it = pcdt.mKnownDialogueTopics.begin();
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace ESSImport
|
||||||
bool mHasACSC;
|
bool mHasACSC;
|
||||||
ACSC mACSC;
|
ACSC mACSC;
|
||||||
|
|
||||||
int mSkills[27][2];
|
int mSkills[27][2]; // skills, base and modified
|
||||||
|
|
||||||
// creature combat stats, base and modified
|
// creature combat stats, base and modified
|
||||||
// I think these can be ignored in the conversion, because it is not possible
|
// I think these can be ignored in the conversion, because it is not possible
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace ESSImport
|
||||||
ActorData::load(esm);
|
ActorData::load(esm);
|
||||||
if (esm.isNextSub("LVCR"))
|
if (esm.isNextSub("LVCR"))
|
||||||
{
|
{
|
||||||
// occurs on leveled creature spawner references
|
// occurs on levelled creature spawner references
|
||||||
// probably some identifier for the creature that has been spawned?
|
// probably some identifier for the creature that has been spawned?
|
||||||
unsigned char lvcr;
|
unsigned char lvcr;
|
||||||
esm.getHT(lvcr);
|
esm.getHT(lvcr);
|
||||||
|
@ -32,7 +32,7 @@ namespace ESSImport
|
||||||
mEnabled = true;
|
mEnabled = true;
|
||||||
esm.getHNOT(mEnabled, "ZNAM");
|
esm.getHNOT(mEnabled, "ZNAM");
|
||||||
|
|
||||||
// DATA should occur for all references, except leveled creature spawners
|
// DATA should occur for all references, except levelled creature spawners
|
||||||
// I've seen DATA *twice* on a creature record, and with the exact same content too! weird
|
// I've seen DATA *twice* on a creature record, and with the exact same content too! weird
|
||||||
// alarmvoi0000.ess
|
// alarmvoi0000.ess
|
||||||
esm.getHNOT(mPos, "DATA", 24);
|
esm.getHNOT(mPos, "DATA", 24);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#define MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
|
#define MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
|
||||||
#endif // MAC_OS_X_VERSION_MIN_REQUIRED
|
#endif // MAC_OS_X_VERSION_MIN_REQUIRED
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL_video.h>
|
||||||
|
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
#include <OgreRenderSystem.h>
|
#include <OgreRenderSystem.h>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <csignal>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
|
@ -26,6 +27,8 @@ int main(int argc, char *argv[])
|
||||||
qDebug() << "SDL_Init failed: " << QString::fromStdString(SDL_GetError());
|
qDebug() << "SDL_Init failed: " << QString::fromStdString(SDL_GetError());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
signal(SIGINT, SIG_DFL); // We don't want to use the SDL event loop in the launcher,
|
||||||
|
// so reset SIGINT which SDL wants to redirect to an SDL_Quit event.
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,6 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
||||||
|
|
||||||
OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
||||||
: mOgre (0)
|
: mOgre (0)
|
||||||
, mFpsLevel(0)
|
|
||||||
, mVerboseScripts (false)
|
, mVerboseScripts (false)
|
||||||
, mSkipMenu (false)
|
, mSkipMenu (false)
|
||||||
, mUseSound (true)
|
, mUseSound (true)
|
||||||
|
@ -292,16 +291,10 @@ std::string OMW::Engine::loadSettings (Settings::Manager & settings)
|
||||||
else
|
else
|
||||||
throw std::runtime_error ("No default settings file found! Make sure the file \"settings-default.cfg\" was properly installed.");
|
throw std::runtime_error ("No default settings file found! Make sure the file \"settings-default.cfg\" was properly installed.");
|
||||||
|
|
||||||
// load user settings if they exist, otherwise just load the default settings as user settings
|
// load user settings if they exist
|
||||||
const std::string settingspath = mCfgMgr.getUserConfigPath().string() + "/settings.cfg";
|
const std::string settingspath = mCfgMgr.getUserConfigPath().string() + "/settings.cfg";
|
||||||
if (boost::filesystem::exists(settingspath))
|
if (boost::filesystem::exists(settingspath))
|
||||||
settings.loadUser(settingspath);
|
settings.loadUser(settingspath);
|
||||||
else if (boost::filesystem::exists(localdefault))
|
|
||||||
settings.loadUser(localdefault);
|
|
||||||
else if (boost::filesystem::exists(globaldefault))
|
|
||||||
settings.loadUser(globaldefault);
|
|
||||||
|
|
||||||
mFpsLevel = settings.getInt("fps", "HUD");
|
|
||||||
|
|
||||||
// load nif overrides
|
// load nif overrides
|
||||||
NifOverrides::Overrides nifOverrides;
|
NifOverrides::Overrides nifOverrides;
|
||||||
|
@ -377,7 +370,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||||
mEnvironment.setInputManager (input);
|
mEnvironment.setInputManager (input);
|
||||||
|
|
||||||
MWGui::WindowManager* window = new MWGui::WindowManager(
|
MWGui::WindowManager* window = new MWGui::WindowManager(
|
||||||
mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
|
mExtensions, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
|
||||||
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts, mFallbackMap);
|
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts, mFallbackMap);
|
||||||
mEnvironment.setWindowManager (window);
|
mEnvironment.setWindowManager (window);
|
||||||
|
|
||||||
|
@ -578,11 +571,6 @@ void OMW::Engine::setSoundUsage(bool soundUsage)
|
||||||
mUseSound = soundUsage;
|
mUseSound = soundUsage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OMW::Engine::showFPS(int level)
|
|
||||||
{
|
|
||||||
mFpsLevel = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OMW::Engine::setEncoding(const ToUTF8::FromType& encoding)
|
void OMW::Engine::setEncoding(const ToUTF8::FromType& encoding)
|
||||||
{
|
{
|
||||||
mEncoding = encoding;
|
mEncoding = encoding;
|
||||||
|
|
|
@ -71,7 +71,6 @@ namespace OMW
|
||||||
OEngine::Render::OgreRenderer *mOgre;
|
OEngine::Render::OgreRenderer *mOgre;
|
||||||
std::string mCellName;
|
std::string mCellName;
|
||||||
std::vector<std::string> mContentFiles;
|
std::vector<std::string> mContentFiles;
|
||||||
int mFpsLevel;
|
|
||||||
bool mVerboseScripts;
|
bool mVerboseScripts;
|
||||||
bool mSkipMenu;
|
bool mSkipMenu;
|
||||||
bool mUseSound;
|
bool mUseSound;
|
||||||
|
@ -151,9 +150,6 @@ namespace OMW
|
||||||
*/
|
*/
|
||||||
void addContentFile(const std::string& file);
|
void addContentFile(const std::string& file);
|
||||||
|
|
||||||
/// Enable fps counter
|
|
||||||
void showFPS(int level);
|
|
||||||
|
|
||||||
/// Enable or disable verbose script output
|
/// Enable or disable verbose script output
|
||||||
void setScriptsVerbosity(bool scriptsVerbosity);
|
void setScriptsVerbosity(bool scriptsVerbosity);
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||||
->default_value(true), "enable script blacklisting")
|
->default_value(true), "enable script blacklisting")
|
||||||
|
|
||||||
("load-savegame", bpo::value<std::string>()->default_value(""),
|
("load-savegame", bpo::value<std::string>()->default_value(""),
|
||||||
"load a save game file on game startup")
|
"load a save game file on game startup (specify an absolute filename or a filename relative to the current working directory)")
|
||||||
|
|
||||||
("skip-menu", bpo::value<bool>()->implicit_value(true)
|
("skip-menu", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(false), "skip main menu on game startup")
|
->default_value(false), "skip main menu on game startup")
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef GAME_BASE_INVIRONMENT_H
|
#ifndef GAME_BASE_ENVIRONMENT_H
|
||||||
#define GAME_BASE_INVIRONMENT_H
|
#define GAME_BASE_ENVIRONMENT_H
|
||||||
|
|
||||||
namespace MWBase
|
namespace MWBase
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
#define GAME_MWBASE_INPUTMANAGER_H
|
#define GAME_MWBASE_INPUTMANAGER_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <set>
|
||||||
#include <components/settings/settings.hpp>
|
#include <vector>
|
||||||
|
|
||||||
namespace MWBase
|
namespace MWBase
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void changeInputMode(bool guiMode) = 0;
|
virtual void changeInputMode(bool guiMode) = 0;
|
||||||
|
|
||||||
virtual void processChangedSettings(const Settings::CategorySettingVector& changed) = 0;
|
virtual void processChangedSettings(const std::set< std::pair<std::string, std::string> >& changed) = 0;
|
||||||
|
|
||||||
virtual void setDragDrop(bool dragDrop) = 0;
|
virtual void setDragDrop(bool dragDrop) = 0;
|
||||||
|
|
||||||
|
|
|
@ -129,16 +129,15 @@ namespace MWBase
|
||||||
/// @return false if the attack was considered a "friendly hit" and forgiven
|
/// @return false if the attack was considered a "friendly hit" and forgiven
|
||||||
virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0;
|
virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0;
|
||||||
/// Utility to check if taking this item is illegal and calling commitCrime if so
|
/// Utility to check if taking this item is illegal and calling commitCrime if so
|
||||||
virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count) = 0;
|
/// @param container The container the item is in; may be empty for an item in the world
|
||||||
|
virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container,
|
||||||
|
int count) = 0;
|
||||||
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so
|
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so
|
||||||
virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) = 0;
|
virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) = 0;
|
||||||
/// Attempt sleeping in a bed. If this is illegal, call commitCrime.
|
/// Attempt sleeping in a bed. If this is illegal, call commitCrime.
|
||||||
/// @return was it illegal, and someone saw you doing it?
|
/// @return was it illegal, and someone saw you doing it?
|
||||||
virtual bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed) = 0;
|
virtual bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed) = 0;
|
||||||
|
|
||||||
/// @return is \a ptr allowed to take/use \a item or is it a crime?
|
|
||||||
virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, MWWorld::Ptr& victim) = 0;
|
|
||||||
|
|
||||||
enum PersuasionType
|
enum PersuasionType
|
||||||
{
|
{
|
||||||
PT_Admire,
|
PT_Admire,
|
||||||
|
@ -203,6 +202,15 @@ namespace MWBase
|
||||||
virtual void keepPlayerAlive() = 0;
|
virtual void keepPlayerAlive() = 0;
|
||||||
|
|
||||||
virtual bool isReadyToBlock (const MWWorld::Ptr& ptr) const = 0;
|
virtual bool isReadyToBlock (const MWWorld::Ptr& ptr) const = 0;
|
||||||
|
|
||||||
|
virtual void confiscateStolenItems (const MWWorld::Ptr& player, const MWWorld::Ptr& targetContainer) = 0;
|
||||||
|
|
||||||
|
/// List the owners that the player has stolen this item from (the owner can be an NPC or a faction).
|
||||||
|
/// <Owner, item count>
|
||||||
|
virtual std::vector<std::pair<std::string, int> > getStolenItemOwners(const std::string& itemid) = 0;
|
||||||
|
|
||||||
|
/// Has the player stolen this item from the given owner?
|
||||||
|
virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,9 @@
|
||||||
#define GAME_MWBASE_SOUNDMANAGER_H
|
#define GAME_MWBASE_SOUNDMANAGER_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <set>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
|
@ -74,7 +72,7 @@ namespace MWBase
|
||||||
|
|
||||||
virtual ~SoundManager() {}
|
virtual ~SoundManager() {}
|
||||||
|
|
||||||
virtual void processChangedSettings(const Settings::CategorySettingVector& settings) = 0;
|
virtual void processChangedSettings(const std::set< std::pair<std::string, std::string> >& settings) = 0;
|
||||||
|
|
||||||
virtual void stopMusic() = 0;
|
virtual void stopMusic() = 0;
|
||||||
///< Stops music if it's playing
|
///< Stops music if it's playing
|
||||||
|
|
|
@ -5,16 +5,20 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
|
||||||
|
|
||||||
#include <components/translation/translation.hpp>
|
|
||||||
|
|
||||||
#include <components/loadinglistener/loadinglistener.hpp>
|
|
||||||
|
|
||||||
#include "../mwmechanics/stat.hpp"
|
#include "../mwmechanics/stat.hpp"
|
||||||
|
|
||||||
#include "../mwgui/mode.hpp"
|
#include "../mwgui/mode.hpp"
|
||||||
|
|
||||||
|
namespace Loading
|
||||||
|
{
|
||||||
|
class Listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Translation
|
||||||
|
{
|
||||||
|
class Storage;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MyGUI
|
namespace MyGUI
|
||||||
{
|
{
|
||||||
class Gui;
|
class Gui;
|
||||||
|
@ -267,7 +271,7 @@ namespace MWBase
|
||||||
*/
|
*/
|
||||||
virtual std::string getGameSettingString(const std::string &id, const std::string &default_) = 0;
|
virtual std::string getGameSettingString(const std::string &id, const std::string &default_) = 0;
|
||||||
|
|
||||||
virtual void processChangedSettings(const Settings::CategorySettingVector& changed) = 0;
|
virtual void processChangedSettings(const std::set< std::pair<std::string, std::string> >& changed) = 0;
|
||||||
|
|
||||||
virtual void windowResized(int x, int y) = 0;
|
virtual void windowResized(int x, int y) = 0;
|
||||||
|
|
||||||
|
|
|
@ -3,26 +3,23 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <set>
|
||||||
#include <components/settings/settings.hpp>
|
|
||||||
|
|
||||||
#include <components/esm/cellid.hpp>
|
#include <components/esm/cellid.hpp>
|
||||||
|
|
||||||
#include "../mwworld/globals.hpp"
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
class Vector2;
|
class Vector2;
|
||||||
class Vector3;
|
class Vector3;
|
||||||
|
class Quaternion;
|
||||||
|
class Image;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace OEngine
|
namespace Loading
|
||||||
{
|
{
|
||||||
namespace Physic
|
class Listener;
|
||||||
{
|
|
||||||
class PhysicEngine;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
|
@ -390,7 +387,7 @@ namespace MWBase
|
||||||
virtual bool canPlaceObject (float cursorX, float cursorY) = 0;
|
virtual bool canPlaceObject (float cursorX, float cursorY) = 0;
|
||||||
///< @return true if it is possible to place on object at specified cursor location
|
///< @return true if it is possible to place on object at specified cursor location
|
||||||
|
|
||||||
virtual void processChangedSettings (const Settings::CategorySettingVector& settings) = 0;
|
virtual void processChangedSettings (const std::set< std::pair<std::string, std::string> >& settings) = 0;
|
||||||
|
|
||||||
virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0;
|
virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0;
|
||||||
virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const = 0;
|
virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const = 0;
|
||||||
|
|
|
@ -59,8 +59,10 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Container> *ref =
|
MWWorld::LiveCellRef<ESM::Container> *ref =
|
||||||
ptr.get<ESM::Container>();
|
ptr.get<ESM::Container>();
|
||||||
|
|
||||||
|
// setting ownership not needed, since taking items from a container inherits the
|
||||||
|
// container's owner automatically
|
||||||
data->mContainerStore.fill(
|
data->mContainerStore.fill(
|
||||||
ref->mBase->mInventory, ptr.getCellRef().getOwner(), ptr.getCellRef().getFaction(), ptr.getCellRef().getFactionRank(), MWBase::Environment::get().getWorld()->getStore());
|
ref->mBase->mInventory, "");
|
||||||
|
|
||||||
// store
|
// store
|
||||||
ptr.getRefData().setCustomData (data.release());
|
ptr.getRefData().setCustomData (data.release());
|
||||||
|
@ -82,7 +84,10 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Container> *ref = ptr.get<ESM::Container>();
|
MWWorld::LiveCellRef<ESM::Container> *ref = ptr.get<ESM::Container>();
|
||||||
const ESM::InventoryList& list = ref->mBase->mInventory;
|
const ESM::InventoryList& list = ref->mBase->mInventory;
|
||||||
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
||||||
store.restock(list, ptr, ptr.getCellRef().getOwner(), ptr.getCellRef().getFaction(), ptr.getCellRef().getFactionRank());
|
|
||||||
|
// setting ownership not needed, since taking items from a container inherits the
|
||||||
|
// container's owner automatically
|
||||||
|
store.restock(list, ptr, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
|
void Container::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
|
||||||
|
|
|
@ -139,8 +139,7 @@ namespace MWClass
|
||||||
// store
|
// store
|
||||||
ptr.getRefData().setCustomData(data.release());
|
ptr.getRefData().setCustomData(data.release());
|
||||||
|
|
||||||
getContainerStore(ptr).fill(ref->mBase->mInventory, getId(ptr), "", -1,
|
getContainerStore(ptr).fill(ref->mBase->mInventory, getId(ptr));
|
||||||
MWBase::Environment::get().getWorld()->getStore());
|
|
||||||
|
|
||||||
if (ref->mBase->mFlags & ESM::Creature::Weapon)
|
if (ref->mBase->mFlags & ESM::Creature::Weapon)
|
||||||
getInventoryStore(ptr).autoEquip(ptr);
|
getInventoryStore(ptr).autoEquip(ptr);
|
||||||
|
@ -886,7 +885,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
|
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
|
||||||
const ESM::InventoryList& list = ref->mBase->mInventory;
|
const ESM::InventoryList& list = ref->mBase->mInventory;
|
||||||
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
||||||
store.restock(list, ptr, ptr.getCellRef().getRefId(), "", -1);
|
store.restock(list, ptr, ptr.getCellRef().getRefId());
|
||||||
}
|
}
|
||||||
|
|
||||||
int Creature::getBaseFightRating(const MWWorld::Ptr &ptr) const
|
int Creature::getBaseFightRating(const MWWorld::Ptr &ptr) const
|
||||||
|
|
|
@ -384,8 +384,8 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
|
|
||||||
// inventory
|
// inventory
|
||||||
data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr), "", -1,
|
// setting ownership is used to make the NPC auto-equip his initial equipment only, and not bartered items
|
||||||
MWBase::Environment::get().getWorld()->getStore());
|
data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr));
|
||||||
|
|
||||||
data->mNpcStats.setGoldPool(gold);
|
data->mNpcStats.setGoldPool(gold);
|
||||||
|
|
||||||
|
@ -1328,7 +1328,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
||||||
const ESM::InventoryList& list = ref->mBase->mInventory;
|
const ESM::InventoryList& list = ref->mBase->mInventory;
|
||||||
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
||||||
store.restock(list, ptr, ptr.getCellRef().getRefId(), "", -1);
|
store.restock(list, ptr, ptr.getCellRef().getRefId());
|
||||||
}
|
}
|
||||||
|
|
||||||
int Npc::getBaseFightRating (const MWWorld::Ptr& ptr) const
|
int Npc::getBaseFightRating (const MWWorld::Ptr& ptr) const
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "scripttest.hpp"
|
#include "scripttest.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "../mwworld/manualref.hpp"
|
#include "../mwworld/manualref.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
|
|
@ -285,7 +285,7 @@ namespace MWGui
|
||||||
if (mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead())
|
if (mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead())
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item.mBase, count);
|
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item.mBase, mPtr, count);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -339,7 +339,8 @@ namespace MWGui
|
||||||
for (int i=0; i<2; ++i)
|
for (int i=0; i<2; ++i)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr item = (i == 0) ? mEnchanting.getOldItem() : mEnchanting.getGem();
|
MWWorld::Ptr item = (i == 0) ? mEnchanting.getOldItem() : mEnchanting.getGem();
|
||||||
if (Misc::StringUtils::ciEqual(item.getCellRef().getOwner(), mPtr.getCellRef().getRefId()))
|
if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(item.getCellRef().getRefId(),
|
||||||
|
mPtr.getCellRef().getRefId()))
|
||||||
{
|
{
|
||||||
std::string msg = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage49")->getString();
|
std::string msg = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage49")->getString();
|
||||||
if (msg.find("%s") != std::string::npos)
|
if (msg.find("%s") != std::string::npos)
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <MyGUI_ScrollView.h>
|
#include <MyGUI_ScrollView.h>
|
||||||
|
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
|
|
|
@ -65,16 +65,7 @@ MWWorld::Ptr InventoryItemModel::moveItem(const ItemStack &item, size_t count, I
|
||||||
if (item.mFlags & ItemStack::Flag_Bound)
|
if (item.mFlags & ItemStack::Flag_Bound)
|
||||||
return MWWorld::Ptr();
|
return MWWorld::Ptr();
|
||||||
|
|
||||||
bool setNewOwner = false;
|
MWWorld::Ptr ret = otherModel->copyItem(item, count, false);
|
||||||
|
|
||||||
// Are you dead? Then you wont need that anymore
|
|
||||||
if (mActor.getClass().isActor() && mActor.getClass().getCreatureStats(mActor).isDead()
|
|
||||||
// Make sure that the item is actually owned by the dead actor
|
|
||||||
// Prevents a potential exploit for resetting the owner of any item, by placing the item in a corpse
|
|
||||||
&& Misc::StringUtils::ciEqual(item.mBase.getCellRef().getOwner(), mActor.getCellRef().getRefId()))
|
|
||||||
setNewOwner = true;
|
|
||||||
|
|
||||||
MWWorld::Ptr ret = otherModel->copyItem(item, count, setNewOwner);
|
|
||||||
removeItem(item, count);
|
removeItem(item, count);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include <MyGUI_InputManager.h>
|
#include <MyGUI_InputManager.h>
|
||||||
#include <MyGUI_Button.h>
|
#include <MyGUI_Button.h>
|
||||||
|
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
|
@ -622,7 +624,7 @@ namespace MWGui
|
||||||
throw std::runtime_error("Added item not found");
|
throw std::runtime_error("Added item not found");
|
||||||
mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count);
|
mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count);
|
||||||
|
|
||||||
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, newObject, count);
|
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, newObject, MWWorld::Ptr(), count);
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getSpellWindow())
|
if (MWBase::Environment::get().getWindowManager()->getSpellWindow())
|
||||||
MWBase::Environment::get().getWindowManager()->getSpellWindow()->updateSpells();
|
MWBase::Environment::get().getWindowManager()->getSpellWindow()->updateSpells();
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "itemmodel.hpp"
|
#include "itemmodel.hpp"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
#include "../mwworld/store.hpp"
|
#include "../mwworld/store.hpp"
|
||||||
|
|
|
@ -46,20 +46,27 @@ namespace MWGui
|
||||||
ItemModel();
|
ItemModel();
|
||||||
virtual ~ItemModel() {}
|
virtual ~ItemModel() {}
|
||||||
|
|
||||||
typedef int ModelIndex;
|
typedef int ModelIndex; // -1 means invalid index
|
||||||
|
|
||||||
|
/// Throws for invalid index or out of range index
|
||||||
virtual ItemStack getItem (ModelIndex index) = 0;
|
virtual ItemStack getItem (ModelIndex index) = 0;
|
||||||
///< throws for invalid index
|
|
||||||
|
/// The number of items in the model, this specifies the range of indices you can pass to
|
||||||
|
/// the getItem function (but this range is only valid until the next call to update())
|
||||||
virtual size_t getItemCount() = 0;
|
virtual size_t getItemCount() = 0;
|
||||||
|
|
||||||
|
/// Returns an invalid index if the item was not found
|
||||||
virtual ModelIndex getIndex (ItemStack item) = 0;
|
virtual ModelIndex getIndex (ItemStack item) = 0;
|
||||||
|
|
||||||
|
/// Rebuild the item model, this will invalidate existing model indices
|
||||||
virtual void update() = 0;
|
virtual void update() = 0;
|
||||||
|
|
||||||
/// Move items from this model to \a otherModel.
|
/// Move items from this model to \a otherModel.
|
||||||
|
/// @note Derived implementations may return an empty Ptr if the move was unsuccessful.
|
||||||
virtual MWWorld::Ptr moveItem (const ItemStack& item, size_t count, ItemModel* otherModel);
|
virtual MWWorld::Ptr moveItem (const ItemStack& item, size_t count, ItemModel* otherModel);
|
||||||
|
|
||||||
/// @param setNewOwner Set the copied item's owner to the actor we are copying to, or keep the original owner?
|
/// @param setNewOwner If true, set the copied item's owner to the actor we are copying to,
|
||||||
|
/// otherwise reset owner to ""
|
||||||
virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner=false) = 0;
|
virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner=false) = 0;
|
||||||
virtual void removeItem (const ItemStack& item, size_t count) = 0;
|
virtual void removeItem (const ItemStack& item, size_t count) = 0;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#include <components/misc/utf8stream.hpp>
|
#include <components/misc/utf8stream.hpp>
|
||||||
|
|
||||||
|
#include <components/translation/translation.hpp>
|
||||||
|
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/journal.hpp"
|
#include "../mwbase/journal.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
|
@ -139,7 +139,6 @@ namespace MWGui
|
||||||
|
|
||||||
if(world->getStore().get<ESM::Class>().isDynamic(cls->mId))
|
if(world->getStore().get<ESM::Class>().isDynamic(cls->mId))
|
||||||
{
|
{
|
||||||
// Vanilla uses thief.dds for custom classes.
|
|
||||||
// Choosing Stealth specialization and Speed/Agility as attributes, if possible. Otherwise fall back to first class found.
|
// Choosing Stealth specialization and Speed/Agility as attributes, if possible. Otherwise fall back to first class found.
|
||||||
MWWorld::SharedIterator<ESM::Class> it = world->getStore().get<ESM::Class>().begin();
|
MWWorld::SharedIterator<ESM::Class> it = world->getStore().get<ESM::Class>().begin();
|
||||||
for(; it != world->getStore().get<ESM::Class>().end(); ++it)
|
for(; it != world->getStore().get<ESM::Class>().end(); ++it)
|
||||||
|
@ -173,14 +172,17 @@ namespace MWGui
|
||||||
if (pcStats.getAttribute(i).getBase() < 100)
|
if (pcStats.getAttribute(i).getBase() < 100)
|
||||||
{
|
{
|
||||||
mAttributes[i]->setEnabled(true);
|
mAttributes[i]->setEnabled(true);
|
||||||
|
mAttributeValues[i]->setEnabled(true);
|
||||||
availableAttributes++;
|
availableAttributes++;
|
||||||
|
|
||||||
int mult = pcStats.getLevelupAttributeMultiplier (i);
|
int mult = pcStats.getLevelupAttributeMultiplier (i);
|
||||||
|
mult = std::min(mult, 100-pcStats.getAttribute(i).getBase());
|
||||||
text->setCaption(mult <= 1 ? "" : "x" + MyGUI::utility::toString(mult));
|
text->setCaption(mult <= 1 ? "" : "x" + MyGUI::utility::toString(mult));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mAttributes[i]->setEnabled(false);
|
mAttributes[i]->setEnabled(false);
|
||||||
|
mAttributeValues[i]->setEnabled(false);
|
||||||
|
|
||||||
text->setCaption("");
|
text->setCaption("");
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#include <MyGUI_Gui.h>
|
#include <MyGUI_Gui.h>
|
||||||
#include <MyGUI_TextBox.h>
|
#include <MyGUI_TextBox.h>
|
||||||
|
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/statemanager.hpp"
|
#include "../mwbase/statemanager.hpp"
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <components/version/version.hpp>
|
#include <components/version/version.hpp>
|
||||||
|
|
||||||
#include <components/widgets/imagebutton.hpp>
|
#include <components/widgets/imagebutton.hpp>
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <MyGUI_FactoryManager.h>
|
#include <MyGUI_FactoryManager.h>
|
||||||
|
|
||||||
#include <components/esm/globalmap.hpp>
|
#include <components/esm/globalmap.hpp>
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <SDL_video.h>
|
#include <SDL_video.h>
|
||||||
|
|
||||||
#include <components/widgets/sharedstatebutton.hpp>
|
#include <components/widgets/sharedstatebutton.hpp>
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
|
@ -376,18 +376,26 @@ namespace MWGui
|
||||||
for (SkillList::const_iterator it = skills.begin(); it != end; ++it)
|
for (SkillList::const_iterator it = skills.begin(); it != end; ++it)
|
||||||
{
|
{
|
||||||
int skillId = *it;
|
int skillId = *it;
|
||||||
if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes
|
if (skillId < 0 || skillId >= ESM::Skill::Length) // Skip unknown skill indexes
|
||||||
continue;
|
continue;
|
||||||
assert(skillId >= 0 && skillId < ESM::Skill::Length);
|
|
||||||
const std::string &skillNameId = ESM::Skill::sSkillNameIds[skillId];
|
const std::string &skillNameId = ESM::Skill::sSkillNameIds[skillId];
|
||||||
const MWMechanics::SkillValue &stat = mSkillValues.find(skillId)->second;
|
const MWMechanics::SkillValue &stat = mSkillValues.find(skillId)->second;
|
||||||
int base = stat.getBase();
|
int base = stat.getBase();
|
||||||
int modified = stat.getModified();
|
int modified = stat.getModified();
|
||||||
int progressPercent = stat.getProgress() * 100;
|
|
||||||
|
|
||||||
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
const MWWorld::ESMStore &esmStore =
|
const MWWorld::ESMStore &esmStore =
|
||||||
MWBase::Environment::get().getWorld()->getStore();
|
MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
|
||||||
|
float progressRequirement = player.getClass().getNpcStats(player).getSkillProgressRequirement(skillId,
|
||||||
|
*esmStore.get<ESM::Class>().find(player.get<ESM::NPC>()->mBase->mClass));
|
||||||
|
|
||||||
|
// This is how vanilla MW displays the progress bar (I think). Note it's slightly inaccurate,
|
||||||
|
// due to the int casting in the skill levelup logic. Also the progress label could in rare cases
|
||||||
|
// reach 100% without the skill levelling up.
|
||||||
|
// Leaving the original display logic for now, for consistency with ess-imported savegames.
|
||||||
|
int progressPercent = int(float(stat.getProgress()) / float(progressRequirement) * 100.f + 0.5f);
|
||||||
|
|
||||||
const ESM::Skill* skill = esmStore.get<ESM::Skill>().find(skillId);
|
const ESM::Skill* skill = esmStore.get<ESM::Skill>().find(skillId);
|
||||||
|
|
||||||
std::string icon = "icons\\k\\" + ESM::Skill::sIconNames[skillId];
|
std::string icon = "icons\\k\\" + ESM::Skill::sIconNames[skillId];
|
||||||
|
|
|
@ -8,10 +8,12 @@
|
||||||
#include <MyGUI_ImageBox.h>
|
#include <MyGUI_ImageBox.h>
|
||||||
|
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
@ -585,6 +587,15 @@ namespace MWGui
|
||||||
ret += getMiscString(cellref.getFaction(), "Faction");
|
ret += getMiscString(cellref.getFaction(), "Faction");
|
||||||
if (cellref.getFactionRank() > 0)
|
if (cellref.getFactionRank() > 0)
|
||||||
ret += getValueString(cellref.getFactionRank(), "Rank");
|
ret += getValueString(cellref.getFactionRank(), "Rank");
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, int> > itemOwners =
|
||||||
|
MWBase::Environment::get().getMechanicsManager()->getStolenItemOwners(cellref.getRefId());
|
||||||
|
|
||||||
|
for (std::vector<std::pair<std::string, int> >::const_iterator it = itemOwners.begin(); it != itemOwners.end(); ++it)
|
||||||
|
{
|
||||||
|
ret += std::string("\nStolen from ") + it->first;
|
||||||
|
}
|
||||||
|
|
||||||
ret += getMiscString(cellref.getGlobalVariable(), "Global");
|
ret += getMiscString(cellref.getGlobalVariable(), "Global");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,11 +135,9 @@ namespace MWGui
|
||||||
if (i == sourceModel->getItemCount())
|
if (i == sourceModel->getItemCount())
|
||||||
throw std::runtime_error("The borrowed item disappeared");
|
throw std::runtime_error("The borrowed item disappeared");
|
||||||
|
|
||||||
// reset owner while copying, but only for items bought by the player
|
|
||||||
bool setNewOwner = (mMerchant.isEmpty());
|
|
||||||
const ItemStack& item = sourceModel->getItem(i);
|
const ItemStack& item = sourceModel->getItem(i);
|
||||||
// copy the borrowed items to our model
|
// copy the borrowed items to our model
|
||||||
copyItem(item, it->mCount, setNewOwner);
|
copyItem(item, it->mCount);
|
||||||
// then remove them from the source model
|
// then remove them from the source model
|
||||||
sourceModel->removeItem(item, it->mCount);
|
sourceModel->removeItem(item, it->mCount);
|
||||||
}
|
}
|
||||||
|
|
|
@ -300,7 +300,8 @@ namespace MWGui
|
||||||
// check if the player is attempting to sell back an item stolen from this actor
|
// check if the player is attempting to sell back an item stolen from this actor
|
||||||
for (std::vector<ItemStack>::iterator it = merchantBought.begin(); it != merchantBought.end(); ++it)
|
for (std::vector<ItemStack>::iterator it = merchantBought.begin(); it != merchantBought.end(); ++it)
|
||||||
{
|
{
|
||||||
if (Misc::StringUtils::ciEqual(it->mBase.getCellRef().getOwner(), mPtr.getCellRef().getRefId()))
|
if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(it->mBase.getCellRef().getRefId(),
|
||||||
|
mPtr.getCellRef().getRefId()))
|
||||||
{
|
{
|
||||||
std::string msg = gmst.find("sNotifyMessage49")->getString();
|
std::string msg = gmst.find("sNotifyMessage49")->getString();
|
||||||
if (msg.find("%s") != std::string::npos)
|
if (msg.find("%s") != std::string::npos)
|
||||||
|
@ -315,6 +316,8 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: move to mwmechanics
|
||||||
|
|
||||||
// Is the player buying?
|
// Is the player buying?
|
||||||
bool buying = (mCurrentMerchantOffer < 0);
|
bool buying = (mCurrentMerchantOffer < 0);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <MyGUI_ProgressBar.h>
|
#include <MyGUI_ProgressBar.h>
|
||||||
|
|
||||||
#include <components/widgets/box.hpp>
|
#include <components/widgets/box.hpp>
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <MyGUI_InputManager.h>
|
#include <MyGUI_InputManager.h>
|
||||||
|
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,9 @@
|
||||||
#include <MyGUI_ClipboardManager.h>
|
#include <MyGUI_ClipboardManager.h>
|
||||||
#include <MyGUI_RenderManager.h>
|
#include <MyGUI_RenderManager.h>
|
||||||
|
|
||||||
|
#include <SDL_keyboard.h>
|
||||||
|
#include <SDL_clipboard.h>
|
||||||
|
|
||||||
#include <openengine/ogre/renderer.hpp>
|
#include <openengine/ogre/renderer.hpp>
|
||||||
#include <openengine/gui/manager.hpp>
|
#include <openengine/gui/manager.hpp>
|
||||||
|
|
||||||
|
@ -26,6 +29,8 @@
|
||||||
|
|
||||||
#include <components/fontloader/fontloader.hpp>
|
#include <components/fontloader/fontloader.hpp>
|
||||||
|
|
||||||
|
#include <components/translation/translation.hpp>
|
||||||
|
|
||||||
#include <components/widgets/widgets.hpp>
|
#include <components/widgets/widgets.hpp>
|
||||||
#include <components/widgets/tags.hpp>
|
#include <components/widgets/tags.hpp>
|
||||||
|
|
||||||
|
@ -91,7 +96,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
WindowManager::WindowManager(
|
WindowManager::WindowManager(
|
||||||
const Compiler::Extensions& extensions, int fpsLevel, OEngine::Render::OgreRenderer *ogre,
|
const Compiler::Extensions& extensions, OEngine::Render::OgreRenderer *ogre,
|
||||||
const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts,
|
const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts,
|
||||||
Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, bool exportFonts, const std::map<std::string, std::string>& fallbackMap)
|
Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, bool exportFonts, const std::map<std::string, std::string>& fallbackMap)
|
||||||
: mConsoleOnlyScripts(consoleOnlyScripts)
|
: mConsoleOnlyScripts(consoleOnlyScripts)
|
||||||
|
@ -162,7 +167,6 @@ namespace MWGui
|
||||||
, mForceHidden(GW_None)
|
, mForceHidden(GW_None)
|
||||||
, mAllowed(GW_ALL)
|
, mAllowed(GW_ALL)
|
||||||
, mRestAllowed(true)
|
, mRestAllowed(true)
|
||||||
, mShowFPSLevel(fpsLevel)
|
|
||||||
, mFPS(0.0f)
|
, mFPS(0.0f)
|
||||||
, mTriangleCount(0)
|
, mTriangleCount(0)
|
||||||
, mBatchCount(0)
|
, mBatchCount(0)
|
||||||
|
@ -264,7 +268,7 @@ namespace MWGui
|
||||||
trackWindow(mDialogueWindow, "dialogue");
|
trackWindow(mDialogueWindow, "dialogue");
|
||||||
mContainerWindow = new ContainerWindow(mDragAndDrop);
|
mContainerWindow = new ContainerWindow(mDragAndDrop);
|
||||||
trackWindow(mContainerWindow, "container");
|
trackWindow(mContainerWindow, "container");
|
||||||
mHud = new HUD(mCustomMarkers, mShowFPSLevel, mDragAndDrop);
|
mHud = new HUD(mCustomMarkers, Settings::Manager::getInt("fps", "HUD"), mDragAndDrop);
|
||||||
mToolTips = new ToolTips();
|
mToolTips = new ToolTips();
|
||||||
mScrollWindow = new ScrollWindow();
|
mScrollWindow = new ScrollWindow();
|
||||||
mBookWindow = new BookWindow();
|
mBookWindow = new BookWindow();
|
||||||
|
|
|
@ -5,13 +5,14 @@
|
||||||
This class owns and controls all the MW specific windows in the
|
This class owns and controls all the MW specific windows in the
|
||||||
GUI. It can enable/disable Gui mode, and is responsible for sending
|
GUI. It can enable/disable Gui mode, and is responsible for sending
|
||||||
and retrieving information from the Gui.
|
and retrieving information from the Gui.
|
||||||
|
|
||||||
MyGUI should be initialized separately before creating instances of
|
|
||||||
this class.
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "mapwindow.hpp"
|
#include "mapwindow.hpp"
|
||||||
|
|
||||||
#include <MyGUI_KeyCode.h>
|
#include <MyGUI_KeyCode.h>
|
||||||
|
@ -96,7 +97,7 @@ namespace MWGui
|
||||||
typedef std::pair<std::string, int> Faction;
|
typedef std::pair<std::string, int> Faction;
|
||||||
typedef std::vector<Faction> FactionList;
|
typedef std::vector<Faction> FactionList;
|
||||||
|
|
||||||
WindowManager(const Compiler::Extensions& extensions, int fpsLevel,
|
WindowManager(const Compiler::Extensions& extensions,
|
||||||
OEngine::Render::OgreRenderer *mOgre, const std::string& logpath,
|
OEngine::Render::OgreRenderer *mOgre, const std::string& logpath,
|
||||||
const std::string& cacheDir, bool consoleOnlyScripts,
|
const std::string& cacheDir, bool consoleOnlyScripts,
|
||||||
Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, bool exportFonts, const std::map<std::string,std::string>& fallbackMap);
|
Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, bool exportFonts, const std::map<std::string,std::string>& fallbackMap);
|
||||||
|
@ -450,7 +451,6 @@ namespace MWGui
|
||||||
|
|
||||||
void updateVisible(); // Update visibility of all windows based on mode, shown and allowed settings
|
void updateVisible(); // Update visibility of all windows based on mode, shown and allowed settings
|
||||||
|
|
||||||
int mShowFPSLevel;
|
|
||||||
float mFPS;
|
float mFPS;
|
||||||
unsigned int mTriangleCount;
|
unsigned int mTriangleCount;
|
||||||
unsigned int mBatchCount;
|
unsigned int mBatchCount;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include "movement.hpp"
|
#include "movement.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include "creaturestats.hpp"
|
#include "creaturestats.hpp"
|
||||||
#include "security.hpp"
|
#include "security.hpp"
|
||||||
|
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "../mwrender/animation.hpp"
|
#include "../mwrender/animation.hpp"
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
|
@ -12,9 +12,9 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
|
|
||||||
/// @return ID of resulting item, or empty if none
|
/// @return ID of resulting item, or empty if none
|
||||||
inline std::string getLevelledItem (const ESM::LeveledListBase* levItem, bool creature, unsigned char failChance=0)
|
inline std::string getLevelledItem (const ESM::LevelledListBase* levItem, bool creature, unsigned char failChance=0)
|
||||||
{
|
{
|
||||||
const std::vector<ESM::LeveledListBase::LevelItem>& items = levItem->mList;
|
const std::vector<ESM::LevelledListBase::LevelItem>& items = levItem->mList;
|
||||||
|
|
||||||
const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
int playerLevel = player.getClass().getCreatureStats(player).getLevel();
|
int playerLevel = player.getClass().getCreatureStats(player).getLevel();
|
||||||
|
@ -27,7 +27,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
std::vector<std::string> candidates;
|
std::vector<std::string> candidates;
|
||||||
int highestLevel = 0;
|
int highestLevel = 0;
|
||||||
for (std::vector<ESM::LeveledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
|
for (std::vector<ESM::LevelledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
|
||||||
{
|
{
|
||||||
if (it->mLevel > highestLevel && it->mLevel <= playerLevel)
|
if (it->mLevel > highestLevel && it->mLevel <= playerLevel)
|
||||||
highestLevel = it->mLevel;
|
highestLevel = it->mLevel;
|
||||||
|
@ -39,7 +39,7 @@ namespace MWMechanics
|
||||||
allLevels = levItem->mFlags & ESM::CreatureLevList::AllLevels;
|
allLevels = levItem->mFlags & ESM::CreatureLevList::AllLevels;
|
||||||
|
|
||||||
std::pair<int, std::string> highest = std::make_pair(-1, "");
|
std::pair<int, std::string> highest = std::make_pair(-1, "");
|
||||||
for (std::vector<ESM::LeveledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
|
for (std::vector<ESM::LevelledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
|
||||||
{
|
{
|
||||||
if (playerLevel >= it->mLevel
|
if (playerLevel >= it->mLevel
|
||||||
&& (allLevels || it->mLevel == highestLevel))
|
&& (allLevels || it->mLevel == highestLevel))
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#include "mechanicsmanagerimp.hpp"
|
#include "mechanicsmanagerimp.hpp"
|
||||||
#include "npcstats.hpp"
|
#include "npcstats.hpp"
|
||||||
|
|
||||||
|
#include <components/esm/stolenitems.hpp>
|
||||||
|
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
|
|
||||||
|
@ -873,31 +875,31 @@ namespace MWMechanics
|
||||||
mAI = true;
|
mAI = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MechanicsManager::isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, MWWorld::Ptr& victim)
|
bool MechanicsManager::isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::CellRef& cellref, MWWorld::Ptr& victim)
|
||||||
{
|
{
|
||||||
const std::string& owner = item.getCellRef().getOwner();
|
const std::string& owner = cellref.getOwner();
|
||||||
bool isOwned = !owner.empty() && owner != "player";
|
bool isOwned = !owner.empty() && owner != "player";
|
||||||
|
|
||||||
const std::string& faction = item.getCellRef().getFaction();
|
const std::string& faction = cellref.getFaction();
|
||||||
bool isFactionOwned = false;
|
bool isFactionOwned = false;
|
||||||
if (!faction.empty() && ptr.getClass().isNpc())
|
if (!faction.empty() && ptr.getClass().isNpc())
|
||||||
{
|
{
|
||||||
const std::map<std::string, int>& factions = ptr.getClass().getNpcStats(ptr).getFactionRanks();
|
const std::map<std::string, int>& factions = ptr.getClass().getNpcStats(ptr).getFactionRanks();
|
||||||
std::map<std::string, int>::const_iterator found = factions.find(Misc::StringUtils::lowerCase(faction));
|
std::map<std::string, int>::const_iterator found = factions.find(Misc::StringUtils::lowerCase(faction));
|
||||||
if (found == factions.end()
|
if (found == factions.end()
|
||||||
|| found->second < item.getCellRef().getFactionRank())
|
|| found->second < cellref.getFactionRank())
|
||||||
isFactionOwned = true;
|
isFactionOwned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& globalVariable = item.getCellRef().getGlobalVariable();
|
const std::string& globalVariable = cellref.getGlobalVariable();
|
||||||
if (!globalVariable.empty() && MWBase::Environment::get().getWorld()->getGlobalInt(Misc::StringUtils::lowerCase(globalVariable)) == 1)
|
if (!globalVariable.empty() && MWBase::Environment::get().getWorld()->getGlobalInt(Misc::StringUtils::lowerCase(globalVariable)) == 1)
|
||||||
{
|
{
|
||||||
isOwned = false;
|
isOwned = false;
|
||||||
isFactionOwned = false;
|
isFactionOwned = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!item.getCellRef().getOwner().empty())
|
if (!cellref.getOwner().empty())
|
||||||
victim = MWBase::Environment::get().getWorld()->searchPtr(item.getCellRef().getOwner(), true);
|
victim = MWBase::Environment::get().getWorld()->searchPtr(cellref.getOwner(), true);
|
||||||
|
|
||||||
return (!isOwned && !isFactionOwned);
|
return (!isOwned && !isFactionOwned);
|
||||||
}
|
}
|
||||||
|
@ -916,7 +918,7 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::Ptr victim;
|
MWWorld::Ptr victim;
|
||||||
if (isAllowedToUse(ptr, bed, victim))
|
if (isAllowedToUse(ptr, bed.getCellRef(), victim))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(commitCrime(ptr, victim, OT_SleepingInOwnedBed))
|
if(commitCrime(ptr, victim, OT_SleepingInOwnedBed))
|
||||||
|
@ -931,16 +933,103 @@ namespace MWMechanics
|
||||||
void MechanicsManager::objectOpened(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item)
|
void MechanicsManager::objectOpened(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr victim;
|
MWWorld::Ptr victim;
|
||||||
if (isAllowedToUse(ptr, item, victim))
|
if (isAllowedToUse(ptr, item.getCellRef(), victim))
|
||||||
return;
|
return;
|
||||||
commitCrime(ptr, victim, OT_Trespassing);
|
commitCrime(ptr, victim, OT_Trespassing);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, int count)
|
std::vector<std::pair<std::string, int> > MechanicsManager::getStolenItemOwners(const std::string& itemid)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr victim;
|
std::vector<std::pair<std::string, int> > result;
|
||||||
if (isAllowedToUse(ptr, item, victim))
|
StolenItemsMap::const_iterator it = mStolenItems.find(Misc::StringUtils::lowerCase(itemid));
|
||||||
|
if (it == mStolenItems.end())
|
||||||
|
return result;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const OwnerMap& owners = it->second;
|
||||||
|
for (OwnerMap::const_iterator ownerIt = owners.begin(); ownerIt != owners.end(); ++ownerIt)
|
||||||
|
result.push_back(std::make_pair(ownerIt->first.first, ownerIt->second));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MechanicsManager::isItemStolenFrom(const std::string &itemid, const std::string &ownerid)
|
||||||
|
{
|
||||||
|
StolenItemsMap::const_iterator it = mStolenItems.find(Misc::StringUtils::lowerCase(itemid));
|
||||||
|
if (it == mStolenItems.end())
|
||||||
|
return false;
|
||||||
|
const OwnerMap& owners = it->second;
|
||||||
|
OwnerMap::const_iterator ownerFound = owners.find(std::make_pair(Misc::StringUtils::lowerCase(ownerid), false));
|
||||||
|
return ownerFound != owners.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MechanicsManager::confiscateStolenItems(const MWWorld::Ptr &player, const MWWorld::Ptr &targetContainer)
|
||||||
|
{
|
||||||
|
MWWorld::ContainerStore& store = player.getClass().getContainerStore(player);
|
||||||
|
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
||||||
|
{
|
||||||
|
StolenItemsMap::iterator stolenIt = mStolenItems.find(Misc::StringUtils::lowerCase(it->getClass().getId(*it)));
|
||||||
|
if (stolenIt == mStolenItems.end())
|
||||||
|
continue;
|
||||||
|
OwnerMap& owners = stolenIt->second;
|
||||||
|
int itemCount = it->getRefData().getCount();
|
||||||
|
for (OwnerMap::iterator ownerIt = owners.begin(); ownerIt != owners.end();)
|
||||||
|
{
|
||||||
|
int toRemove = std::min(itemCount, ownerIt->second);
|
||||||
|
itemCount -= toRemove;
|
||||||
|
ownerIt->second -= toRemove;
|
||||||
|
if (ownerIt->second == 0)
|
||||||
|
owners.erase(ownerIt++);
|
||||||
|
else
|
||||||
|
++ownerIt;
|
||||||
|
}
|
||||||
|
|
||||||
|
int toMove = it->getRefData().getCount() - itemCount;
|
||||||
|
|
||||||
|
targetContainer.getClass().getContainerStore(targetContainer).add(*it, toMove, targetContainer);
|
||||||
|
store.remove(*it, toMove, player);
|
||||||
|
}
|
||||||
|
// TODO: unhardcode the locklevel
|
||||||
|
targetContainer.getClass().lock(targetContainer,50);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, const MWWorld::Ptr& container,
|
||||||
|
int count)
|
||||||
|
{
|
||||||
|
if (ptr != MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
MWWorld::Ptr victim;
|
||||||
|
|
||||||
|
const MWWorld::CellRef* ownerCellRef = &item.getCellRef();
|
||||||
|
if (!container.isEmpty())
|
||||||
|
{
|
||||||
|
// Inherit the owner of the container
|
||||||
|
ownerCellRef = &container.getCellRef();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!item.getCellRef().hasContentFile())
|
||||||
|
{
|
||||||
|
// this is a manually placed item, which means it was already stolen
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAllowedToUse(ptr, *ownerCellRef, victim))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Owner owner;
|
||||||
|
owner.first = ownerCellRef->getOwner();
|
||||||
|
owner.second = false;
|
||||||
|
if (owner.first.empty())
|
||||||
|
{
|
||||||
|
owner.first = ownerCellRef->getFaction();
|
||||||
|
owner.second = true;
|
||||||
|
}
|
||||||
|
Misc::StringUtils::toLower(owner.first);
|
||||||
|
mStolenItems[Misc::StringUtils::lowerCase(item.getClass().getId(item))][owner] += count;
|
||||||
|
|
||||||
commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count);
|
commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -949,7 +1038,7 @@ namespace MWMechanics
|
||||||
// NOTE: victim may be empty
|
// NOTE: victim may be empty
|
||||||
|
|
||||||
// Only player can commit crime
|
// Only player can commit crime
|
||||||
if (player.getRefData().getHandle() != "player")
|
if (player != MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Find all the actors within the alarm radius
|
// Find all the actors within the alarm radius
|
||||||
|
@ -1351,22 +1440,37 @@ namespace MWMechanics
|
||||||
|
|
||||||
int MechanicsManager::countSavedGameRecords() const
|
int MechanicsManager::countSavedGameRecords() const
|
||||||
{
|
{
|
||||||
return 1; // Death counter
|
return 1 // Death counter
|
||||||
|
+1; // Stolen items
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::write(ESM::ESMWriter &writer, Loading::Listener &listener) const
|
void MechanicsManager::write(ESM::ESMWriter &writer, Loading::Listener &listener) const
|
||||||
{
|
{
|
||||||
mActors.write(writer, listener);
|
mActors.write(writer, listener);
|
||||||
|
|
||||||
|
ESM::StolenItems items;
|
||||||
|
items.mStolenItems = mStolenItems;
|
||||||
|
writer.startRecord(ESM::REC_STLN);
|
||||||
|
items.write(writer);
|
||||||
|
writer.endRecord(ESM::REC_STLN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::readRecord(ESM::ESMReader &reader, uint32_t type)
|
void MechanicsManager::readRecord(ESM::ESMReader &reader, uint32_t type)
|
||||||
{
|
{
|
||||||
mActors.readRecord(reader, type);
|
if (type == ESM::REC_STLN)
|
||||||
|
{
|
||||||
|
ESM::StolenItems items;
|
||||||
|
items.load(reader);
|
||||||
|
mStolenItems = items.mStolenItems;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mActors.readRecord(reader, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::clear()
|
void MechanicsManager::clear()
|
||||||
{
|
{
|
||||||
mActors.clear();
|
mActors.clear();
|
||||||
|
mStolenItems.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MechanicsManager::isAggressive(const MWWorld::Ptr &ptr, const MWWorld::Ptr &target)
|
bool MechanicsManager::isAggressive(const MWWorld::Ptr &ptr, const MWWorld::Ptr &target)
|
||||||
|
|
|
@ -35,6 +35,11 @@ namespace MWMechanics
|
||||||
Objects mObjects;
|
Objects mObjects;
|
||||||
Actors mActors;
|
Actors mActors;
|
||||||
|
|
||||||
|
typedef std::pair<std::string, bool> Owner; // < Owner id, bool isFaction >
|
||||||
|
typedef std::map<Owner, int> OwnerMap; // < Owner, number of stolen items with this id from this owner >
|
||||||
|
typedef std::map<std::string, OwnerMap> StolenItemsMap;
|
||||||
|
StolenItemsMap mStolenItems;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void buildPlayer();
|
void buildPlayer();
|
||||||
|
@ -121,16 +126,15 @@ namespace MWMechanics
|
||||||
/// @return false if the attack was considered a "friendly hit" and forgiven
|
/// @return false if the attack was considered a "friendly hit" and forgiven
|
||||||
virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker);
|
virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker);
|
||||||
/// Utility to check if taking this item is illegal and calling commitCrime if so
|
/// Utility to check if taking this item is illegal and calling commitCrime if so
|
||||||
virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count);
|
/// @param container The container the item is in; may be empty for an item in the world
|
||||||
|
virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container,
|
||||||
|
int count);
|
||||||
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so
|
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so
|
||||||
virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item);
|
virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item);
|
||||||
/// Attempt sleeping in a bed. If this is illegal, call commitCrime.
|
/// Attempt sleeping in a bed. If this is illegal, call commitCrime.
|
||||||
/// @return was it illegal, and someone saw you doing it? Also returns fail when enemies are nearby
|
/// @return was it illegal, and someone saw you doing it? Also returns fail when enemies are nearby
|
||||||
virtual bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed);
|
virtual bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed);
|
||||||
|
|
||||||
/// @return is \a ptr allowed to take/use \a item or is it a crime?
|
|
||||||
virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, MWWorld::Ptr& victim);
|
|
||||||
|
|
||||||
virtual void forceStateUpdate(const MWWorld::Ptr &ptr);
|
virtual void forceStateUpdate(const MWWorld::Ptr &ptr);
|
||||||
|
|
||||||
virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
|
virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
|
||||||
|
@ -168,9 +172,21 @@ namespace MWMechanics
|
||||||
|
|
||||||
virtual bool isReadyToBlock (const MWWorld::Ptr& ptr) const;
|
virtual bool isReadyToBlock (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
|
virtual void confiscateStolenItems (const MWWorld::Ptr& player, const MWWorld::Ptr& targetContainer);
|
||||||
|
|
||||||
|
/// List the owners that the player has stolen this item from (the owner can be an NPC or a faction).
|
||||||
|
/// <Owner, item count>
|
||||||
|
virtual std::vector<std::pair<std::string, int> > getStolenItemOwners(const std::string& itemid);
|
||||||
|
|
||||||
|
/// Has the player stolen this item from the given owner?
|
||||||
|
virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim,
|
void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim,
|
||||||
OffenseType type, int arg=0);
|
OffenseType type, int arg=0);
|
||||||
|
|
||||||
|
/// @return is \a ptr allowed to take/use \a cellref or is it a crime?
|
||||||
|
virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::CellRef& cellref, MWWorld::Ptr& victim);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,32 +125,9 @@ bool MWMechanics::NpcStats::isInFaction (const std::string& faction) const
|
||||||
return (mFactionRank.find(Misc::StringUtils::lowerCase(faction)) != mFactionRank.end());
|
return (mFactionRank.find(Misc::StringUtils::lowerCase(faction)) != mFactionRank.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& class_, int usageType,
|
float MWMechanics::NpcStats::getSkillProgressRequirement (int skillIndex, const ESM::Class& class_) const
|
||||||
int level, float extraFactor) const
|
|
||||||
{
|
{
|
||||||
if (level<0)
|
float progressRequirement = 1 + getSkill (skillIndex).getBase();
|
||||||
level = static_cast<int> (getSkill (skillIndex).getBase());
|
|
||||||
|
|
||||||
const ESM::Skill *skill =
|
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find (skillIndex);
|
|
||||||
|
|
||||||
float skillFactor = 1;
|
|
||||||
|
|
||||||
if (usageType>=4)
|
|
||||||
throw std::runtime_error ("skill usage type out of range");
|
|
||||||
|
|
||||||
if (usageType>=0)
|
|
||||||
{
|
|
||||||
skillFactor = skill->mData.mUseValue[usageType];
|
|
||||||
|
|
||||||
if (skillFactor<0)
|
|
||||||
throw std::runtime_error ("invalid skill gain factor");
|
|
||||||
|
|
||||||
if (skillFactor==0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
skillFactor *= extraFactor;
|
|
||||||
|
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
@ -173,11 +150,15 @@ float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& cla
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progressRequirement *= typeFactor;
|
||||||
|
|
||||||
if (typeFactor<=0)
|
if (typeFactor<=0)
|
||||||
throw std::runtime_error ("invalid skill type factor");
|
throw std::runtime_error ("invalid skill type factor");
|
||||||
|
|
||||||
float specialisationFactor = 1;
|
float specialisationFactor = 1;
|
||||||
|
|
||||||
|
const ESM::Skill *skill =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find (skillIndex);
|
||||||
if (skill->mData.mSpecialization==class_.mData.mSpecialization)
|
if (skill->mData.mSpecialization==class_.mData.mSpecialization)
|
||||||
{
|
{
|
||||||
specialisationFactor = gmst.find ("fSpecialSkillBonus")->getFloat();
|
specialisationFactor = gmst.find ("fSpecialSkillBonus")->getFloat();
|
||||||
|
@ -185,7 +166,9 @@ float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& cla
|
||||||
if (specialisationFactor<=0)
|
if (specialisationFactor<=0)
|
||||||
throw std::runtime_error ("invalid skill specialisation factor");
|
throw std::runtime_error ("invalid skill specialisation factor");
|
||||||
}
|
}
|
||||||
return 1.0 / ((level+1) * (1.0/skillFactor) * typeFactor * specialisationFactor);
|
progressRequirement *= specialisationFactor;
|
||||||
|
|
||||||
|
return progressRequirement;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, int usageType, float extraFactor)
|
void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, int usageType, float extraFactor)
|
||||||
|
@ -194,13 +177,26 @@ void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_,
|
||||||
if(mIsWerewolf)
|
if(mIsWerewolf)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const ESM::Skill *skill =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find (skillIndex);
|
||||||
|
float skillGain = 1;
|
||||||
|
if (usageType>=4)
|
||||||
|
throw std::runtime_error ("skill usage type out of range");
|
||||||
|
if (usageType>=0)
|
||||||
|
{
|
||||||
|
skillGain = skill->mData.mUseValue[usageType];
|
||||||
|
if (skillGain<0)
|
||||||
|
throw std::runtime_error ("invalid skill gain factor");
|
||||||
|
}
|
||||||
|
skillGain *= extraFactor;
|
||||||
|
|
||||||
MWMechanics::SkillValue& value = getSkill (skillIndex);
|
MWMechanics::SkillValue& value = getSkill (skillIndex);
|
||||||
|
|
||||||
value.setProgress(value.getProgress() + getSkillGain (skillIndex, class_, usageType, -1, extraFactor));
|
value.setProgress(value.getProgress() + skillGain);
|
||||||
|
|
||||||
if (value.getProgress()>=1)
|
if (int(value.getProgress())>=int(getSkillProgressRequirement(skillIndex, class_)))
|
||||||
{
|
{
|
||||||
// skill leveled up
|
// skill levelled up
|
||||||
increaseSkill(skillIndex, class_, false);
|
increaseSkill(skillIndex, class_, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,7 +252,7 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas
|
||||||
MWBase::Environment::get().getWindowManager ()->messageBox ("#{sLevelUpMsg}", MWGui::ShowInDialogueMode_Never);
|
MWBase::Environment::get().getWindowManager ()->messageBox ("#{sLevelUpMsg}", MWGui::ShowInDialogueMode_Never);
|
||||||
}
|
}
|
||||||
|
|
||||||
getSkill (skillIndex).setBase (base);
|
getSkill(skillIndex).setBase (base);
|
||||||
if (!preserveProgress)
|
if (!preserveProgress)
|
||||||
getSkill(skillIndex).setProgress(0);
|
getSkill(skillIndex).setProgress(0);
|
||||||
}
|
}
|
||||||
|
@ -268,13 +264,15 @@ int MWMechanics::NpcStats::getLevelProgress () const
|
||||||
|
|
||||||
void MWMechanics::NpcStats::levelUp()
|
void MWMechanics::NpcStats::levelUp()
|
||||||
{
|
{
|
||||||
mLevelProgress -= 10;
|
|
||||||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
|
||||||
mSkillIncreases[i] = 0;
|
|
||||||
|
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
|
mLevelProgress -= gmst.find("iLevelUpTotal")->getInt();
|
||||||
|
mLevelProgress = std::max(0, mLevelProgress); // might be necessary when levelup was invoked via console
|
||||||
|
|
||||||
|
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||||
|
mSkillIncreases[i] = 0;
|
||||||
|
|
||||||
const int endurance = getAttribute(ESM::Attribute::Endurance).getBase();
|
const int endurance = getAttribute(ESM::Attribute::Endurance).getBase();
|
||||||
|
|
||||||
// "When you gain a level, in addition to increasing three primary attributes, your Health
|
// "When you gain a level, in addition to increasing three primary attributes, your Health
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace MWMechanics
|
||||||
class NpcStats : public CreatureStats
|
class NpcStats : public CreatureStats
|
||||||
{
|
{
|
||||||
int mDisposition;
|
int mDisposition;
|
||||||
SkillValue mSkill[ESM::Skill::Length];
|
SkillValue mSkill[ESM::Skill::Length]; // SkillValue.mProgress used by the player only
|
||||||
SkillValue mWerewolfSkill[ESM::Skill::Length];
|
SkillValue mWerewolfSkill[ESM::Skill::Length];
|
||||||
int mReputation;
|
int mReputation;
|
||||||
int mCrimeId;
|
int mCrimeId;
|
||||||
|
@ -74,11 +74,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
bool isInFaction (const std::string& faction) const;
|
bool isInFaction (const std::string& faction) const;
|
||||||
|
|
||||||
float getSkillGain (int skillIndex, const ESM::Class& class_, int usageType = -1,
|
float getSkillProgressRequirement (int skillIndex, const ESM::Class& class_) const;
|
||||||
int level = -1, float extraFactor=1.f) const;
|
|
||||||
///< \param usageType: Usage specific factor, specified in the respective skill record;
|
|
||||||
/// -1: use a factor of 1.0 instead.
|
|
||||||
/// \param level Level to base calculation on; -1: use current level.
|
|
||||||
|
|
||||||
void useSkill (int skillIndex, const ESM::Class& class_, int usageType = -1, float extraFactor=1.f);
|
void useSkill (int skillIndex, const ESM::Class& class_, int usageType = -1, float extraFactor=1.f);
|
||||||
///< Increase skill by usage.
|
///< Increase skill by usage.
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <components/esm/loadench.hpp>
|
#include <components/esm/loadench.hpp>
|
||||||
#include <components/esm/loadstat.hpp>
|
#include <components/esm/loadstat.hpp>
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include <libs/openengine/ogre/lights.hpp>
|
#include <libs/openengine/ogre/lights.hpp>
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <OgreHardwarePixelBuffer.h>
|
#include <OgreHardwarePixelBuffer.h>
|
||||||
|
|
||||||
#include <components/loadinglistener/loadinglistener.hpp>
|
#include <components/loadinglistener/loadinglistener.hpp>
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include <components/esm/globalmap.hpp>
|
#include <components/esm/globalmap.hpp>
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "animationextensions.hpp"
|
#include "animationextensions.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include <components/compiler/extensions.hpp>
|
#include <components/compiler/extensions.hpp>
|
||||||
#include <components/compiler/opcodes.hpp>
|
#include <components/compiler/opcodes.hpp>
|
||||||
|
|
|
@ -34,24 +34,24 @@
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
void addToLevList(ESM::LeveledListBase* list, const std::string& itemId, int level)
|
void addToLevList(ESM::LevelledListBase* list, const std::string& itemId, int level)
|
||||||
{
|
{
|
||||||
for (std::vector<ESM::LeveledListBase::LevelItem>::iterator it = list->mList.begin(); it != list->mList.end();)
|
for (std::vector<ESM::LevelledListBase::LevelItem>::iterator it = list->mList.begin(); it != list->mList.end();)
|
||||||
{
|
{
|
||||||
if (it->mLevel == level && itemId == it->mId)
|
if (it->mLevel == level && itemId == it->mId)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESM::LeveledListBase::LevelItem item;
|
ESM::LevelledListBase::LevelItem item;
|
||||||
item.mId = itemId;
|
item.mId = itemId;
|
||||||
item.mLevel = level;
|
item.mLevel = level;
|
||||||
list->mList.push_back(item);
|
list->mList.push_back(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeFromLevList(ESM::LeveledListBase* list, const std::string& itemId, int level)
|
void removeFromLevList(ESM::LevelledListBase* list, const std::string& itemId, int level)
|
||||||
{
|
{
|
||||||
// level of -1 removes all items with that itemId
|
// level of -1 removes all items with that itemId
|
||||||
for (std::vector<ESM::LeveledListBase::LevelItem>::iterator it = list->mList.begin(); it != list->mList.end();)
|
for (std::vector<ESM::LevelledListBase::LevelItem>::iterator it = list->mList.begin(); it != list->mList.end();)
|
||||||
{
|
{
|
||||||
if (level != -1 && it->mLevel != level)
|
if (level != -1 && it->mLevel != level)
|
||||||
{
|
{
|
||||||
|
|
|
@ -348,29 +348,12 @@ namespace MWScript
|
||||||
|
|
||||||
MWMechanics::NpcStats& stats = ptr.getClass().getNpcStats (ptr);
|
MWMechanics::NpcStats& stats = ptr.getClass().getNpcStats (ptr);
|
||||||
|
|
||||||
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
|
||||||
|
|
||||||
assert (ref);
|
|
||||||
|
|
||||||
const ESM::Class& class_ =
|
|
||||||
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find (ref->mBase->mClass);
|
|
||||||
|
|
||||||
float level = stats.getSkill(mIndex).getBase();
|
|
||||||
float progress = stats.getSkill(mIndex).getProgress();
|
|
||||||
|
|
||||||
int newLevel = value - (stats.getSkill(mIndex).getModified() - stats.getSkill(mIndex).getBase());
|
int newLevel = value - (stats.getSkill(mIndex).getModified() - stats.getSkill(mIndex).getBase());
|
||||||
|
|
||||||
if (newLevel<0)
|
if (newLevel<0)
|
||||||
newLevel = 0;
|
newLevel = 0;
|
||||||
|
|
||||||
progress = (progress / stats.getSkillGain (mIndex, class_, -1, level))
|
|
||||||
* stats.getSkillGain (mIndex, class_, -1, newLevel);
|
|
||||||
|
|
||||||
if (progress>=1)
|
|
||||||
progress = 0.999999999;
|
|
||||||
|
|
||||||
stats.getSkill (mIndex).setBase (newLevel);
|
stats.getSkill (mIndex).setBase (newLevel);
|
||||||
stats.getSkill (mIndex).setProgress(progress);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -691,10 +691,10 @@ namespace MWScript
|
||||||
if (!ptr.getRefData().getBaseNode())
|
if (!ptr.getRefData().getBaseNode())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Ogre::Vector3 worldPos = ptr.getRefData().getBaseNode()->convertLocalToWorldPosition(posChange);
|
Ogre::Vector3 diff = ptr.getRefData().getBaseNode()->getOrientation() * posChange;
|
||||||
|
Ogre::Vector3 worldPos(ptr.getRefData().getPosition().pos);
|
||||||
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(
|
worldPos += diff;
|
||||||
MWBase::Environment::get().getWorld()->moveObject(ptr, worldPos.x, worldPos.y, worldPos.z));
|
MWBase::Environment::get().getWorld()->moveObject(ptr, worldPos.x, worldPos.y, worldPos.z);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <OgreImage.h>
|
#include <OgreImage.h>
|
||||||
|
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
|
#include <boost/filesystem/operations.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
@ -420,6 +421,7 @@ void MWState::StateManager::loadGame (const Character *character, const std::str
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ESM::REC_DCOU:
|
case ESM::REC_DCOU:
|
||||||
|
case ESM::REC_STLN:
|
||||||
|
|
||||||
MWBase::Environment::get().getMechanicsManager()->readRecord(reader, n.val);
|
MWBase::Environment::get().getMechanicsManager()->readRecord(reader, n.val);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace MWWorld
|
||||||
void ActionTake::executeImp (const Ptr& actor)
|
void ActionTake::executeImp (const Ptr& actor)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getMechanicsManager()->itemTaken(
|
MWBase::Environment::get().getMechanicsManager()->itemTaken(
|
||||||
actor, getTarget(), getTarget().getRefData().getCount());
|
actor, getTarget(), MWWorld::Ptr(), getTarget().getRefData().getCount());
|
||||||
actor.getClass().getContainerStore (actor).add (getTarget(), getTarget().getRefData().getCount(), actor);
|
actor.getClass().getContainerStore (actor).add (getTarget(), getTarget().getRefData().getCount(), actor);
|
||||||
MWBase::Environment::get().getWorld()->deleteObject (getTarget());
|
MWBase::Environment::get().getWorld()->deleteObject (getTarget());
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,15 @@ namespace MWWorld
|
||||||
return mCellRef.mGlobalVariable;
|
return mCellRef.mGlobalVariable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CellRef::resetGlobalVariable()
|
||||||
|
{
|
||||||
|
if (!mCellRef.mGlobalVariable.empty())
|
||||||
|
{
|
||||||
|
mChanged = true;
|
||||||
|
mCellRef.mGlobalVariable.erase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CellRef::setFactionRank(int factionRank)
|
void CellRef::setFactionRank(int factionRank)
|
||||||
{
|
{
|
||||||
if (factionRank != mCellRef.mFactionRank)
|
if (factionRank != mCellRef.mFactionRank)
|
||||||
|
|
|
@ -75,6 +75,8 @@ namespace MWWorld
|
||||||
// Used by bed rent scripts to allow the player to use the bed for the duration of the rent.
|
// Used by bed rent scripts to allow the player to use the bed for the duration of the rent.
|
||||||
std::string getGlobalVariable() const;
|
std::string getGlobalVariable() const;
|
||||||
|
|
||||||
|
void resetGlobalVariable();
|
||||||
|
|
||||||
// ID of creature trapped in this soul gem
|
// ID of creature trapped in this soul gem
|
||||||
std::string getSoul() const;
|
std::string getSoul() const;
|
||||||
void setSoul(const std::string& soul);
|
void setSoul(const std::string& soul);
|
||||||
|
|
|
@ -80,6 +80,8 @@ namespace MWWorld
|
||||||
virtual std::string getId (const Ptr& ptr) const;
|
virtual std::string getId (const Ptr& ptr) const;
|
||||||
///< Return ID of \a ptr or throw an exception, if class does not support ID retrieval
|
///< Return ID of \a ptr or throw an exception, if class does not support ID retrieval
|
||||||
/// (default implementation: throw an exception)
|
/// (default implementation: throw an exception)
|
||||||
|
/// @note This function is currently redundant; the same ID can be retrieved by CellRef::getRefId.
|
||||||
|
/// Leaving it here for now in case we want to optimize later.
|
||||||
|
|
||||||
virtual void insertObjectRendering (const Ptr& ptr, const std::string& mesh, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const Ptr& ptr, const std::string& mesh, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
virtual void insertObject(const Ptr& ptr, const std::string& mesh, MWWorld::PhysicsSystem& physics) const;
|
virtual void insertObject(const Ptr& ptr, const std::string& mesh, MWWorld::PhysicsSystem& physics) const;
|
||||||
|
|
|
@ -222,29 +222,22 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr
|
||||||
|
|
||||||
MWWorld::ContainerStoreIterator it = end();
|
MWWorld::ContainerStoreIterator it = end();
|
||||||
|
|
||||||
if (setOwner && actorPtr.getClass().isActor())
|
// HACK: Set owner on the original item, then reset it after we have copied it
|
||||||
|
// If we set the owner on the copied item, it would not stack correctly...
|
||||||
|
std::string oldOwner = itemPtr.getCellRef().getOwner();
|
||||||
|
if (!setOwner || actorPtr == MWBase::Environment::get().getWorld()->getPlayerPtr()) // No point in setting owner to the player - NPCs will not respect this anyway
|
||||||
{
|
{
|
||||||
// HACK: Set owner on the original item, then reset it after we have copied it
|
itemPtr.getCellRef().setOwner("");
|
||||||
// If we set the owner on the copied item, it would not stack correctly...
|
|
||||||
std::string oldOwner = itemPtr.getCellRef().getOwner();
|
|
||||||
if (actorPtr == player)
|
|
||||||
{
|
|
||||||
// No point in setting owner to the player - NPCs will not respect this anyway
|
|
||||||
// Additionally, setting it to "player" would make those items not stack with items that don't have an owner
|
|
||||||
itemPtr.getCellRef().setOwner("");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
itemPtr.getCellRef().setOwner(actorPtr.getCellRef().getRefId());
|
|
||||||
|
|
||||||
it = addImp(itemPtr, count);
|
|
||||||
|
|
||||||
itemPtr.getCellRef().setOwner(oldOwner);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
it = addImp(itemPtr, count);
|
itemPtr.getCellRef().setOwner(actorPtr.getCellRef().getRefId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it = addImp(itemPtr, count);
|
||||||
|
|
||||||
|
itemPtr.getCellRef().setOwner(oldOwner);
|
||||||
|
|
||||||
// The copy of the original item we just made
|
// The copy of the original item we just made
|
||||||
MWWorld::Ptr item = *it;
|
MWWorld::Ptr item = *it;
|
||||||
|
|
||||||
|
@ -258,6 +251,14 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr
|
||||||
pos.pos[1] = 0;
|
pos.pos[1] = 0;
|
||||||
pos.pos[2] = 0;
|
pos.pos[2] = 0;
|
||||||
item.getCellRef().setPosition(pos);
|
item.getCellRef().setPosition(pos);
|
||||||
|
|
||||||
|
// reset ownership stuff, owner was already handled above
|
||||||
|
item.getCellRef().resetGlobalVariable();
|
||||||
|
item.getCellRef().setFaction("");
|
||||||
|
item.getCellRef().setFactionRank(-1);
|
||||||
|
|
||||||
|
// must reset the RefNum on the copied item, so that the RefNum on the original item stays unique
|
||||||
|
// maybe we should do this in the copy constructor instead?
|
||||||
item.getCellRef().unsetRefNum(); // destroy link to content file
|
item.getCellRef().unsetRefNum(); // destroy link to content file
|
||||||
|
|
||||||
std::string script = item.getClass().getScript(item);
|
std::string script = item.getClass().getScript(item);
|
||||||
|
@ -399,19 +400,19 @@ int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor
|
||||||
return count - toRemove;
|
return count - toRemove;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std::string& owner, const std::string& faction, int factionRank, const MWWorld::ESMStore& store)
|
void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std::string& owner)
|
||||||
{
|
{
|
||||||
for (std::vector<ESM::ContItem>::const_iterator iter (items.mList.begin()); iter!=items.mList.end();
|
for (std::vector<ESM::ContItem>::const_iterator iter (items.mList.begin()); iter!=items.mList.end();
|
||||||
++iter)
|
++iter)
|
||||||
{
|
{
|
||||||
std::string id = Misc::StringUtils::lowerCase(iter->mItem.toString());
|
std::string id = Misc::StringUtils::lowerCase(iter->mItem.toString());
|
||||||
addInitialItem(id, owner, faction, factionRank, iter->mCount);
|
addInitialItem(id, owner, iter->mCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
flagAsModified();
|
flagAsModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner, const std::string& faction, int factionRank,
|
void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner,
|
||||||
int count, bool topLevel, const std::string& levItem)
|
int count, bool topLevel, const std::string& levItem)
|
||||||
{
|
{
|
||||||
ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id, count);
|
ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id, count);
|
||||||
|
@ -423,7 +424,7 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::
|
||||||
if (topLevel && std::abs(count) > 1 && levItem->mFlags & ESM::ItemLevList::Each)
|
if (topLevel && std::abs(count) > 1 && levItem->mFlags & ESM::ItemLevList::Each)
|
||||||
{
|
{
|
||||||
for (int i=0; i<std::abs(count); ++i)
|
for (int i=0; i<std::abs(count); ++i)
|
||||||
addInitialItem(id, owner, faction, factionRank, count > 0 ? 1 : -1, true, levItem->mId);
|
addInitialItem(id, owner, count > 0 ? 1 : -1, true, levItem->mId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -431,7 +432,7 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::
|
||||||
std::string id = MWMechanics::getLevelledItem(ref.getPtr().get<ESM::ItemLevList>()->mBase, false);
|
std::string id = MWMechanics::getLevelledItem(ref.getPtr().get<ESM::ItemLevList>()->mBase, false);
|
||||||
if (id.empty())
|
if (id.empty())
|
||||||
return;
|
return;
|
||||||
addInitialItem(id, owner, faction, factionRank, count, false, levItem->mId);
|
addInitialItem(id, owner, count, false, levItem->mId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -447,13 +448,11 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::
|
||||||
count = std::abs(count);
|
count = std::abs(count);
|
||||||
|
|
||||||
ref.getPtr().getCellRef().setOwner(owner);
|
ref.getPtr().getCellRef().setOwner(owner);
|
||||||
ref.getPtr().getCellRef().setFaction(faction);
|
|
||||||
ref.getPtr().getCellRef().setFactionRank(factionRank);
|
|
||||||
addImp (ref.getPtr(), count);
|
addImp (ref.getPtr(), count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWWorld::ContainerStore::restock (const ESM::InventoryList& items, const MWWorld::Ptr& ptr, const std::string& owner, const std::string& faction, int factionRank)
|
void MWWorld::ContainerStore::restock (const ESM::InventoryList& items, const MWWorld::Ptr& ptr, const std::string& owner)
|
||||||
{
|
{
|
||||||
// Remove the items already spawned by levelled items that will restock
|
// Remove the items already spawned by levelled items that will restock
|
||||||
for (std::map<std::string, int>::iterator it = mLevelledItemMap.begin(); it != mLevelledItemMap.end(); ++it)
|
for (std::map<std::string, int>::iterator it = mLevelledItemMap.begin(); it != mLevelledItemMap.end(); ++it)
|
||||||
|
@ -472,13 +471,13 @@ void MWWorld::ContainerStore::restock (const ESM::InventoryList& items, const MW
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWorld()->getStore().get<ESM::ItemLevList>().search(it->mItem.toString()))
|
if (MWBase::Environment::get().getWorld()->getStore().get<ESM::ItemLevList>().search(it->mItem.toString()))
|
||||||
{
|
{
|
||||||
addInitialItem(item, owner, faction, factionRank, it->mCount, true);
|
addInitialItem(item, owner, it->mCount, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int currentCount = count(item);
|
int currentCount = count(item);
|
||||||
if (currentCount < std::abs(it->mCount))
|
if (currentCount < std::abs(it->mCount))
|
||||||
addInitialItem(item, owner, faction, factionRank, std::abs(it->mCount) - currentCount, true);
|
addInitialItem(item, owner, std::abs(it->mCount) - currentCount, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
flagAsModified();
|
flagAsModified();
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace MWWorld
|
||||||
mutable float mCachedWeight;
|
mutable float mCachedWeight;
|
||||||
mutable bool mWeightUpToDate;
|
mutable bool mWeightUpToDate;
|
||||||
ContainerStoreIterator addImp (const Ptr& ptr, int count);
|
ContainerStoreIterator addImp (const Ptr& ptr, int count);
|
||||||
void addInitialItem (const std::string& id, const std::string& owner, const std::string& faction, int factionRank, int count, bool topLevel=true, const std::string& levItem = "");
|
void addInitialItem (const std::string& id, const std::string& owner, int count, bool topLevel=true, const std::string& levItem = "");
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ContainerStoreIterator getState (CellRefList<T>& collection,
|
ContainerStoreIterator getState (CellRefList<T>& collection,
|
||||||
|
@ -112,7 +112,7 @@ namespace MWWorld
|
||||||
/// \attention Do not add items to an existing stack by increasing the count instead of
|
/// \attention Do not add items to an existing stack by increasing the count instead of
|
||||||
/// calling this function!
|
/// calling this function!
|
||||||
///
|
///
|
||||||
/// @param setOwner Set the owner of the added item to \a actorPtr?
|
/// @param setOwner Set the owner of the added item to \a actorPtr? If false, the owner is reset to "".
|
||||||
///
|
///
|
||||||
/// @return if stacking happened, return iterator to the item that was stacked against, otherwise iterator to the newly inserted item.
|
/// @return if stacking happened, return iterator to the item that was stacked against, otherwise iterator to the newly inserted item.
|
||||||
|
|
||||||
|
@ -151,10 +151,10 @@ namespace MWWorld
|
||||||
virtual bool stacks (const Ptr& ptr1, const Ptr& ptr2);
|
virtual bool stacks (const Ptr& ptr1, const Ptr& ptr2);
|
||||||
///< @return true if the two specified objects can stack with each other
|
///< @return true if the two specified objects can stack with each other
|
||||||
|
|
||||||
void fill (const ESM::InventoryList& items, const std::string& owner, const std::string& faction, int factionRank, const MWWorld::ESMStore& store);
|
void fill (const ESM::InventoryList& items, const std::string& owner);
|
||||||
///< Insert items into *this.
|
///< Insert items into *this.
|
||||||
|
|
||||||
void restock (const ESM::InventoryList& items, const MWWorld::Ptr& ptr, const std::string& owner, const std::string& faction, int factionRank);
|
void restock (const ESM::InventoryList& items, const MWWorld::Ptr& ptr, const std::string& owner);
|
||||||
|
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
///< Empty container.
|
///< Empty container.
|
||||||
|
|
|
@ -133,12 +133,11 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr,
|
||||||
const MWWorld::ContainerStoreIterator& retVal = MWWorld::ContainerStore::add(itemPtr, count, actorPtr, setOwner);
|
const MWWorld::ContainerStoreIterator& retVal = MWWorld::ContainerStore::add(itemPtr, count, actorPtr, setOwner);
|
||||||
|
|
||||||
// Auto-equip items if an armor/clothing or weapon item is added, but not for the player nor werewolves
|
// Auto-equip items if an armor/clothing or weapon item is added, but not for the player nor werewolves
|
||||||
if ((actorPtr.getRefData().getHandle() != "player")
|
if (actorPtr.getRefData().getHandle() != "player"
|
||||||
&& !(actorPtr.getClass().isNpc() && actorPtr.getClass().getNpcStats(actorPtr).isWerewolf())
|
&& !(actorPtr.getClass().isNpc() && actorPtr.getClass().getNpcStats(actorPtr).isWerewolf()))
|
||||||
&& !actorPtr.getClass().getCreatureStats(actorPtr).isDead())
|
|
||||||
{
|
{
|
||||||
std::string type = itemPtr.getTypeName();
|
std::string type = itemPtr.getTypeName();
|
||||||
if ((type == typeid(ESM::Armor).name()) || (type == typeid(ESM::Clothing).name()) || (type == typeid(ESM::Weapon).name()))
|
if (type == typeid(ESM::Armor).name() || type == typeid(ESM::Clothing).name())
|
||||||
autoEquip(actorPtr);
|
autoEquip(actorPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +233,9 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
|
||||||
// ...unless this is a companion, he should always equip items given to him.
|
// ...unless this is a companion, he should always equip items given to him.
|
||||||
if (!Misc::StringUtils::ciEqual(test.getCellRef().getOwner(), actor.getCellRef().getRefId()) &&
|
if (!Misc::StringUtils::ciEqual(test.getCellRef().getOwner(), actor.getCellRef().getRefId()) &&
|
||||||
(actor.getClass().getScript(actor).empty() ||
|
(actor.getClass().getScript(actor).empty() ||
|
||||||
!actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion")))
|
!actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion"))
|
||||||
|
&& !actor.getClass().getCreatureStats(actor).isDead() // Corpses can be dressed up by the player as desired
|
||||||
|
)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -506,8 +507,7 @@ int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor
|
||||||
&& !(actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()))
|
&& !(actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()))
|
||||||
{
|
{
|
||||||
std::string type = item.getTypeName();
|
std::string type = item.getTypeName();
|
||||||
if (((type == typeid(ESM::Armor).name()) || (type == typeid(ESM::Clothing).name()))
|
if (type == typeid(ESM::Armor).name() || type == typeid(ESM::Clothing).name())
|
||||||
&& !actor.getClass().getCreatureStats(actor).isDead())
|
|
||||||
autoEquip(actor);
|
autoEquip(actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
#include "livecellref.hpp"
|
#include "livecellref.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include <components/esm/objectstate.hpp>
|
#include <components/esm/objectstate.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
|
@ -260,9 +260,20 @@ namespace MWWorld
|
||||||
mCellStore = world.getExterior(0,0);
|
mCellStore = world.getExterior(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!player.mBirthsign.empty() &&
|
if (!player.mBirthsign.empty())
|
||||||
!world.getStore().get<ESM::BirthSign>().search (player.mBirthsign))
|
{
|
||||||
throw std::runtime_error ("invalid player state record (birthsign)");
|
const ESM::BirthSign* sign = world.getStore().get<ESM::BirthSign>().search (player.mBirthsign);
|
||||||
|
if (!sign)
|
||||||
|
throw std::runtime_error ("invalid player state record (birthsign does not exist)");
|
||||||
|
|
||||||
|
// To handle the case where a birth sign was edited in between play sessions (does not yet handle removing the old spells)
|
||||||
|
// Also needed for ess-imported savegames which do not specify the birtsign spells in the player's spell list.
|
||||||
|
for (std::vector<std::string>::const_iterator iter (sign->mPowers.mList.begin());
|
||||||
|
iter!=sign->mPowers.mList.end(); ++iter)
|
||||||
|
{
|
||||||
|
getPlayer().getClass().getCreatureStats(getPlayer()).getSpells().add (*iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mCurrentCrimeId = player.mCurrentCrimeId;
|
mCurrentCrimeId = player.mCurrentCrimeId;
|
||||||
mPaidCrimeId = player.mPaidCrimeId;
|
mPaidCrimeId = player.mPaidCrimeId;
|
||||||
|
|
|
@ -2988,18 +2988,10 @@ namespace MWWorld
|
||||||
|
|
||||||
if (!closestChest.isEmpty()) //Found a close chest
|
if (!closestChest.isEmpty()) //Found a close chest
|
||||||
{
|
{
|
||||||
ContainerStore& store = ptr.getClass().getContainerStore(ptr);
|
MWBase::Environment::get().getMechanicsManager()->confiscateStolenItems(ptr, closestChest);
|
||||||
for (ContainerStoreIterator it = store.begin(); it != store.end(); ++it) //Move all stolen stuff into chest
|
|
||||||
{
|
|
||||||
MWWorld::Ptr dummy;
|
|
||||||
if (!MWBase::Environment::get().getMechanicsManager()->isAllowedToUse(getPlayerPtr(), *it, dummy))
|
|
||||||
{
|
|
||||||
closestChest.getClass().getContainerStore(closestChest).add(*it, it->getRefData().getCount(), closestChest);
|
|
||||||
store.remove(*it, it->getRefData().getCount(), ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closestChest.getClass().lock(closestChest,50);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
std::cerr << "Failed to confiscate items: no stolen_goods container found" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::goToJail()
|
void World::goToJail()
|
||||||
|
|
|
@ -63,7 +63,7 @@ add_component_dir (esm
|
||||||
loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter
|
loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter
|
||||||
savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap inventorystate containerstate npcstate creaturestate dialoguestate statstate
|
savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap inventorystate containerstate npcstate creaturestate dialoguestate statstate
|
||||||
npcstats creaturestats weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate debugprofile
|
npcstats creaturestats weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate debugprofile
|
||||||
aisequence magiceffects util custommarkerstate
|
aisequence magiceffects util custommarkerstate stolenitems
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (esmterrain
|
add_component_dir (esmterrain
|
||||||
|
|
|
@ -15,8 +15,7 @@ ContentSelectorModel::ContentModel::ContentModel(QObject *parent, QIcon warningI
|
||||||
mMimeType ("application/omwcontent"),
|
mMimeType ("application/omwcontent"),
|
||||||
mMimeTypes (QStringList() << mMimeType),
|
mMimeTypes (QStringList() << mMimeType),
|
||||||
mColumnCount (1),
|
mColumnCount (1),
|
||||||
mDragDropFlags (Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled),
|
mDropActions (Qt::MoveAction)
|
||||||
mDropActions (Qt::CopyAction | Qt::MoveAction)
|
|
||||||
{
|
{
|
||||||
setEncoding ("win1252");
|
setEncoding ("win1252");
|
||||||
uncheckAll();
|
uncheckAll();
|
||||||
|
@ -104,7 +103,7 @@ QModelIndex ContentSelectorModel::ContentModel::indexFromItem(const EsmFile *ite
|
||||||
Qt::ItemFlags ContentSelectorModel::ContentModel::flags(const QModelIndex &index) const
|
Qt::ItemFlags ContentSelectorModel::ContentModel::flags(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return Qt::NoItemFlags;
|
return Qt::ItemIsDropEnabled;
|
||||||
|
|
||||||
const EsmFile *file = item(index.row());
|
const EsmFile *file = item(index.row());
|
||||||
|
|
||||||
|
@ -152,7 +151,7 @@ Qt::ItemFlags ContentSelectorModel::ContentModel::flags(const QModelIndex &index
|
||||||
if (gamefileChecked)
|
if (gamefileChecked)
|
||||||
{
|
{
|
||||||
if (allDependenciesFound)
|
if (allDependenciesFound)
|
||||||
returnFlags = returnFlags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | mDragDropFlags;
|
returnFlags = returnFlags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled;
|
||||||
else
|
else
|
||||||
returnFlags = Qt::ItemIsSelectable;
|
returnFlags = Qt::ItemIsSelectable;
|
||||||
}
|
}
|
||||||
|
@ -443,11 +442,6 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path)
|
||||||
filters << "*.esp" << "*.esm" << "*.omwgame" << "*.omwaddon";
|
filters << "*.esp" << "*.esm" << "*.omwgame" << "*.omwaddon";
|
||||||
dir.setNameFilters(filters);
|
dir.setNameFilters(filters);
|
||||||
|
|
||||||
QTextCodec *codec = QTextCodec::codecForName("UTF8");
|
|
||||||
|
|
||||||
// Create a decoder for non-latin characters in esx metadata
|
|
||||||
QTextDecoder *decoder = codec->makeDecoder();
|
|
||||||
|
|
||||||
foreach (const QString &path, dir.entryList())
|
foreach (const QString &path, dir.entryList())
|
||||||
{
|
{
|
||||||
QFileInfo info(dir.absoluteFilePath(path));
|
QFileInfo info(dir.absoluteFilePath(path));
|
||||||
|
@ -467,11 +461,11 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path)
|
||||||
foreach (const ESM::Header::MasterData &item, fileReader.getGameFiles())
|
foreach (const ESM::Header::MasterData &item, fileReader.getGameFiles())
|
||||||
file->addGameFile(QString::fromStdString(item.name));
|
file->addGameFile(QString::fromStdString(item.name));
|
||||||
|
|
||||||
file->setAuthor (decoder->toUnicode(fileReader.getAuthor().c_str()));
|
file->setAuthor (QString::fromUtf8(fileReader.getAuthor().c_str()));
|
||||||
file->setDate (info.lastModified());
|
file->setDate (info.lastModified());
|
||||||
file->setFormat (fileReader.getFormat());
|
file->setFormat (fileReader.getFormat());
|
||||||
file->setFilePath (info.absoluteFilePath());
|
file->setFilePath (info.absoluteFilePath());
|
||||||
file->setDescription(decoder->toUnicode(fileReader.getDesc().c_str()));
|
file->setDescription(QString::fromUtf8(fileReader.getDesc().c_str()));
|
||||||
|
|
||||||
// Put the file in the table
|
// Put the file in the table
|
||||||
addFile(file);
|
addFile(file);
|
||||||
|
@ -484,8 +478,6 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete decoder;
|
|
||||||
|
|
||||||
sortFiles();
|
sortFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,6 @@ namespace ContentSelectorModel
|
||||||
QString mMimeType;
|
QString mMimeType;
|
||||||
QStringList mMimeTypes;
|
QStringList mMimeTypes;
|
||||||
int mColumnCount;
|
int mColumnCount;
|
||||||
Qt::ItemFlags mDragDropFlags;
|
|
||||||
Qt::DropActions mDropActions;
|
Qt::DropActions mDropActions;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent) :
|
ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent) :
|
||||||
QObject(parent)
|
QObject(parent)
|
||||||
{
|
{
|
||||||
ui.setupUi (parent);
|
ui.setupUi(parent);
|
||||||
|
ui.addonView->setDragDropMode(QAbstractItemView::InternalMove);
|
||||||
|
|
||||||
buildContentModel();
|
buildContentModel();
|
||||||
buildGameFileView();
|
buildGameFileView();
|
||||||
|
|
|
@ -117,6 +117,7 @@ enum RecNameInts
|
||||||
REC_MARK = FourCC<'M','A','R','K'>::value,
|
REC_MARK = FourCC<'M','A','R','K'>::value,
|
||||||
REC_ENAB = FourCC<'E','N','A','B'>::value,
|
REC_ENAB = FourCC<'E','N','A','B'>::value,
|
||||||
REC_CAM_ = FourCC<'C','A','M','_'>::value,
|
REC_CAM_ = FourCC<'C','A','M','_'>::value,
|
||||||
|
REC_STLN = FourCC<'S','T','L','N'>::value,
|
||||||
|
|
||||||
// format 1
|
// format 1
|
||||||
REC_FILT = FourCC<'F','I','L','T'>::value,
|
REC_FILT = FourCC<'F','I','L','T'>::value,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
|
|
||||||
void LeveledListBase::load(ESMReader &esm)
|
void LevelledListBase::load(ESMReader &esm)
|
||||||
{
|
{
|
||||||
esm.getHNT(mFlags, "DATA");
|
esm.getHNT(mFlags, "DATA");
|
||||||
esm.getHNT(mChanceNone, "NNAM");
|
esm.getHNT(mChanceNone, "NNAM");
|
||||||
|
@ -19,13 +19,17 @@ void LeveledListBase::load(ESMReader &esm)
|
||||||
mList.resize(len);
|
mList.resize(len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
esm.skipRecord();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Merge with an existing lists here. This can be done
|
// If this levelled list was already loaded by a previous content file,
|
||||||
// simply by adding the lists together, making sure that they are
|
// we overwrite the list. Merging lists should probably be left to external tools,
|
||||||
// sorted by level. A better way might be to exclude repeated
|
// with the limited amount of information there is in the records, all merging methods
|
||||||
// items. Also, some times we don't want to merge lists, just
|
// will be flawed in some way. For a proper fix the ESM format would have to be changed
|
||||||
// overwrite. Figure out a way to give the user this option.
|
// to actually track list changes instead of including the whole list for every file
|
||||||
|
// that does something with that list.
|
||||||
|
|
||||||
for (size_t i = 0; i < mList.size(); i++)
|
for (size_t i = 0; i < mList.size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -34,7 +38,7 @@ void LeveledListBase::load(ESMReader &esm)
|
||||||
esm.getHNT(li.mLevel, "INTV");
|
esm.getHNT(li.mLevel, "INTV");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void LeveledListBase::save(ESMWriter &esm) const
|
void LevelledListBase::save(ESMWriter &esm) const
|
||||||
{
|
{
|
||||||
esm.writeHNT("DATA", mFlags);
|
esm.writeHNT("DATA", mFlags);
|
||||||
esm.writeHNT("NNAM", mChanceNone);
|
esm.writeHNT("NNAM", mChanceNone);
|
||||||
|
@ -47,7 +51,7 @@ void LeveledListBase::save(ESMWriter &esm) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeveledListBase::blank()
|
void LevelledListBase::blank()
|
||||||
{
|
{
|
||||||
mFlags = 0;
|
mFlags = 0;
|
||||||
mChanceNone = 0;
|
mChanceNone = 0;
|
||||||
|
|
|
@ -11,14 +11,14 @@ class ESMReader;
|
||||||
class ESMWriter;
|
class ESMWriter;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Leveled lists. Since these have identical layout, I only bothered
|
* Levelled lists. Since these have identical layout, I only bothered
|
||||||
* to implement it once.
|
* to implement it once.
|
||||||
*
|
*
|
||||||
* We should later implement the ability to merge leveled lists from
|
* We should later implement the ability to merge levelled lists from
|
||||||
* several files.
|
* several files.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct LeveledListBase
|
struct LevelledListBase
|
||||||
{
|
{
|
||||||
int mFlags;
|
int mFlags;
|
||||||
unsigned char mChanceNone; // Chance that none are selected (0-100)
|
unsigned char mChanceNone; // Chance that none are selected (0-100)
|
||||||
|
@ -43,7 +43,7 @@ struct LeveledListBase
|
||||||
///< Set record to default state (does not touch the ID).
|
///< Set record to default state (does not touch the ID).
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CreatureLevList: LeveledListBase
|
struct CreatureLevList: LevelledListBase
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ struct CreatureLevList: LeveledListBase
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ItemLevList: LeveledListBase
|
struct ItemLevList: LevelledListBase
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ struct ItemLevList: LeveledListBase
|
||||||
// list is instantiated, instead of
|
// list is instantiated, instead of
|
||||||
// giving several identical items
|
// giving several identical items
|
||||||
// (used when a container has more
|
// (used when a container has more
|
||||||
// than one instance of one leveled
|
// than one instance of one levelled
|
||||||
// list.)
|
// list.)
|
||||||
AllLevels = 0x02 // Calculate from all levels <= player
|
AllLevels = 0x02 // Calculate from all levels <= player
|
||||||
// level, not just the closest below
|
// level, not just the closest below
|
||||||
|
|
47
components/esm/stolenitems.cpp
Normal file
47
components/esm/stolenitems.cpp
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#include "stolenitems.hpp"
|
||||||
|
|
||||||
|
#include <components/esm/esmreader.hpp>
|
||||||
|
#include <components/esm/esmwriter.hpp>
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
|
||||||
|
void StolenItems::write(ESMWriter &esm) const
|
||||||
|
{
|
||||||
|
for (StolenItemsMap::const_iterator it = mStolenItems.begin(); it != mStolenItems.end(); ++it)
|
||||||
|
{
|
||||||
|
esm.writeHNString("NAME", it->first);
|
||||||
|
for (std::map<std::pair<std::string, bool>, int>::const_iterator ownerIt = it->second.begin();
|
||||||
|
ownerIt != it->second.end(); ++ownerIt)
|
||||||
|
{
|
||||||
|
if (ownerIt->first.second)
|
||||||
|
esm.writeHNString("FNAM", ownerIt->first.first);
|
||||||
|
else
|
||||||
|
esm.writeHNString("ONAM", ownerIt->first.first);
|
||||||
|
esm.writeHNT("COUN", ownerIt->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StolenItems::load(ESMReader &esm)
|
||||||
|
{
|
||||||
|
while (esm.isNextSub("NAME"))
|
||||||
|
{
|
||||||
|
std::string itemid = esm.getHString();
|
||||||
|
|
||||||
|
std::map<std::pair<std::string, bool>, int> ownerMap;
|
||||||
|
while (esm.isNextSub("FNAM") || esm.isNextSub("ONAM"))
|
||||||
|
{
|
||||||
|
std::string subname = esm.retSubName().toString();
|
||||||
|
std::string owner = esm.getHString();
|
||||||
|
bool isFaction = (subname == "FNAM");
|
||||||
|
int count;
|
||||||
|
esm.getHNT(count, "COUN");
|
||||||
|
ownerMap.insert(std::make_pair(std::make_pair(owner, isFaction), count));
|
||||||
|
}
|
||||||
|
|
||||||
|
mStolenItems[itemid] = ownerMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
24
components/esm/stolenitems.hpp
Normal file
24
components/esm/stolenitems.hpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef OPENMW_COMPONENTS_ESM_STOLENITEMS_H
|
||||||
|
#define OPENMW_COMPONENTS_ESM_STOLENITEMS_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
class ESMReader;
|
||||||
|
class ESMWriter;
|
||||||
|
|
||||||
|
// format 0, saved games only
|
||||||
|
struct StolenItems
|
||||||
|
{
|
||||||
|
typedef std::map<std::string, std::map<std::pair<std::string, bool>, int> > StolenItemsMap;
|
||||||
|
StolenItemsMap mStolenItems;
|
||||||
|
|
||||||
|
void load(ESM::ESMReader& esm);
|
||||||
|
void write(ESM::ESMWriter& esm) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,95 +1,144 @@
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <boost/filesystem/path.hpp>
|
|
||||||
#include <boost/filesystem/fstream.hpp>
|
|
||||||
|
|
||||||
#include <OgreResourceGroupManager.h>
|
|
||||||
#include <OgreStringConverter.h>
|
#include <OgreStringConverter.h>
|
||||||
#include <OgreDataStream.h>
|
|
||||||
|
|
||||||
#include <components/files/constrainedfiledatastream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
|
#include <boost/filesystem/path.hpp>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
using namespace Settings;
|
namespace Settings
|
||||||
|
{
|
||||||
|
|
||||||
namespace bfs = boost::filesystem;
|
CategorySettingValueMap Manager::mDefaultSettings = CategorySettingValueMap();
|
||||||
|
CategorySettingValueMap Manager::mUserSettings = CategorySettingValueMap();
|
||||||
Ogre::ConfigFile Manager::mFile = Ogre::ConfigFile();
|
|
||||||
Ogre::ConfigFile Manager::mDefaultFile = Ogre::ConfigFile();
|
|
||||||
CategorySettingVector Manager::mChangedSettings = CategorySettingVector();
|
CategorySettingVector Manager::mChangedSettings = CategorySettingVector();
|
||||||
CategorySettingValueMap Manager::mNewSettings = CategorySettingValueMap();
|
|
||||||
|
|
||||||
void Manager::loadUser (const std::string& file)
|
|
||||||
|
class SettingsFileParser
|
||||||
{
|
{
|
||||||
Ogre::DataStreamPtr stream = openConstrainedFileDataStream(file.c_str());
|
public:
|
||||||
mFile.load(stream);
|
SettingsFileParser() : mLine(0) {}
|
||||||
}
|
|
||||||
|
|
||||||
void Manager::loadDefault (const std::string& file)
|
void loadSettingsFile (const std::string& file, CategorySettingValueMap& settings)
|
||||||
{
|
|
||||||
Ogre::DataStreamPtr stream = openConstrainedFileDataStream(file.c_str());
|
|
||||||
mDefaultFile.load(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Manager::saveUser(const std::string& file)
|
|
||||||
{
|
|
||||||
bfs::ofstream fout((bfs::path(file)));
|
|
||||||
|
|
||||||
Ogre::ConfigFile::SectionIterator seci = mFile.getSectionIterator();
|
|
||||||
|
|
||||||
while (seci.hasMoreElements())
|
|
||||||
{
|
{
|
||||||
Ogre::String sectionName = seci.peekNextKey();
|
mFile = file;
|
||||||
|
boost::filesystem::ifstream stream;
|
||||||
if (sectionName.length() > 0)
|
stream.open(boost::filesystem::path(file));
|
||||||
fout << '\n' << '[' << seci.peekNextKey() << ']' << '\n';
|
std::string currentCategory;
|
||||||
|
mLine = 0;
|
||||||
Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
|
while (!stream.eof() && !stream.fail())
|
||||||
Ogre::ConfigFile::SettingsMultiMap::iterator i;
|
|
||||||
for (i = settings->begin(); i != settings->end(); ++i)
|
|
||||||
{
|
{
|
||||||
fout << i->first.c_str() << " = " << i->second.c_str() << '\n';
|
++mLine;
|
||||||
}
|
std::string line;
|
||||||
|
std::getline( stream, line );
|
||||||
|
|
||||||
CategorySettingValueMap::iterator it = mNewSettings.begin();
|
size_t i = 0;
|
||||||
while (it != mNewSettings.end())
|
if (!skipWhiteSpace(i, line))
|
||||||
{
|
continue;
|
||||||
if (it->first.first == sectionName)
|
|
||||||
|
if (line[i] == '#') // skip comment
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (line[i] == '[')
|
||||||
{
|
{
|
||||||
fout << it->first.second << " = " << it->second << '\n';
|
size_t end = line.find(']', i);
|
||||||
mNewSettings.erase(it++);
|
if (end == std::string::npos)
|
||||||
|
fail("unterminated category");
|
||||||
|
|
||||||
|
currentCategory = line.substr(i+1, end - (i+1));
|
||||||
|
boost::algorithm::trim(currentCategory);
|
||||||
|
i = end+1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
++it;
|
if (!skipWhiteSpace(i, line))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (currentCategory.empty())
|
||||||
|
fail("empty category name");
|
||||||
|
|
||||||
|
size_t settingEnd = line.find('=', i);
|
||||||
|
if (settingEnd == std::string::npos)
|
||||||
|
fail("unterminated setting name");
|
||||||
|
|
||||||
|
std::string setting = line.substr(i, (settingEnd-i));
|
||||||
|
boost::algorithm::trim(setting);
|
||||||
|
|
||||||
|
size_t valueBegin = settingEnd+1;
|
||||||
|
std::string value = line.substr(valueBegin);
|
||||||
|
boost::algorithm::trim(value);
|
||||||
|
|
||||||
|
if (settings.insert(std::make_pair(std::make_pair(currentCategory, setting), value)).second == false)
|
||||||
|
fail(std::string("duplicate setting: [" + currentCategory + "] " + setting));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string category = "";
|
private:
|
||||||
for (CategorySettingValueMap::iterator it = mNewSettings.begin();
|
/// Increment i until it longer points to a whitespace character
|
||||||
it != mNewSettings.end(); ++it)
|
/// in the string or has reached the end of the string.
|
||||||
|
/// @return false if we have reached the end of the string
|
||||||
|
bool skipWhiteSpace(size_t& i, std::string& str)
|
||||||
{
|
{
|
||||||
if (category != it->first.first)
|
while (i < str.size() && std::isspace(str[i], std::locale::classic()))
|
||||||
{
|
{
|
||||||
category = it->first.first;
|
++i;
|
||||||
fout << '\n' << '[' << category << ']' << '\n';
|
|
||||||
}
|
}
|
||||||
fout << it->first.second << " = " << it->second << '\n';
|
return i < str.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
fout.close();
|
void fail(const std::string& message)
|
||||||
|
{
|
||||||
|
std::stringstream error;
|
||||||
|
error << "Error on line " << mLine << " in " << mFile << ":\n" << message;
|
||||||
|
throw std::runtime_error(error.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mFile;
|
||||||
|
int mLine;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Manager::loadDefault(const std::string &file)
|
||||||
|
{
|
||||||
|
SettingsFileParser parser;
|
||||||
|
parser.loadSettingsFile(file, mDefaultSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Manager::getString (const std::string& setting, const std::string& category)
|
void Manager::loadUser(const std::string &file)
|
||||||
{
|
{
|
||||||
if (mNewSettings.find(std::make_pair(category, setting)) != mNewSettings.end())
|
SettingsFileParser parser;
|
||||||
return mNewSettings[std::make_pair(category, setting)];
|
parser.loadSettingsFile(file, mUserSettings);
|
||||||
|
}
|
||||||
|
|
||||||
std::string defaultval = mDefaultFile.getSetting(setting, category, "NOTFOUND");
|
void Manager::saveUser(const std::string &file)
|
||||||
std::string val = mFile.getSetting(setting, category, defaultval);
|
{
|
||||||
|
boost::filesystem::ofstream stream;
|
||||||
|
stream.open(boost::filesystem::path(file));
|
||||||
|
std::string currentCategory;
|
||||||
|
for (CategorySettingValueMap::iterator it = mUserSettings.begin(); it != mUserSettings.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->first.first != currentCategory)
|
||||||
|
{
|
||||||
|
currentCategory = it->first.first;
|
||||||
|
stream << "\n[" << currentCategory << "]\n";
|
||||||
|
}
|
||||||
|
stream << it->first.second << " = " << it->second << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (val == "NOTFOUND")
|
std::string Manager::getString(const std::string &setting, const std::string &category)
|
||||||
throw std::runtime_error("Trying to retrieve a non-existing setting: " + setting + " Make sure the settings-default.cfg file was properly installed.");
|
{
|
||||||
return val;
|
CategorySettingValueMap::key_type key = std::make_pair(category, setting);
|
||||||
|
CategorySettingValueMap::iterator it = mUserSettings.find(key);
|
||||||
|
if (it != mUserSettings.end())
|
||||||
|
return it->second;
|
||||||
|
|
||||||
|
it = mDefaultSettings.find(key);
|
||||||
|
if (it != mDefaultSettings.end())
|
||||||
|
return it->second;
|
||||||
|
|
||||||
|
throw std::runtime_error(std::string("Trying to retrieve a non-existing setting: ") + setting
|
||||||
|
+ ".\nMake sure the settings-default.cfg file file was properly installed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
float Manager::getFloat (const std::string& setting, const std::string& category)
|
float Manager::getFloat (const std::string& setting, const std::string& category)
|
||||||
|
@ -107,51 +156,20 @@ bool Manager::getBool (const std::string& setting, const std::string& category)
|
||||||
return Ogre::StringConverter::parseBool( getString(setting, category) );
|
return Ogre::StringConverter::parseBool( getString(setting, category) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::setString (const std::string& setting, const std::string& category, const std::string& value)
|
void Manager::setString(const std::string &setting, const std::string &category, const std::string &value)
|
||||||
{
|
{
|
||||||
CategorySetting s = std::make_pair(category, setting);
|
CategorySettingValueMap::key_type key = std::make_pair(category, setting);
|
||||||
|
|
||||||
bool found=false;
|
CategorySettingValueMap::iterator found = mUserSettings.find(key);
|
||||||
try
|
if (found != mUserSettings.end())
|
||||||
{
|
{
|
||||||
Ogre::ConfigFile::SettingsIterator it = mFile.getSettingsIterator(category);
|
if (found->second == value)
|
||||||
while (it.hasMoreElements())
|
return;
|
||||||
{
|
|
||||||
Ogre::ConfigFile::SettingsMultiMap::iterator i = it.current();
|
|
||||||
|
|
||||||
if ((*i).first == setting)
|
|
||||||
{
|
|
||||||
if ((*i).second != value)
|
|
||||||
{
|
|
||||||
mChangedSettings.push_back(std::make_pair(category, setting));
|
|
||||||
(*i).second = value;
|
|
||||||
}
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
it.getNext();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Ogre::Exception&)
|
|
||||||
{}
|
|
||||||
|
|
||||||
if (!found)
|
mUserSettings[key] = value;
|
||||||
{
|
|
||||||
if (mNewSettings.find(s) != mNewSettings.end())
|
mChangedSettings.insert(key);
|
||||||
{
|
|
||||||
if (mNewSettings[s] != value)
|
|
||||||
{
|
|
||||||
mChangedSettings.push_back(std::make_pair(category, setting));
|
|
||||||
mNewSettings[s] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (mDefaultFile.getSetting(setting, category) != value)
|
|
||||||
mChangedSettings.push_back(std::make_pair(category, setting));
|
|
||||||
mNewSettings[s] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::setInt (const std::string& setting, const std::string& category, const int value)
|
void Manager::setInt (const std::string& setting, const std::string& category, const int value)
|
||||||
|
@ -159,12 +177,12 @@ void Manager::setInt (const std::string& setting, const std::string& category, c
|
||||||
setString(setting, category, Ogre::StringConverter::toString(value));
|
setString(setting, category, Ogre::StringConverter::toString(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::setFloat (const std::string& setting, const std::string& category, const float value)
|
void Manager::setFloat (const std::string &setting, const std::string &category, const float value)
|
||||||
{
|
{
|
||||||
setString(setting, category, Ogre::StringConverter::toString(value));
|
setString(setting, category, Ogre::StringConverter::toString(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::setBool (const std::string& setting, const std::string& category, const bool value)
|
void Manager::setBool(const std::string &setting, const std::string &category, const bool value)
|
||||||
{
|
{
|
||||||
setString(setting, category, Ogre::StringConverter::toString(value));
|
setString(setting, category, Ogre::StringConverter::toString(value));
|
||||||
}
|
}
|
||||||
|
@ -175,3 +193,5 @@ const CategorySettingVector Manager::apply()
|
||||||
mChangedSettings.clear();
|
mChangedSettings.clear();
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
#ifndef COMPONENTS_SETTINGS_H
|
#ifndef COMPONENTS_SETTINGS_H
|
||||||
#define COMPONENTS_SETTINGS_H
|
#define COMPONENTS_SETTINGS_H
|
||||||
|
|
||||||
#include <OgreConfigFile.h>
|
#include <set>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace Settings
|
namespace Settings
|
||||||
{
|
{
|
||||||
typedef std::pair < std::string, std::string > CategorySetting;
|
typedef std::pair < std::string, std::string > CategorySetting;
|
||||||
typedef std::vector< std::pair<std::string, std::string> > CategorySettingVector;
|
typedef std::set< std::pair<std::string, std::string> > CategorySettingVector;
|
||||||
typedef std::map < CategorySetting, std::string > CategorySettingValueMap;
|
typedef std::map < CategorySetting, std::string > CategorySettingValueMap;
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -15,15 +17,12 @@ namespace Settings
|
||||||
class Manager
|
class Manager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static Ogre::ConfigFile mFile;
|
static CategorySettingValueMap mDefaultSettings;
|
||||||
static Ogre::ConfigFile mDefaultFile;
|
static CategorySettingValueMap mUserSettings;
|
||||||
|
|
||||||
static CategorySettingVector mChangedSettings;
|
static CategorySettingVector mChangedSettings;
|
||||||
///< tracks all the settings that were changed since the last apply() call
|
///< tracks all the settings that were changed since the last apply() call
|
||||||
|
|
||||||
static CategorySettingValueMap mNewSettings;
|
|
||||||
///< tracks all the settings that are in the default file, but not in user file yet
|
|
||||||
|
|
||||||
void loadDefault (const std::string& file);
|
void loadDefault (const std::string& file);
|
||||||
///< load file as the default settings (can be overridden by user settings)
|
///< load file as the default settings (can be overridden by user settings)
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,6 @@ namespace Terrain
|
||||||
DefaultWorld* getTerrain() { return mTerrain; }
|
DefaultWorld* getTerrain() { return mTerrain; }
|
||||||
|
|
||||||
/// Adjust LODs for the given camera position, possibly splitting up chunks or merging them.
|
/// Adjust LODs for the given camera position, possibly splitting up chunks or merging them.
|
||||||
/// @param force Always choose to render this node, even if not the perfect LOD.
|
|
||||||
/// @return Did we (or all of our children) choose to render?
|
/// @return Did we (or all of our children) choose to render?
|
||||||
bool update (const Ogre::Vector3& cameraPos);
|
bool update (const Ogre::Vector3& cameraPos);
|
||||||
|
|
||||||
|
@ -124,7 +123,6 @@ namespace Terrain
|
||||||
/// call this method on their children.
|
/// call this method on their children.
|
||||||
/// @note Do not call this before World::areLayersLoaded() == true
|
/// @note Do not call this before World::areLayersLoaded() == true
|
||||||
/// @param area area in image space to put the quad
|
/// @param area area in image space to put the quad
|
||||||
/// @param quads collect quads here so they can be deleted later
|
|
||||||
void prepareForCompositeMap(Ogre::TRect<float> area);
|
void prepareForCompositeMap(Ogre::TRect<float> area);
|
||||||
|
|
||||||
/// Create a chunk for this node from the given data.
|
/// Create a chunk for this node from the given data.
|
||||||
|
|
6
extern/sdl4ogre/events.h
vendored
6
extern/sdl4ogre/events.h
vendored
|
@ -1,8 +1,8 @@
|
||||||
#ifndef _SFO_EVENTS_H
|
#ifndef _SFO_EVENTS_H
|
||||||
#define _SFO_EVENTS_H
|
#define _SFO_EVENTS_H
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL_types.h>
|
||||||
|
#include <SDL_events.h>
|
||||||
|
|
||||||
////////////
|
////////////
|
||||||
// Events //
|
// Events //
|
||||||
|
@ -65,7 +65,7 @@ public:
|
||||||
virtual ~WindowListener() {}
|
virtual ~WindowListener() {}
|
||||||
|
|
||||||
/** @remarks The window's visibility changed */
|
/** @remarks The window's visibility changed */
|
||||||
virtual void windowVisibilityChange( bool visible ) {};
|
virtual void windowVisibilityChange( bool visible ) {}
|
||||||
|
|
||||||
/** @remarks The window got / lost input focus */
|
/** @remarks The window got / lost input focus */
|
||||||
virtual void windowFocusChange( bool have_focus ) {}
|
virtual void windowFocusChange( bool have_focus ) {}
|
||||||
|
|
3
extern/sdl4ogre/sdlcursormanager.cpp
vendored
3
extern/sdl4ogre/sdlcursormanager.cpp
vendored
|
@ -4,6 +4,9 @@
|
||||||
#include <OgreTextureManager.h>
|
#include <OgreTextureManager.h>
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
|
|
||||||
|
#include <SDL_mouse.h>
|
||||||
|
#include <SDL_endian.h>
|
||||||
|
|
||||||
#include <openengine/ogre/imagerotate.hpp>
|
#include <openengine/ogre/imagerotate.hpp>
|
||||||
|
|
||||||
namespace SFO
|
namespace SFO
|
||||||
|
|
5
extern/sdl4ogre/sdlcursormanager.hpp
vendored
5
extern/sdl4ogre/sdlcursormanager.hpp
vendored
|
@ -1,11 +1,12 @@
|
||||||
#ifndef SDL4OGRE_CURSORMANAGER_H
|
#ifndef SDL4OGRE_CURSORMANAGER_H
|
||||||
#define SDL4OGRE_CURSORMANAGER_H
|
#define SDL4OGRE_CURSORMANAGER_H
|
||||||
|
|
||||||
#include <SDL.h>
|
|
||||||
|
|
||||||
#include "cursormanager.hpp"
|
#include "cursormanager.hpp"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
struct SDL_Cursor;
|
||||||
|
struct SDL_Surface;
|
||||||
|
|
||||||
namespace SFO
|
namespace SFO
|
||||||
{
|
{
|
||||||
class SDLCursorManager :
|
class SDLCursorManager :
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_strength.dds"/>
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_strength.dds"/>
|
||||||
<Property key="Caption" value="#{sAttributeStrength}"/>
|
<Property key="Caption" value="#{sAttributeStrength}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal1">
|
<Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal1">
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_int.dds"/>
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_int.dds"/>
|
||||||
<Property key="Caption" value="#{sAttributeIntelligence}"/>
|
<Property key="Caption" value="#{sAttributeIntelligence}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal2">
|
<Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal2">
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_wilpower.dds"/>
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_wilpower.dds"/>
|
||||||
<Property key="Caption" value="#{sAttributeWillpower}"/>
|
<Property key="Caption" value="#{sAttributeWillpower}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal3">
|
<Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal3">
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@
|
||||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_agility.dds"/>
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_agility.dds"/>
|
||||||
<Property key="Caption" value="#{sAttributeAgility}"/>
|
<Property key="Caption" value="#{sAttributeAgility}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal4">
|
<Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal4">
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_speed.dds"/>
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_speed.dds"/>
|
||||||
<Property key="Caption" value="#{sAttributeSpeed}"/>
|
<Property key="Caption" value="#{sAttributeSpeed}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal5">
|
<Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal5">
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@
|
||||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_endurance.dds"/>
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_endurance.dds"/>
|
||||||
<Property key="Caption" value="#{sAttributeEndurance}"/>
|
<Property key="Caption" value="#{sAttributeEndurance}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal6">
|
<Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal6">
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@
|
||||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_personality.dds"/>
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_personality.dds"/>
|
||||||
<Property key="Caption" value="#{sAttributePersonality}"/>
|
<Property key="Caption" value="#{sAttributePersonality}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal7">
|
<Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal7">
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@
|
||||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_luck.dds"/>
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_luck.dds"/>
|
||||||
<Property key="Caption" value="#{sAttributeLuck}"/>
|
<Property key="Caption" value="#{sAttributeLuck}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal8">
|
<Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal8">
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
Loading…
Reference in a new issue