1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-20 09:53:51 +00:00

merge openmw master

This commit is contained in:
mrcheko 2014-06-09 22:37:49 +04:00
commit 08e8dab067
269 changed files with 4048 additions and 2153 deletions

View file

@ -90,13 +90,13 @@ endif(UNIX AND NOT APPLE)
# Location of morrowind data files # Location of morrowind data files
if (APPLE) if (APPLE)
set(MORROWIND_DATA_FILES "./data" CACHE PATH "location of Morrowind data files") set(MORROWIND_DATA_FILES "./data" CACHE PATH "location of Morrowind data files")
set(MORROWIND_RESOURCE_FILES "./resources" CACHE PATH "location of OpenMW resources files") set(OPENMW_RESOURCE_FILES "./resources" CACHE PATH "location of OpenMW resources files")
elseif(UNIX) elseif(UNIX)
set(MORROWIND_DATA_FILES "/usr/share/games/openmw/data/" CACHE PATH "location of Morrowind data files") set(MORROWIND_DATA_FILES "${CMAKE_INSTALL_PREFIX}/share/games/openmw/data/" CACHE PATH "location of Morrowind data files")
set(MORROWIND_RESOURCE_FILES "/usr/share/games/openmw/resources/" CACHE PATH "location of OpenMW resources files") set(OPENMW_RESOURCE_FILES "${CMAKE_INSTALL_PREFIX}/share/games/openmw/resources/" CACHE PATH "location of OpenMW resources files")
else() else()
set(MORROWIND_DATA_FILES "data" CACHE PATH "location of Morrowind data files") set(MORROWIND_DATA_FILES "data" CACHE PATH "location of Morrowind data files")
set(MORROWIND_RESOURCE_FILES "resources" CACHE PATH "location of OpenMW resources files") set(OPENMW_RESOURCE_FILES "resources" CACHE PATH "location of OpenMW resources files")
endif(APPLE) endif(APPLE)
if (WIN32) if (WIN32)
@ -239,16 +239,40 @@ find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
find_package(SDL2 REQUIRED) find_package(SDL2 REQUIRED)
find_package(OpenAL REQUIRED) find_package(OpenAL REQUIRED)
find_package(Bullet REQUIRED) find_package(Bullet REQUIRED)
IF(OGRE_STATIC)
find_package(Cg) set(OGRE_PLUGIN_INCLUDE_DIRS "")
IF(WIN32) set(OGRE_STATIC_PLUGINS "")
set(OGRE_PLUGIN_INCLUDE_DIRS ${OGRE_Plugin_CgProgramManager_INCLUDE_DIRS} ${OGRE_Plugin_OctreeSceneManager_INCLUDE_DIRS} ${OGRE_Plugin_ParticleFX_INCLUDE_DIRS} ${OGRE_RenderSystem_Direct3D9_INCLUDE_DIRS} ${OGRE_RenderSystem_GL_INCLUDE_DIRS})
ELSE(WIN32) macro(add_static_ogre_plugin PLUGIN)
set(OGRE_PLUGIN_INCLUDE_DIRS ${OGRE_Plugin_CgProgramManager_INCLUDE_DIRS} ${OGRE_Plugin_OctreeSceneManager_INCLUDE_DIRS} ${OGRE_Plugin_ParticleFX_INCLUDE_DIRS} ${OGRE_RenderSystem_GL_INCLUDE_DIRS}) if(OGRE_${PLUGIN}_FOUND)
ENDIF(WIN32) # strip RenderSystem_ or Plugin_ prefix from plugin name
ENDIF(OGRE_STATIC) string(REPLACE "RenderSystem_" "" PLUGIN_TEMP ${PLUGIN})
string(REPLACE "Plugin_" "" PLUGIN_NAME ${PLUGIN_TEMP})
add_definitions(-DENABLE_PLUGIN_${PLUGIN_NAME})
list(APPEND OGRE_PLUGIN_INCLUDE_DIRS ${OGRE_${PLUGIN}_INCLUDE_DIRS})
list(APPEND OGRE_STATIC_PLUGINS ${OGRE_${PLUGIN}_LIBRARIES})
endif(OGRE_${PLUGIN}_FOUND)
endmacro(add_static_ogre_plugin)
if(OGRE_STATIC)
# set up OGRE_PLUGIN_INCLUDE_DIRS and OGRE_STATIC_PLUGINS
add_static_ogre_plugin(Plugin_OctreeSceneManager)
add_static_ogre_plugin(Plugin_ParticleFX)
find_package(Cg)
if(Cg_FOUND)
add_static_ogre_plugin(Plugin_CgProgramManager)
list(APPEND OGRE_STATIC_PLUGINS ${Cg_LIBRARIES})
endif(Cg_FOUND)
add_static_ogre_plugin(RenderSystem_GL)
if(WIN32)
add_static_ogre_plugin(RenderSystem_Direct3D9)
endif(WIN32)
endif(OGRE_STATIC)
include_directories("." include_directories("."
${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_PLUGIN_INCLUDE_DIRS} ${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_INCLUDE_DIRS} ${OGRE_PLUGIN_INCLUDE_DIRS}
${SDL2_INCLUDE_DIR} ${SDL2_INCLUDE_DIR}
${Boost_INCLUDE_DIR} ${Boost_INCLUDE_DIR}
${PLATFORM_INCLUDE_DIR} ${PLATFORM_INCLUDE_DIR}
@ -260,6 +284,10 @@ include_directories("."
link_directories(${SDL2_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR}) link_directories(${SDL2_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR})
if(MYGUI_STATIC)
add_definitions(-DMYGUI_STATIC)
endif (MYGUI_STATIC)
if (APPLE) if (APPLE)
# List used Ogre plugins # List used Ogre plugins
SET(USED_OGRE_PLUGINS ${OGRE_RenderSystem_GL_LIBRARY_REL} SET(USED_OGRE_PLUGINS ${OGRE_RenderSystem_GL_LIBRARY_REL}

View file

@ -387,7 +387,7 @@ std::string magicEffectLabel(int idx)
"sEffectSummonCreature04", "sEffectSummonCreature04",
"sEffectSummonCreature05" "sEffectSummonCreature05"
}; };
if (idx >= 0 && idx <= 143) if (idx >= 0 && idx <= 142)
return magicEffectLabels[idx]; return magicEffectLabels[idx];
else else
return "Invalid"; return "Invalid";
@ -471,7 +471,7 @@ std::string skillLabel(int idx)
"Speechcraft", "Speechcraft",
"Hand-to-hand" "Hand-to-hand"
}; };
if (idx >= 0 && idx <= 27) if (idx >= 0 && idx <= 26)
return skillLabels[idx]; return skillLabels[idx];
else else
return "Invalid"; return "Invalid";
@ -498,7 +498,7 @@ std::string rangeTypeLabel(int idx)
"Touch", "Touch",
"Target" "Target"
}; };
if (idx >= 0 && idx <= 3) if (idx >= 0 && idx <= 2)
return rangeTypeLabels[idx]; return rangeTypeLabels[idx];
else else
return "Invalid"; return "Invalid";

View file

@ -707,9 +707,9 @@ void Record<ESM::Faction>::print()
std::cout << " Faction Reaction: " std::cout << " Faction Reaction: "
<< mData.mData.mRankData[i].mFactReaction << std::endl; << mData.mData.mRankData[i].mFactReaction << std::endl;
} }
std::vector<ESM::Faction::Reaction>::iterator rit; std::map<std::string, int>::iterator rit;
for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); rit++) for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); rit++)
std::cout << " Reaction: " << rit->mReaction << " = " << rit->mFaction << std::endl; std::cout << " Reaction: " << rit->second << " = " << rit->first << std::endl;
} }
template<> template<>

View file

@ -94,15 +94,6 @@ if(NOT WIN32)
endif(NOT WIN32) endif(NOT WIN32)
# Main executable # Main executable
IF(OGRE_STATIC)
IF(WIN32)
ADD_DEFINITIONS(-DENABLE_PLUGIN_Direct3D9 -DENABLE_PLUGIN_GL)
set(OGRE_STATIC_PLUGINS ${OGRE_RenderSystem_Direct3D9_LIBRARIES} ${OGRE_RenderSystem_GL_LIBRARIES})
ELSE(WIN32)
ADD_DEFINITIONS(-DENABLE_PLUGIN_GL)
set(OGRE_STATIC_PLUGINS ${OGRE_RenderSystem_GL_LIBRARIES})
ENDIF(WIN32)
ENDIF(OGRE_STATIC)
add_executable(omwlauncher add_executable(omwlauncher
${GUI_TYPE} ${GUI_TYPE}
${LAUNCHER} ${LAUNCHER}
@ -116,7 +107,7 @@ target_link_libraries(omwlauncher
${Boost_LIBRARIES} ${Boost_LIBRARIES}
${OGRE_LIBRARIES} ${OGRE_LIBRARIES}
${OGRE_STATIC_PLUGINS} ${OGRE_STATIC_PLUGINS}
${SDL2_LIBRARY} ${SDL2_LIBRARY_ONLY}
${QT_LIBRARIES} ${QT_LIBRARIES}
components components
) )

View file

@ -806,7 +806,7 @@ void Launcher::MainDialog::play()
msgBox.setWindowTitle(tr("No game file selected")); msgBox.setWindowTitle(tr("No game file selected"));
msgBox.setIcon(QMessageBox::Warning); msgBox.setIcon(QMessageBox::Warning);
msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setText(tr("<br><b>You do not have no game file selected.</b><br><br> \ msgBox.setText(tr("<br><b>You do not have a game file selected.</b><br><br> \
OpenMW will not start without a game file selected.<br>")); OpenMW will not start without a game file selected.<br>"));
msgBox.exec(); msgBox.exec();
return; return;

View file

@ -192,6 +192,7 @@ endif(APPLE)
target_link_libraries(opencs target_link_libraries(opencs
${OGRE_LIBRARIES} ${OGRE_LIBRARIES}
${OGRE_STATIC_PLUGINS}
${SHINY_LIBRARIES} ${SHINY_LIBRARIES}
${Boost_LIBRARIES} ${Boost_LIBRARIES}
${QT_LIBRARIES} ${QT_LIBRARIES}

View file

@ -65,7 +65,11 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje
appendStage (new WriteRefIdCollectionStage (mDocument, mState)); appendStage (new WriteRefIdCollectionStage (mDocument, mState));
appendStage (new CollectionReferencesStage (mDocument, mState));
appendStage (new WriteCellCollectionStage (mDocument, mState));
// close file and clean up
appendStage (new CloseSaveStage (mState)); appendStage (new CloseSaveStage (mState));
appendStage (new FinalSavingStage (mDocument, mState)); appendStage (new FinalSavingStage (mDocument, mState));

View file

@ -9,6 +9,8 @@
#include <components/esm/loaddial.hpp> #include <components/esm/loaddial.hpp>
#include <components/misc/stringops.hpp>
#include "../world/infocollection.hpp" #include "../world/infocollection.hpp"
#include "document.hpp" #include "document.hpp"
@ -216,6 +218,143 @@ void CSMDoc::WriteFilterStage::perform (int stage, Messages& messages)
} }
CSMDoc::CollectionReferencesStage::CollectionReferencesStage (Document& document,
SavingState& state)
: mDocument (document), mState (state)
{}
int CSMDoc::CollectionReferencesStage::setup()
{
mState.getSubRecords().clear();
int size = mDocument.getData().getReferences().getSize();
int steps = size/100;
if (size%100) ++steps;
return steps;
}
void CSMDoc::CollectionReferencesStage::perform (int stage, Messages& messages)
{
int size = mDocument.getData().getReferences().getSize();
for (int i=stage*100; i<stage*100+100 && i<size; ++i)
{
const CSMWorld::Record<CSMWorld::CellRef>& record =
mDocument.getData().getReferences().getRecord (i);
if (record.mState==CSMWorld::RecordBase::State_Deleted ||
record.mState==CSMWorld::RecordBase::State_Modified ||
record.mState==CSMWorld::RecordBase::State_ModifiedOnly)
{
mState.getSubRecords()[Misc::StringUtils::lowerCase (record.get().mCell)]
.push_back (i);
}
}
}
CSMDoc::WriteCellCollectionStage::WriteCellCollectionStage (Document& document,
SavingState& state)
: mDocument (document), mState (state)
{}
int CSMDoc::WriteCellCollectionStage::setup()
{
return mDocument.getData().getCells().getSize();
}
void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
{
const CSMWorld::Record<CSMWorld::Cell>& cell =
mDocument.getData().getCells().getRecord (stage);
std::map<std::string, std::vector<int> >::const_iterator references =
mState.getSubRecords().find (Misc::StringUtils::lowerCase (cell.get().mId));
if (cell.mState==CSMWorld::RecordBase::State_Modified ||
cell.mState==CSMWorld::RecordBase::State_ModifiedOnly ||
references!=mState.getSubRecords().end())
{
bool interior = cell.get().mId.substr (0, 1)!="#";
// write cell data
mState.getWriter().startRecord (cell.mModified.sRecordId);
mState.getWriter().writeHNOCString ("NAME", cell.get().mName);
ESM::Cell cell2 = cell.get();
if (interior)
cell2.mData.mFlags |= ESM::Cell::Interior;
else
{
cell2.mData.mFlags &= ~ESM::Cell::Interior;
std::istringstream stream (cell.get().mId.c_str());
char ignore;
stream >> ignore >> cell2.mData.mX >> cell2.mData.mY;
}
cell2.save (mState.getWriter());
// write references
if (references!=mState.getSubRecords().end())
{
// first pass: find highest RefNum
int lastRefNum = -1;
for (std::vector<int>::const_iterator iter (references->second.begin());
iter!=references->second.end(); ++iter)
{
const CSMWorld::Record<CSMWorld::CellRef>& ref =
mDocument.getData().getReferences().getRecord (*iter);
if (ref.get().mRefNum.mContentFile==0 && ref.get().mRefNum.mIndex>lastRefNum)
lastRefNum = ref.get().mRefNum.mIndex;
}
// second pass: write
for (std::vector<int>::const_iterator iter (references->second.begin());
iter!=references->second.end(); ++iter)
{
const CSMWorld::Record<CSMWorld::CellRef>& ref =
mDocument.getData().getReferences().getRecord (*iter);
if (ref.mState==CSMWorld::RecordBase::State_Modified ||
ref.mState==CSMWorld::RecordBase::State_ModifiedOnly)
{
if (ref.get().mRefNum.mContentFile==-2)
{
if (lastRefNum>=0xffffff)
throw std::runtime_error (
"RefNums exhausted in cell: " + cell.get().mId);
ESM::CellRef ref2 = ref.get();
ref2.mRefNum.mContentFile = 0;
ref2.mRefNum.mIndex = ++lastRefNum;
ref2.save (mState.getWriter());
}
else
ref.get().save (mState.getWriter());
}
else if (ref.mState==CSMWorld::RecordBase::State_Deleted)
{
/// \todo write record with delete flag
}
}
}
mState.getWriter().endRecord (cell.mModified.sRecordId);
}
else if (cell.mState==CSMWorld::RecordBase::State_Deleted)
{
/// \todo write record with delete flag
}
}
CSMDoc::CloseSaveStage::CloseSaveStage (SavingState& state) CSMDoc::CloseSaveStage::CloseSaveStage (SavingState& state)
: mState (state) : mState (state)
{} {}

View file

@ -163,8 +163,40 @@ namespace CSMDoc
virtual void perform (int stage, Messages& messages); virtual void perform (int stage, Messages& messages);
///< Messages resulting from this stage will be appended to \a messages. ///< Messages resulting from this stage will be appended to \a messages.
}; };
class CollectionReferencesStage : public Stage
{
Document& mDocument;
SavingState& mState;
public:
CollectionReferencesStage (Document& document, SavingState& state);
virtual int setup();
///< \return number of steps
virtual void perform (int stage, Messages& messages);
///< Messages resulting from this stage will be appended to \a messages.
};
class WriteCellCollectionStage : public Stage
{
Document& mDocument;
SavingState& mState;
public:
WriteCellCollectionStage (Document& document, SavingState& state);
virtual int setup();
///< \return number of steps
virtual void perform (int stage, Messages& messages);
///< Messages resulting from this stage will be appended to \a messages.
};
class CloseSaveStage : public Stage class CloseSaveStage : public Stage
{ {

View file

@ -25,6 +25,8 @@ void CSMDoc::SavingState::start (Document& document, bool project)
mStream.clear(); mStream.clear();
mSubRecords.clear();
if (project) if (project)
mPath = mProjectPath; mPath = mProjectPath;
else else
@ -61,3 +63,8 @@ bool CSMDoc::SavingState::isProjectFile() const
{ {
return mProjectFile; return mProjectFile;
} }
std::map<std::string, std::vector<int> >& CSMDoc::SavingState::getSubRecords()
{
return mSubRecords;
}

View file

@ -2,6 +2,7 @@
#define CSM_DOC_SAVINGSTATE_H #define CSM_DOC_SAVINGSTATE_H
#include <fstream> #include <fstream>
#include <map>
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
@ -25,6 +26,7 @@ namespace CSMDoc
ESM::ESMWriter mWriter; ESM::ESMWriter mWriter;
boost::filesystem::path mProjectPath; boost::filesystem::path mProjectPath;
bool mProjectFile; bool mProjectFile;
std::map<std::string, std::vector<int> > mSubRecords; // record ID, list of subrecords
public: public:
@ -46,6 +48,8 @@ namespace CSMDoc
bool isProjectFile() const; bool isProjectFile() const;
///< Currently saving project file? (instead of content file) ///< Currently saving project file? (instead of content file)
std::map<std::string, std::vector<int> >& getSubRecords();
}; };

View file

@ -621,12 +621,6 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
} }
else else
{ {
if (npc.mNpdt52.mMana < 0)
messages.push_back (std::make_pair (id, npc.mId + " mana has negative value"));
if (npc.mNpdt52.mFatigue < 0)
messages.push_back (std::make_pair (id, npc.mId + " fatigue has negative value"));
if (npc.mNpdt52.mAgility == 0) if (npc.mNpdt52.mAgility == 0)
messages.push_back (std::make_pair (id, npc.mId + " agility has zero value")); messages.push_back (std::make_pair (id, npc.mId + " agility has zero value"));

View file

@ -18,8 +18,3 @@ void CSMWorld::Cell::load (ESM::ESMReader &esm)
mId = stream.str(); mId = stream.str();
} }
} }
void CSMWorld::Cell::addRef (const std::string& id)
{
mRefs.push_back (std::make_pair (id, false));
}

View file

@ -15,12 +15,9 @@ namespace CSMWorld
struct Cell : public ESM::Cell struct Cell : public ESM::Cell
{ {
std::string mId; std::string mId;
std::vector<std::pair<std::string, bool> > mRefs; // ID, modified
std::vector<std::string> mDeletedRefs;
void load (ESM::ESMReader &esm); void load (ESM::ESMReader &esm);
void addRef (const std::string& id);
}; };
} }

View file

@ -489,6 +489,7 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base
delete mReader; delete mReader;
mReader = 0; mReader = 0;
mDialogue = 0; mDialogue = 0;
mRefLoadCache.clear();
mReader = new ESM::ESMReader; mReader = new ESM::ESMReader;
mReader->setEncoder (&mEncoder); mReader->setEncoder (&mEncoder);
@ -513,6 +514,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
delete mReader; delete mReader;
mReader = 0; mReader = 0;
mDialogue = 0; mDialogue = 0;
mRefLoadCache.clear();
return true; return true;
} }
@ -534,9 +536,12 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
case ESM::REC_SPEL: mSpells.load (*mReader, mBase); break; case ESM::REC_SPEL: mSpells.load (*mReader, mBase); break;
case ESM::REC_CELL: case ESM::REC_CELL:
{
mCells.load (*mReader, mBase); mCells.load (*mReader, mBase);
mRefs.load (*mReader, mCells.getSize()-1, mBase); std::string cellId = Misc::StringUtils::lowerCase (mCells.getId (mCells.getSize()-1));
mRefs.load (*mReader, mCells.getSize()-1, mBase, mRefLoadCache[cellId], messages);
break; break;
}
case ESM::REC_ACTI: mReferenceables.load (*mReader, mBase, UniversalId::Type_Activator); break; case ESM::REC_ACTI: mReferenceables.load (*mReader, mBase, UniversalId::Type_Activator); break;
case ESM::REC_ALCH: mReferenceables.load (*mReader, mBase, UniversalId::Type_Potion); break; case ESM::REC_ALCH: mReferenceables.load (*mReader, mBase, UniversalId::Type_Potion); break;

View file

@ -77,6 +77,7 @@ namespace CSMWorld
const ESM::Dialogue *mDialogue; // last loaded dialogue const ESM::Dialogue *mDialogue; // last loaded dialogue
bool mBase; bool mBase;
bool mProject; bool mProject;
std::map<std::string, std::map<ESM::RefNum, std::string> > mRefLoadCache;
// not implemented // not implemented
Data (const Data&); Data (const Data&);

View file

@ -1,12 +1,10 @@
#include "ref.hpp" #include "ref.hpp"
#include "cell.hpp" CSMWorld::CellRef::CellRef()
void CSMWorld::CellRef::load (ESM::ESMReader &esm, Cell& cell, const std::string& id)
{ {
mId = id; mRefNum.mIndex = 0;
mCell = cell.mId;
cell.addRef (mId); // special marker: This reference does not have a RefNum assign to it yet.
mRefNum.mContentFile = -2;
} }

View file

@ -3,11 +3,6 @@
#include <components/esm/cellref.hpp> #include <components/esm/cellref.hpp>
namespace ESM
{
class ESMReader;
}
namespace CSMWorld namespace CSMWorld
{ {
class Cell; class Cell;
@ -18,8 +13,7 @@ namespace CSMWorld
std::string mId; std::string mId;
std::string mCell; std::string mCell;
void load (ESM::ESMReader &esm, Cell& cell, const std::string& id); CellRef();
///< Load cell ref and register it with \a cell.
}; };
} }

View file

@ -3,12 +3,15 @@
#include <sstream> #include <sstream>
#include <components/misc/stringops.hpp>
#include "ref.hpp" #include "ref.hpp"
#include "cell.hpp" #include "cell.hpp"
#include "universalid.hpp" #include "universalid.hpp"
#include "record.hpp" #include "record.hpp"
void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool base) void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool base,
std::map<ESM::RefNum, std::string>& cache, CSMDoc::Stage::Messages& messages)
{ {
Record<Cell> cell = mCells.getRecord (cellIndex); Record<Cell> cell = mCells.getRecord (cellIndex);
@ -17,19 +20,73 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
CellRef ref; CellRef ref;
bool deleted = false; bool deleted = false;
while (cell2.getNextRef (reader, ref, deleted))
while (ESM::Cell::getNextRef (reader, ref, deleted))
{ {
/// \todo handle deleted and moved references ref.mCell = cell2.mId;
ref.load (reader, cell2, getNewId());
Record<CellRef> record2; /// \todo handle moved references
record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
(base ? record2.mBase : record2.mModified) = ref;
appendRecord (record2); std::map<ESM::RefNum, std::string>::iterator iter = cache.find (ref.mRefNum);
if (deleted)
{
if (iter==cache.end())
{
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Cell,
mCells.getId (cellIndex));
messages.push_back (std::make_pair (id,
"Attempt to delete a non-existing reference"));
continue;
}
int index = getIndex (iter->second);
Record<CellRef> record = getRecord (index);
if (record.mState==RecordBase::State_BaseOnly)
{
removeRows (index, 1);
cache.erase (iter);
}
else
{
record.mState = RecordBase::State_Deleted;
setRecord (index, record);
}
continue;
}
if (iter==cache.end())
{
// new reference
ref.mId = getNewId();
Record<CellRef> record;
record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
(base ? record.mBase : record.mModified) = ref;
appendRecord (record);
cache.insert (std::make_pair (ref.mRefNum, ref.mId));
}
else
{
// old reference -> merge
ref.mId = iter->second;
int index = getIndex (ref.mId);
Record<CellRef> record = getRecord (index);
record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_Modified;
(base ? record.mBase : record.mModified) = ref;
setRecord (index, record);
}
} }
mCells.setRecord (cellIndex, cell);
} }
std::string CSMWorld::RefCollection::getNewId() std::string CSMWorld::RefCollection::getNewId()

View file

@ -1,6 +1,10 @@
#ifndef CSM_WOLRD_REFCOLLECTION_H #ifndef CSM_WOLRD_REFCOLLECTION_H
#define CSM_WOLRD_REFCOLLECTION_H #define CSM_WOLRD_REFCOLLECTION_H
#include <map>
#include "../doc/stage.hpp"
#include "collection.hpp" #include "collection.hpp"
#include "ref.hpp" #include "ref.hpp"
#include "record.hpp" #include "record.hpp"
@ -22,7 +26,9 @@ namespace CSMWorld
: mCells (cells), mNextId (0) : mCells (cells), mNextId (0)
{} {}
void load (ESM::ESMReader& reader, int cellIndex, bool base); void load (ESM::ESMReader& reader, int cellIndex, bool base,
std::map<ESM::RefNum, std::string>& cache,
CSMDoc::Stage::Messages& messages);
///< Load a sequence of references. ///< Load a sequence of references.
std::string getNewId(); std::string getNewId();

View file

@ -304,10 +304,17 @@ CSMWorld::RefIdCollection::RefIdCollection()
mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponReach, ColumnBase::Display_Float)); mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponReach, ColumnBase::Display_Float));
weaponColumns.mReach = &mColumns.back(); weaponColumns.mReach = &mColumns.back();
for (int i=0; i<6; ++i) for (int i=0; i<3; ++i)
{ {
mColumns.push_back (RefIdColumn (Columns::ColumnId_MinChop + i, ColumnBase::Display_Integer)); const RefIdColumn **column =
weaponColumns.mChop[i] = &mColumns.back(); i==0 ? weaponColumns.mChop : (i==1 ? weaponColumns.mSlash : weaponColumns.mThrust);
for (int j=0; j<2; ++j)
{
mColumns.push_back (
RefIdColumn (Columns::ColumnId_MinChop+i*2+j, ColumnBase::Display_Integer));
column[j] = &mColumns.back();
}
} }
static const struct static const struct

View file

@ -33,7 +33,7 @@ add_openmw_dir (mwgui
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers savegamedialog tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers savegamedialog
recharge mode videowidget backgroundimage recharge mode videowidget backgroundimage itemwidget
) )
add_openmw_dir (mwdialogue add_openmw_dir (mwdialogue
@ -57,7 +57,7 @@ add_openmw_dir (mwworld
cells localscripts customdata weather inventorystore ptr actionopen actionread cells localscripts customdata weather inventorystore ptr actionopen actionread
actionequip timestamp actionalchemy cellstore actionapply actioneat actionequip timestamp actionalchemy cellstore actionapply actioneat
esmstore store recordcmp fallback actionrepair actionsoulgem livecellref actiondoor esmstore store recordcmp fallback actionrepair actionsoulgem livecellref actiondoor
contentloader esmloader omwloader actiontrap cellreflist projectilemanager contentloader esmloader omwloader actiontrap cellreflist projectilemanager cellref
) )
add_openmw_dir (mwclass add_openmw_dir (mwclass
@ -89,19 +89,6 @@ endif(WIN32)
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
IF(OGRE_STATIC)
ADD_DEFINITIONS(-DENABLE_PLUGIN_OctreeSceneManager -DENABLE_PLUGIN_ParticleFX -DENABLE_PLUGIN_GL)
set(OGRE_STATIC_PLUGINS ${OGRE_Plugin_OctreeSceneManager_LIBRARIES} ${OGRE_Plugin_ParticleFX_LIBRARIES} ${OGRE_RenderSystem_GL_LIBRARIES})
IF(WIN32)
ADD_DEFINITIONS(-DENABLE_PLUGIN_Direct3D9)
list (APPEND OGRE_STATIC_PLUGINS ${OGRE_RenderSystem_Direct3D9_LIBRARIES})
ENDIF(WIN32)
IF (Cg_FOUND)
ADD_DEFINITIONS(-DENABLE_PLUGIN_CgProgramManager)
list (APPEND OGRE_STATIC_PLUGINS ${OGRE_Plugin_CgProgramManager_LIBRARIES} ${Cg_LIBRARIES})
ENDIF (Cg_FOUND)
ENDIF(OGRE_STATIC)
add_executable(openmw add_executable(openmw
${OPENMW_LIBS} ${OPENMW_LIBS_HEADER} ${OPENMW_LIBS} ${OPENMW_LIBS_HEADER}
${OPENMW_FILES} ${OPENMW_FILES}

View file

@ -137,6 +137,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
} }
// update GUI // update GUI
MWBase::Environment::get().getWindowManager()->onFrame(frametime);
if (MWBase::Environment::get().getStateManager()->getState()!= if (MWBase::Environment::get().getStateManager()->getState()!=
MWBase::StateManager::State_NoGame) MWBase::StateManager::State_NoGame)
{ {
@ -145,7 +146,6 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
MWBase::Environment::get().getWorld()->getTriangleBatchCount(tri, batch); MWBase::Environment::get().getWorld()->getTriangleBatchCount(tri, batch);
MWBase::Environment::get().getWindowManager()->wmUpdateFps(window->getLastFPS(), tri, batch); MWBase::Environment::get().getWindowManager()->wmUpdateFps(window->getLastFPS(), tri, batch);
MWBase::Environment::get().getWindowManager()->onFrame(frametime);
MWBase::Environment::get().getWindowManager()->update(); MWBase::Environment::get().getWindowManager()->update();
} }
} }
@ -491,10 +491,7 @@ void OMW::Engine::activate()
MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr); MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr);
boost::shared_ptr<MWWorld::Action> action = interpreterContext.activate (ptr);
ptr.getClass().activate (ptr, MWBase::Environment::get().getWorld()->getPlayerPtr());
interpreterContext.activate (ptr, action);
std::string script = ptr.getClass().getScript (ptr); std::string script = ptr.getClass().getScript (ptr);
@ -508,7 +505,7 @@ void OMW::Engine::activate()
if (!interpreterContext.hasActivationBeenHandled()) if (!interpreterContext.hasActivationBeenHandled())
{ {
interpreterContext.executeActivation(); interpreterContext.executeActivation(ptr);
} }
} }

View file

@ -61,6 +61,8 @@ namespace MWBase
virtual void persuade (int type) = 0; virtual void persuade (int type) = 0;
virtual int getTemporaryDispositionChange () const = 0; virtual int getTemporaryDispositionChange () const = 0;
/// @note This change is temporary and gets discarded when dialogue ends.
virtual void applyDispositionChange (int delta) = 0; virtual void applyDispositionChange (int delta) = 0;
virtual int countSavedGameRecords() const = 0; virtual int countSavedGameRecords() const = 0;
@ -68,6 +70,12 @@ namespace MWBase
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const = 0; virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const = 0;
virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0; virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0;
/// Changes faction1's opinion of faction2 by \a diff.
virtual void modFactionReaction (const std::string& faction1, const std::string& faction2, int diff) = 0;
/// @return faction1's opinion of faction2
virtual int getFactionReaction (const std::string& faction1, const std::string& faction2) const = 0;
}; };
} }

View file

@ -1,7 +1,7 @@
#ifndef GAME_MWSTATE_STATEMANAGER_H #ifndef GAME_MWSTATE_STATEMANAGER_H
#define GAME_MWSTATE_STATEMANAGER_H #define GAME_MWSTATE_STATEMANAGER_H
#include <vector> #include <list>
#include <string> #include <string>
namespace MWState namespace MWState
@ -24,7 +24,7 @@ namespace MWBase
State_Running State_Running
}; };
typedef std::vector<MWState::Character>::const_iterator CharacterIterator; typedef std::list<MWState::Character>::const_iterator CharacterIterator;
private: private:

View file

@ -57,6 +57,7 @@ namespace MWGui
class InventoryWindow; class InventoryWindow;
class ContainerWindow; class ContainerWindow;
class DialogueWindow; class DialogueWindow;
class WindowModal;
enum ShowInDialogueMode { enum ShowInDialogueMode {
ShowInDialogueMode_IfPossible, ShowInDialogueMode_IfPossible,
@ -234,14 +235,19 @@ namespace MWBase
virtual void addVisitedLocation(const std::string& name, int x, int y) = 0; virtual void addVisitedLocation(const std::string& name, int x, int y) = 0;
/// Hides dialog and schedules dialog to be deleted.
virtual void removeDialog(OEngine::GUI::Layout* dialog) = 0; virtual void removeDialog(OEngine::GUI::Layout* dialog) = 0;
///< Hides dialog and schedules dialog to be deleted.
///Gracefully attempts to exit the topmost GUI mode
/** No guarentee of actually closing the window **/
virtual void exitCurrentGuiMode() = 0;
virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons = std::vector<std::string>(), enum MWGui::ShowInDialogueMode showInDialogueMode = MWGui::ShowInDialogueMode_IfPossible) = 0; virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons = std::vector<std::string>(), enum MWGui::ShowInDialogueMode showInDialogueMode = MWGui::ShowInDialogueMode_IfPossible) = 0;
virtual void staticMessageBox(const std::string& message) = 0; virtual void staticMessageBox(const std::string& message) = 0;
virtual void removeStaticMessageBox() = 0; virtual void removeStaticMessageBox() = 0;
/// returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox)
virtual int readPressedButton() = 0; virtual int readPressedButton() = 0;
///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox)
virtual void onFrame (float frameDuration) = 0; virtual void onFrame (float frameDuration) = 0;
@ -309,6 +315,19 @@ namespace MWBase
/// Does the current stack of GUI-windows permit saving? /// Does the current stack of GUI-windows permit saving?
virtual bool isSavingAllowed() const = 0; virtual bool isSavingAllowed() const = 0;
/// Returns the current Modal
/** Used to send exit command to active Modal when Esc is pressed **/
virtual MWGui::WindowModal* getCurrentModal() const = 0;
/// Sets the current Modal
/** Used to send exit command to active Modal when Esc is pressed **/
virtual void addCurrentModal(MWGui::WindowModal* input) = 0;
/// Removes the top Modal
/** Used when one Modal adds another Modal
\param input Pointer to the current modal, to ensure proper modal is removed **/
virtual void removeCurrentModal(MWGui::WindowModal* input) = 0;
}; };
} }

View file

@ -97,8 +97,8 @@ namespace MWClass
std::string text; std::string text;
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) if (MWBase::Environment::get().getWindowManager()->getFullHelp())
{ {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.text = text; info.text = text;

View file

@ -127,8 +127,8 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.text = text; info.text = text;

View file

@ -168,10 +168,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref = MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
if (ptr.getCellRef().mCharge == -1) return ref->mBase->mData.mValue * (static_cast<float>(getItemHealth(ptr)) / getItemMaxHealth(ptr));
return ref->mBase->mData.mValue;
else
return ref->mBase->mData.mValue * (static_cast<float>(ptr.getCellRef().mCharge) / getItemMaxHealth(ptr));
} }
void Armor::registerSelf() void Armor::registerSelf()
@ -242,7 +239,7 @@ namespace MWClass
text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->mBase->mData.mArmor); text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->mBase->mData.mArmor);
int remainingHealth = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mHealth; int remainingHealth = getItemHealth(ptr);
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(remainingHealth) + "/" text += "\n#{sCondition}: " + MWGui::ToolTips::toString(remainingHealth) + "/"
+ MWGui::ToolTips::toString(ref->mBase->mData.mHealth); + MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
@ -250,14 +247,14 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.enchant = ref->mBase->mEnchant; info.enchant = ref->mBase->mEnchant;
if (!info.enchant.empty()) if (!info.enchant.empty())
info.remainingEnchantCharge = ptr.getCellRef().mEnchantmentCharge; info.remainingEnchantCharge = ptr.getCellRef().getEnchantmentCharge();
info.text = text; info.text = text;
@ -272,7 +269,7 @@ namespace MWClass
return ref->mBase->mEnchant; return ref->mBase->mEnchant;
} }
void Armor::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const std::string Armor::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
{ {
MWWorld::LiveCellRef<ESM::Armor> *ref = MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
@ -283,15 +280,14 @@ namespace MWClass
newItem.mData.mEnchant=enchCharge; newItem.mData.mEnchant=enchCharge;
newItem.mEnchant=enchId; newItem.mEnchant=enchId;
const ESM::Armor *record = MWBase::Environment::get().getWorld()->createRecord (newItem); const ESM::Armor *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
ref->mBase = record; return record->mId;
ref->mRef.mRefID = record->mId;
} }
std::pair<int, std::string> Armor::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const std::pair<int, std::string> Armor::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const
{ {
MWWorld::InventoryStore& invStore = npc.getClass().getInventoryStore(npc); MWWorld::InventoryStore& invStore = npc.getClass().getInventoryStore(npc);
if (ptr.getCellRef().mCharge == 0) if (ptr.getCellRef().getCharge() == 0)
return std::make_pair(0, "#{sInventoryMessage1}"); return std::make_pair(0, "#{sInventoryMessage1}");
// slots that this item can be equipped in // slots that this item can be equipped in

View file

@ -67,7 +67,8 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @return the enchantment ID if the object is enchanted, otherwise an empty string
virtual void applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const; virtual std::string applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const;
///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it.
virtual std::pair<int, std::string> canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const; virtual std::pair<int, std::string> canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const;
///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon conflicts with that. \n ///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon conflicts with that. \n

View file

@ -139,8 +139,8 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
@ -159,7 +159,7 @@ namespace MWClass
return ref->mBase->mEnchant; return ref->mBase->mEnchant;
} }
void Book::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const std::string Book::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
{ {
MWWorld::LiveCellRef<ESM::Book> *ref = MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>(); ptr.get<ESM::Book>();
@ -171,8 +171,7 @@ namespace MWClass
newItem.mData.mEnchant=enchCharge; newItem.mData.mEnchant=enchCharge;
newItem.mEnchant=enchId; newItem.mEnchant=enchId;
const ESM::Book *record = MWBase::Environment::get().getWorld()->createRecord (newItem); const ESM::Book *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
ref->mBase = record; return record->mId;
ref->mRef.mRefID = record->mId;
} }
boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const

View file

@ -51,7 +51,8 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @return the enchantment ID if the object is enchanted, otherwise an empty string
virtual void applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const; virtual std::string applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const;
///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it.
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) const; virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu

View file

@ -193,14 +193,14 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.enchant = ref->mBase->mEnchant; info.enchant = ref->mBase->mEnchant;
if (!info.enchant.empty()) if (!info.enchant.empty())
info.remainingEnchantCharge = ptr.getCellRef().mEnchantmentCharge; info.remainingEnchantCharge = ptr.getCellRef().getEnchantmentCharge();
info.text = text; info.text = text;
@ -215,7 +215,7 @@ namespace MWClass
return ref->mBase->mEnchant; return ref->mBase->mEnchant;
} }
void Clothing::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const std::string Clothing::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
{ {
MWWorld::LiveCellRef<ESM::Clothing> *ref = MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
@ -226,8 +226,7 @@ namespace MWClass
newItem.mData.mEnchant=enchCharge; newItem.mData.mEnchant=enchCharge;
newItem.mEnchant=enchId; newItem.mEnchant=enchId;
const ESM::Clothing *record = MWBase::Environment::get().getWorld()->createRecord (newItem); const ESM::Clothing *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
ref->mBase = record; return record->mId;
ref->mRef.mRefID = record->mId;
} }
std::pair<int, std::string> Clothing::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const std::pair<int, std::string> Clothing::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const

View file

@ -59,7 +59,8 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @return the enchantment ID if the object is enchanted, otherwise an empty string
virtual void applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const; virtual std::string applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const;
///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it.
virtual std::pair<int, std::string> canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const; virtual std::pair<int, std::string> canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const;
///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon conflicts with that. ///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon conflicts with that.

View file

@ -53,7 +53,7 @@ namespace MWClass
ptr.get<ESM::Container>(); ptr.get<ESM::Container>();
data->mContainerStore.fill( data->mContainerStore.fill(
ref->mBase->mInventory, ptr.getCellRef().mOwner, ptr.getCellRef().mFaction, MWBase::Environment::get().getWorld()->getStore()); ref->mBase->mInventory, ptr.getCellRef().getOwner(), ptr.getCellRef().getFaction(), MWBase::Environment::get().getWorld()->getStore());
// store // store
ptr.getRefData().setCustomData (data.release()); ptr.getRefData().setCustomData (data.release());
@ -75,7 +75,7 @@ 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().mOwner, ptr.getCellRef().mFaction); store.restock(list, ptr, ptr.getCellRef().getOwner(), ptr.getCellRef().getFaction());
} }
void Container::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Container::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -129,16 +129,16 @@ namespace MWClass
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
MWWorld::InventoryStore& invStore = player.getClass().getInventoryStore(player); MWWorld::InventoryStore& invStore = player.getClass().getInventoryStore(player);
bool needKey = ptr.getCellRef().mLockLevel > 0; bool needKey = ptr.getCellRef().getLockLevel() > 0;
bool hasKey = false; bool hasKey = false;
std::string keyName; std::string keyName;
// make key id lowercase // make key id lowercase
std::string keyId = ptr.getCellRef().mKey; std::string keyId = ptr.getCellRef().getKey();
Misc::StringUtils::toLower(keyId); Misc::StringUtils::toLower(keyId);
for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it) for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it)
{ {
std::string refId = it->getCellRef().mRefID; std::string refId = it->getCellRef().getRefId();
Misc::StringUtils::toLower(refId); Misc::StringUtils::toLower(refId);
if (refId == keyId) if (refId == keyId)
{ {
@ -152,13 +152,13 @@ namespace MWClass
MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}"); MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}");
unlock(ptr); unlock(ptr);
// using a key disarms the trap // using a key disarms the trap
ptr.getCellRef().mTrap = ""; ptr.getCellRef().setTrap("");
} }
if (!needKey || hasKey) if (!needKey || hasKey)
{ {
if(ptr.getCellRef().mTrap.empty()) if(ptr.getCellRef().getTrap().empty())
{ {
boost::shared_ptr<MWWorld::Action> action (new MWWorld::ActionOpen(ptr)); boost::shared_ptr<MWWorld::Action> action (new MWWorld::ActionOpen(ptr));
return action; return action;
@ -166,7 +166,7 @@ namespace MWClass
else else
{ {
// Activate trap // Activate trap
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTrap(actor, ptr.getCellRef().mTrap, ptr)); boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTrap(actor, ptr.getCellRef().getTrap(), ptr));
action->setSound(trapActivationSound); action->setSound(trapActivationSound);
return action; return action;
} }
@ -227,16 +227,16 @@ namespace MWClass
info.caption = ref->mBase->mName; info.caption = ref->mBase->mName;
std::string text; std::string text;
if (ref->mRef.mLockLevel > 0) if (ptr.getCellRef().getLockLevel() > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel); text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ptr.getCellRef().getLockLevel());
else if (ref->mRef.mLockLevel < 0) else if (ptr.getCellRef().getLockLevel() < 0)
text += "\n#{sUnlocked}"; text += "\n#{sUnlocked}";
if (ref->mRef.mTrap != "") if (ptr.getCellRef().getTrap() != "")
text += "\n#{sTrapped}"; text += "\n#{sTrapped}";
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
@ -261,14 +261,14 @@ namespace MWClass
void Container::lock (const MWWorld::Ptr& ptr, int lockLevel) const void Container::lock (const MWWorld::Ptr& ptr, int lockLevel) const
{ {
if(lockLevel!=0) if(lockLevel!=0)
ptr.getCellRef().mLockLevel = abs(lockLevel); //Changes lock to locklevel, in positive ptr.getCellRef().setLockLevel(abs(lockLevel)); //Changes lock to locklevel, in positive
else else
ptr.getCellRef().mLockLevel = abs(ptr.getCellRef().mLockLevel); //No locklevel given, just flip the oriional one ptr.getCellRef().setLockLevel(abs(ptr.getCellRef().getLockLevel())); //No locklevel given, just flip the original one
} }
void Container::unlock (const MWWorld::Ptr& ptr) const void Container::unlock (const MWWorld::Ptr& ptr) const
{ {
ptr.getCellRef().mLockLevel = -abs(ptr.getCellRef().mLockLevel); //Makes lockLevel negative ptr.getCellRef().setLockLevel(-abs(ptr.getCellRef().getLockLevel())); //Makes lockLevel negative
} }

View file

@ -291,20 +291,24 @@ namespace MWClass
weaponDamage *= 0.5f + (stats.getAttribute(ESM::Attribute::Luck).getModified() / 100.0f); weaponDamage *= 0.5f + (stats.getAttribute(ESM::Attribute::Luck).getModified() / 100.0f);
if(weaphashealth) if(weaphashealth)
{ {
int weapmaxhealth = weapon.get<ESM::Weapon>()->mBase->mData.mHealth; int weapmaxhealth = weapon.getClass().getItemMaxHealth(weapon);
if(weapon.getCellRef().mCharge == -1) int weaphealth = weapon.getClass().getItemHealth(weapon);
weapon.getCellRef().mCharge = weapmaxhealth; weaponDamage *= float(weaphealth) / weapmaxhealth;
weaponDamage *= float(weapon.getCellRef().mCharge) / weapmaxhealth;
if (!MWBase::Environment::get().getWorld()->getGodModeState())
{
// Reduce weapon charge by at least one, but cap at 0
weaphealth -= std::min(std::max(1,
(int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), weaphealth);
weapon.getCellRef().setCharge(weaphealth);
}
// Weapon broken? unequip it
if (weapon.getCellRef().getCharge() == 0)
weapon = *getInventoryStore(ptr).unequipItem(weapon, ptr);
} }
if (!MWBase::Environment::get().getWorld()->getGodModeState())
weapon.getCellRef().mCharge -= std::min(std::max(1,
(int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), weapon.getCellRef().mCharge);
// Weapon broken? unequip it
if (weapon.getCellRef().mCharge == 0)
weapon = *getInventoryStore(ptr).unequipItem(weapon, ptr);
damage += weaponDamage; damage += weaponDamage;
} }
@ -825,14 +829,14 @@ namespace MWClass
{ {
// Note we do not respawn moved references in the cell they were moved to. Instead they are respawned in the original cell. // Note we do not respawn moved references in the cell they were moved to. Instead they are respawned in the original cell.
// This also means we cannot respawn dynamically placed references with no content file connection. // This also means we cannot respawn dynamically placed references with no content file connection.
if (ptr.getCellRef().mRefNum.mContentFile != -1) if (ptr.getCellRef().getRefNum().mContentFile != -1)
{ {
if (ptr.getRefData().getCount() == 0) if (ptr.getRefData().getCount() == 0)
ptr.getRefData().setCount(1); ptr.getRefData().setCount(1);
// Reset to original position // Reset to original position
ESM::Position& pos = ptr.getRefData().getPosition(); ESM::Position& pos = ptr.getRefData().getPosition();
pos = ptr.getCellRef().mPos; pos = ptr.getCellRef().getPosition();
ptr.getRefData().setCustomData(NULL); ptr.getRefData().setCustomData(NULL);
} }
@ -844,7 +848,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().mRefID, ptr.getCellRef().mFaction); store.restock(list, ptr, ptr.getCellRef().getRefId(), ptr.getCellRef().getFaction());
} }
const ESM::GameSetting* Creature::fMinWalkSpeedCreature; const ESM::GameSetting* Creature::fMinWalkSpeedCreature;

View file

@ -73,8 +73,8 @@ namespace MWClass
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
MWWorld::ManualRef ref(store, id); MWWorld::ManualRef ref(store, id);
ref.getPtr().getCellRef().mPos = ptr.getCellRef().mPos; ref.getPtr().getCellRef().setPosition(ptr.getCellRef().getPosition());
MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(), ptr.getCell() , ptr.getCellRef().mPos); MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(), ptr.getCell() , ptr.getCellRef().getPosition());
customData.mSpawnActorId = placed.getClass().getCreatureStats(placed).getActorId(); customData.mSpawnActorId = placed.getClass().getCreatureStats(placed).getActorId();
customData.mSpawn = false; customData.mSpawn = false;
} }

View file

@ -83,8 +83,8 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref = MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>(); ptr.get<ESM::Door>();
if (ref->mRef.mTeleport && !ref->mRef.mDestCell.empty()) // TODO doors that lead to exteriors if (ptr.getCellRef().getTeleport() && !ptr.getCellRef().getDestCell().empty()) // TODO doors that lead to exteriors
return ref->mRef.mDestCell; return ptr.getCellRef().getDestCell();
return ref->mBase->mName; return ref->mBase->mName;
} }
@ -101,16 +101,16 @@ namespace MWClass
MWWorld::ContainerStore &invStore = actor.getClass().getContainerStore(actor); MWWorld::ContainerStore &invStore = actor.getClass().getContainerStore(actor);
bool needKey = ptr.getCellRef().mLockLevel > 0; bool needKey = ptr.getCellRef().getLockLevel() > 0;
bool hasKey = false; bool hasKey = false;
std::string keyName; std::string keyName;
// make key id lowercase // make key id lowercase
std::string keyId = ptr.getCellRef().mKey; std::string keyId = ptr.getCellRef().getKey();
Misc::StringUtils::toLower(keyId); Misc::StringUtils::toLower(keyId);
for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it) for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it)
{ {
std::string refId = it->getCellRef().mRefID; std::string refId = it->getCellRef().getRefId();
Misc::StringUtils::toLower(refId); Misc::StringUtils::toLower(refId);
if (refId == keyId) if (refId == keyId)
{ {
@ -125,22 +125,22 @@ namespace MWClass
MWBase::Environment::get().getWindowManager()->messageBox(keyName + " #{sKeyUsed}"); MWBase::Environment::get().getWindowManager()->messageBox(keyName + " #{sKeyUsed}");
unlock(ptr); //Call the function here. because that makes sense. unlock(ptr); //Call the function here. because that makes sense.
// using a key disarms the trap // using a key disarms the trap
ptr.getCellRef().mTrap = ""; ptr.getCellRef().getTrap() = "";
} }
if (!needKey || hasKey) if (!needKey || hasKey)
{ {
if(!ptr.getCellRef().mTrap.empty()) if(!ptr.getCellRef().getTrap().empty())
{ {
// Trap activation // Trap activation
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTrap(actor, ptr.getCellRef().mTrap, ptr)); boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTrap(actor, ptr.getCellRef().getTrap(), ptr));
action->setSound(trapActivationSound); action->setSound(trapActivationSound);
return action; return action;
} }
if (ref->mRef.mTeleport) if (ptr.getCellRef().getTeleport())
{ {
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport (ref->mRef.mDestCell, ref->mRef.mDoorDest)); boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport (ptr.getCellRef().getDestCell(), ptr.getCellRef().getDoorDest()));
action->setSound(openSound); action->setSound(openSound);
@ -191,14 +191,14 @@ namespace MWClass
void Door::lock (const MWWorld::Ptr& ptr, int lockLevel) const void Door::lock (const MWWorld::Ptr& ptr, int lockLevel) const
{ {
if(lockLevel!=0) if(lockLevel!=0)
ptr.getCellRef().mLockLevel = abs(lockLevel); //Changes lock to locklevel, in positive ptr.getCellRef().setLockLevel(abs(lockLevel)); //Changes lock to locklevel, in positive
else else
ptr.getCellRef().mLockLevel = abs(ptr.getCellRef().mLockLevel); //No locklevel given, just flip the origional one ptr.getCellRef().setLockLevel(abs(ptr.getCellRef().getLockLevel())); //No locklevel given, just flip the origional one
} }
void Door::unlock (const MWWorld::Ptr& ptr) const void Door::unlock (const MWWorld::Ptr& ptr) const
{ {
ptr.getCellRef().mLockLevel = -abs(ptr.getCellRef().mLockLevel); //Makes lockLevel negative ptr.getCellRef().setLockLevel(-abs(ptr.getCellRef().getLockLevel())); //Makes lockLevel negative
} }
std::string Door::getScript (const MWWorld::Ptr& ptr) const std::string Door::getScript (const MWWorld::Ptr& ptr) const
@ -234,17 +234,17 @@ namespace MWClass
std::string text; std::string text;
if (ref->mRef.mTeleport) if (ptr.getCellRef().getTeleport())
{ {
text += "\n#{sTo}"; text += "\n#{sTo}";
text += "\n" + getDestination(*ref); text += "\n" + getDestination(*ref);
} }
if (ref->mRef.mLockLevel > 0) if (ptr.getCellRef().getLockLevel() > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel); text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ptr.getCellRef().getLockLevel());
else if (ref->mRef.mLockLevel < 0) else if (ptr.getCellRef().getLockLevel() < 0)
text += "\n#{sUnlocked}"; text += "\n#{sUnlocked}";
if (ref->mRef.mTrap != "") if (ptr.getCellRef().getTrap() != "")
text += "\n#{sTrapped}"; text += "\n#{sTrapped}";
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) if (MWBase::Environment::get().getWindowManager()->getFullHelp())
@ -260,16 +260,16 @@ namespace MWClass
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
std::string dest; std::string dest;
if (door.mRef.mDestCell != "") if (door.mRef.getDestCell() != "")
{ {
// door leads to an interior, use interior name as tooltip // door leads to an interior, use interior name as tooltip
dest = door.mRef.mDestCell; dest = door.mRef.getDestCell();
} }
else else
{ {
// door leads to exterior, use cell name (if any), otherwise translated region name // door leads to exterior, use cell name (if any), otherwise translated region name
int x,y; int x,y;
MWBase::Environment::get().getWorld()->positionToIndex (door.mRef.mDoorDest.pos[0], door.mRef.mDoorDest.pos[1], x, y); MWBase::Environment::get().getWorld()->positionToIndex (door.mRef.getDoorDest().pos[0], door.mRef.getDoorDest().pos[1], x, y);
const ESM::Cell* cell = store.get<ESM::Cell>().find(x,y); const ESM::Cell* cell = store.get<ESM::Cell>().find(x,y);
if (cell->mName != "") if (cell->mName != "")
dest = cell->mName; dest = cell->mName;

View file

@ -147,8 +147,8 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }

View file

@ -50,9 +50,9 @@ namespace MWClass
void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) {
renderingInterface.getObjects().insertModel(ptr, model); // Insert even if model is empty, so that the light is added
} renderingInterface.getObjects().insertModel(ptr, model);
} }
void Light::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Light::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
@ -187,8 +187,8 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }

View file

@ -86,10 +86,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Lockpick> *ref = MWWorld::LiveCellRef<ESM::Lockpick> *ref =
ptr.get<ESM::Lockpick>(); ptr.get<ESM::Lockpick>();
if (ptr.getCellRef().mCharge == -1) return ref->mBase->mData.mValue * (static_cast<float>(getItemHealth(ptr)) / getItemMaxHealth(ptr));
return ref->mBase->mData.mValue;
else
return ref->mBase->mData.mValue * (static_cast<float>(ptr.getCellRef().mCharge) / getItemMaxHealth(ptr));
} }
void Lockpick::registerSelf() void Lockpick::registerSelf()
@ -136,7 +133,7 @@ namespace MWClass
std::string text; std::string text;
int remainingUses = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mUses; int remainingUses = getItemHealth(ptr);
text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses); text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
@ -144,8 +141,8 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }

View file

@ -64,6 +64,9 @@ namespace MWClass
virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const; virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const;
///< Return item max health or throw an exception, if class does not have item health ///< Return item max health or throw an exception, if class does not have item health
virtual bool hasItemHealth (const MWWorld::Ptr& ptr) const { return true; }
///< \return Item health data available? (default implementation: false)
}; };
} }

View file

@ -28,11 +28,11 @@ namespace
{ {
bool isGold (const MWWorld::Ptr& ptr) bool isGold (const MWWorld::Ptr& ptr)
{ {
return Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_001") return Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_001")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_005") || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_005")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_010") || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_010")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_025") || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_025")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_100"); || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_100");
} }
} }
@ -94,12 +94,12 @@ namespace MWClass
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();
int value = ref->mBase->mData.mValue; int value = ref->mBase->mData.mValue;
if (ptr.getCellRef().mGoldValue > 1 && ptr.getRefData().getCount() == 1) if (ptr.getCellRef().getGoldValue() > 1 && ptr.getRefData().getCount() == 1)
value = ptr.getCellRef().mGoldValue; value = ptr.getCellRef().getGoldValue();
if (ptr.getCellRef().mSoul != "") if (ptr.getCellRef().getSoul() != "")
{ {
const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get<ESM::Creature>().find(ref->mRef.mSoul); const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get<ESM::Creature>().find(ref->mRef.getSoul());
value *= creature->mData.mSoul; value *= creature->mData.mSoul;
} }
@ -167,9 +167,9 @@ namespace MWClass
info.caption = ref->mBase->mName + countString; info.caption = ref->mBase->mName + countString;
info.icon = ref->mBase->mIcon; info.icon = ref->mBase->mIcon;
if (ref->mRef.mSoul != "") if (ref->mRef.getSoul() != "")
{ {
const ESM::Creature *creature = store.get<ESM::Creature>().find(ref->mRef.mSoul); const ESM::Creature *creature = store.get<ESM::Creature>().find(ref->mRef.getSoul());
info.caption += " (" + creature->mName + ")"; info.caption += " (" + creature->mName + ")";
} }
@ -182,8 +182,8 @@ namespace MWClass
} }
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
@ -219,7 +219,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
newRef.getPtr().get<ESM::Miscellaneous>(); newRef.getPtr().get<ESM::Miscellaneous>();
newPtr = MWWorld::Ptr(&cell.get<ESM::Miscellaneous>().insert(*ref), &cell); newPtr = MWWorld::Ptr(&cell.get<ESM::Miscellaneous>().insert(*ref), &cell);
newPtr.getCellRef().mGoldValue = goldAmount; newPtr.getCellRef().setGoldValue(goldAmount);
newPtr.getRefData().setCount(1); newPtr.getRefData().setCount(1);
} else { } else {
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
@ -231,7 +231,7 @@ namespace MWClass
boost::shared_ptr<MWWorld::Action> Miscellaneous::use (const MWWorld::Ptr& ptr) const boost::shared_ptr<MWWorld::Action> Miscellaneous::use (const MWWorld::Ptr& ptr) const
{ {
if (ptr.getCellRef().mSoul == "") if (ptr.getCellRef().getSoul().empty())
return boost::shared_ptr<MWWorld::Action>(new MWWorld::NullAction()); return boost::shared_ptr<MWWorld::Action>(new MWWorld::NullAction());
else else
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionSoulgem(ptr)); return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionSoulgem(ptr));
@ -242,12 +242,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
item.get<ESM::Miscellaneous>(); item.get<ESM::Miscellaneous>();
return !ref->mBase->mData.mIsKey && (npcServices & ESM::NPC::Misc) return !ref->mBase->mData.mIsKey && (npcServices & ESM::NPC::Misc) && !isGold(item);
&& !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_001")
&& !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_005")
&& !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_010")
&& !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_025")
&& !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_100");
} }
float Miscellaneous::getWeight(const MWWorld::Ptr &ptr) const float Miscellaneous::getWeight(const MWWorld::Ptr &ptr) const

View file

@ -526,20 +526,24 @@ namespace MWClass
(stats.getAttribute(ESM::Attribute::Strength).getModified() * fDamageStrengthMult->getFloat() * 0.1); (stats.getAttribute(ESM::Attribute::Strength).getModified() * fDamageStrengthMult->getFloat() * 0.1);
if(weaphashealth) if(weaphashealth)
{ {
int weapmaxhealth = weapon.get<ESM::Weapon>()->mBase->mData.mHealth; int weapmaxhealth = weapon.getClass().getItemMaxHealth(weapon);
if(weapon.getCellRef().mCharge == -1) int weaphealth = weapon.getClass().getItemHealth(weapon);
weapon.getCellRef().mCharge = weapmaxhealth;
damage *= float(weapon.getCellRef().mCharge) / weapmaxhealth; damage *= float(weaphealth) / weapmaxhealth;
if (!MWBase::Environment::get().getWorld()->getGodModeState())
{
// Reduce weapon charge by at least one, but cap at 0
weaphealth -= std::min(std::max(1,
(int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), weaphealth);
weapon.getCellRef().setCharge(weaphealth);
}
// Weapon broken? unequip it
if (weaphealth == 0)
weapon = *inv.unequipItem(weapon, ptr);
} }
if (!MWBase::Environment::get().getWorld()->getGodModeState())
weapon.getCellRef().mCharge -= std::min(std::max(1,
(int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), weapon.getCellRef().mCharge);
// Weapon broken? unequip it
if (weapon.getCellRef().mCharge == 0)
weapon = *inv.unequipItem(weapon, ptr);
} }
healthdmg = true; healthdmg = true;
} }
@ -676,7 +680,7 @@ namespace MWClass
else else
getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur? getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur?
if(ishealth) if(ishealth && !attacker.isEmpty()) // Don't use armor mitigation for fall damage
{ {
// Hit percentages: // Hit percentages:
// cuirass = 30% // cuirass = 30%
@ -705,14 +709,13 @@ namespace MWClass
MWWorld::Ptr armor = ((armorslot != inv.end()) ? *armorslot : MWWorld::Ptr()); MWWorld::Ptr armor = ((armorslot != inv.end()) ? *armorslot : MWWorld::Ptr());
if(!armor.isEmpty() && armor.getTypeName() == typeid(ESM::Armor).name()) if(!armor.isEmpty() && armor.getTypeName() == typeid(ESM::Armor).name())
{ {
ESM::CellRef &armorref = armor.getCellRef(); int armorhealth = armor.getClass().getItemHealth(armor);
if(armorref.mCharge == -1) armorhealth -= std::min(std::max(1, (int)damagediff),
armorref.mCharge = armor.get<ESM::Armor>()->mBase->mData.mHealth; armorhealth);
armorref.mCharge -= std::min(std::max(1, (int)damagediff), armor.getCellRef().setCharge(armorhealth);
armorref.mCharge);
// Armor broken? unequip it // Armor broken? unequip it
if (armorref.mCharge == 0) if (armorhealth == 0)
inv.unequipItem(armor, ptr); inv.unequipItem(armor, ptr);
if (ptr.getRefData().getHandle() == "player") if (ptr.getRefData().getHandle() == "player")
@ -1316,14 +1319,14 @@ namespace MWClass
{ {
// Note we do not respawn moved references in the cell they were moved to. Instead they are respawned in the original cell. // Note we do not respawn moved references in the cell they were moved to. Instead they are respawned in the original cell.
// This also means we cannot respawn dynamically placed references with no content file connection. // This also means we cannot respawn dynamically placed references with no content file connection.
if (ptr.getCellRef().mRefNum.mContentFile != -1) if (ptr.getCellRef().getRefNum().mContentFile != -1)
{ {
if (ptr.getRefData().getCount() == 0) if (ptr.getRefData().getCount() == 0)
ptr.getRefData().setCount(1); ptr.getRefData().setCount(1);
// Reset to original position // Reset to original position
ESM::Position& pos = ptr.getRefData().getPosition(); ESM::Position& pos = ptr.getRefData().getPosition();
pos = ptr.getCellRef().mPos; pos = ptr.getCellRef().getPosition();
ptr.getRefData().setCustomData(NULL); ptr.getRefData().setCustomData(NULL);
} }
@ -1335,7 +1338,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().mRefID, ptr.getCellRef().mFaction); store.restock(list, ptr, ptr.getCellRef().getRefId(), ptr.getCellRef().getFaction());
} }
const ESM::GameSetting *Npc::fMinWalkSpeed; const ESM::GameSetting *Npc::fMinWalkSpeed;

View file

@ -151,8 +151,8 @@ namespace MWClass
info.isPotion = true; info.isPotion = true;
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }

View file

@ -85,10 +85,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref = MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>(); ptr.get<ESM::Probe>();
if (ptr.getCellRef().mCharge == -1) return ref->mBase->mData.mValue * (static_cast<float>(getItemHealth(ptr)) / getItemMaxHealth(ptr));
return ref->mBase->mData.mValue;
else
return ref->mBase->mData.mValue * (static_cast<float>(ptr.getCellRef().mCharge) / getItemMaxHealth(ptr));
} }
void Probe::registerSelf() void Probe::registerSelf()
@ -135,7 +132,7 @@ namespace MWClass
std::string text; std::string text;
int remainingUses = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mUses; int remainingUses = getItemHealth(ptr);
text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses); text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
@ -143,8 +140,8 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }

View file

@ -64,6 +64,9 @@ namespace MWClass
virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const; virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const;
///< Return item max health or throw an exception, if class does not have item health ///< Return item max health or throw an exception, if class does not have item health
virtual bool hasItemHealth (const MWWorld::Ptr& ptr) const { return true; }
///< \return Item health data available? (default implementation: false)
}; };
} }

View file

@ -76,10 +76,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref = MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>(); ptr.get<ESM::Repair>();
if (ptr.getCellRef().mCharge == -1) return ref->mBase->mData.mValue * (static_cast<float>(getItemHealth(ptr)) / getItemMaxHealth(ptr));
return ref->mBase->mData.mValue;
else
return ref->mBase->mData.mValue * (static_cast<float>(ptr.getCellRef().mCharge) / getItemMaxHealth(ptr));
} }
void Repair::registerSelf() void Repair::registerSelf()
@ -139,7 +136,7 @@ namespace MWClass
std::string text; std::string text;
int remainingUses = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mUses; int remainingUses = getItemHealth(ptr);
text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses); text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
@ -147,8 +144,8 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }

View file

@ -154,10 +154,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
if (ptr.getCellRef().mCharge == -1) return ref->mBase->mData.mValue * (static_cast<float>(getItemHealth(ptr)) / getItemMaxHealth(ptr));
return ref->mBase->mData.mValue;
else
return ref->mBase->mData.mValue * (static_cast<float>(ptr.getCellRef().mCharge) / getItemMaxHealth(ptr));
} }
void Weapon::registerSelf() void Weapon::registerSelf()
@ -340,7 +337,7 @@ namespace MWClass
if (ref->mBase->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity if (ref->mBase->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity
{ {
int remainingHealth = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mHealth; int remainingHealth = getItemHealth(ptr);
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(remainingHealth) + "/" text += "\n#{sCondition}: " + MWGui::ToolTips::toString(remainingHealth) + "/"
+ MWGui::ToolTips::toString(ref->mBase->mData.mHealth); + MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
} }
@ -351,11 +348,11 @@ namespace MWClass
info.enchant = ref->mBase->mEnchant; info.enchant = ref->mBase->mEnchant;
if (!info.enchant.empty()) if (!info.enchant.empty())
info.remainingEnchantCharge = ptr.getCellRef().mEnchantmentCharge; info.remainingEnchantCharge = ptr.getCellRef().getEnchantmentCharge();
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
@ -372,7 +369,7 @@ namespace MWClass
return ref->mBase->mEnchant; return ref->mBase->mEnchant;
} }
void Weapon::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const std::string Weapon::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
{ {
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
@ -383,13 +380,12 @@ namespace MWClass
newItem.mData.mEnchant=enchCharge; newItem.mData.mEnchant=enchCharge;
newItem.mEnchant=enchId; newItem.mEnchant=enchId;
const ESM::Weapon *record = MWBase::Environment::get().getWorld()->createRecord (newItem); const ESM::Weapon *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
ref->mBase = record; return record->mId;
ref->mRef.mRefID = record->mId;
} }
std::pair<int, std::string> Weapon::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const std::pair<int, std::string> Weapon::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const
{ {
if (ptr.getCellRef().mCharge == 0) if (ptr.getCellRef().getCharge() == 0)
return std::make_pair(0, "#{sInventoryMessage1}"); return std::make_pair(0, "#{sInventoryMessage1}");
std::pair<std::vector<int>, bool> slots_ = ptr.getClass().getEquipmentSlots(ptr); std::pair<std::vector<int>, bool> slots_ = ptr.getClass().getEquipmentSlots(ptr);

View file

@ -68,7 +68,8 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @return the enchantment ID if the object is enchanted, otherwise an empty string
virtual void applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const; virtual std::string applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const;
///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it.
virtual std::pair<int, std::string> canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const; virtual std::pair<int, std::string> canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const;
///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon conflicts with that. ///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon conflicts with that.

View file

@ -560,17 +560,7 @@ namespace MWDialogue
void DialogueManager::applyDispositionChange(int delta) void DialogueManager::applyDispositionChange(int delta)
{ {
int oldTemp = mTemporaryDispositionChange;
mTemporaryDispositionChange += delta; mTemporaryDispositionChange += delta;
// don't allow increasing beyond 100 or decreasing below 0
int curDisp = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor);
if (curDisp + mTemporaryDispositionChange < 0)
mTemporaryDispositionChange = -curDisp;
else if (curDisp + mTemporaryDispositionChange > 100)
mTemporaryDispositionChange = 100 - curDisp;
int diff = mTemporaryDispositionChange - oldTemp;
mPermanentDispositionChange += diff;
} }
bool DialogueManager::checkServiceRefused() bool DialogueManager::checkServiceRefused()
@ -642,6 +632,8 @@ namespace MWDialogue
if (iter->second) if (iter->second)
state.mKnownTopics.push_back (iter->first); state.mKnownTopics.push_back (iter->first);
state.mModFactionReaction = mModFactionReaction;
writer.startRecord (ESM::REC_DIAS); writer.startRecord (ESM::REC_DIAS);
state.save (writer); state.save (writer);
writer.endRecord (ESM::REC_DIAS); writer.endRecord (ESM::REC_DIAS);
@ -661,9 +653,46 @@ namespace MWDialogue
iter!=state.mKnownTopics.end(); ++iter) iter!=state.mKnownTopics.end(); ++iter)
if (store.get<ESM::Dialogue>().search (*iter)) if (store.get<ESM::Dialogue>().search (*iter))
mKnownTopics.insert (std::make_pair (*iter, true)); mKnownTopics.insert (std::make_pair (*iter, true));
mModFactionReaction = state.mModFactionReaction;
} }
} }
void DialogueManager::modFactionReaction(const std::string &faction1, const std::string &faction2, int diff)
{
std::string fact1 = Misc::StringUtils::lowerCase(faction1);
std::string fact2 = Misc::StringUtils::lowerCase(faction2);
// Make sure the factions exist
MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(fact1);
MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(fact2);
std::map<std::string, int>& map = mModFactionReaction[fact1];
if (map.find(fact2) == map.end())
map[fact2] = 0;
map[fact2] += diff;
}
int DialogueManager::getFactionReaction(const std::string &faction1, const std::string &faction2) const
{
std::string fact1 = Misc::StringUtils::lowerCase(faction1);
std::string fact2 = Misc::StringUtils::lowerCase(faction2);
ModFactionReactionMap::const_iterator map = mModFactionReaction.find(fact1);
int diff = 0;
if (map != mModFactionReaction.end() && map->second.find(fact2) != map->second.end())
diff = map->second.at(fact2);
const ESM::Faction* faction = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(fact1);
std::map<std::string, int>::const_iterator it = faction->mReactions.begin();
for (; it != faction->mReactions.end(); ++it)
{
if (Misc::StringUtils::ciEqual(it->first, fact2))
return it->second + diff;
}
return diff;
}
std::vector<HyperTextToken> ParseHyperText(const std::string& text) std::vector<HyperTextToken> ParseHyperText(const std::string& text)
{ {

View file

@ -24,6 +24,11 @@ namespace MWDialogue
{ {
std::map<std::string, ESM::Dialogue> mDialogueMap; std::map<std::string, ESM::Dialogue> mDialogueMap;
std::map<std::string, bool> mKnownTopics;// Those are the topics the player knows. std::map<std::string, bool> mKnownTopics;// Those are the topics the player knows.
// Modified faction reactions. <Faction1, <Faction2, Difference> >
typedef std::map<std::string, std::map<std::string, int> > ModFactionReactionMap;
ModFactionReactionMap mModFactionReaction;
std::list<std::string> mActorKnownTopics; std::list<std::string> mActorKnownTopics;
Translation::Storage& mTranslationDataStorage; Translation::Storage& mTranslationDataStorage;
@ -79,6 +84,8 @@ namespace MWDialogue
virtual void persuade (int type); virtual void persuade (int type);
virtual int getTemporaryDispositionChange () const; virtual int getTemporaryDispositionChange () const;
/// @note This change is temporary and gets discarded when dialogue ends.
virtual void applyDispositionChange (int delta); virtual void applyDispositionChange (int delta);
virtual int countSavedGameRecords() const; virtual int countSavedGameRecords() const;
@ -86,6 +93,12 @@ namespace MWDialogue
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const; virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
virtual void readRecord (ESM::ESMReader& reader, int32_t type); virtual void readRecord (ESM::ESMReader& reader, int32_t type);
/// Changes faction1's opinion of faction2 by \a diff.
virtual void modFactionReaction (const std::string& faction1, const std::string& faction2, int diff);
/// @return faction1's opinion of faction2
virtual int getFactionReaction (const std::string& faction1, const std::string& faction2) const;
}; };

View file

@ -264,15 +264,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
{ {
MWWorld::ContainerStore& store = player.getClass().getContainerStore (player); MWWorld::ContainerStore& store = player.getClass().getContainerStore (player);
int sum = 0; return store.count(select.getName());
std::string name = select.getName();
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
if (Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, name))
sum += iter->getRefData().getCount();
return sum;
} }
case SelectWrapper::Function_Dead: case SelectWrapper::Function_Dead:
@ -404,16 +396,15 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
int value = 0; int value = 0;
const ESM::Faction& faction =
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId);
MWMechanics::NpcStats& playerStats = player.getClass().getNpcStats (player); MWMechanics::NpcStats& playerStats = player.getClass().getNpcStats (player);
for (std::vector<ESM::Faction::Reaction>::const_iterator iter (faction.mReactions.begin()); std::map<std::string, int>::const_iterator playerFactionIt = playerStats.getFactionRanks().begin();
iter!=faction.mReactions.end(); ++iter) for (; playerFactionIt != playerStats.getFactionRanks().end(); ++playerFactionIt)
if (playerStats.getFactionRanks().find (iter->mFaction)!=playerStats.getFactionRanks().end()) {
if (low ? iter->mReaction<value : iter->mReaction>value) int reaction = MWBase::Environment::get().getDialogueManager()->getFactionReaction(factionId, playerFactionIt->first);
value = iter->mReaction; if (low ? reaction < value : reaction > value)
value = reaction;
}
return value; return value;
} }
@ -539,7 +530,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
case SelectWrapper::Function_ShouldAttack: case SelectWrapper::Function_ShouldAttack:
return mActor.getClass().getCreatureStats (mActor).isHostile(); return mActor.getClass().getCreatureStats(mActor).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() >= 80;
case SelectWrapper::Function_CreatureTargetted: case SelectWrapper::Function_CreatureTargetted:

View file

@ -13,20 +13,7 @@
#include "inventoryitemmodel.hpp" #include "inventoryitemmodel.hpp"
#include "sortfilteritemmodel.hpp" #include "sortfilteritemmodel.hpp"
#include "itemview.hpp" #include "itemview.hpp"
#include "itemwidget.hpp"
namespace
{
std::string getIconPath(MWWorld::Ptr ptr)
{
std::string path = std::string("icons\\");
path += ptr.getClass().getInventoryIcon(ptr);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
return path;
}
}
namespace MWGui namespace MWGui
{ {
@ -66,10 +53,7 @@ namespace MWGui
void AlchemyWindow::onCancelButtonClicked(MyGUI::Widget* _sender) void AlchemyWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
{ {
mAlchemy.clear(); exit();
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Alchemy);
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Inventory);
} }
void AlchemyWindow::onCreateButtonClicked(MyGUI::Widget* _sender) void AlchemyWindow::onCreateButtonClicked(MyGUI::Widget* _sender)
@ -152,13 +136,19 @@ namespace MWGui
{ {
mApparatus.at (index)->setUserString ("ToolTipType", "ItemPtr"); mApparatus.at (index)->setUserString ("ToolTipType", "ItemPtr");
mApparatus.at (index)->setUserData (*iter); mApparatus.at (index)->setUserData (*iter);
mApparatus.at (index)->setImageTexture (getIconPath (*iter)); mApparatus.at (index)->setItem(*iter);
} }
} }
update(); update();
} }
void AlchemyWindow::exit() {
mAlchemy.clear();
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Alchemy);
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Inventory);
}
void AlchemyWindow::onIngredientSelected(MyGUI::Widget* _sender) void AlchemyWindow::onIngredientSelected(MyGUI::Widget* _sender)
{ {
removeIngredient(_sender); removeIngredient(_sender);
@ -186,7 +176,7 @@ namespace MWGui
MWMechanics::Alchemy::TIngredientsIterator it = mAlchemy.beginIngredients (); MWMechanics::Alchemy::TIngredientsIterator it = mAlchemy.beginIngredients ();
for (int i=0; i<4; ++i) for (int i=0; i<4; ++i)
{ {
MyGUI::ImageBox* ingredient = mIngredients[i]; ItemWidget* ingredient = mIngredients[i];
MWWorld::Ptr item; MWWorld::Ptr item;
if (it != mAlchemy.endIngredients ()) if (it != mAlchemy.endIngredients ())
@ -201,15 +191,15 @@ namespace MWGui
if (ingredient->getChildCount()) if (ingredient->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0));
ingredient->setImageTexture("");
ingredient->clearUserStrings (); ingredient->clearUserStrings ();
ingredient->setItem(item);
if (item.isEmpty ()) if (item.isEmpty ())
continue; continue;
ingredient->setUserString("ToolTipType", "ItemPtr"); ingredient->setUserString("ToolTipType", "ItemPtr");
ingredient->setUserData(item); ingredient->setUserData(item);
ingredient->setImageTexture(getIconPath(item));
MyGUI::TextBox* text = ingredient->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label")); MyGUI::TextBox* text = ingredient->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label"));
text->setTextAlign(MyGUI::Align::Right); text->setTextAlign(MyGUI::Align::Right);

View file

@ -11,6 +11,7 @@
namespace MWGui namespace MWGui
{ {
class ItemView; class ItemView;
class ItemWidget;
class SortFilterItemModel; class SortFilterItemModel;
class AlchemyWindow : public WindowBase class AlchemyWindow : public WindowBase
@ -19,6 +20,7 @@ namespace MWGui
AlchemyWindow(); AlchemyWindow();
virtual void open(); virtual void open();
virtual void exit();
private: private:
ItemView* mItemView; ItemView* mItemView;
@ -43,8 +45,8 @@ namespace MWGui
MWMechanics::Alchemy mAlchemy; MWMechanics::Alchemy mAlchemy;
std::vector<MyGUI::ImageBox *> mApparatus; std::vector<ItemWidget*> mApparatus;
std::vector<MyGUI::ImageBox *> mIngredients; std::vector<ItemWidget*> mIngredients;
}; };
} }

View file

@ -114,6 +114,14 @@ namespace MWGui
setTakeButtonShow(true); setTakeButtonShow(true);
} }
void BookWindow::exit()
{
// no 3d sounds because the object could be in a container.
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Book);
}
void BookWindow::setTakeButtonShow(bool show) void BookWindow::setTakeButtonShow(bool show)
{ {
mTakeButtonShow = show; mTakeButtonShow = show;
@ -128,10 +136,7 @@ namespace MWGui
void BookWindow::onCloseButtonClicked (MyGUI::Widget* sender) void BookWindow::onCloseButtonClicked (MyGUI::Widget* sender)
{ {
// no 3d sounds because the object could be in a container. exit();
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Book);
} }
void BookWindow::onTakeButtonClicked (MyGUI::Widget* sender) void BookWindow::onTakeButtonClicked (MyGUI::Widget* sender)

View file

@ -14,6 +14,8 @@ namespace MWGui
public: public:
BookWindow(); BookWindow();
virtual void exit();
void open(MWWorld::Ptr book); void open(MWWorld::Ptr book);
void setTakeButtonShow(bool show); void setTakeButtonShow(bool show);
void nextPage(); void nextPage();

View file

@ -718,6 +718,11 @@ namespace MWGui
} }
void SelectSpecializationDialog::onCancelClicked(MyGUI::Widget* _sender) void SelectSpecializationDialog::onCancelClicked(MyGUI::Widget* _sender)
{
exit();
}
void SelectSpecializationDialog::exit()
{ {
eventCancel(); eventCancel();
} }
@ -764,6 +769,11 @@ namespace MWGui
} }
void SelectAttributeDialog::onCancelClicked(MyGUI::Widget* _sender) void SelectAttributeDialog::onCancelClicked(MyGUI::Widget* _sender)
{
exit();
}
void SelectAttributeDialog::exit()
{ {
eventCancel(); eventCancel();
} }
@ -855,6 +865,11 @@ namespace MWGui
} }
void SelectSkillDialog::onCancelClicked(MyGUI::Widget* _sender) void SelectSkillDialog::onCancelClicked(MyGUI::Widget* _sender)
{
exit();
}
void SelectSkillDialog::exit()
{ {
eventCancel(); eventCancel();
} }

View file

@ -136,6 +136,8 @@ namespace MWGui
SelectSpecializationDialog(); SelectSpecializationDialog();
~SelectSpecializationDialog(); ~SelectSpecializationDialog();
virtual void exit();
ESM::Class::Specialization getSpecializationId() const { return mSpecializationId; } ESM::Class::Specialization getSpecializationId() const { return mSpecializationId; }
// Events // Events
@ -167,6 +169,8 @@ namespace MWGui
SelectAttributeDialog(); SelectAttributeDialog();
~SelectAttributeDialog(); ~SelectAttributeDialog();
virtual void exit();
ESM::Attribute::AttributeID getAttributeId() const { return mAttributeId; } ESM::Attribute::AttributeID getAttributeId() const { return mAttributeId; }
// Events // Events
@ -196,6 +200,8 @@ namespace MWGui
SelectSkillDialog(); SelectSkillDialog();
~SelectSkillDialog(); ~SelectSkillDialog();
virtual void exit();
ESM::Skill::SkillEnum getSkillId() const { return mSkillId; } ESM::Skill::SkillEnum getSkillId() const { return mSkillId; }
// Events // Events

View file

@ -118,6 +118,11 @@ void CompanionWindow::updateEncumbranceBar()
} }
void CompanionWindow::onCloseButtonClicked(MyGUI::Widget* _sender) void CompanionWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
{
exit();
}
void CompanionWindow::exit()
{ {
if (mPtr.getTypeName() == typeid(ESM::NPC).name() && mPtr.getClass().getNpcStats(mPtr).getProfit() < 0) if (mPtr.getTypeName() == typeid(ESM::NPC).name() && mPtr.getClass().getNpcStats(mPtr).getProfit() < 0)
{ {

View file

@ -18,6 +18,8 @@ namespace MWGui
public: public:
CompanionWindow(DragAndDrop* dragAndDrop, MessageBoxManager* manager); CompanionWindow(DragAndDrop* dragAndDrop, MessageBoxManager* manager);
virtual void exit();
void open(const MWWorld::Ptr& npc); void open(const MWWorld::Ptr& npc);
void onFrame (); void onFrame ();

View file

@ -28,13 +28,18 @@ namespace MWGui
center(); center();
} }
void ConfirmationDialog::onCancelButtonClicked(MyGUI::Widget* _sender) void ConfirmationDialog::exit()
{ {
eventCancelClicked(); eventCancelClicked();
setVisible(false); setVisible(false);
} }
void ConfirmationDialog::onCancelButtonClicked(MyGUI::Widget* _sender)
{
exit();
}
void ConfirmationDialog::onOkButtonClicked(MyGUI::Widget* _sender) void ConfirmationDialog::onOkButtonClicked(MyGUI::Widget* _sender)
{ {
eventOkClicked(); eventOkClicked();

View file

@ -10,6 +10,7 @@ namespace MWGui
public: public:
ConfirmationDialog(); ConfirmationDialog();
void open(const std::string& message); void open(const std::string& message);
virtual void exit();
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;

View file

@ -61,7 +61,7 @@ namespace MWGui
} }
catch (const std::exception& error) catch (const std::exception& error)
{ {
printError (std::string ("An exception has been thrown: ") + error.what()); printError (std::string ("Error: ") + error.what());
} }
return false; return false;
@ -143,6 +143,11 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(NULL); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(NULL);
} }
void Console::exit()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Console);
}
void Console::setFont(const std::string &fntName) void Console::setFont(const std::string &fntName)
{ {
mHistory->setFontName(fntName); mHistory->setFontName(fntName);
@ -190,7 +195,7 @@ namespace MWGui
} }
catch (const std::exception& error) catch (const std::exception& error)
{ {
printError (std::string ("An exception has been thrown: ") + error.what()); printError (std::string ("Error: ") + error.what());
} }
} }
} }
@ -413,7 +418,7 @@ namespace MWGui
} }
else else
{ {
setTitle("#{sConsoleTitle} (" + object.getCellRef().mRefID + ")"); setTitle("#{sConsoleTitle} (" + object.getCellRef().getRefId() + ")");
mPtr = object; mPtr = object;
} }
// User clicked on an object. Restore focus to the console command line. // User clicked on an object. Restore focus to the console command line.

View file

@ -21,86 +21,83 @@
namespace MWGui namespace MWGui
{ {
class Console : public WindowBase, private Compiler::ErrorHandler, public ReferenceInterface class Console : public WindowBase, private Compiler::ErrorHandler, public ReferenceInterface
{ {
private: public:
/// Set the implicit object for script execution
void setSelectedObject(const MWWorld::Ptr& object);
Compiler::Extensions mExtensions; MyGUI::EditBox* mCommandLine;
MWScript::CompilerContext mCompilerContext; MyGUI::EditBox* mHistory;
std::vector<std::string> mNames;
bool mConsoleOnlyScripts;
bool compile (const std::string& cmd, Compiler::Output& output); typedef std::list<std::string> StringList;
/// Report error to the user. // History of previous entered commands
virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type); StringList mCommandHistory;
StringList::iterator mCurrent;
std::string mEditString;
/// Report a file related error Console(int w, int h, bool consoleOnlyScripts);
virtual void report (const std::string& message, Type type);
void listNames(); virtual void open();
///< Write all valid identifiers and keywords into mNames and sort them. virtual void close();
/// \note If mNames is not empty, this function is a no-op.
/// \note The list may contain duplicates (if a name is a keyword and an identifier at the same
/// time).
public: virtual void exit();
void setSelectedObject(const MWWorld::Ptr& object); void setFont(const std::string &fntName);
///< Set the implicit object for script execution
protected: void onResChange(int width, int height);
virtual void onReferenceUnavailable(); void clearHistory();
// Print a message to the console. Messages may contain color
// code, eg. "#FFFFFF this is white".
void print(const std::string &msg);
public: // These are pre-colored versions that you should use.
MyGUI::EditBox* mCommandLine;
MyGUI::EditBox* mHistory;
typedef std::list<std::string> StringList; /// Output from successful console command
void printOK(const std::string &msg);
// History of previous entered commands /// Error message
StringList mCommandHistory; void printError(const std::string &msg);
StringList::iterator mCurrent;
std::string mEditString;
Console(int w, int h, bool consoleOnlyScripts); void execute (const std::string& command);
virtual void open(); void executeFile (const std::string& path);
virtual void close();
void setFont(const std::string &fntName); protected:
void onResChange(int width, int height); virtual void onReferenceUnavailable();
void clearHistory(); private:
// Print a message to the console. Messages may contain color void keyPress(MyGUI::Widget* _sender,
// code, eg. "#FFFFFF this is white". MyGUI::KeyCode key,
void print(const std::string &msg); MyGUI::Char _char);
// These are pre-colored versions that you should use. void acceptCommand(MyGUI::EditBox* _sender);
/// Output from successful console command std::string complete( std::string input, std::vector<std::string> &matches );
void printOK(const std::string &msg);
/// Error message Compiler::Extensions mExtensions;
void printError(const std::string &msg); MWScript::CompilerContext mCompilerContext;
std::vector<std::string> mNames;
bool mConsoleOnlyScripts;
void execute (const std::string& command); bool compile (const std::string& cmd, Compiler::Output& output);
void executeFile (const std::string& path); /// Report error to the user.
virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type);
private: /// Report a file related error
virtual void report (const std::string& message, Type type);
void keyPress(MyGUI::Widget* _sender, /// Write all valid identifiers and keywords into mNames and sort them.
MyGUI::KeyCode key, /// \note If mNames is not empty, this function is a no-op.
MyGUI::Char _char); /// \note The list may contain duplicates (if a name is a keyword and an identifier at the same
/// time).
void acceptCommand(MyGUI::EditBox* _sender); void listNames();
std::string complete( std::string input, std::vector<std::string> &matches );
}; };
} }
#endif #endif

View file

@ -20,6 +20,7 @@
#include "inventorywindow.hpp" #include "inventorywindow.hpp"
#include "itemview.hpp" #include "itemview.hpp"
#include "itemwidget.hpp"
#include "inventoryitemmodel.hpp" #include "inventoryitemmodel.hpp"
#include "sortfilteritemmodel.hpp" #include "sortfilteritemmodel.hpp"
#include "pickpocketitemmodel.hpp" #include "pickpocketitemmodel.hpp"
@ -46,22 +47,15 @@ namespace MWGui
mSourceSortModel->addDragItem(mItem.mBase, count); mSourceSortModel->addDragItem(mItem.mBase, count);
} }
std::string path = std::string("icons\\"); ItemWidget* baseWidget = mDragAndDropWidget->createWidget<ItemWidget>
path += mItem.mBase.getClass().getInventoryIcon(mItem.mBase); ("MW_ItemIcon", MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default);
MyGUI::ImageBox* baseWidget = mDragAndDropWidget->createWidget<MyGUI::ImageBox>
("ImageBox", MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default);
mDraggedWidget = baseWidget; mDraggedWidget = baseWidget;
MyGUI::ImageBox* image = baseWidget->createWidget<MyGUI::ImageBox>("ImageBox", baseWidget->setItem(mItem.mBase);
MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default); baseWidget->setNeedMouseFocus(false);
size_t pos = path.rfind(".");
if (pos != std::string::npos)
path.erase(pos);
path.append(".dds");
image->setImageTexture(path);
image->setNeedMouseFocus(false);
// text widget that shows item count // text widget that shows item count
MyGUI::TextBox* text = image->createWidget<MyGUI::TextBox>("SandBrightText", // TODO: move to ItemWidget
MyGUI::TextBox* text = baseWidget->createWidget<MyGUI::TextBox>("SandBrightText",
MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label")); MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label"));
text->setTextAlign(MyGUI::Align::Right); text->setTextAlign(MyGUI::Align::Right);
text->setNeedMouseFocus(false); text->setNeedMouseFocus(false);
@ -263,7 +257,7 @@ namespace MWGui
} }
} }
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender) void ContainerWindow::exit()
{ {
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop) if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
{ {
@ -271,6 +265,11 @@ namespace MWGui
} }
} }
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
{
exit();
}
void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender) void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
{ {
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop) if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)

View file

@ -54,6 +54,8 @@ namespace MWGui
void open(const MWWorld::Ptr& container, bool loot=false); void open(const MWWorld::Ptr& container, bool loot=false);
virtual void close(); virtual void close();
virtual void exit();
private: private:
DragAndDrop* mDragAndDrop; DragAndDrop* mDragAndDrop;

View file

@ -49,7 +49,12 @@ namespace MWGui
mItemEdit->setCaption(boost::lexical_cast<std::string>(maxCount)); mItemEdit->setCaption(boost::lexical_cast<std::string>(maxCount));
} }
void CountDialog::cancel() void CountDialog::cancel() //Keeping this here as I don't know if anything else relies on it.
{
exit();
}
void CountDialog::exit()
{ {
setVisible(false); setVisible(false);
} }
@ -65,16 +70,16 @@ namespace MWGui
setVisible(false); setVisible(false);
} }
// essentially duplicating what the OK button does if user presses // essentially duplicating what the OK button does if user presses
// Enter key // Enter key
void CountDialog::onEnterKeyPressed(MyGUI::EditBox* _sender) void CountDialog::onEnterKeyPressed(MyGUI::EditBox* _sender)
{ {
eventOkClicked(NULL, mSlider->getScrollPosition()+1); eventOkClicked(NULL, mSlider->getScrollPosition()+1);
setVisible(false); setVisible(false);
} }
void CountDialog::onEditTextChange(MyGUI::EditBox* _sender) void CountDialog::onEditTextChange(MyGUI::EditBox* _sender)
{ {
if (_sender->getCaption() == "") if (_sender->getCaption() == "")

View file

@ -11,6 +11,7 @@ namespace MWGui
CountDialog(); CountDialog();
void open(const std::string& item, const std::string& message, const int maxCount); void open(const std::string& item, const std::string& message, const int maxCount);
void cancel(); void cancel();
virtual void exit();
typedef MyGUI::delegates::CMultiDelegate2<MyGUI::Widget*, int> EventHandle_WidgetInt; typedef MyGUI::delegates::CMultiDelegate2<MyGUI::Widget*, int> EventHandle_WidgetInt;

View file

@ -51,7 +51,7 @@ namespace MWGui
void PersuasionDialog::onCancel(MyGUI::Widget *sender) void PersuasionDialog::onCancel(MyGUI::Widget *sender)
{ {
setVisible(false); exit();
} }
void PersuasionDialog::onPersuade(MyGUI::Widget *sender) void PersuasionDialog::onPersuade(MyGUI::Widget *sender)
@ -87,6 +87,11 @@ namespace MWGui
mGoldLabel->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(playerGold)); mGoldLabel->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(playerGold));
} }
void PersuasionDialog::exit()
{
setVisible(false);
}
// -------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------
Response::Response(const std::string &text, const std::string &title) Response::Response(const std::string &text, const std::string &title)
@ -264,6 +269,14 @@ namespace MWGui
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &DialogueWindow::onWindowResize); static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &DialogueWindow::onWindowResize);
} }
void DialogueWindow::exit()
{
if ((!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice())
&& !mGoodbye)
return;
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
}
void DialogueWindow::onWindowResize(MyGUI::Window* _sender) void DialogueWindow::onWindowResize(MyGUI::Window* _sender)
{ {
mTopicsList->adjustSize(); mTopicsList->adjustSize();
@ -281,9 +294,7 @@ namespace MWGui
void DialogueWindow::onByeClicked(MyGUI::Widget* _sender) void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
{ {
if (!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice()) exit();
return;
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
} }
void DialogueWindow::onSelectTopic(const std::string& topic, int id) void DialogueWindow::onSelectTopic(const std::string& topic, int id)
@ -504,6 +515,15 @@ namespace MWGui
// no scrollbar // no scrollbar
onScrollbarMoved(mScrollBar, 0); onScrollbarMoved(mScrollBar, 0);
} }
MyGUI::Button* byeButton;
getWidget(byeButton, "ByeButton");
if(MWBase::Environment::get().getDialogueManager()->isInChoice() && !mGoodbye) {
byeButton->setEnabled(false);
}
else {
byeButton->setEnabled(true);
}
} }
void DialogueWindow::notifyLinkClicked (TypesetBook::InteractiveId link) void DialogueWindow::notifyLinkClicked (TypesetBook::InteractiveId link)

View file

@ -34,6 +34,7 @@ namespace MWGui
PersuasionDialog(); PersuasionDialog();
virtual void open(); virtual void open();
virtual void exit();
private: private:
MyGUI::Button* mCancelButton; MyGUI::Button* mCancelButton;
@ -103,6 +104,8 @@ namespace MWGui
public: public:
DialogueWindow(); DialogueWindow();
virtual void exit();
// Events // Events
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;

View file

@ -14,6 +14,7 @@
#include "itemselection.hpp" #include "itemselection.hpp"
#include "container.hpp" #include "container.hpp"
#include "itemwidget.hpp"
#include "sortfilteritemmodel.hpp" #include "sortfilteritemmodel.hpp"
@ -57,8 +58,50 @@ namespace MWGui
void EnchantingDialog::open() void EnchantingDialog::open()
{ {
center(); center();
onRemoveItem(NULL);
onRemoveSoul(NULL); setSoulGem(MWWorld::Ptr());
setItem(MWWorld::Ptr());
}
void EnchantingDialog::setSoulGem(const MWWorld::Ptr &gem)
{
if (gem.isEmpty())
{
mSoulBox->setItem(MWWorld::Ptr());
mSoulBox->clearUserStrings();
mEnchanting.setSoulGem(MWWorld::Ptr());
}
else
{
mSoulBox->setItem(gem);
mSoulBox->setUserString ("ToolTipType", "ItemPtr");
mSoulBox->setUserData(gem);
mEnchanting.setSoulGem(gem);
}
updateLabels();
}
void EnchantingDialog::setItem(const MWWorld::Ptr &item)
{
if (item.isEmpty())
{
mItemBox->setItem(MWWorld::Ptr());
mItemBox->clearUserStrings();
mEnchanting.setOldItem(MWWorld::Ptr());
}
else
{
mItemBox->setItem(item);
mItemBox->setUserString ("ToolTipType", "ItemPtr");
mItemBox->setUserData(item);
mEnchanting.setOldItem(item);
}
updateLabels();
}
void EnchantingDialog::exit()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Enchanting);
} }
void EnchantingDialog::updateLabels() void EnchantingDialog::updateLabels()
@ -117,16 +160,7 @@ namespace MWGui
startEditing(); startEditing();
mEnchanting.setSoulGem(soulgem); mEnchanting.setSoulGem(soulgem);
MyGUI::ImageBox* image = mSoulBox->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 32, 32), MyGUI::Align::Default); setSoulGem(soulgem);
std::string path = std::string("icons\\");
path += soulgem.getClass().getInventoryIcon(soulgem);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
image->setImageTexture (path);
image->setUserString ("ToolTipType", "ItemPtr");
image->setUserData(soulgem);
image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveSoul);
mPrice->setVisible(false); mPrice->setVisible(false);
mPriceText->setVisible(false); mPriceText->setVisible(false);
@ -141,51 +175,36 @@ namespace MWGui
void EnchantingDialog::onCancelButtonClicked(MyGUI::Widget* sender) void EnchantingDialog::onCancelButtonClicked(MyGUI::Widget* sender)
{ {
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Enchanting); exit();
} }
void EnchantingDialog::onSelectItem(MyGUI::Widget *sender) void EnchantingDialog::onSelectItem(MyGUI::Widget *sender)
{ {
delete mItemSelectionDialog; if (mEnchanting.getOldItem().isEmpty())
mItemSelectionDialog = new ItemSelectionDialog("#{sEnchantItems}"); {
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onItemSelected); delete mItemSelectionDialog;
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onItemCancel); mItemSelectionDialog = new ItemSelectionDialog("#{sEnchantItems}");
mItemSelectionDialog->setVisible(true); mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onItemSelected);
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr()); mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onItemCancel);
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyEnchantable); mItemSelectionDialog->setVisible(true);
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr());
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyEnchantable);
}
else
{
setItem(MWWorld::Ptr());
}
} }
void EnchantingDialog::onItemSelected(MWWorld::Ptr item) void EnchantingDialog::onItemSelected(MWWorld::Ptr item)
{ {
mItemSelectionDialog->setVisible(false); mItemSelectionDialog->setVisible(false);
while (mItemBox->getChildCount ()) setItem(item);
MyGUI::Gui::getInstance ().destroyWidget (mItemBox->getChildAt(0));
MyGUI::ImageBox* image = mItemBox->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 32, 32), MyGUI::Align::Default);
std::string path = std::string("icons\\");
path += item.getClass().getInventoryIcon(item);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
image->setImageTexture (path);
image->setUserString ("ToolTipType", "ItemPtr");
image->setUserData(item);
image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveItem);
mEnchanting.setOldItem(item);
mEnchanting.nextCastStyle(); mEnchanting.nextCastStyle();
updateLabels(); updateLabels();
} }
void EnchantingDialog::onRemoveItem(MyGUI::Widget *sender)
{
while (mItemBox->getChildCount ())
MyGUI::Gui::getInstance ().destroyWidget (mItemBox->getChildAt(0));
mEnchanting.setOldItem(MWWorld::Ptr());
updateLabels();
}
void EnchantingDialog::onItemCancel() void EnchantingDialog::onItemCancel()
{ {
mItemSelectionDialog->setVisible(false); mItemSelectionDialog->setVisible(false);
@ -202,28 +221,7 @@ namespace MWGui
return; return;
} }
while (mSoulBox->getChildCount ()) setSoulGem(item);
MyGUI::Gui::getInstance ().destroyWidget (mSoulBox->getChildAt(0));
MyGUI::ImageBox* image = mSoulBox->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 32, 32), MyGUI::Align::Default);
std::string path = std::string("icons\\");
path += item.getClass().getInventoryIcon(item);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
image->setImageTexture (path);
image->setUserString ("ToolTipType", "ItemPtr");
image->setUserData(item);
image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveSoul);
updateLabels();
}
void EnchantingDialog::onRemoveSoul(MyGUI::Widget *sender)
{
while (mSoulBox->getChildCount ())
MyGUI::Gui::getInstance ().destroyWidget (mSoulBox->getChildAt(0));
mEnchanting.setSoulGem(MWWorld::Ptr());
updateLabels();
} }
void EnchantingDialog::onSoulCancel() void EnchantingDialog::onSoulCancel()
@ -233,15 +231,22 @@ namespace MWGui
void EnchantingDialog::onSelectSoul(MyGUI::Widget *sender) void EnchantingDialog::onSelectSoul(MyGUI::Widget *sender)
{ {
delete mItemSelectionDialog; if (mEnchanting.getGem().isEmpty())
mItemSelectionDialog = new ItemSelectionDialog("#{sSoulGemsWithSouls}"); {
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onSoulSelected); delete mItemSelectionDialog;
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onSoulCancel); mItemSelectionDialog = new ItemSelectionDialog("#{sSoulGemsWithSouls}");
mItemSelectionDialog->setVisible(true); mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onSoulSelected);
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr()); mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onSoulCancel);
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyChargedSoulstones); mItemSelectionDialog->setVisible(true);
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr());
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyChargedSoulstones);
//MWBase::Environment::get().getWindowManager()->messageBox("#{sInventorySelectNoSoul}"); //MWBase::Environment::get().getWindowManager()->messageBox("#{sInventorySelectNoSoul}");
}
else
{
setSoulGem(MWWorld::Ptr());
}
} }
void EnchantingDialog::notifyEffectsChanged () void EnchantingDialog::notifyEffectsChanged ()
@ -306,7 +311,7 @@ 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().mOwner, mPtr.getCellRef().mRefID)) if (Misc::StringUtils::ciEqual(item.getCellRef().getOwner(), 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)

View file

@ -11,6 +11,7 @@ namespace MWGui
{ {
class ItemSelectionDialog; class ItemSelectionDialog;
class ItemWidget;
class EnchantingDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase class EnchantingDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase
{ {
@ -19,6 +20,12 @@ namespace MWGui
virtual ~EnchantingDialog(); virtual ~EnchantingDialog();
virtual void open(); virtual void open();
virtual void exit();
void setSoulGem (const MWWorld::Ptr& gem);
void setItem (const MWWorld::Ptr& item);
void startEnchanting(MWWorld::Ptr actor); void startEnchanting(MWWorld::Ptr actor);
void startSelfEnchanting(MWWorld::Ptr soulgem); void startSelfEnchanting(MWWorld::Ptr soulgem);
@ -29,8 +36,6 @@ namespace MWGui
void onCancelButtonClicked(MyGUI::Widget* sender); void onCancelButtonClicked(MyGUI::Widget* sender);
void onSelectItem (MyGUI::Widget* sender); void onSelectItem (MyGUI::Widget* sender);
void onSelectSoul (MyGUI::Widget* sender); void onSelectSoul (MyGUI::Widget* sender);
void onRemoveItem (MyGUI::Widget* sender);
void onRemoveSoul (MyGUI::Widget* sender);
void onItemSelected(MWWorld::Ptr item); void onItemSelected(MWWorld::Ptr item);
void onItemCancel(); void onItemCancel();
@ -43,8 +48,8 @@ namespace MWGui
ItemSelectionDialog* mItemSelectionDialog; ItemSelectionDialog* mItemSelectionDialog;
MyGUI::Button* mCancelButton; MyGUI::Button* mCancelButton;
MyGUI::ImageBox* mItemBox; ItemWidget* mItemBox;
MyGUI::ImageBox* mSoulBox; ItemWidget* mSoulBox;
MyGUI::Button* mTypeButton; MyGUI::Button* mTypeButton;
MyGUI::Button* mBuyButton; MyGUI::Button* mBuyButton;

View file

@ -64,10 +64,15 @@ namespace
return unicode; return unicode;
} }
// getUtf8, aka the worst function ever written.
// This includes various hacks for dealing with Morrowind's .fnt files that are *mostly*
// in the expected win12XX encoding, but also have randomly swapped characters sometimes.
// Looks like the Morrowind developers found standard encodings too boring and threw in some twists for fun.
std::string getUtf8 (unsigned char c, ToUTF8::Utf8Encoder& encoder, ToUTF8::FromType encoding) std::string getUtf8 (unsigned char c, ToUTF8::Utf8Encoder& encoder, ToUTF8::FromType encoding)
{ {
if (encoding == ToUTF8::WINDOWS_1250) if (encoding == ToUTF8::WINDOWS_1250)
{ {
// Hacks for polish font
unsigned char win1250; unsigned char win1250;
std::map<unsigned char, unsigned char> conv; std::map<unsigned char, unsigned char> conv;
conv[0x80] = 0xc6; conv[0x80] = 0xc6;
@ -101,7 +106,8 @@ namespace
conv[0xa3] = 0xbf; conv[0xa3] = 0xbf;
conv[0xa4] = 0x0; // not contained in win1250 conv[0xa4] = 0x0; // not contained in win1250
conv[0xe1] = 0x8c; conv[0xe1] = 0x8c;
conv[0xe1] = 0x8c; // Can't remember if this was supposed to read 0xe2, or is it just an extraneous copypaste?
//conv[0xe1] = 0x8c;
conv[0xe3] = 0x0; // not contained in win1250 conv[0xe3] = 0x0; // not contained in win1250
conv[0xf5] = 0x0; // not contained in win1250 conv[0xf5] = 0x0; // not contained in win1250
@ -252,6 +258,21 @@ namespace MWGui
code->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " " code->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
+ MyGUI::utility::toString((fontSize-data[i].ascent))); + MyGUI::utility::toString((fontSize-data[i].ascent)));
// More hacks! The french game uses U+2019, which is nowhere to be found in
// the CP437 encoding of the font. Fall back to 39 (regular apostrophe)
if (i == 39 && mEncoding == ToUTF8::CP437)
{
MyGUI::xml::ElementPtr code = codes->createChild("Code");
code->addAttribute("index", 0x2019);
code->addAttribute("coord", MyGUI::utility::toString(x1) + " "
+ MyGUI::utility::toString(y1) + " "
+ MyGUI::utility::toString(w) + " "
+ MyGUI::utility::toString(h));
code->addAttribute("advance", data[i].width);
code->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
+ MyGUI::utility::toString((fontSize-data[i].ascent)));
}
// ASCII vertical bar, use this as text input cursor // ASCII vertical bar, use this as text input cursor
if (i == 124) if (i == 124)
{ {
@ -265,18 +286,30 @@ namespace MWGui
cursorCode->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " " cursorCode->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
+ MyGUI::utility::toString((fontSize-data[i].ascent))); + MyGUI::utility::toString((fontSize-data[i].ascent)));
} }
// Question mark, use for NotDefined marker (used for glyphs not existing in the font)
if (i == 63)
{
MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code");
cursorCode->addAttribute("index", MyGUI::FontCodeType::NotDefined);
cursorCode->addAttribute("coord", MyGUI::utility::toString(x1) + " "
+ MyGUI::utility::toString(y1) + " "
+ MyGUI::utility::toString(w) + " "
+ MyGUI::utility::toString(h));
cursorCode->addAttribute("advance", data[i].width);
cursorCode->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
+ MyGUI::utility::toString((fontSize-data[i].ascent)));
}
} }
// These are required as well, but the fonts don't provide them // These are required as well, but the fonts don't provide them
for (int i=0; i<3; ++i) for (int i=0; i<2; ++i)
{ {
MyGUI::FontCodeType::Enum type; MyGUI::FontCodeType::Enum type;
if(i == 0) if(i == 0)
type = MyGUI::FontCodeType::Selected; type = MyGUI::FontCodeType::Selected;
else if (i == 1) else if (i == 1)
type = MyGUI::FontCodeType::SelectedBack; type = MyGUI::FontCodeType::SelectedBack;
else if (i == 2)
type = MyGUI::FontCodeType::NotDefined;
MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code"); MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code");
cursorCode->addAttribute("index", type); cursorCode->addAttribute("index", type);

View file

@ -18,6 +18,7 @@
#include "container.hpp" #include "container.hpp"
#include "itemmodel.hpp" #include "itemmodel.hpp"
#include "itemwidget.hpp"
namespace MWGui namespace MWGui
{ {
@ -40,7 +41,7 @@ namespace MWGui
else else
dropped = world->dropObjectOnGround(world->getPlayerPtr(), item.mBase, count); dropped = world->dropObjectOnGround(world->getPlayerPtr(), item.mBase, count);
if (setNewOwner) if (setNewOwner)
dropped.getCellRef().mOwner = ""; dropped.getCellRef().setOwner("");
return dropped; return dropped;
} }
@ -423,9 +424,6 @@ namespace MWGui
mSpellStatus->setProgressRange(100); mSpellStatus->setProgressRange(100);
mSpellStatus->setProgressPosition(successChancePercent); mSpellStatus->setProgressPosition(successChancePercent);
if (mSpellImage->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mSpellImage->getChildAt(0));
mSpellBox->setUserString("ToolTipType", "Spell"); mSpellBox->setUserString("ToolTipType", "Spell");
mSpellBox->setUserString("Spell", spellId); mSpellBox->setUserString("Spell", spellId);
@ -438,7 +436,9 @@ namespace MWGui
icon.insert(slashPos+1, "b_"); icon.insert(slashPos+1, "b_");
icon = std::string("icons\\") + icon; icon = std::string("icons\\") + icon;
Widgets::fixTexturePath(icon); Widgets::fixTexturePath(icon);
mSpellImage->setImageTexture(icon);
mSpellImage->setItem(MWWorld::Ptr());
mSpellImage->setIcon(icon);
} }
void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent) void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent)
@ -455,21 +455,10 @@ namespace MWGui
mSpellStatus->setProgressRange(100); mSpellStatus->setProgressRange(100);
mSpellStatus->setProgressPosition(chargePercent); mSpellStatus->setProgressPosition(chargePercent);
if (mSpellImage->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mSpellImage->getChildAt(0));
mSpellBox->setUserString("ToolTipType", "ItemPtr"); mSpellBox->setUserString("ToolTipType", "ItemPtr");
mSpellBox->setUserData(item); mSpellBox->setUserData(item);
mSpellImage->setImageTexture("textures\\menu_icon_magic_mini.dds"); mSpellImage->setItem(item);
MyGUI::ImageBox* itemBox = mSpellImage->createWidgetReal<MyGUI::ImageBox>("ImageBox", MyGUI::FloatCoord(0,0,1,1)
, MyGUI::Align::Stretch);
std::string path = std::string("icons\\");
path+=item.getClass().getInventoryIcon(item);
Widgets::fixTexturePath(path);
itemBox->setImageTexture(path);
itemBox->setNeedMouseFocus(false);
} }
void HUD::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent) void HUD::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent)
@ -489,23 +478,7 @@ namespace MWGui
mWeapStatus->setProgressRange(100); mWeapStatus->setProgressRange(100);
mWeapStatus->setProgressPosition(durabilityPercent); mWeapStatus->setProgressPosition(durabilityPercent);
if (mWeapImage->getChildCount()) mWeapImage->setItem(item);
MyGUI::Gui::getInstance().destroyWidget(mWeapImage->getChildAt(0));
std::string path = std::string("icons\\");
path+=item.getClass().getInventoryIcon(item);
Widgets::fixTexturePath(path);
if (item.getClass().getEnchantment(item) != "")
{
mWeapImage->setImageTexture("textures\\menu_icon_magic_mini.dds");
MyGUI::ImageBox* itemBox = mWeapImage->createWidgetReal<MyGUI::ImageBox>("ImageBox", MyGUI::FloatCoord(0,0,1,1)
, MyGUI::Align::Stretch);
itemBox->setImageTexture(path);
itemBox->setNeedMouseFocus(false);
}
else
mWeapImage->setImageTexture(path);
} }
void HUD::unsetSelectedSpell() void HUD::unsetSelectedSpell()
@ -519,11 +492,9 @@ namespace MWGui
mWeaponSpellBox->setVisible(true); mWeaponSpellBox->setVisible(true);
} }
if (mSpellImage->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mSpellImage->getChildAt(0));
mSpellStatus->setProgressRange(100); mSpellStatus->setProgressRange(100);
mSpellStatus->setProgressPosition(0); mSpellStatus->setProgressPosition(0);
mSpellImage->setImageTexture(""); mSpellImage->setItem(MWWorld::Ptr());
mSpellBox->clearUserStrings(); mSpellBox->clearUserStrings();
} }
@ -538,17 +509,17 @@ namespace MWGui
mWeaponSpellBox->setVisible(true); mWeaponSpellBox->setVisible(true);
} }
if (mWeapImage->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mWeapImage->getChildAt(0));
mWeapStatus->setProgressRange(100); mWeapStatus->setProgressRange(100);
mWeapStatus->setProgressPosition(0); mWeapStatus->setProgressPosition(0);
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
MWWorld::Ptr player = world->getPlayerPtr(); MWWorld::Ptr player = world->getPlayerPtr();
mWeapImage->setItem(MWWorld::Ptr());
if (player.getClass().getNpcStats(player).isWerewolf()) if (player.getClass().getNpcStats(player).isWerewolf())
mWeapImage->setImageTexture("icons\\k\\tx_werewolf_hand.dds"); mWeapImage->setIcon("icons\\k\\tx_werewolf_hand.dds");
else else
mWeapImage->setImageTexture("icons\\k\\stealth_handtohand.dds"); mWeapImage->setIcon("icons\\k\\stealth_handtohand.dds");
mWeapBox->clearUserStrings(); mWeapBox->clearUserStrings();
} }

View file

@ -10,6 +10,7 @@ namespace MWGui
{ {
class DragAndDrop; class DragAndDrop;
class SpellIcons; class SpellIcons;
class ItemWidget;
class HUD : public OEngine::GUI::Layout, public LocalMapBase class HUD : public OEngine::GUI::Layout, public LocalMapBase
{ {
@ -63,7 +64,7 @@ namespace MWGui
MyGUI::ProgressBar *mHealth, *mMagicka, *mStamina, *mEnemyHealth, *mDrowning; MyGUI::ProgressBar *mHealth, *mMagicka, *mStamina, *mEnemyHealth, *mDrowning;
MyGUI::Widget* mHealthFrame; MyGUI::Widget* mHealthFrame;
MyGUI::Widget *mWeapBox, *mSpellBox, *mSneakBox; MyGUI::Widget *mWeapBox, *mSpellBox, *mSneakBox;
MyGUI::ImageBox *mWeapImage, *mSpellImage; ItemWidget *mWeapImage, *mSpellImage;
MyGUI::ProgressBar *mWeapStatus, *mSpellStatus; MyGUI::ProgressBar *mWeapStatus, *mSpellStatus;
MyGUI::Widget *mEffectBox, *mMinimapBox; MyGUI::Widget *mEffectBox, *mMinimapBox;
MyGUI::Button* mMinimapButton; MyGUI::Button* mMinimapButton;

View file

@ -67,7 +67,7 @@ MWWorld::Ptr InventoryItemModel::moveItem(const ItemStack &item, size_t count, I
if (mActor.getClass().isActor() && mActor.getClass().getCreatureStats(mActor).isDead() if (mActor.getClass().isActor() && mActor.getClass().getCreatureStats(mActor).isDead()
// Make sure that the item is actually owned by the dead actor // 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 // Prevents a potential exploit for resetting the owner of any item, by placing the item in a corpse
&& Misc::StringUtils::ciEqual(item.mBase.getCellRef().mOwner, mActor.getCellRef().mRefID)) && Misc::StringUtils::ciEqual(item.mBase.getCellRef().getOwner(), mActor.getCellRef().getRefId()))
setNewOwner = true; setNewOwner = true;
MWWorld::Ptr ret = otherModel->copyItem(item, count, setNewOwner); MWWorld::Ptr ret = otherModel->copyItem(item, count, setNewOwner);
@ -87,7 +87,7 @@ void InventoryItemModel::update()
// NOTE: Don't show WerewolfRobe objects in the inventory, or allow them to be taken. // NOTE: Don't show WerewolfRobe objects in the inventory, or allow them to be taken.
// Vanilla likely uses a hack like this since there's no other way to prevent it from // Vanilla likely uses a hack like this since there's no other way to prevent it from
// being shown or taken. // being shown or taken.
if(item.getCellRef().mRefID == "werewolfrobe") if(item.getCellRef().getRefId() == "werewolfrobe")
continue; continue;
ItemStack newItem (item, this, item.getRefData().getCount()); ItemStack newItem (item, this, item.getRefData().getCount());

View file

@ -168,8 +168,8 @@ namespace MWGui
int count = item.mCount; int count = item.mCount;
// Bound items may not be moved // Bound items may not be moved
if (item.mBase.getCellRef().mRefID.size() > 6 if (item.mBase.getCellRef().getRefId().size() > 6
&& item.mBase.getCellRef().mRefID.substr(0,6) == "bound_") && item.mBase.getCellRef().getRefId().substr(0,6) == "bound_")
{ {
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0); MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog12}"); MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog12}");
@ -454,7 +454,7 @@ namespace MWGui
// NOTE: Don't allow users to select WerewolfRobe objects in the inventory. Vanilla // NOTE: Don't allow users to select WerewolfRobe objects in the inventory. Vanilla
// likely uses a hack like this since there's no other way to prevent it from being // likely uses a hack like this since there's no other way to prevent it from being
// taken. // taken.
if(item.getCellRef().mRefID == "werewolfrobe") if(item.getCellRef().getRefId() == "werewolfrobe")
return MWWorld::Ptr(); return MWWorld::Ptr();
return item; return item;
} }

View file

@ -100,7 +100,7 @@ namespace MWGui
for (size_t i=0; i<mSourceModel->getItemCount(); ++i) for (size_t i=0; i<mSourceModel->getItemCount(); ++i)
{ {
const ItemStack& item = mSourceModel->getItem(i); const ItemStack& item = mSourceModel->getItem(i);
if (item == itemToSearch) if (item.mBase == itemToSearch.mBase)
return i; return i;
} }
return -1; return -1;
@ -112,7 +112,7 @@ namespace MWGui
for (size_t i=0; i<getItemCount(); ++i) for (size_t i=0; i<getItemCount(); ++i)
{ {
const ItemStack& item = getItem(i); const ItemStack& item = getItem(i);
if (item == itemToSearch) if (item.mBase == itemToSearch.mBase)
return i; return i;
} }
return -1; return -1;

View file

@ -26,6 +26,11 @@ namespace MWGui
center(); center();
} }
void ItemSelectionDialog::exit()
{
eventDialogCanceled();
}
void ItemSelectionDialog::openContainer(const MWWorld::Ptr& container) void ItemSelectionDialog::openContainer(const MWWorld::Ptr& container)
{ {
mModel = new InventoryItemModel(container); mModel = new InventoryItemModel(container);
@ -53,7 +58,7 @@ namespace MWGui
void ItemSelectionDialog::onCancelButtonClicked(MyGUI::Widget* sender) void ItemSelectionDialog::onCancelButtonClicked(MyGUI::Widget* sender)
{ {
eventDialogCanceled(); exit();
} }
} }

View file

@ -14,6 +14,8 @@ namespace MWGui
public: public:
ItemSelectionDialog(const std::string& label); ItemSelectionDialog(const std::string& label);
virtual void exit();
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
typedef MyGUI::delegates::CMultiDelegate1<MWWorld::Ptr> EventHandle_Item; typedef MyGUI::delegates::CMultiDelegate1<MWWorld::Ptr> EventHandle_Item;

View file

@ -12,6 +12,7 @@
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "itemmodel.hpp" #include "itemmodel.hpp"
#include "itemwidget.hpp"
namespace MWGui namespace MWGui
{ {
@ -80,53 +81,24 @@ void ItemView::update()
const ItemStack& item = mModel->getItem(i); const ItemStack& item = mModel->getItem(i);
/// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them /// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
std::string path = std::string("icons\\"); ItemWidget* itemWidget = dragArea->createWidget<ItemWidget>("MW_ItemIcon",
path += item.mBase.getClass().getInventoryIcon(item.mBase);
// background widget (for the "equipped" frame and magic item background image)
bool isMagic = (item.mFlags & ItemStack::Flag_Enchanted);
MyGUI::ImageBox* backgroundWidget = dragArea->createWidget<MyGUI::ImageBox>("ImageBox",
MyGUI::IntCoord(x, y, 42, 42), MyGUI::Align::Default); MyGUI::IntCoord(x, y, 42, 42), MyGUI::Align::Default);
backgroundWidget->setUserString("ToolTipType", "ItemModelIndex"); itemWidget->setUserString("ToolTipType", "ItemModelIndex");
backgroundWidget->setUserData(std::make_pair(i, mModel)); itemWidget->setUserData(std::make_pair(i, mModel));
ItemWidget::ItemState state = ItemWidget::None;
if (item.mType == ItemStack::Type_Barter)
state = ItemWidget::Barter;
if (item.mType == ItemStack::Type_Equipped)
state = ItemWidget::Equip;
itemWidget->setItem(item.mBase, state);
std::string backgroundTex = "textures\\menu_icon"; itemWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ItemView::onSelectedItem);
if (isMagic) itemWidget->eventMouseWheel += MyGUI::newDelegate(this, &ItemView::onMouseWheel);
backgroundTex += "_magic";
if (item.mType == ItemStack::Type_Normal)
{
if (!isMagic)
backgroundTex = "";
}
else if (item.mType == ItemStack::Type_Equipped)
backgroundTex += "_equip";
else if (item.mType == ItemStack::Type_Barter)
backgroundTex += "_barter";
if (backgroundTex != "")
backgroundTex += ".dds";
backgroundWidget->setImageTexture(backgroundTex);
if ((item.mType == ItemStack::Type_Barter) && !isMagic)
backgroundWidget->setProperty("ImageCoord", "2 2 42 42");
else
backgroundWidget->setProperty("ImageCoord", "0 0 42 42");
backgroundWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ItemView::onSelectedItem);
backgroundWidget->eventMouseWheel += MyGUI::newDelegate(this, &ItemView::onMouseWheel);
// image
MyGUI::ImageBox* image = backgroundWidget->createWidget<MyGUI::ImageBox>("ImageBox",
MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
std::string::size_type pos = path.rfind(".");
if(pos != std::string::npos)
path.erase(pos);
path.append(".dds");
image->setImageTexture(path);
image->setNeedMouseFocus(false);
// text widget that shows item count // text widget that shows item count
MyGUI::TextBox* text = image->createWidget<MyGUI::TextBox>("SandBrightText", // TODO: move to ItemWidget
MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label")); MyGUI::TextBox* text = itemWidget->createWidget<MyGUI::TextBox>("SandBrightText",
MyGUI::IntCoord(5, 19, 32, 18), MyGUI::Align::Default, std::string("Label"));
text->setTextAlign(MyGUI::Align::Right); text->setTextAlign(MyGUI::Align::Right);
text->setNeedMouseFocus(false); text->setNeedMouseFocus(false);
text->setTextShadow(true); text->setTextShadow(true);

View file

@ -0,0 +1,105 @@
#include "itemwidget.hpp"
#include <MyGUI_FactoryManager.h>
#include <MyGUI_ImageBox.h>
#include "../mwworld/class.hpp"
namespace MWGui
{
ItemWidget::ItemWidget()
: mItem(NULL)
{
}
void ItemWidget::registerComponents()
{
MyGUI::FactoryManager::getInstance().registerFactory<ItemWidget>("Widget");
}
void ItemWidget::initialiseOverride()
{
assignWidget(mItem, "Item");
if (mItem)
mItem->setNeedMouseFocus(false);
assignWidget(mFrame, "Frame");
if (mFrame)
mFrame->setNeedMouseFocus(false);
Base::initialiseOverride();
}
void ItemWidget::setIcon(const std::string &icon)
{
if (mItem)
mItem->setImageTexture(icon);
}
void ItemWidget::setFrame(const std::string &frame, const MyGUI::IntCoord &coord)
{
if (mFrame)
{
mFrame->setImageTexture(frame);
mFrame->setImageTile(MyGUI::IntSize(coord.width, coord.height)); // Why is this needed? MyGUI bug?
mFrame->setImageCoord(coord);
}
}
void ItemWidget::setIcon(const MWWorld::Ptr &ptr)
{
// image
std::string path = std::string("icons\\");
path += ptr.getClass().getInventoryIcon(ptr);
std::string::size_type pos = path.rfind(".");
if(pos != std::string::npos)
path.erase(pos);
path.append(".dds");
setIcon(path);
}
void ItemWidget::setItem(const MWWorld::Ptr &ptr, ItemState state)
{
if (!mItem)
return;
if (ptr.isEmpty())
{
if (mFrame)
mFrame->setImageTexture("");
mItem->setImageTexture("");
return;
}
bool isMagic = !ptr.getClass().getEnchantment(ptr).empty();
std::string backgroundTex = "textures\\menu_icon";
if (isMagic)
backgroundTex += "_magic";
if (state == None)
{
if (!isMagic)
backgroundTex = "";
}
else if (state == Equip)
{
backgroundTex += "_equip";
}
else if (state == Barter)
backgroundTex += "_barter";
if (backgroundTex != "")
backgroundTex += ".dds";
if (state == Barter && !isMagic)
setFrame(backgroundTex, MyGUI::IntCoord(2,2,42,42));
else
setFrame(backgroundTex, MyGUI::IntCoord(0,0,42,42));
setIcon(ptr);
}
}

View file

@ -0,0 +1,49 @@
#ifndef OPENMW_MWGUI_ITEMWIDGET_H
#define OPENMW_MWGUI_ITEMWIDGET_H
#include <MyGUI_Widget.h>
namespace MWWorld
{
class Ptr;
}
namespace MWGui
{
/// @brief A widget that shows an icon for an MWWorld::Ptr
class ItemWidget : public MyGUI::Widget
{
MYGUI_RTTI_DERIVED(ItemWidget)
public:
ItemWidget();
/// Register needed components with MyGUI's factory manager
static void registerComponents ();
enum ItemState
{
None,
Equip,
Barter,
Magic
};
/// \a ptr may be empty
void setItem (const MWWorld::Ptr& ptr, ItemState state = None);
// Set icon and frame manually
void setIcon (const std::string& icon);
void setIcon (const MWWorld::Ptr& ptr);
void setFrame (const std::string& frame, const MyGUI::IntCoord& coord);
private:
virtual void initialiseOverride();
MyGUI::ImageBox* mItem;
MyGUI::ImageBox* mFrame;
};
}
#endif

View file

@ -148,22 +148,6 @@ namespace
mTypesetter->lineBreak (); mTypesetter->lineBreak ();
} }
}; };
struct AddQuestLink : AddContent
{
AddQuestLink (MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* style) :
AddContent (typesetter, style)
{
}
void operator () (MWGui::JournalViewModel::QuestId id, MWGui::JournalViewModel::Utf8Span name)
{
MWGui::BookTypesetter::Style* style = mTypesetter->createHotStyle (mBodyStyle, MyGUI::Colour::Black, linkHot, linkActive, id);
mTypesetter->write (style, name);
mTypesetter->lineBreak ();
}
};
} }
namespace MWGui namespace MWGui
@ -206,7 +190,7 @@ book JournalBooks::createJournalBook ()
BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f)); BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f));
BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black);
mModel->visitJournalEntries (0, AddJournalEntry (typesetter, body, header, true)); mModel->visitJournalEntries ("", AddJournalEntry (typesetter, body, header, true));
return typesetter->complete (); return typesetter->complete ();
} }
@ -227,16 +211,17 @@ book JournalBooks::createTopicBook (uintptr_t topicId)
return typesetter->complete (); return typesetter->complete ();
} }
book JournalBooks::createQuestBook (uintptr_t questId) book JournalBooks::createQuestBook (const std::string& questName)
{ {
BookTypesetter::Ptr typesetter = createTypesetter (); BookTypesetter::Ptr typesetter = createTypesetter ();
BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f)); BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f));
BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black);
mModel->visitQuestName (questId, AddQuestName (typesetter, header)); AddQuestName addName (typesetter, header);
addName(to_utf8_span(questName.c_str()));
mModel->visitJournalEntries (questId, AddJournalEntry (typesetter, body, header, false)); mModel->visitJournalEntries (questName, AddJournalEntry (typesetter, body, header, false));
return typesetter->complete (); return typesetter->complete ();
} }
@ -269,26 +254,6 @@ book JournalBooks::createTopicIndexBook ()
return typesetter->complete (); return typesetter->complete ();
} }
book JournalBooks::createTopicIndexBook (char character)
{
BookTypesetter::Ptr typesetter = BookTypesetter::create (0x7FFFFFFF, 0x7FFFFFFF);
BookTypesetter::Style* style = typesetter->createStyle ("", MyGUI::Colour::Black);
mModel->visitTopicNamesStartingWith (character, AddTopicLink (typesetter, style));
return typesetter->complete ();
}
book JournalBooks::createQuestIndexBook (bool activeOnly)
{
BookTypesetter::Ptr typesetter = BookTypesetter::create (0x7FFFFFFF, 0x7FFFFFFF);
BookTypesetter::Style* base = typesetter->createStyle ("", MyGUI::Colour::Black);
mModel->visitQuestNames (activeOnly, AddQuestLink (typesetter, base));
return typesetter->complete ();
}
BookTypesetter::Ptr JournalBooks::createTypesetter () BookTypesetter::Ptr JournalBooks::createTypesetter ()
{ {
//TODO: determine page size from layout... //TODO: determine page size from layout...

View file

@ -18,10 +18,9 @@ namespace MWGui
Book createEmptyJournalBook (); Book createEmptyJournalBook ();
Book createJournalBook (); Book createJournalBook ();
Book createTopicBook (uintptr_t topicId); Book createTopicBook (uintptr_t topicId);
Book createQuestBook (uintptr_t questId); Book createTopicBook (const std::string& topicId);
Book createQuestBook (const std::string& questName);
Book createTopicIndexBook (); Book createTopicIndexBook ();
Book createTopicIndexBook (char character);
Book createQuestIndexBook (bool showAll);
private: private:
BookTypesetter::Ptr createTypesetter (); BookTypesetter::Ptr createTypesetter ();

View file

@ -195,10 +195,12 @@ struct JournalViewModelImpl : JournalViewModel
}; };
void visitQuestNames (bool active_only, boost::function <void (QuestId, Utf8Span)> visitor) const void visitQuestNames (bool active_only, boost::function <void (const std::string&)> visitor) const
{ {
MWBase::Journal * journal = MWBase::Environment::get ().getJournal (); MWBase::Journal * journal = MWBase::Environment::get ().getJournal ();
std::set<std::string> visitedQuests;
for (MWBase::Journal::TQuestIter i = journal->questBegin (); i != journal->questEnd (); ++i) for (MWBase::Journal::TQuestIter i = journal->questBegin (); i != journal->questEnd (); ++i)
{ {
if (active_only && i->second.isFinished ()) if (active_only && i->second.isFinished ())
@ -209,7 +211,15 @@ struct JournalViewModelImpl : JournalViewModel
// Note that even with Tribunal, some quests still don't have quest names. I'm assuming those are not supposed // Note that even with Tribunal, some quests still don't have quest names. I'm assuming those are not supposed
// to appear in the quest book. // to appear in the quest book.
if (!quest.getName().empty()) if (!quest.getName().empty())
visitor (reinterpret_cast <QuestId> (&i->second), toUtf8Span (quest.getName())); {
// Don't list the same quest name twice
if (visitedQuests.find(quest.getName()) != visitedQuests.end())
continue;
visitor (quest.getName());
visitedQuests.insert(quest.getName());
}
} }
} }
@ -258,20 +268,29 @@ struct JournalViewModelImpl : JournalViewModel
} }
}; };
void visitJournalEntries (QuestId questId, boost::function <void (JournalEntry const &)> visitor) const void visitJournalEntries (const std::string& questName, boost::function <void (JournalEntry const &)> visitor) const
{ {
MWBase::Journal * journal = MWBase::Environment::get().getJournal(); MWBase::Journal * journal = MWBase::Environment::get().getJournal();
if (questId != 0) if (!questName.empty())
{ {
MWDialogue::Quest const * quest = reinterpret_cast <MWDialogue::Quest const *> (questId); std::vector<MWDialogue::Quest const*> quests;
for (MWBase::Journal::TQuestIter questIt = journal->questBegin(); questIt != journal->questEnd(); ++questIt)
{
if (Misc::StringUtils::ciEqual(questIt->second.getName(), questName))
quests.push_back(&questIt->second);
}
for(MWBase::Journal::TEntryIter i = journal->begin(); i != journal->end (); ++i) for(MWBase::Journal::TEntryIter i = journal->begin(); i != journal->end (); ++i)
{ {
for (MWDialogue::Topic::TEntryIter j = quest->begin (); j != quest->end (); ++j) for (std::vector<MWDialogue::Quest const*>::iterator questIt = quests.begin(); questIt != quests.end(); ++questIt)
{ {
if (i->mInfoId == j->mInfoId) MWDialogue::Quest const* quest = *questIt;
visitor (JournalEntryImpl <MWBase::Journal::TEntryIter> (this, i)); for (MWDialogue::Topic::TEntryIter j = quest->begin (); j != quest->end (); ++j)
{
if (i->mInfoId == j->mInfoId)
visitor (JournalEntryImpl <MWBase::Journal::TEntryIter> (this, i));
}
} }
} }
} }
@ -293,7 +312,7 @@ struct JournalViewModelImpl : JournalViewModel
visitor (toUtf8Span (topic.getName())); visitor (toUtf8Span (topic.getName()));
} }
void visitTopicNamesStartingWith (char character, boost::function < void (TopicId , Utf8Span) > visitor) const void visitTopicNamesStartingWith (char character, boost::function < void (const std::string&) > visitor) const
{ {
MWBase::Journal * journal = MWBase::Environment::get().getJournal(); MWBase::Journal * journal = MWBase::Environment::get().getJournal();
@ -302,7 +321,7 @@ struct JournalViewModelImpl : JournalViewModel
if (i->first [0] != std::tolower (character, mLocale)) if (i->first [0] != std::tolower (character, mLocale))
continue; continue;
visitor (TopicId (&i->second), toUtf8Span (i->second.getName())); visitor (i->second.getName());
} }
} }

View file

@ -70,17 +70,18 @@ namespace MWGui
/// provides access to the name of the quest with the specified identifier /// provides access to the name of the quest with the specified identifier
virtual void visitQuestName (TopicId topicId, boost::function <void (Utf8Span)> visitor) const = 0; virtual void visitQuestName (TopicId topicId, boost::function <void (Utf8Span)> visitor) const = 0;
/// walks the active and optionally completed, quests providing the quest id and name /// walks the active and optionally completed, quests providing the name
virtual void visitQuestNames (bool active_only, boost::function <void (QuestId, Utf8Span)> visitor) const = 0; virtual void visitQuestNames (bool active_only, boost::function <void (const std::string&)> visitor) const = 0;
/// walks over the journal entries related to the specified quest identified by its id /// walks over the journal entries related to all quests with the given name
virtual void visitJournalEntries (QuestId questId, boost::function <void (JournalEntry const &)> visitor) const = 0; /// If \a questName is empty, simply visits all journal entries
virtual void visitJournalEntries (const std::string& questName, boost::function <void (JournalEntry const &)> visitor) const = 0;
/// provides the name of the topic specified by its id /// provides the name of the topic specified by its id
virtual void visitTopicName (TopicId topicId, boost::function <void (Utf8Span)> visitor) const = 0; virtual void visitTopicName (TopicId topicId, boost::function <void (Utf8Span)> visitor) const = 0;
/// walks over the topics whose names start with the specified character providing the topics id and name /// walks over the topics whose names start with the specified character providing the topics name
virtual void visitTopicNamesStartingWith (char character, boost::function < void (TopicId , Utf8Span) > visitor) const = 0; virtual void visitTopicNamesStartingWith (char character, boost::function < void (const std::string&) > visitor) const = 0;
/// walks over the topic entries for the topic specified by its identifier /// walks over the topic entries for the topic specified by its identifier
virtual void visitTopicEntries (TopicId topicId, boost::function <void (TopicEntry const &)> visitor) const = 0; virtual void visitTopicEntries (TopicId topicId, boost::function <void (TopicEntry const &)> visitor) const = 0;

View file

@ -3,6 +3,7 @@
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/journal.hpp"
#include "list.hpp" #include "list.hpp"
#include <sstream> #include <sstream>
@ -19,6 +20,7 @@
#include "imagebutton.hpp" #include "imagebutton.hpp"
#include "journalviewmodel.hpp" #include "journalviewmodel.hpp"
#include "journalbooks.hpp" #include "journalbooks.hpp"
#include "list.hpp"
namespace namespace
{ {
@ -36,9 +38,7 @@ namespace
static char const PageOneNum [] = "PageOneNum"; static char const PageOneNum [] = "PageOneNum";
static char const PageTwoNum [] = "PageTwoNum"; static char const PageTwoNum [] = "PageTwoNum";
static char const TopicsList [] = "TopicsList"; static char const TopicsList [] = "TopicsList";
static char const TopicsPage [] = "TopicsPage";
static char const QuestsList [] = "QuestsList"; static char const QuestsList [] = "QuestsList";
static char const QuestsPage [] = "QuestsPage";
static char const LeftBookPage [] = "LeftBookPage"; static char const LeftBookPage [] = "LeftBookPage";
static char const RightBookPage [] = "RightBookPage"; static char const RightBookPage [] = "RightBookPage";
static char const LeftTopicIndex [] = "LeftTopicIndex"; static char const LeftTopicIndex [] = "LeftTopicIndex";
@ -110,12 +110,17 @@ namespace
adviseButtonClick (ShowAllBTN, &JournalWindowImpl::notifyShowAll ); adviseButtonClick (ShowAllBTN, &JournalWindowImpl::notifyShowAll );
adviseButtonClick (ShowActiveBTN, &JournalWindowImpl::notifyShowActive); adviseButtonClick (ShowActiveBTN, &JournalWindowImpl::notifyShowActive);
MWGui::Widgets::MWList* list = getWidget<MWGui::Widgets::MWList>(QuestsList);
list->eventItemSelected += MyGUI::newDelegate(this, &JournalWindowImpl::notifyQuestClicked);
MWGui::Widgets::MWList* topicsList = getWidget<MWGui::Widgets::MWList>(TopicsList);
topicsList->eventItemSelected += MyGUI::newDelegate(this, &JournalWindowImpl::notifyTopicSelected);
{ {
MWGui::BookPage::ClickCallback callback; MWGui::BookPage::ClickCallback callback;
callback = boost::bind (&JournalWindowImpl::notifyTopicClicked, this, _1); callback = boost::bind (&JournalWindowImpl::notifyTopicClicked, this, _1);
getPage (TopicsPage)->adviseLinkClicked (callback);
getPage (LeftBookPage)->adviseLinkClicked (callback); getPage (LeftBookPage)->adviseLinkClicked (callback);
getPage (RightBookPage)->adviseLinkClicked (callback); getPage (RightBookPage)->adviseLinkClicked (callback);
} }
@ -129,14 +134,6 @@ namespace
getPage (RightTopicIndex)->adviseLinkClicked (callback); getPage (RightTopicIndex)->adviseLinkClicked (callback);
} }
{
MWGui::BookPage::ClickCallback callback;
callback = boost::bind (&JournalWindowImpl::notifyQuestClicked, this, _1);
getPage (QuestsPage)->adviseLinkClicked (callback);
}
adjustButton(OptionsBTN, true); adjustButton(OptionsBTN, true);
adjustButton(PrevPageBTN); adjustButton(PrevPageBTN);
adjustButton(NextPageBTN); adjustButton(NextPageBTN);
@ -271,6 +268,10 @@ namespace
//TODO: figure out how to make "options" page overlay book page //TODO: figure out how to make "options" page overlay book page
// correctly, so that text may show underneath // correctly, so that text may show underneath
getPage (RightBookPage)->showPage (Book (), 0); getPage (RightBookPage)->showPage (Book (), 0);
// If in quest mode, ensure the quest list is updated
if (mQuestMode)
notifyQuests(getWidget<MyGUI::Widget>(QuestsList));
} }
void pushBook (Book book, unsigned int page) void pushBook (Book book, unsigned int page)
@ -349,9 +350,22 @@ namespace
setVisible (JournalBTN, true); setVisible (JournalBTN, true);
} }
void notifyQuestClicked (intptr_t questId) void notifyTopicSelected (const std::string& topic, int id)
{ {
Book book = createQuestBook (questId); const MWBase::Journal* journal = MWBase::Environment::get().getJournal();
intptr_t topicId = 0; /// \todo get rid of intptr ids
for(MWBase::Journal::TTopicIter i = journal->topicBegin(); i != journal->topicEnd (); ++i)
{
if (Misc::StringUtils::ciEqual(i->first, topic))
topicId = intptr_t (&i->second);
}
notifyTopicClicked(topicId);
}
void notifyQuestClicked (const std::string& name, int id)
{
Book book = createQuestBook (name);
if (mStates.size () > 1) if (mStates.size () > 1)
replaceBook (book, 0); replaceBook (book, 0);
@ -395,7 +409,14 @@ namespace
setVisible (RightTopicIndex, false); setVisible (RightTopicIndex, false);
setVisible (TopicsList, true); setVisible (TopicsList, true);
showList (TopicsList, TopicsPage, createTopicIndexBook ((char)character)); MWGui::Widgets::MWList* list = getWidget<MWGui::Widgets::MWList>(TopicsList);
list->clear();
AddNamesToList add(list);
mModel->visitTopicNamesStartingWith((char) character, add);
list->adjustSize();
} }
void notifyTopics(MyGUI::Widget* _sender) void notifyTopics(MyGUI::Widget* _sender)
@ -409,9 +430,21 @@ namespace
setVisible (ShowActiveBTN, false); setVisible (ShowActiveBTN, false);
} }
struct AddNamesToList
{
AddNamesToList(MWGui::Widgets::MWList* list) : mList(list) {}
MWGui::Widgets::MWList* mList;
void operator () (const std::string& name)
{
mList->addItem(name);
}
};
void notifyQuests(MyGUI::Widget* _sender) void notifyQuests(MyGUI::Widget* _sender)
{ {
mQuestMode = true; mQuestMode = true;
setVisible (LeftTopicIndex, false); setVisible (LeftTopicIndex, false);
setVisible (RightTopicIndex, false); setVisible (RightTopicIndex, false);
setVisible (TopicsList, false); setVisible (TopicsList, false);
@ -419,23 +452,26 @@ namespace
setVisible (ShowAllBTN, !mAllQuests); setVisible (ShowAllBTN, !mAllQuests);
setVisible (ShowActiveBTN, mAllQuests); setVisible (ShowActiveBTN, mAllQuests);
showList (QuestsList, QuestsPage, createQuestIndexBook (!mAllQuests)); MWGui::Widgets::MWList* list = getWidget<MWGui::Widgets::MWList>(QuestsList);
list->clear();
AddNamesToList add(list);
mModel->visitQuestNames(!mAllQuests, add);
list->adjustSize();
} }
void notifyShowAll(MyGUI::Widget* _sender) void notifyShowAll(MyGUI::Widget* _sender)
{ {
mAllQuests = true; mAllQuests = true;
setVisible (ShowAllBTN, !mAllQuests); notifyQuests(_sender);
setVisible (ShowActiveBTN, mAllQuests);
showList (QuestsList, QuestsPage, createQuestIndexBook (!mAllQuests));
} }
void notifyShowActive(MyGUI::Widget* _sender) void notifyShowActive(MyGUI::Widget* _sender)
{ {
mAllQuests = false; mAllQuests = false;
setVisible (ShowAllBTN, !mAllQuests); notifyQuests(_sender);
setVisible (ShowActiveBTN, mAllQuests);
showList (QuestsList, QuestsPage, createQuestIndexBook (!mAllQuests));
} }
void notifyCancel(MyGUI::Widget* _sender) void notifyCancel(MyGUI::Widget* _sender)

View file

@ -65,8 +65,10 @@ namespace MWGui
{ {
if (*it != "") if (*it != "")
{ {
if (mListItemSkin.empty())
throw std::runtime_error("MWList needs a ListItemSkin property");
MyGUI::Button* button = mScrollView->createWidget<MyGUI::Button>( MyGUI::Button* button = mScrollView->createWidget<MyGUI::Button>(
"MW_ListLine", MyGUI::IntCoord(0, mItemHeight, mScrollView->getSize().width - scrollBarWidth - 2, 24), mListItemSkin, MyGUI::IntCoord(0, mItemHeight, mScrollView->getSize().width - scrollBarWidth - 2, 24),
MyGUI::Align::Left | MyGUI::Align::Top, getName() + "_item_" + (*it)); MyGUI::Align::Left | MyGUI::Align::Top, getName() + "_item_" + (*it));
button->setCaption((*it)); button->setCaption((*it));
button->getSubWidgetText()->setWordWrap(true); button->getSubWidgetText()->setWordWrap(true);
@ -102,6 +104,14 @@ namespace MWGui
mScrollView->setViewOffset(MyGUI::IntPoint(0, -viewPosition)); mScrollView->setViewOffset(MyGUI::IntPoint(0, -viewPosition));
} }
void MWList::setPropertyOverride(const std::string &_key, const std::string &_value)
{
if (_key == "ListItemSkin")
mListItemSkin = _value;
else
Base::setPropertyOverride(_key, _value);
}
bool MWList::hasItem(const std::string& name) bool MWList::hasItem(const std::string& name)
{ {
return (std::find(mItems.begin(), mItems.end(), name) != mItems.end()); return (std::find(mItems.begin(), mItems.end(), name) != mItems.end());

View file

@ -22,7 +22,7 @@ namespace MWGui
/** /**
* Event: Item selected with the mouse. * Event: Item selected with the mouse.
* signature: void method(std::string itemName) * signature: void method(std::string itemName, int index)
*/ */
EventHandle_StringInt eventItemSelected; EventHandle_StringInt eventItemSelected;
@ -49,6 +49,8 @@ namespace MWGui
MyGUI::Widget* getItemWidget(const std::string& name); MyGUI::Widget* getItemWidget(const std::string& name);
///< get widget for an item name, useful to set up tooltip ///< get widget for an item name, useful to set up tooltip
virtual void setPropertyOverride(const std::string& _key, const std::string& _value);
protected: protected:
void initialiseOverride(); void initialiseOverride();
@ -60,6 +62,7 @@ namespace MWGui
private: private:
MyGUI::ScrollView* mScrollView; MyGUI::ScrollView* mScrollView;
MyGUI::Widget* mClient; MyGUI::Widget* mClient;
std::string mListItemSkin;
std::vector<std::string> mItems; std::vector<std::string> mItems;

View file

@ -11,6 +11,7 @@
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/statemanager.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/inputmanager.hpp" #include "../mwbase/inputmanager.hpp"
@ -26,7 +27,6 @@ namespace MWGui
, WindowBase("openmw_loading_screen.layout") , WindowBase("openmw_loading_screen.layout")
, mLastRenderTime(0.f) , mLastRenderTime(0.f)
, mLastWallpaperChangeTime(0.f) , mLastWallpaperChangeTime(0.f)
, mFirstLoad(true)
, mProgress(0) , mProgress(0)
, mVSyncWasEnabled(false) , mVSyncWasEnabled(false)
{ {
@ -77,7 +77,11 @@ namespace MWGui
mWindow->setVSyncEnabled(false); mWindow->setVSyncEnabled(false);
#endif #endif
if (!mFirstLoad) bool showWallpaper = (MWBase::Environment::get().getStateManager()->getState()
== MWBase::StateManager::State_NoGame);
if (!showWallpaper)
{ {
mBackgroundImage->setImageTexture(""); mBackgroundImage->setImageTexture("");
int width = mWindow->getWidth(); int width = mWindow->getWidth();
@ -103,12 +107,12 @@ namespace MWGui
setVisible(true); setVisible(true);
if (mFirstLoad) if (showWallpaper)
{ {
changeWallpaper(); changeWallpaper();
} }
MWBase::Environment::get().getWindowManager()->pushGuiMode(mFirstLoad ? GM_LoadingWallpaper : GM_Loading); MWBase::Environment::get().getWindowManager()->pushGuiMode(showWallpaper ? GM_LoadingWallpaper : GM_Loading);
} }
void LoadingScreen::loadingOff() void LoadingScreen::loadingOff()
@ -188,11 +192,6 @@ namespace MWGui
draw(); draw();
} }
void LoadingScreen::removeWallpaper()
{
mFirstLoad = false;
}
void LoadingScreen::draw() void LoadingScreen::draw()
{ {
const float loadingScreenFps = 20.f; const float loadingScreenFps = 20.f;
@ -201,7 +200,10 @@ namespace MWGui
{ {
mLastRenderTime = mTimer.getMilliseconds (); mLastRenderTime = mTimer.getMilliseconds ();
if (mFirstLoad && mTimer.getMilliseconds () > mLastWallpaperChangeTime + 5000*1) bool showWallpaper = (MWBase::Environment::get().getStateManager()->getState()
== MWBase::StateManager::State_NoGame);
if (showWallpaper && mTimer.getMilliseconds () > mLastWallpaperChangeTime + 5000*1)
{ {
mLastWallpaperChangeTime = mTimer.getMilliseconds (); mLastWallpaperChangeTime = mTimer.getMilliseconds ();
changeWallpaper(); changeWallpaper();

View file

@ -29,8 +29,6 @@ namespace MWGui
virtual void setVisible(bool visible); virtual void setVisible(bool visible);
virtual void removeWallpaper();
LoadingScreen(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* rw); LoadingScreen(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* rw);
virtual ~LoadingScreen(); virtual ~LoadingScreen();
@ -42,8 +40,6 @@ namespace MWGui
void updateWindow(Ogre::RenderWindow* rw) { mWindow = rw; } void updateWindow(Ogre::RenderWindow* rw) { mWindow = rw; }
private: private:
bool mFirstLoad;
Ogre::SceneManager* mSceneMgr; Ogre::SceneManager* mSceneMgr;
Ogre::RenderWindow* mWindow; Ogre::RenderWindow* mWindow;

View file

@ -1,5 +1,7 @@
#include "mainmenu.hpp" #include "mainmenu.hpp"
#include <OgreResourceGroupManager.h>
#include <components/version/version.hpp> #include <components/version/version.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
@ -16,6 +18,7 @@
#include "confirmationdialog.hpp" #include "confirmationdialog.hpp"
#include "imagebutton.hpp" #include "imagebutton.hpp"
#include "backgroundimage.hpp" #include "backgroundimage.hpp"
#include "videowidget.hpp"
namespace MWGui namespace MWGui
{ {
@ -25,6 +28,7 @@ namespace MWGui
, mButtonBox(0), mWidth (w), mHeight (h) , mButtonBox(0), mWidth (w), mHeight (h)
, mSaveGameDialog(NULL) , mSaveGameDialog(NULL)
, mBackground(NULL) , mBackground(NULL)
, mVideo(NULL)
{ {
getWidget(mVersionText, "VersionText"); getWidget(mVersionText, "VersionText");
std::stringstream sstream; std::stringstream sstream;
@ -42,6 +46,8 @@ namespace MWGui
std::string output = sstream.str(); std::string output = sstream.str();
mVersionText->setCaption(output); mVersionText->setCaption(output);
mHasAnimatedMenu = (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup("video\\menu_background.bik"));
updateMenu(); updateMenu();
} }
@ -134,14 +140,73 @@ namespace MWGui
void MainMenu::showBackground(bool show) void MainMenu::showBackground(bool show)
{ {
if (show && !mBackground) if (mVideo && !show)
{ {
mBackground = MyGUI::Gui::getInstance().createWidgetReal<BackgroundImage>("ImageBox", 0,0,1,1, MyGUI::Gui::getInstance().destroyWidget(mVideoBackground);
MyGUI::Align::Stretch, "Menu"); mVideoBackground = NULL;
mBackground->setBackgroundImage("textures\\menu_morrowind.dds"); mVideo = NULL;
}
if (mBackground && !show)
{
MyGUI::Gui::getInstance().destroyWidget(mBackground);
mBackground = NULL;
}
if (!show)
return;
if (mHasAnimatedMenu)
{
if (!mVideo)
{
// Use black background to correct aspect ratio
mVideoBackground = MyGUI::Gui::getInstance().createWidgetReal<MyGUI::ImageBox>("ImageBox", 0,0,1,1,
MyGUI::Align::Default, "Menu");
mVideoBackground->setImageTexture("black.png");
mVideo = mVideoBackground->createWidget<VideoWidget>("ImageBox", 0,0,1,1,
MyGUI::Align::Stretch, "Menu");
mVideo->playVideo("video\\menu_background.bik", false);
}
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
int screenWidth = viewSize.width;
int screenHeight = viewSize.height;
mVideoBackground->setSize(screenWidth, screenHeight);
double imageaspect = static_cast<double>(mVideo->getVideoWidth())/mVideo->getVideoHeight();
int leftPadding = std::max(0.0, (screenWidth - screenHeight * imageaspect) / 2);
int topPadding = std::max(0.0, (screenHeight - screenWidth / imageaspect) / 2);
mVideo->setCoord(leftPadding, topPadding,
screenWidth - leftPadding*2, screenHeight - topPadding*2);
mVideo->setVisible(true);
}
else
{
if (!mBackground)
{
mBackground = MyGUI::Gui::getInstance().createWidgetReal<BackgroundImage>("ImageBox", 0,0,1,1,
MyGUI::Align::Stretch, "Menu");
mBackground->setBackgroundImage("textures\\menu_morrowind.dds");
}
mBackground->setVisible(true);
}
}
void MainMenu::update(float dt)
{
if (mVideo)
{
if (!mVideo->update())
{
// If finished playing, start again
mVideo->playVideo("video\\menu_background.bik", 0);
}
} }
if (mBackground)
mBackground->setVisible(show);
} }
void MainMenu::updateMenu() void MainMenu::updateMenu()
@ -165,15 +230,15 @@ namespace MWGui
buttons.push_back("newgame"); buttons.push_back("newgame");
if (MWBase::Environment::get().getStateManager()->characterBegin()!=
MWBase::Environment::get().getStateManager()->characterEnd())
buttons.push_back("loadgame");
if (state==MWBase::StateManager::State_Running && if (state==MWBase::StateManager::State_Running &&
MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")==-1 && MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")==-1 &&
MWBase::Environment::get().getWindowManager()->isSavingAllowed()) MWBase::Environment::get().getWindowManager()->isSavingAllowed())
buttons.push_back("savegame"); buttons.push_back("savegame");
if (MWBase::Environment::get().getStateManager()->characterBegin()!=
MWBase::Environment::get().getStateManager()->characterEnd())
buttons.push_back("loadgame");
buttons.push_back("options"); buttons.push_back("options");
if (state==MWBase::StateManager::State_NoGame) if (state==MWBase::StateManager::State_NoGame)
@ -229,7 +294,7 @@ namespace MWGui
if (state == MWBase::StateManager::State_NoGame) if (state == MWBase::StateManager::State_NoGame)
{ {
// Align with the background image // Align with the background image
int bottomPadding=48; int bottomPadding=24;
mButtonBox->setCoord (mWidth/2 - maxwidth/2, mHeight - curH - bottomPadding, maxwidth, curH); mButtonBox->setCoord (mWidth/2 - maxwidth/2, mHeight - curH - bottomPadding, maxwidth, curH);
} }
else else

View file

@ -9,12 +9,15 @@ namespace MWGui
class ImageButton; class ImageButton;
class BackgroundImage; class BackgroundImage;
class SaveGameDialog; class SaveGameDialog;
class VideoWidget;
class MainMenu : public OEngine::GUI::Layout class MainMenu : public OEngine::GUI::Layout
{ {
int mWidth; int mWidth;
int mHeight; int mHeight;
bool mHasAnimatedMenu;
public: public:
MainMenu(int w, int h); MainMenu(int w, int h);
@ -24,6 +27,8 @@ namespace MWGui
virtual void setVisible (bool visible); virtual void setVisible (bool visible);
void update(float dt);
private: private:
MyGUI::Widget* mButtonBox; MyGUI::Widget* mButtonBox;
@ -31,6 +36,9 @@ namespace MWGui
BackgroundImage* mBackground; BackgroundImage* mBackground;
MyGUI::ImageBox* mVideoBackground;
VideoWidget* mVideo; // For animated main menus
std::map<std::string, MWGui::ImageButton*> mButtons; std::map<std::string, MWGui::ImageButton*> mButtons;
void onButtonClicked (MyGUI::Widget* sender); void onButtonClicked (MyGUI::Widget* sender);

View file

@ -47,7 +47,7 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
if (iter->getClass().hasItemHealth(*iter)) if (iter->getClass().hasItemHealth(*iter))
{ {
int maxDurability = iter->getClass().getItemMaxHealth(*iter); int maxDurability = iter->getClass().getItemMaxHealth(*iter);
int durability = (iter->getCellRef().mCharge == -1) ? maxDurability : iter->getCellRef().mCharge; int durability = iter->getClass().getItemHealth(*iter);
if (maxDurability == durability) if (maxDurability == durability)
continue; continue;
@ -110,11 +110,16 @@ void MerchantRepair::open()
center(); center();
} }
void MerchantRepair::exit()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_MerchantRepair);
}
void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender) void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender)
{ {
// repair // repair
MWWorld::Ptr item = *sender->getUserData<MWWorld::Ptr>(); MWWorld::Ptr item = *sender->getUserData<MWWorld::Ptr>();
item.getCellRef().mCharge = item.getClass().getItemMaxHealth(item); item.getCellRef().setCharge(item.getClass().getItemMaxHealth(item));
MWBase::Environment::get().getSoundManager()->playSound("Repair",1,1); MWBase::Environment::get().getSoundManager()->playSound("Repair",1,1);
@ -128,7 +133,7 @@ void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender)
void MerchantRepair::onOkButtonClick(MyGUI::Widget *sender) void MerchantRepair::onOkButtonClick(MyGUI::Widget *sender)
{ {
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_MerchantRepair); exit();
} }
} }

View file

@ -16,6 +16,8 @@ public:
virtual void open(); virtual void open();
virtual void exit();
void startRepair(const MWWorld::Ptr& actor); void startRepair(const MWWorld::Ptr& actor);
private: private:

View file

@ -179,7 +179,6 @@ namespace MWGui
{ {
WindowModal::open(); WindowModal::open();
int fixedWidth = 500;
int textPadding = 10; // padding between text-widget and main-widget int textPadding = 10; // padding between text-widget and main-widget
int textButtonPadding = 20; // padding between the text-widget und the button-widget int textButtonPadding = 20; // padding between the text-widget und the button-widget
int buttonLeftPadding = 10; // padding between the buttons if horizontal int buttonLeftPadding = 10; // padding between the buttons if horizontal
@ -232,102 +231,52 @@ namespace MWGui
buttonsWidth += buttonLeftPadding; buttonsWidth += buttonLeftPadding;
MyGUI::IntSize mainWidgetSize; MyGUI::IntSize mainWidgetSize;
if(buttonsWidth < fixedWidth) // among each other
{ if(biggestButtonWidth > textSize.width) {
// on one line mainWidgetSize.width = biggestButtonWidth + buttonTopPadding;
if(textSize.width + 2*textPadding < buttonsWidth)
{
mainWidgetSize.width = buttonsWidth;
}
else
{
mainWidgetSize.width = textSize.width + 3*textPadding;
}
mainWidgetSize.height = textSize.height + textButtonPadding + buttonHeight + buttonMainPadding;
MyGUI::IntPoint absPos;
absPos.left = (gameWindowSize.width - mainWidgetSize.width)/2;
absPos.top = (gameWindowSize.height - mainWidgetSize.height)/2;
mMainWidget->setPosition(absPos);
mMainWidget->setSize(mainWidgetSize);
MyGUI::IntCoord messageWidgetCoord;
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
messageWidgetCoord.top = textPadding;
mMessageWidget->setCoord(messageWidgetCoord);
mMessageWidget->setSize(textSize);
MyGUI::IntCoord buttonCord;
MyGUI::IntSize buttonSize(0, buttonHeight);
int left = (mainWidgetSize.width - buttonsWidth)/2 + buttonPadding;
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
{
buttonCord.left = left;
buttonCord.top = textSize.height + textButtonPadding;
buttonSize.width = (*button)->getTextSize().width + 2*buttonPadding;
buttonSize.height = (*button)->getTextSize().height + 2*buttonPadding;
(*button)->setCoord(buttonCord);
(*button)->setSize(buttonSize);
left += buttonSize.width + buttonLeftPadding;
}
} }
else else {
{ mainWidgetSize.width = textSize.width + 3*textPadding;
// among each other
if(biggestButtonWidth > textSize.width) {
mainWidgetSize.width = biggestButtonWidth + buttonTopPadding;
}
else {
mainWidgetSize.width = textSize.width + 3*textPadding;
}
MyGUI::IntCoord buttonCord;
MyGUI::IntSize buttonSize(0, buttonHeight);
int top = textButtonPadding + buttonTopPadding + textSize.height;
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
{
buttonSize.width = (*button)->getTextSize().width + buttonPadding*2;
buttonSize.height = (*button)->getTextSize().height + buttonPadding*2;
buttonCord.top = top;
buttonCord.left = (mainWidgetSize.width - buttonSize.width)/2 - 5; // FIXME: -5 is not so nice :/
(*button)->setCoord(buttonCord);
(*button)->setSize(buttonSize);
top += buttonSize.height + 2*buttonTopPadding;
}
mainWidgetSize.height = top + buttonMainPadding;
mMainWidget->setSize(mainWidgetSize);
MyGUI::IntPoint absPos;
absPos.left = (gameWindowSize.width - mainWidgetSize.width)/2;
absPos.top = (gameWindowSize.height - mainWidgetSize.height)/2;
mMainWidget->setPosition(absPos);
MyGUI::IntCoord messageWidgetCoord;
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
messageWidgetCoord.top = textPadding;
messageWidgetCoord.width = textSize.width;
messageWidgetCoord.height = textSize.height;
mMessageWidget->setCoord(messageWidgetCoord);
} }
MyGUI::IntCoord buttonCord;
MyGUI::IntSize buttonSize(0, buttonHeight);
int top = textButtonPadding + buttonTopPadding + textSize.height;
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
{
buttonSize.width = (*button)->getTextSize().width + buttonPadding*2;
buttonSize.height = (*button)->getTextSize().height + buttonPadding*2;
buttonCord.top = top;
buttonCord.left = (mainWidgetSize.width - buttonSize.width)/2 - 5; // FIXME: -5 is not so nice :/
(*button)->setCoord(buttonCord);
(*button)->setSize(buttonSize);
top += buttonSize.height + 2*buttonTopPadding;
}
mainWidgetSize.height = top + buttonMainPadding;
mMainWidget->setSize(mainWidgetSize);
MyGUI::IntPoint absPos;
absPos.left = (gameWindowSize.width - mainWidgetSize.width)/2;
absPos.top = (gameWindowSize.height - mainWidgetSize.height)/2;
mMainWidget->setPosition(absPos);
MyGUI::IntCoord messageWidgetCoord;
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
messageWidgetCoord.top = textPadding;
messageWidgetCoord.width = textSize.width;
messageWidgetCoord.height = textSize.height;
mMessageWidget->setCoord(messageWidgetCoord);
// Set key focus to "Ok" button // Set key focus to "Ok" button
std::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}")); std::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}"));
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button) for(button = mButtons.begin(); button != mButtons.end(); ++button)
{ {
if(Misc::StringUtils::ciEqual((*button)->getCaption(), ok)) if(Misc::StringUtils::ciEqual((*button)->getCaption(), ok))

View file

@ -42,8 +42,8 @@ namespace MWGui
const ItemStack& item = mSourceModel->getItem(i); const ItemStack& item = mSourceModel->getItem(i);
// Bound items may not be stolen // Bound items may not be stolen
if (item.mBase.getCellRef().mRefID.size() > 6 if (item.mBase.getCellRef().getRefId().size() > 6
&& item.mBase.getCellRef().mRefID.substr(0,6) == "bound_") && item.mBase.getCellRef().getRefId().substr(0,6) == "bound_")
{ {
continue; continue;
} }

View file

@ -23,6 +23,8 @@
#include "spellwindow.hpp" #include "spellwindow.hpp"
#include "itemwidget.hpp"
namespace MWGui namespace MWGui
{ {
@ -46,17 +48,24 @@ namespace MWGui
for (int i = 0; i < 10; ++i) for (int i = 0; i < 10; ++i)
{ {
MyGUI::Button* button; ItemWidget* button;
getWidget(button, "QuickKey" + boost::lexical_cast<std::string>(i+1)); getWidget(button, "QuickKey" + boost::lexical_cast<std::string>(i+1));
button->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked); button->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked);
unassign(button, i);
mQuickKeyButtons.push_back(button); mQuickKeyButtons.push_back(button);
mAssigned.push_back(Type_Unassigned);
unassign(button, i);
} }
} }
void QuickKeysMenu::exit()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_QuickKeysMenu);
}
void QuickKeysMenu::clear() void QuickKeysMenu::clear()
{ {
for (int i=0; i<10; ++i) for (int i=0; i<10; ++i)
@ -72,12 +81,14 @@ namespace MWGui
delete mMagicSelectionDialog; delete mMagicSelectionDialog;
} }
void QuickKeysMenu::unassign(MyGUI::Widget* key, int index) void QuickKeysMenu::unassign(ItemWidget* key, int index)
{ {
while (key->getChildCount ()) key->clearUserStrings();
MyGUI::Gui::getInstance ().destroyWidget (key->getChildAt(0)); key->setItem(MWWorld::Ptr());
while (key->getChildCount()) // Destroy number label
MyGUI::Gui::getInstance().destroyWidget(key->getChildAt(0));
key->setUserData(Type_Unassigned); mAssigned[index] = Type_Unassigned;
MyGUI::TextBox* textBox = key->createWidgetReal<MyGUI::TextBox>("SandText", MyGUI::FloatCoord(0,0,1,1), MyGUI::Align::Default); MyGUI::TextBox* textBox = key->createWidgetReal<MyGUI::TextBox>("SandText", MyGUI::FloatCoord(0,0,1,1), MyGUI::Align::Default);
textBox->setTextAlign (MyGUI::Align::Center); textBox->setTextAlign (MyGUI::Align::Center);
@ -151,27 +162,16 @@ namespace MWGui
void QuickKeysMenu::onAssignItem(MWWorld::Ptr item) void QuickKeysMenu::onAssignItem(MWWorld::Ptr item)
{ {
MyGUI::Button* button = mQuickKeyButtons[mSelectedIndex]; assert (mSelectedIndex > 0);
while (button->getChildCount ()) ItemWidget* button = mQuickKeyButtons[mSelectedIndex];
MyGUI::Gui::getInstance ().destroyWidget (button->getChildAt(0)); while (button->getChildCount()) // Destroy number label
MyGUI::Gui::getInstance().destroyWidget(button->getChildAt(0));
button->setUserData(Type_Item); mAssigned[mSelectedIndex] = Type_Item;
MyGUI::ImageBox* frame = button->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(9, 8, 42, 42), MyGUI::Align::Default); button->setItem(item, ItemWidget::Barter);
std::string backgroundTex = "textures\\menu_icon_barter.dds"; button->setUserString ("ToolTipType", "ItemPtr");
frame->setImageTexture (backgroundTex); button->setUserData(item);
frame->setImageCoord (MyGUI::IntCoord(4, 4, 40, 40));
frame->setUserString ("ToolTipType", "ItemPtr");
frame->setUserData(item);
frame->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked);
MyGUI::ImageBox* image = frame->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
std::string path = std::string("icons\\");
path += item.getClass().getInventoryIcon(item);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
image->setImageTexture (path);
image->setNeedMouseFocus (false);
if (mItemSelectionDialog) if (mItemSelectionDialog)
mItemSelectionDialog->setVisible(false); mItemSelectionDialog->setVisible(false);
@ -184,28 +184,18 @@ namespace MWGui
void QuickKeysMenu::onAssignMagicItem (MWWorld::Ptr item) void QuickKeysMenu::onAssignMagicItem (MWWorld::Ptr item)
{ {
MyGUI::Button* button = mQuickKeyButtons[mSelectedIndex]; assert (mSelectedIndex > 0);
while (button->getChildCount ()) ItemWidget* button = mQuickKeyButtons[mSelectedIndex];
MyGUI::Gui::getInstance ().destroyWidget (button->getChildAt(0)); while (button->getChildCount()) // Destroy number label
MyGUI::Gui::getInstance().destroyWidget(button->getChildAt(0));
button->setUserData(Type_MagicItem); mAssigned[mSelectedIndex] = Type_MagicItem;
MyGUI::ImageBox* frame = button->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(9, 8, 42, 42), MyGUI::Align::Default); button->setFrame("textures\\menu_icon_select_magic_magic.dds", MyGUI::IntCoord(2, 2, 40, 40));
std::string backgroundTex = "textures\\menu_icon_select_magic_magic.dds"; button->setIcon(item);
frame->setImageTexture (backgroundTex);
frame->setImageCoord (MyGUI::IntCoord(2, 2, 40, 40));
frame->setUserString ("ToolTipType", "ItemPtr");
frame->setUserData(item);
frame->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked);
MyGUI::ImageBox* image = frame->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default); button->setUserString ("ToolTipType", "ItemPtr");
std::string path = std::string("icons\\"); button->setUserData(item);
path += item.getClass().getInventoryIcon(item);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
image->setImageTexture (path);
image->setNeedMouseFocus (false);
if (mMagicSelectionDialog) if (mMagicSelectionDialog)
mMagicSelectionDialog->setVisible(false); mMagicSelectionDialog->setVisible(false);
@ -213,21 +203,16 @@ namespace MWGui
void QuickKeysMenu::onAssignMagic (const std::string& spellId) void QuickKeysMenu::onAssignMagic (const std::string& spellId)
{ {
MyGUI::Button* button = mQuickKeyButtons[mSelectedIndex]; assert (mSelectedIndex > 0);
while (button->getChildCount ()) ItemWidget* button = mQuickKeyButtons[mSelectedIndex];
MyGUI::Gui::getInstance ().destroyWidget (button->getChildAt(0)); while (button->getChildCount()) // Destroy number label
MyGUI::Gui::getInstance().destroyWidget(button->getChildAt(0));
button->setUserData(Type_Magic); mAssigned[mSelectedIndex] = Type_Magic;
MyGUI::ImageBox* frame = button->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(9, 8, 42, 42), MyGUI::Align::Default); button->setItem(MWWorld::Ptr());
std::string backgroundTex = "textures\\menu_icon_select_magic.dds"; button->setUserString ("ToolTipType", "Spell");
frame->setImageTexture (backgroundTex); button->setUserString ("Spell", spellId);
frame->setImageCoord (MyGUI::IntCoord(2, 2, 40, 40));
frame->setUserString ("ToolTipType", "Spell");
frame->setUserString ("Spell", spellId);
frame->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked);
MyGUI::ImageBox* image = frame->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
const MWWorld::ESMStore &esmStore = const MWWorld::ESMStore &esmStore =
MWBase::Environment::get().getWorld()->getStore(); MWBase::Environment::get().getWorld()->getStore();
@ -246,8 +231,8 @@ namespace MWGui
path.erase(pos); path.erase(pos);
path.append(".dds"); path.append(".dds");
image->setImageTexture (path); button->setFrame("textures\\menu_icon_select_magic.dds", MyGUI::IntCoord(2, 2, 40, 40));
image->setNeedMouseFocus (false); button->setIcon(path);
if (mMagicSelectionDialog) if (mMagicSelectionDialog)
mMagicSelectionDialog->setVisible(false); mMagicSelectionDialog->setVisible(false);
@ -260,28 +245,29 @@ namespace MWGui
void QuickKeysMenu::activateQuickKey(int index) void QuickKeysMenu::activateQuickKey(int index)
{ {
MyGUI::Button* button = mQuickKeyButtons[index-1]; assert (index-1 > 0);
ItemWidget* button = mQuickKeyButtons[index-1];
QuickKeyType type = *button->getUserData<QuickKeyType>(); QuickKeyType type = mAssigned[index-1];
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player); MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
if (type == Type_Item || type == Type_MagicItem) if (type == Type_Item || type == Type_MagicItem)
{ {
MWWorld::Ptr item = *button->getChildAt (0)->getUserData<MWWorld::Ptr>(); MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
// make sure the item is available // make sure the item is available
if (item.getRefData ().getCount() < 1) if (item.getRefData ().getCount() < 1)
{ {
// Try searching for a compatible replacement // Try searching for a compatible replacement
std::string id = item.getCellRef().mRefID; std::string id = item.getCellRef().getRefId();
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
{ {
if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, id)) if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), id))
{ {
item = *it; item = *it;
button->getChildAt(0)->setUserData(item); button->setUserData(item);
break; break;
} }
} }
@ -298,7 +284,7 @@ namespace MWGui
if (type == Type_Magic) if (type == Type_Magic)
{ {
std::string spellId = button->getChildAt(0)->getUserString("Spell"); std::string spellId = button->getUserString("Spell");
// Make sure the player still has this spell // Make sure the player still has this spell
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
@ -310,13 +296,13 @@ namespace MWGui
} }
else if (type == Type_Item) else if (type == Type_Item)
{ {
MWWorld::Ptr item = *button->getChildAt (0)->getUserData<MWWorld::Ptr>(); MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->useItem(item); MWBase::Environment::get().getWindowManager()->getInventoryWindow()->useItem(item);
} }
else if (type == Type_MagicItem) else if (type == Type_MagicItem)
{ {
MWWorld::Ptr item = *button->getChildAt (0)->getUserData<MWWorld::Ptr>(); MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
// retrieve ContainerStoreIterator to the item // retrieve ContainerStoreIterator to the item
MWWorld::ContainerStoreIterator it = store.begin(); MWWorld::ContainerStoreIterator it = store.begin();
@ -385,6 +371,11 @@ namespace MWGui
center(); center();
} }
void QuickKeysMenuAssign::exit()
{
setVisible(false);
}
void QuickKeysMenu::write(ESM::ESMWriter &writer) void QuickKeysMenu::write(ESM::ESMWriter &writer)
{ {
writer.startRecord(ESM::REC_KEYS); writer.startRecord(ESM::REC_KEYS);
@ -393,9 +384,9 @@ namespace MWGui
for (int i=0; i<10; ++i) for (int i=0; i<10; ++i)
{ {
MyGUI::Button* button = mQuickKeyButtons[i]; ItemWidget* button = mQuickKeyButtons[i];
int type = *button->getUserData<QuickKeyType>(); int type = mAssigned[i];
ESM::QuickKeys::QuickKey key; ESM::QuickKeys::QuickKey key;
key.mType = type; key.mType = type;
@ -407,12 +398,12 @@ namespace MWGui
case Type_Item: case Type_Item:
case Type_MagicItem: case Type_MagicItem:
{ {
MWWorld::Ptr item = *button->getChildAt(0)->getUserData<MWWorld::Ptr>(); MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
key.mId = item.getCellRef().mRefID; key.mId = item.getCellRef().getRefId();
break; break;
} }
case Type_Magic: case Type_Magic:
std::string spellId = button->getChildAt(0)->getUserString("Spell"); std::string spellId = button->getUserString("Spell");
key.mId = spellId; key.mId = spellId;
break; break;
} }
@ -442,7 +433,7 @@ namespace MWGui
mSelectedIndex = i; mSelectedIndex = i;
int keyType = it->mType; int keyType = it->mType;
std::string id = it->mId; std::string id = it->mId;
MyGUI::Button* button = mQuickKeyButtons[i]; ItemWidget* button = mQuickKeyButtons[i];
switch (keyType) switch (keyType)
{ {
@ -458,11 +449,12 @@ namespace MWGui
MWWorld::Ptr item; MWWorld::Ptr item;
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
{ {
if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, id)) if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), id))
{ {
if (item.isEmpty() || if (item.isEmpty() ||
// Prefer the stack with the lowest remaining uses // Prefer the stack with the lowest remaining uses
(it->getCellRef().mCharge != -1 && (item.getCellRef().mCharge == -1 || it->getCellRef().mCharge < item.getCellRef().mCharge) )) !item.getClass().hasItemHealth(*it) ||
it->getClass().getItemHealth(*it) < item.getClass().getItemHealth(item))
{ {
item = *it; item = *it;
} }
@ -507,7 +499,12 @@ namespace MWGui
void MagicSelectionDialog::onCancelButtonClicked (MyGUI::Widget *sender) void MagicSelectionDialog::onCancelButtonClicked (MyGUI::Widget *sender)
{ {
mParent->onAssignMagicCancel (); exit();
}
void MagicSelectionDialog::exit()
{
mParent->onAssignMagicCancel();
} }
void MagicSelectionDialog::open () void MagicSelectionDialog::open ()

Some files were not shown because too many files have changed in this diff Show more