mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 07:53:53 +00:00
Merge remote-tracking branch 'zini/master' into nifogre
Conflicts: components/nifogre/ogrenifloader.cpp
This commit is contained in:
commit
01a1a0b846
54 changed files with 387 additions and 67 deletions
|
@ -36,6 +36,7 @@ opencs_units (model/tools
|
|||
|
||||
opencs_units_noqt (model/tools
|
||||
stage verifier mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
|
||||
birthsigncheck
|
||||
)
|
||||
|
||||
|
||||
|
|
39
apps/opencs/model/tools/birthsigncheck.cpp
Normal file
39
apps/opencs/model/tools/birthsigncheck.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
#include "birthsigncheck.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
|
||||
#include <components/esm/loadbsgn.hpp>
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
CSMTools::BirthsignCheckStage::BirthsignCheckStage (const CSMWorld::IdCollection<ESM::BirthSign>& birthsigns)
|
||||
: mBirthsigns (birthsigns)
|
||||
{}
|
||||
|
||||
int CSMTools::BirthsignCheckStage::setup()
|
||||
{
|
||||
return mBirthsigns.getSize();
|
||||
}
|
||||
|
||||
void CSMTools::BirthsignCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::BirthSign& birthsign = mBirthsigns.getRecord (stage).get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Birthsign, birthsign.mId);
|
||||
|
||||
// test for empty name, description and texture
|
||||
if (birthsign.mName.empty())
|
||||
messages.push_back (id.toString() + "|" + birthsign.mId + " has an empty name");
|
||||
|
||||
if (birthsign.mDescription.empty())
|
||||
messages.push_back (id.toString() + "|" + birthsign.mId + " has an empty description");
|
||||
|
||||
if (birthsign.mTexture.empty())
|
||||
messages.push_back (id.toString() + "|" + birthsign.mId + " is missing a texture");
|
||||
|
||||
/// \todo test if the texture exists
|
||||
|
||||
/// \todo check data members that can't be edited in the table view
|
||||
}
|
29
apps/opencs/model/tools/birthsigncheck.hpp
Normal file
29
apps/opencs/model/tools/birthsigncheck.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSM_TOOLS_BIRTHSIGNCHECK_H
|
||||
#define CSM_TOOLS_BIRTHSIGNCHECK_H
|
||||
|
||||
#include <components/esm/loadbsgn.hpp>
|
||||
|
||||
#include "../world/idcollection.hpp"
|
||||
|
||||
#include "stage.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
/// \brief VerifyStage: make sure that birthsign records are internally consistent
|
||||
class BirthsignCheckStage : public Stage
|
||||
{
|
||||
const CSMWorld::IdCollection<ESM::BirthSign>& mBirthsigns;
|
||||
|
||||
public:
|
||||
|
||||
BirthsignCheckStage (const CSMWorld::IdCollection<ESM::BirthSign>& birthsigns);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, std::vector<std::string>& messages);
|
||||
///< Messages resulting from this tage will be appended to \a messages.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -18,6 +18,7 @@
|
|||
#include "racecheck.hpp"
|
||||
#include "soundcheck.hpp"
|
||||
#include "regioncheck.hpp"
|
||||
#include "birthsigncheck.hpp"
|
||||
|
||||
CSMTools::Operation *CSMTools::Tools::get (int type)
|
||||
{
|
||||
|
@ -69,6 +70,8 @@ CSMTools::Verifier *CSMTools::Tools::getVerifier()
|
|||
mVerifier->appendStage (new SoundCheckStage (mData.getSounds()));
|
||||
|
||||
mVerifier->appendStage (new RegionCheckStage (mData.getRegions()));
|
||||
|
||||
mVerifier->appendStage (new BirthsignCheckStage (mData.getBirthsigns()));
|
||||
}
|
||||
|
||||
return mVerifier;
|
||||
|
|
|
@ -650,6 +650,31 @@ namespace CSMWorld
|
|||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct TextureColumn : public Column<ESXRecordT>
|
||||
{
|
||||
TextureColumn() : Column<ESXRecordT> ("Texture", ColumnBase::Display_String) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mTexture.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mTexture = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -93,6 +93,12 @@ CSMWorld::Data::Data()
|
|||
mRegions.addColumn (new MapColourColumn<ESM::Region>);
|
||||
mRegions.addColumn (new SleepListColumn<ESM::Region>);
|
||||
|
||||
mBirthsigns.addColumn (new StringIdColumn<ESM::BirthSign>);
|
||||
mBirthsigns.addColumn (new RecordStateColumn<ESM::BirthSign>);
|
||||
mBirthsigns.addColumn (new NameColumn<ESM::BirthSign>);
|
||||
mBirthsigns.addColumn (new TextureColumn<ESM::BirthSign>);
|
||||
mBirthsigns.addColumn (new DescriptionColumn<ESM::BirthSign>);
|
||||
|
||||
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);
|
||||
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst);
|
||||
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill);
|
||||
|
@ -102,6 +108,7 @@ CSMWorld::Data::Data()
|
|||
addModel (new IdTable (&mSounds), UniversalId::Type_Sounds, UniversalId::Type_Sound);
|
||||
addModel (new IdTable (&mScripts), UniversalId::Type_Scripts, UniversalId::Type_Script);
|
||||
addModel (new IdTable (&mRegions), UniversalId::Type_Regions, UniversalId::Type_Region);
|
||||
addModel (new IdTable (&mBirthsigns), UniversalId::Type_Birthsigns, UniversalId::Type_Birthsign);
|
||||
}
|
||||
|
||||
CSMWorld::Data::~Data()
|
||||
|
@ -200,6 +207,16 @@ CSMWorld::IdCollection<ESM::Region>& CSMWorld::Data::getRegions()
|
|||
return mRegions;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::BirthSign>& CSMWorld::Data::getBirthsigns() const
|
||||
{
|
||||
return mBirthsigns;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::BirthSign>& CSMWorld::Data::getBirthsigns()
|
||||
{
|
||||
return mBirthsigns;
|
||||
}
|
||||
|
||||
QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id)
|
||||
{
|
||||
std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType());
|
||||
|
@ -243,6 +260,7 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base)
|
|||
case ESM::REC_SOUN: mSounds.load (reader, base); break;
|
||||
case ESM::REC_SCPT: mScripts.load (reader, base); break;
|
||||
case ESM::REC_REGN: mRegions.load (reader, base); break;
|
||||
case ESM::REC_BSGN: mBirthsigns.load (reader, base); break;
|
||||
|
||||
default:
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <components/esm/loadsoun.hpp>
|
||||
#include <components/esm/loadscpt.hpp>
|
||||
#include <components/esm/loadregn.hpp>
|
||||
#include <components/esm/loadbsgn.hpp>
|
||||
|
||||
#include "idcollection.hpp"
|
||||
#include "universalid.hpp"
|
||||
|
@ -34,6 +35,7 @@ namespace CSMWorld
|
|||
IdCollection<ESM::Sound> mSounds;
|
||||
IdCollection<ESM::Script> mScripts;
|
||||
IdCollection<ESM::Region> mRegions;
|
||||
IdCollection<ESM::BirthSign> mBirthsigns;
|
||||
std::vector<QAbstractItemModel *> mModels;
|
||||
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
|
||||
|
||||
|
@ -86,6 +88,10 @@ namespace CSMWorld
|
|||
|
||||
IdCollection<ESM::Region>& getRegions();
|
||||
|
||||
const IdCollection<ESM::BirthSign>& getBirthsigns() const;
|
||||
|
||||
IdCollection<ESM::BirthSign>& getBirthsigns();
|
||||
|
||||
QAbstractItemModel *getTableModel (const UniversalId& id);
|
||||
///< If no table model is available for \a id, an exception is thrown.
|
||||
///
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace
|
|||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Sounds, "Sounds" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Scripts, "Scripts" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Regions, "Regions" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Birthsigns, "Birthsigns" },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
||||
};
|
||||
|
@ -41,6 +42,7 @@ namespace
|
|||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Sound, "Sound" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Script, "Script" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Region, "Region" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Birthsign, "Birthsign" },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
||||
};
|
||||
|
|
|
@ -51,7 +51,9 @@ namespace CSMWorld
|
|||
Type_Scripts,
|
||||
Type_Script,
|
||||
Type_Regions,
|
||||
Type_Region
|
||||
Type_Region,
|
||||
Type_Birthsigns,
|
||||
Type_Birthsign
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -117,6 +117,10 @@ void CSVDoc::View::setupWorldMenu()
|
|||
QAction *regions = new QAction (tr ("Regions"), this);
|
||||
connect (regions, SIGNAL (triggered()), this, SLOT (addRegionsSubView()));
|
||||
world->addAction (regions);
|
||||
|
||||
QAction *birthsigns = new QAction (tr ("Birthsigns"), this);
|
||||
connect (birthsigns, SIGNAL (triggered()), this, SLOT (addBirthsignsSubView()));
|
||||
world->addAction (birthsigns);
|
||||
}
|
||||
|
||||
void CSVDoc::View::setupUi()
|
||||
|
@ -307,6 +311,11 @@ void CSVDoc::View::addRegionsSubView()
|
|||
addSubView (CSMWorld::UniversalId::Type_Regions);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addBirthsignsSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Birthsigns);
|
||||
}
|
||||
|
||||
void CSVDoc::View::abortOperation (int type)
|
||||
{
|
||||
mDocument->abortOperation (type);
|
||||
|
|
|
@ -129,6 +129,8 @@ namespace CSVDoc
|
|||
void addScriptsSubView();
|
||||
|
||||
void addRegionsSubView();
|
||||
|
||||
void addBirthsignsSubView();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
|||
CSMWorld::UniversalId::Type_Sounds,
|
||||
CSMWorld::UniversalId::Type_Scripts,
|
||||
CSMWorld::UniversalId::Type_Regions,
|
||||
CSMWorld::UniversalId::Type_Birthsigns,
|
||||
|
||||
CSMWorld::UniversalId::Type_None // end marker
|
||||
};
|
||||
|
|
|
@ -159,4 +159,9 @@ namespace MWClass
|
|||
|
||||
return MWWorld::Ptr(&cell.mAppas.insert(*ref), &cell);
|
||||
}
|
||||
|
||||
bool Apparatus::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||
{
|
||||
return npcServices & ESM::NPC::Apparatus;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,8 @@ namespace MWClass
|
|||
///< Generate action for using via inventory menu
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -315,4 +315,9 @@ namespace MWClass
|
|||
|
||||
return ref->mBase->mData.mEnchant;
|
||||
}
|
||||
|
||||
bool Armor::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||
{
|
||||
return npcServices & ESM::NPC::Armor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,8 @@ namespace MWClass
|
|||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -183,4 +183,9 @@ namespace MWClass
|
|||
|
||||
return ref->mBase->mData.mEnchant;
|
||||
}
|
||||
|
||||
bool Book::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||
{
|
||||
return npcServices & ESM::NPC::Books;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,8 @@ namespace MWClass
|
|||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -262,4 +262,9 @@ namespace MWClass
|
|||
|
||||
return ref->mBase->mData.mEnchant;
|
||||
}
|
||||
|
||||
bool Clothing::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||
{
|
||||
return npcServices & ESM::NPC::Clothing;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,6 +68,8 @@ namespace MWClass
|
|||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -197,4 +197,9 @@ namespace MWClass
|
|||
|
||||
return MWWorld::Ptr(&cell.mIngreds.insert(*ref), &cell);
|
||||
}
|
||||
|
||||
bool Ingredient::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||
{
|
||||
return npcServices & ESM::NPC::Ingredients;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,8 @@ namespace MWClass
|
|||
///< Return name of inventory icon.
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -203,4 +203,9 @@ namespace MWClass
|
|||
|
||||
return MWWorld::Ptr(&cell.mLights.insert(*ref), &cell);
|
||||
}
|
||||
|
||||
bool Light::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||
{
|
||||
return npcServices & ESM::NPC::Lights;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@ namespace MWClass
|
|||
///< Generate action for using via inventory menu
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -176,4 +176,9 @@ namespace MWClass
|
|||
|
||||
return MWWorld::Ptr(&cell.mLockpicks.insert(*ref), &cell);
|
||||
}
|
||||
|
||||
bool Lockpick::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||
{
|
||||
return npcServices & ESM::NPC::Picks;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@ namespace MWClass
|
|||
///< Generate action for using via inventory menu
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -246,4 +246,12 @@ namespace MWClass
|
|||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionSoulgem(ptr));
|
||||
}
|
||||
|
||||
bool Miscellaneous::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
||||
item.get<ESM::Miscellaneous>();
|
||||
|
||||
return !ref->mBase->mData.mIsKey && (npcServices & ESM::NPC::Misc);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -53,6 +53,8 @@ namespace MWClass
|
|||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -194,4 +194,9 @@ namespace MWClass
|
|||
|
||||
return MWWorld::Ptr(&cell.mPotions.insert(*ref), &cell);
|
||||
}
|
||||
|
||||
bool Potion::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||
{
|
||||
return npcServices & ESM::NPC::Potions;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,8 @@ namespace MWClass
|
|||
///< Return name of inventory icon.
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -175,4 +175,9 @@ namespace MWClass
|
|||
|
||||
return MWWorld::Ptr(&cell.mProbes.insert(*ref), &cell);
|
||||
}
|
||||
|
||||
bool Probe::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||
{
|
||||
return npcServices & ESM::NPC::Probes;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@ namespace MWClass
|
|||
///< Generate action for using via inventory menu
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -175,4 +175,9 @@ namespace MWClass
|
|||
{
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRepair(ptr));
|
||||
}
|
||||
|
||||
bool Repair::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||
{
|
||||
return npcServices & ESM::NPC::RepairItem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,8 @@ namespace MWClass
|
|||
virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const;
|
||||
///< Return item max health or throw an exception, if class does not have item health
|
||||
/// (default implementation: throw an exceoption)
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -409,4 +409,9 @@ namespace MWClass
|
|||
|
||||
return ref->mBase->mData.mEnchant;
|
||||
}
|
||||
|
||||
bool Weapon::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||
{
|
||||
return npcServices & ESM::NPC::Weapon;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,6 +73,8 @@ namespace MWClass
|
|||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
|
||||
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -150,6 +150,7 @@ namespace MWGui
|
|||
it = invStore.add(ptr);
|
||||
(*it).getRefData().setCount(mDragAndDrop->mDraggedCount);
|
||||
ptr = *it;
|
||||
mDragAndDrop->mDraggedFrom->notifyItemDragged(ptr, -mDragAndDrop->mDraggedCount);
|
||||
}
|
||||
|
||||
/// \todo scripts
|
||||
|
|
|
@ -114,15 +114,9 @@ MWGui::JournalWindow::JournalWindow (MWBase::WindowManager& parWindowManager)
|
|||
//displayLeftText(list.front());
|
||||
}
|
||||
|
||||
void MWGui::JournalWindow::close()
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
|
||||
}
|
||||
|
||||
void MWGui::JournalWindow::open()
|
||||
{
|
||||
mPageNumber = 0;
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0);
|
||||
if(MWBase::Environment::get().getJournal()->begin()!=MWBase::Environment::get().getJournal()->end())
|
||||
{
|
||||
book journal;
|
||||
|
|
|
@ -16,7 +16,6 @@ namespace MWGui
|
|||
public:
|
||||
JournalWindow(MWBase::WindowManager& parWindowManager);
|
||||
virtual void open();
|
||||
virtual void close();
|
||||
|
||||
private:
|
||||
void displayLeftText(std::string text);
|
||||
|
|
|
@ -257,6 +257,12 @@ namespace MWGui
|
|||
MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterSuccessDisposition);
|
||||
|
||||
// success! make the item transfer.
|
||||
MWWorld::ContainerStore& playerBoughtItems = mWindowManager.getInventoryWindow()->getBoughtItems();
|
||||
for (MWWorld::ContainerStoreIterator it = playerBoughtItems.begin(); it != playerBoughtItems.end(); ++it)
|
||||
{
|
||||
if (Misc::StringUtils::ciEqual(it->getCellRef().mOwner, MWWorld::Class::get(mPtr).getId(mPtr)))
|
||||
it->getCellRef().mOwner = "";
|
||||
}
|
||||
transferBoughtItems();
|
||||
mWindowManager.getInventoryWindow()->transferBoughtItems();
|
||||
|
||||
|
@ -356,32 +362,7 @@ namespace MWGui
|
|||
services = ref->mBase->mAiData.mServices;
|
||||
}
|
||||
|
||||
/// \todo what about potions, there doesn't seem to be a flag for them??
|
||||
|
||||
if (item.getTypeName() == typeid(ESM::Weapon).name())
|
||||
return services & ESM::NPC::Weapon;
|
||||
else if (item.getTypeName() == typeid(ESM::Armor).name())
|
||||
return services & ESM::NPC::Armor;
|
||||
else if (item.getTypeName() == typeid(ESM::Clothing).name())
|
||||
return services & ESM::NPC::Clothing;
|
||||
else if (item.getTypeName() == typeid(ESM::Book).name())
|
||||
return services & ESM::NPC::Books;
|
||||
else if (item.getTypeName() == typeid(ESM::Ingredient).name())
|
||||
return services & ESM::NPC::Ingredients;
|
||||
else if (item.getTypeName() == typeid(ESM::Lockpick).name())
|
||||
return services & ESM::NPC::Picks;
|
||||
else if (item.getTypeName() == typeid(ESM::Probe).name())
|
||||
return services & ESM::NPC::Probes;
|
||||
else if (item.getTypeName() == typeid(ESM::Light).name())
|
||||
return services & ESM::NPC::Lights;
|
||||
else if (item.getTypeName() == typeid(ESM::Apparatus).name())
|
||||
return services & ESM::NPC::Apparatus;
|
||||
else if (item.getTypeName() == typeid(ESM::Repair).name())
|
||||
return services & ESM::NPC::RepairItem;
|
||||
else if (item.getTypeName() == typeid(ESM::Miscellaneous).name())
|
||||
return services & ESM::NPC::Misc;
|
||||
|
||||
return false;
|
||||
return MWWorld::Class::get(item).canSell(item, services);
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> TradeWindow::itemsToIgnore()
|
||||
|
|
|
@ -156,6 +156,7 @@ namespace MWGui
|
|||
MWBase::Environment::get().getWorld()->advanceTime(time);
|
||||
}
|
||||
MWBase::Environment::get().getWorld()->moveObject(player,*cell,pos.pos[0],pos.pos[1],pos.pos[2]);
|
||||
MWWorld::Class::get(player).adjustPosition(player);
|
||||
mWindowManager.removeGuiMode(GM_Travel);
|
||||
mWindowManager.removeGuiMode(GM_Dialogue);
|
||||
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0);
|
||||
|
|
|
@ -656,9 +656,15 @@ namespace MWInput
|
|||
bool gameMode = !mWindows.isGuiMode();
|
||||
|
||||
if(gameMode)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0);
|
||||
mWindows.pushGuiMode(MWGui::GM_Journal);
|
||||
}
|
||||
else if(mWindows.getMode() == MWGui::GM_Journal)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
|
||||
mWindows.popGuiMode();
|
||||
}
|
||||
// .. but don't touch any other mode.
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ void MWWorld::Cells::fillContainers (Ptr::CellStore& cellStore)
|
|||
Ptr container (&*iter, &cellStore);
|
||||
|
||||
Class::get (container).getContainerStore (container).fill (
|
||||
iter->mBase->mInventory, mStore);
|
||||
iter->mBase->mInventory, container.getCellRef().mOwner, mStore);
|
||||
}
|
||||
|
||||
for (CellRefList<ESM::Creature>::List::iterator iter (
|
||||
|
@ -55,7 +55,7 @@ void MWWorld::Cells::fillContainers (Ptr::CellStore& cellStore)
|
|||
Ptr container (&*iter, &cellStore);
|
||||
|
||||
Class::get (container).getContainerStore (container).fill (
|
||||
iter->mBase->mInventory, mStore);
|
||||
iter->mBase->mInventory, Class::get(container).getId(container), mStore);
|
||||
}
|
||||
|
||||
for (CellRefList<ESM::NPC>::List::iterator iter (
|
||||
|
@ -65,7 +65,7 @@ void MWWorld::Cells::fillContainers (Ptr::CellStore& cellStore)
|
|||
Ptr container (&*iter, &cellStore);
|
||||
|
||||
Class::get (container).getContainerStore (container).fill (
|
||||
iter->mBase->mInventory, mStore);
|
||||
iter->mBase->mInventory, Class::get(container).getId(container), mStore);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,11 @@ namespace MWWorld
|
|||
throw std::runtime_error ("class does not represent an actor");
|
||||
}
|
||||
|
||||
bool Class::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MWMechanics::CreatureStats& Class::getCreatureStats (const Ptr& ptr) const
|
||||
{
|
||||
throw std::runtime_error ("class does not have creature stats");
|
||||
|
|
|
@ -238,6 +238,9 @@ namespace MWWorld
|
|||
|
||||
virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
///< Determine whether or not \a item can be sold to an npc with the given \a npcServices
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual void applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const;
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/scriptmanager.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
|
||||
#include "manualref.hpp"
|
||||
#include "refdata.hpp"
|
||||
#include "class.hpp"
|
||||
|
@ -175,26 +177,78 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImpl (const Ptr& ptr
|
|||
return it;
|
||||
}
|
||||
|
||||
void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const MWWorld::ESMStore& store)
|
||||
void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std::string& owner, const MWWorld::ESMStore& store)
|
||||
{
|
||||
for (std::vector<ESM::ContItem>::const_iterator iter (items.mList.begin()); iter!=items.mList.end();
|
||||
++iter)
|
||||
{
|
||||
ManualRef ref (store, iter->mItem.toString());
|
||||
|
||||
if (ref.getPtr().getTypeName()==typeid (ESM::ItemLevList).name())
|
||||
{
|
||||
/// \todo implement leveled item lists
|
||||
continue;
|
||||
}
|
||||
|
||||
ref.getPtr().getRefData().setCount (std::abs(iter->mCount)); /// \todo implement item restocking (indicated by negative count)
|
||||
addImp (ref.getPtr());
|
||||
std::string id = iter->mItem.toString();
|
||||
addInitialItem(id, owner, iter->mCount);
|
||||
}
|
||||
|
||||
flagAsModified();
|
||||
}
|
||||
|
||||
void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner, int count, unsigned char failChance, bool topLevel)
|
||||
{
|
||||
count = std::abs(count); /// \todo implement item restocking (indicated by negative count)
|
||||
|
||||
ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id);
|
||||
|
||||
if (ref.getPtr().getTypeName()==typeid (ESM::ItemLevList).name())
|
||||
{
|
||||
const ESM::ItemLevList* levItem = ref.getPtr().get<ESM::ItemLevList>()->mBase;
|
||||
const std::vector<ESM::LeveledListBase::LevelItem>& items = levItem->mList;
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
int playerLevel = MWWorld::Class::get(player).getCreatureStats(player).getLevel();
|
||||
|
||||
failChance += levItem->mChanceNone;
|
||||
|
||||
if (topLevel && count > 1 && levItem->mFlags & ESM::ItemLevList::Each)
|
||||
{
|
||||
for (int i=0; i<count; ++i)
|
||||
addInitialItem(id, owner, 1, failChance, false);
|
||||
return;
|
||||
}
|
||||
|
||||
float random = static_cast<float> (std::rand()) / RAND_MAX;
|
||||
if (random >= failChance/100.f)
|
||||
{
|
||||
std::vector<std::string> candidates;
|
||||
int highestLevel = 0;
|
||||
for (std::vector<ESM::LeveledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
|
||||
{
|
||||
if (it->mLevel > highestLevel)
|
||||
highestLevel = it->mLevel;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (playerLevel >= it->mLevel
|
||||
&& (levItem->mFlags & ESM::ItemLevList::AllLevels || it->mLevel == highestLevel))
|
||||
{
|
||||
candidates.push_back(it->mId);
|
||||
if (it->mLevel >= highest.first)
|
||||
highest = std::make_pair(it->mLevel, it->mId);
|
||||
}
|
||||
|
||||
}
|
||||
if (!candidates.size())
|
||||
return;
|
||||
std::string item = candidates[std::rand()%candidates.size()];
|
||||
addInitialItem(item, owner, count, failChance, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ref.getPtr().getRefData().setCount (count);
|
||||
ref.getPtr().getCellRef().mOwner = owner;
|
||||
addImp (ref.getPtr());
|
||||
}
|
||||
}
|
||||
|
||||
void MWWorld::ContainerStore::clear()
|
||||
{
|
||||
for (ContainerStoreIterator iter (begin()); iter!=end(); ++iter)
|
||||
|
|
|
@ -53,6 +53,7 @@ namespace MWWorld
|
|||
mutable float mCachedWeight;
|
||||
mutable bool mWeightUpToDate;
|
||||
ContainerStoreIterator addImp (const Ptr& ptr);
|
||||
void addInitialItem (const std::string& id, const std::string& owner, int count, unsigned char failChance=0, bool topLevel=true);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -84,7 +85,7 @@ namespace MWWorld
|
|||
|
||||
public:
|
||||
|
||||
void fill (const ESM::InventoryList& items, const MWWorld::ESMStore& store);
|
||||
void fill (const ESM::InventoryList& items, const std::string& owner, const MWWorld::ESMStore& store);
|
||||
///< Insert items into *this.
|
||||
|
||||
void clear();
|
||||
|
|
|
@ -24,4 +24,12 @@ void BirthSign::save(ESMWriter &esm)
|
|||
mPowers.save(esm);
|
||||
}
|
||||
|
||||
void BirthSign::blank()
|
||||
{
|
||||
mName.clear();
|
||||
mDescription.clear();
|
||||
mTexture.clear();
|
||||
mPowers.mList.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,9 @@ struct BirthSign
|
|||
|
||||
void load(ESMReader &esm);
|
||||
void save(ESMWriter &esm);
|
||||
|
||||
void blank();
|
||||
///< Set record to default state (does not touch the ID/index).
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -22,17 +22,20 @@ struct LeveledListBase
|
|||
{
|
||||
enum Flags
|
||||
{
|
||||
AllLevels = 0x01, // Calculate from all levels <= player
|
||||
// level, not just the closest below
|
||||
// player.
|
||||
Each = 0x02 // Select a new item each time this
|
||||
|
||||
Each = 0x01, // Select a new item each time this
|
||||
// list is instantiated, instead of
|
||||
// giving several identical items
|
||||
}; // (used when a container has more
|
||||
// (used when a container has more
|
||||
// than one instance of one leveled
|
||||
// list.)
|
||||
AllLevels = 0x02 // Calculate from all levels <= player
|
||||
// level, not just the closest below
|
||||
// player.
|
||||
};
|
||||
|
||||
int mFlags;
|
||||
unsigned char mChanceNone; // Chance that none are selected (0-255?)
|
||||
unsigned char mChanceNone; // Chance that none are selected (0-100)
|
||||
std::string mId;
|
||||
|
||||
// Record name used to read references. Must be set before load() is
|
||||
|
|
|
@ -35,11 +35,11 @@ struct NPC
|
|||
Apparatus = 0x00100,
|
||||
RepairItem = 0x00200,
|
||||
Misc = 0x00400,
|
||||
Potions = 0x02000,
|
||||
|
||||
// Other services
|
||||
Spells = 0x00800,
|
||||
MagicItems = 0x01000,
|
||||
Potions = 0x02000,
|
||||
Training = 0x04000, // What skills?
|
||||
Spellmaking = 0x08000,
|
||||
Enchanting = 0x10000,
|
||||
|
|
|
@ -1109,16 +1109,28 @@ static Ogre::String getMaterial(const Nif::ShapeData *shapedata,
|
|||
|
||||
instance->setProperty("diffuseMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BaseTexture]));
|
||||
instance->setProperty("normalMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BumpTexture]));
|
||||
instance->setProperty("detailMap", sh::makeProperty(texName[Nif::NiTexturingProperty::DetailTexture]));
|
||||
instance->setProperty("emissiveMap", sh::makeProperty(texName[Nif::NiTexturingProperty::GlowTexture]));
|
||||
if (!texName[Nif::NiTexturingProperty::GlowTexture].empty())
|
||||
{
|
||||
instance->setProperty("use_emissive_map", sh::makeProperty(new sh::BooleanValue(true)));
|
||||
instance->setProperty("emissiveMapUVSet", sh::makeProperty(new sh::IntValue(texprop->textures[Nif::NiTexturingProperty::GlowTexture].uvSet)));
|
||||
}
|
||||
if (!texName[Nif::NiTexturingProperty::DetailTexture].empty())
|
||||
{
|
||||
instance->setProperty("use_detail_map", sh::makeProperty(new sh::BooleanValue(true)));
|
||||
instance->setProperty("detailMapUVSet", sh::makeProperty(new sh::IntValue(texprop->textures[Nif::NiTexturingProperty::DetailTexture].uvSet)));
|
||||
}
|
||||
if (!texName[Nif::NiTexturingProperty::BumpTexture].empty())
|
||||
{
|
||||
// force automips on normal maps for now
|
||||
instance->setProperty("normalMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BumpTexture] + " 4"));
|
||||
}
|
||||
|
||||
for(int i = 0;i < 7;i++)
|
||||
{
|
||||
if(i == Nif::NiTexturingProperty::BaseTexture ||
|
||||
i == Nif::NiTexturingProperty::DetailTexture ||
|
||||
i == Nif::NiTexturingProperty::BumpTexture ||
|
||||
i == Nif::NiTexturingProperty::GlowTexture)
|
||||
continue;
|
||||
|
@ -1390,18 +1402,20 @@ class NIFObjectLoader : Ogre::ManualResourceLoader
|
|||
size_t numUVs = data->uvlist.size();
|
||||
if(numUVs)
|
||||
{
|
||||
size_t elemSize = Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);
|
||||
vbuf = hwBufMgr->createVertexBuffer(elemSize, srcVerts.size()*numUVs,
|
||||
Ogre::HardwareBuffer::HBU_STATIC);
|
||||
for(size_t i = 0;i < numUVs;i++)
|
||||
{
|
||||
size_t elemSize = Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);
|
||||
vbuf = hwBufMgr->createVertexBuffer(elemSize, srcVerts.size(),
|
||||
Ogre::HardwareBuffer::HBU_STATIC);
|
||||
|
||||
const std::vector<Ogre::Vector2> &uvlist = data->uvlist[i];
|
||||
vbuf->writeData(i*srcVerts.size()*elemSize, elemSize*srcVerts.size(), &uvlist[0], true);
|
||||
decl->addElement(nextBuf, i*srcVerts.size()*elemSize, Ogre::VET_FLOAT2,
|
||||
|
||||
vbuf->writeData(0, elemSize*srcVerts.size(), &uvlist[0], true);
|
||||
decl->addElement(nextBuf, 0, Ogre::VET_FLOAT2,
|
||||
Ogre::VES_TEXTURE_COORDINATES, i);
|
||||
}
|
||||
bind->setBinding(nextBuf++, vbuf);
|
||||
}
|
||||
}
|
||||
|
||||
// Triangle faces
|
||||
const std::vector<short> &srcIdx = data->triangles;
|
||||
|
|
|
@ -9,9 +9,10 @@ material openmw_objects_base
|
|||
normalMap
|
||||
emissiveMap
|
||||
use_emissive_map false
|
||||
use_detail_map false
|
||||
emissiveMapUVSet 0
|
||||
detailMapUVSet 0
|
||||
|
||||
is_transparent false // real transparency, alpha rejection doesn't count here
|
||||
scene_blend default
|
||||
depth_write default
|
||||
depth_check default
|
||||
|
@ -27,10 +28,11 @@ material openmw_objects_base
|
|||
shader_properties
|
||||
{
|
||||
vertexcolor_mode $vertmode
|
||||
is_transparent $is_transparent
|
||||
normalMap $normalMap
|
||||
emissiveMapUVSet $emissiveMapUVSet
|
||||
detailMapUVSet $detailMapUVSet
|
||||
emissiveMap $emissiveMap
|
||||
detailMap $detailMap
|
||||
}
|
||||
|
||||
diffuse $diffuse
|
||||
|
@ -53,7 +55,7 @@ material openmw_objects_base
|
|||
|
||||
texture_unit normalMap
|
||||
{
|
||||
direct_texture $normalMap
|
||||
texture $normalMap
|
||||
}
|
||||
|
||||
texture_unit emissiveMap
|
||||
|
@ -64,6 +66,14 @@ material openmw_objects_base
|
|||
tex_coord_set $emissiveMapUVSet
|
||||
}
|
||||
|
||||
texture_unit detailMap
|
||||
{
|
||||
create_in_ffp $use_detail_map
|
||||
colour_op_ex modulate_x2 src_current src_texture
|
||||
direct_texture $detailMap
|
||||
tex_coord_set $detailMapUVSet
|
||||
}
|
||||
|
||||
texture_unit shadowMap0
|
||||
{
|
||||
content_type shadow
|
||||
|
|
|
@ -16,9 +16,10 @@
|
|||
|
||||
#define NORMAL_MAP @shPropertyHasValue(normalMap)
|
||||
#define EMISSIVE_MAP @shPropertyHasValue(emissiveMap)
|
||||
#define DETAIL_MAP @shPropertyHasValue(detailMap)
|
||||
|
||||
// right now we support 2 UV sets max. implementing them is tedious, and we're probably not going to need more
|
||||
#define SECOND_UV_SET @shPropertyString(emissiveMapUVSet)
|
||||
#define SECOND_UV_SET (@shPropertyString(emissiveMapUVSet) || @shPropertyString(detailMapUVSet))
|
||||
|
||||
// if normal mapping is enabled, we force pixel lighting
|
||||
#define VERTEX_LIGHTING (!@shPropertyHasValue(normalMap))
|
||||
|
@ -238,6 +239,10 @@
|
|||
shSampler2D(emissiveMap)
|
||||
#endif
|
||||
|
||||
#if DETAIL_MAP
|
||||
shSampler2D(detailMap)
|
||||
#endif
|
||||
|
||||
shInput(float4, UV)
|
||||
|
||||
#if NORMAL_MAP
|
||||
|
@ -315,6 +320,14 @@
|
|||
{
|
||||
shOutputColour(0) = shSample(diffuseMap, UV.xy);
|
||||
|
||||
#if DETAIL_MAP
|
||||
#if @shPropertyString(detailMapUVSet)
|
||||
shOutputColour(0) *= shSample(detailMap, UV.zw)*2;
|
||||
#else
|
||||
shOutputColour(0) *= shSample(detailMap, UV.xy)*2;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if NORMAL_MAP
|
||||
float3 normal = normalPassthrough;
|
||||
float3 binormal = cross(tangentPassthrough.xyz, normal.xyz);
|
||||
|
@ -421,7 +434,7 @@
|
|||
#endif
|
||||
|
||||
#if EMISSIVE_MAP
|
||||
#if SECOND_UV_SET
|
||||
#if @shPropertyString(emissiveMapUVSet)
|
||||
shOutputColour(0).xyz += shSample(emissiveMap, UV.zw).xyz;
|
||||
#else
|
||||
shOutputColour(0).xyz += shSample(emissiveMap, UV.xy).xyz;
|
||||
|
|
Loading…
Reference in a new issue