mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 18:19:55 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
36e380c6be
128 changed files with 2000 additions and 1255 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -41,7 +41,7 @@ resources
|
||||||
## generated objects
|
## generated objects
|
||||||
apps/openmw/config.hpp
|
apps/openmw/config.hpp
|
||||||
components/version/version.hpp
|
components/version/version.hpp
|
||||||
Docs/mainpage.hpp
|
docs/mainpage.hpp
|
||||||
moc_*.cxx
|
moc_*.cxx
|
||||||
*.cxx_parameters
|
*.cxx_parameters
|
||||||
*qrc_launcher.cxx
|
*qrc_launcher.cxx
|
||||||
|
|
|
@ -56,7 +56,7 @@ include(OpenMWMacros)
|
||||||
|
|
||||||
# doxygen main page
|
# doxygen main page
|
||||||
|
|
||||||
configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp")
|
configure_file ("${OpenMW_SOURCE_DIR}/docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/docs/mainpage.hpp")
|
||||||
|
|
||||||
option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE)
|
option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE)
|
||||||
option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE)
|
option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE)
|
||||||
|
@ -80,13 +80,6 @@ option(USE_FFMPEG "use ffmpeg for sound" ON)
|
||||||
# OS X deployment
|
# OS X deployment
|
||||||
option(OPENMW_OSX_DEPLOYMENT OFF)
|
option(OPENMW_OSX_DEPLOYMENT OFF)
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
|
||||||
option(BUILD_WITH_DPKG "enable dpkg-based install for debian and debian derivatives" OFF)
|
|
||||||
if(BUILD_WITH_DPKG)
|
|
||||||
find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems")
|
|
||||||
endif(BUILD_WITH_DPKG)
|
|
||||||
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")
|
||||||
|
@ -395,17 +388,8 @@ if (CMAKE_COMPILER_IS_GNUCC)
|
||||||
endif (CMAKE_COMPILER_IS_GNUCC)
|
endif (CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
|
||||||
IF(NOT WIN32 AND NOT APPLE)
|
IF(NOT WIN32 AND NOT APPLE)
|
||||||
## Debian and non debian Linux building
|
# Linux building
|
||||||
# Paths
|
# Paths
|
||||||
IF (DPKG_PROGRAM)
|
|
||||||
## Debian specific
|
|
||||||
SET(CMAKE_INSTALL_PREFIX "/usr")
|
|
||||||
SET(DATAROOTDIR "share" CACHE PATH "Sets the root of data directories to a non-default location")
|
|
||||||
SET(DATADIR "share/games/openmw" CACHE PATH "Sets the openmw data directories to a non-default location")
|
|
||||||
SET(ICONDIR "share/pixmaps" CACHE PATH "Set icon dir")
|
|
||||||
SET(SYSCONFDIR "../etc/openmw" CACHE PATH "Set config dir")
|
|
||||||
ELSE ()
|
|
||||||
## Non debian specific
|
|
||||||
SET(BINDIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Where to install binaries")
|
SET(BINDIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Where to install binaries")
|
||||||
SET(DATAROOTDIR "${CMAKE_INSTALL_PREFIX}/share" CACHE PATH "Sets the root of data directories to a non-default location")
|
SET(DATAROOTDIR "${CMAKE_INSTALL_PREFIX}/share" CACHE PATH "Sets the root of data directories to a non-default location")
|
||||||
SET(DATADIR "${DATAROOTDIR}/games/openmw" CACHE PATH "Sets the openmw data directories to a non-default location")
|
SET(DATADIR "${DATAROOTDIR}/games/openmw" CACHE PATH "Sets the openmw data directories to a non-default location")
|
||||||
|
@ -432,9 +416,8 @@ IF(NOT WIN32 AND NOT APPLE)
|
||||||
ENDIF(BUILD_OPENCS)
|
ENDIF(BUILD_OPENCS)
|
||||||
|
|
||||||
# Install licenses
|
# Install licenses
|
||||||
INSTALL(FILES "DejaVu Font License.txt" DESTINATION "${LICDIR}" )
|
INSTALL(FILES "docs/license/DejaVu Font License.txt" DESTINATION "${LICDIR}" )
|
||||||
INSTALL(FILES "extern/shiny/License.txt" DESTINATION "${LICDIR}" RENAME "Shiny License.txt" )
|
INSTALL(FILES "extern/shiny/License.txt" DESTINATION "${LICDIR}" RENAME "Shiny License.txt" )
|
||||||
ENDIF (DPKG_PROGRAM)
|
|
||||||
|
|
||||||
# Install icon and desktop file
|
# Install icon and desktop file
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "${DATAROOTDIR}/applications" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "${DATAROOTDIR}/applications" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||||
|
|
|
@ -119,10 +119,6 @@ endif(NOT WIN32)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(DPKG_PROGRAM)
|
|
||||||
INSTALL(TARGETS omwlauncher RUNTIME DESTINATION games COMPONENT omwlauncher)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_WITH_CODE_COVERAGE)
|
if (BUILD_WITH_CODE_COVERAGE)
|
||||||
add_definitions (--coverage)
|
add_definitions (--coverage)
|
||||||
target_link_libraries(omwlauncher gcov)
|
target_link_libraries(omwlauncher gcov)
|
||||||
|
|
|
@ -22,8 +22,3 @@ if (BUILD_WITH_CODE_COVERAGE)
|
||||||
add_definitions (--coverage)
|
add_definitions (--coverage)
|
||||||
target_link_libraries(mwiniimport gcov)
|
target_link_libraries(mwiniimport gcov)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(DPKG_PROGRAM)
|
|
||||||
INSTALL(TARGETS mwiniimport RUNTIME DESTINATION games COMPONENT mwiniimport)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ opencs_hdrs_noqt (model/doc
|
||||||
|
|
||||||
|
|
||||||
opencs_units (model/world
|
opencs_units (model/world
|
||||||
idtable idtableproxymodel regionmap data
|
idtable idtableproxymodel regionmap data commanddispatcher
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -199,10 +199,6 @@ target_link_libraries(opencs
|
||||||
components
|
components
|
||||||
)
|
)
|
||||||
|
|
||||||
if(DPKG_PROGRAM)
|
|
||||||
INSTALL(TARGETS opencs RUNTIME DESTINATION games COMPONENT opencs)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
INSTALL(TARGETS opencs BUNDLE DESTINATION OpenMW COMPONENT BUNDLE)
|
INSTALL(TARGETS opencs BUNDLE DESTINATION OpenMW COMPONENT BUNDLE)
|
||||||
endif()
|
endif()
|
||||||
|
|
267
apps/opencs/model/world/commanddispatcher.cpp
Normal file
267
apps/opencs/model/world/commanddispatcher.cpp
Normal file
|
@ -0,0 +1,267 @@
|
||||||
|
|
||||||
|
#include "commanddispatcher.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
|
#include "../doc/document.hpp"
|
||||||
|
|
||||||
|
#include "idtable.hpp"
|
||||||
|
#include "record.hpp"
|
||||||
|
#include "commands.hpp"
|
||||||
|
|
||||||
|
std::vector<std::string> CSMWorld::CommandDispatcher::getDeletableRecords() const
|
||||||
|
{
|
||||||
|
std::vector<std::string> result;
|
||||||
|
|
||||||
|
IdTable& model = dynamic_cast<IdTable&> (*mDocument.getData().getTableModel (mId));
|
||||||
|
|
||||||
|
int stateColumnIndex = model.findColumnIndex (Columns::ColumnId_Modification);
|
||||||
|
|
||||||
|
for (std::vector<std::string>::const_iterator iter (mSelection.begin());
|
||||||
|
iter!=mSelection.end(); ++iter)
|
||||||
|
{
|
||||||
|
int row = model.getModelIndex (*iter, 0).row();
|
||||||
|
|
||||||
|
// check record state
|
||||||
|
RecordBase::State state = static_cast<RecordBase::State> (
|
||||||
|
model.data (model.index (row, stateColumnIndex)).toInt());
|
||||||
|
|
||||||
|
if (state==RecordBase::State_Deleted)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// check other columns (only relevant for a subset of the tables)
|
||||||
|
int dialogueTypeIndex = model.searchColumnIndex (Columns::ColumnId_DialogueType);
|
||||||
|
|
||||||
|
if (dialogueTypeIndex!=-1)
|
||||||
|
{
|
||||||
|
int type = model.data (model.index (row, dialogueTypeIndex)).toInt();
|
||||||
|
|
||||||
|
if (type!=ESM::Dialogue::Topic && type!=ESM::Dialogue::Journal)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push_back (*iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> CSMWorld::CommandDispatcher::getRevertableRecords() const
|
||||||
|
{
|
||||||
|
std::vector<std::string> result;
|
||||||
|
|
||||||
|
IdTable& model = dynamic_cast<IdTable&> (*mDocument.getData().getTableModel (mId));
|
||||||
|
|
||||||
|
/// \todo Reverting temporarily disabled on tables that support reordering, because
|
||||||
|
/// revert logic currently can not handle reordering.
|
||||||
|
if (model.getFeatures() & IdTable::Feature_ReorderWithinTopic)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
int stateColumnIndex = model.findColumnIndex (Columns::ColumnId_Modification);
|
||||||
|
|
||||||
|
for (std::vector<std::string>::const_iterator iter (mSelection.begin());
|
||||||
|
iter!=mSelection.end(); ++iter)
|
||||||
|
{
|
||||||
|
int row = model.getModelIndex (*iter, 0).row();
|
||||||
|
|
||||||
|
// check record state
|
||||||
|
RecordBase::State state = static_cast<RecordBase::State> (
|
||||||
|
model.data (model.index (row, stateColumnIndex)).toInt());
|
||||||
|
|
||||||
|
if (state==RecordBase::State_BaseOnly)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
result.push_back (*iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::CommandDispatcher::CommandDispatcher (CSMDoc::Document& document,
|
||||||
|
const CSMWorld::UniversalId& id, QObject *parent)
|
||||||
|
: QObject (parent), mDocument (document), mId (id), mLocked (false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CSMWorld::CommandDispatcher::setEditLock (bool locked)
|
||||||
|
{
|
||||||
|
mLocked = locked;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::CommandDispatcher::setSelection (const std::vector<std::string>& selection)
|
||||||
|
{
|
||||||
|
mSelection = selection;
|
||||||
|
std::for_each (mSelection.begin(), mSelection.end(), Misc::StringUtils::toLower);
|
||||||
|
std::sort (mSelection.begin(), mSelection.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::CommandDispatcher::setExtendedTypes (const std::vector<UniversalId>& types)
|
||||||
|
{
|
||||||
|
mExtendedTypes = types;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::CommandDispatcher::canDelete() const
|
||||||
|
{
|
||||||
|
if (mLocked)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return getDeletableRecords().size()!=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::CommandDispatcher::canRevert() const
|
||||||
|
{
|
||||||
|
if (mLocked)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return getRevertableRecords().size()!=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<CSMWorld::UniversalId> CSMWorld::CommandDispatcher::getExtendedTypes() const
|
||||||
|
{
|
||||||
|
std::vector<CSMWorld::UniversalId> tables;
|
||||||
|
|
||||||
|
if (mId==UniversalId::Type_Cells)
|
||||||
|
{
|
||||||
|
tables.push_back (mId);
|
||||||
|
tables.push_back (UniversalId::Type_References);
|
||||||
|
/// \todo add other cell-specific types
|
||||||
|
}
|
||||||
|
|
||||||
|
return tables;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::CommandDispatcher::executeDelete()
|
||||||
|
{
|
||||||
|
if (mLocked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<std::string> rows = getDeletableRecords();
|
||||||
|
|
||||||
|
if (rows.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
IdTable& model = dynamic_cast<IdTable&> (*mDocument.getData().getTableModel (mId));
|
||||||
|
|
||||||
|
int columnIndex = model.findColumnIndex (Columns::ColumnId_Id);
|
||||||
|
|
||||||
|
if (rows.size()>1)
|
||||||
|
mDocument.getUndoStack().beginMacro (tr ("Delete multiple records"));
|
||||||
|
|
||||||
|
for (std::vector<std::string>::const_iterator iter (rows.begin()); iter!=rows.end(); ++iter)
|
||||||
|
{
|
||||||
|
std::string id = model.data (model.getModelIndex (*iter, columnIndex)).
|
||||||
|
toString().toUtf8().constData();
|
||||||
|
|
||||||
|
mDocument.getUndoStack().push (new CSMWorld::DeleteCommand (model, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rows.size()>1)
|
||||||
|
mDocument.getUndoStack().endMacro();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::CommandDispatcher::executeRevert()
|
||||||
|
{
|
||||||
|
if (mLocked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<std::string> rows = getRevertableRecords();
|
||||||
|
|
||||||
|
if (rows.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
IdTable& model = dynamic_cast<IdTable&> (*mDocument.getData().getTableModel (mId));
|
||||||
|
|
||||||
|
int columnIndex = model.findColumnIndex (Columns::ColumnId_Id);
|
||||||
|
|
||||||
|
if (rows.size()>1)
|
||||||
|
mDocument.getUndoStack().beginMacro (tr ("Revert multiple records"));
|
||||||
|
|
||||||
|
for (std::vector<std::string>::const_iterator iter (rows.begin()); iter!=rows.end(); ++iter)
|
||||||
|
{
|
||||||
|
std::string id = model.data (model.getModelIndex (*iter, columnIndex)).
|
||||||
|
toString().toUtf8().constData();
|
||||||
|
|
||||||
|
mDocument.getUndoStack().push (new CSMWorld::RevertCommand (model, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rows.size()>1)
|
||||||
|
mDocument.getUndoStack().endMacro();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::CommandDispatcher::executeExtendedDelete()
|
||||||
|
{
|
||||||
|
if (mExtendedTypes.size()>1)
|
||||||
|
mDocument.getUndoStack().beginMacro (tr ("Extended delete of multiple records"));
|
||||||
|
|
||||||
|
for (std::vector<UniversalId>::const_iterator iter (mExtendedTypes.begin());
|
||||||
|
iter!=mExtendedTypes.end(); ++iter)
|
||||||
|
{
|
||||||
|
if (*iter==mId)
|
||||||
|
executeDelete();
|
||||||
|
else if (*iter==UniversalId::Type_References)
|
||||||
|
{
|
||||||
|
IdTable& model = dynamic_cast<IdTable&> (
|
||||||
|
*mDocument.getData().getTableModel (*iter));
|
||||||
|
|
||||||
|
const RefCollection& collection = mDocument.getData().getReferences();
|
||||||
|
|
||||||
|
int size = collection.getSize();
|
||||||
|
|
||||||
|
for (int i=size-1; i>=0; --i)
|
||||||
|
{
|
||||||
|
const Record<CellRef>& record = collection.getRecord (i);
|
||||||
|
|
||||||
|
if (record.mState==RecordBase::State_Deleted)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!std::binary_search (mSelection.begin(), mSelection.end(),
|
||||||
|
Misc::StringUtils::lowerCase (record.get().mCell)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mDocument.getUndoStack().push (
|
||||||
|
new CSMWorld::DeleteCommand (model, record.get().mId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mExtendedTypes.size()>1)
|
||||||
|
mDocument.getUndoStack().endMacro();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::CommandDispatcher::executeExtendedRevert()
|
||||||
|
{
|
||||||
|
if (mExtendedTypes.size()>1)
|
||||||
|
mDocument.getUndoStack().beginMacro (tr ("Extended revert of multiple records"));
|
||||||
|
|
||||||
|
for (std::vector<UniversalId>::const_iterator iter (mExtendedTypes.begin());
|
||||||
|
iter!=mExtendedTypes.end(); ++iter)
|
||||||
|
{
|
||||||
|
if (*iter==mId)
|
||||||
|
executeRevert();
|
||||||
|
else if (*iter==UniversalId::Type_References)
|
||||||
|
{
|
||||||
|
IdTable& model = dynamic_cast<IdTable&> (
|
||||||
|
*mDocument.getData().getTableModel (*iter));
|
||||||
|
|
||||||
|
const RefCollection& collection = mDocument.getData().getReferences();
|
||||||
|
|
||||||
|
int size = collection.getSize();
|
||||||
|
|
||||||
|
for (int i=size-1; i>=0; --i)
|
||||||
|
{
|
||||||
|
const Record<CellRef>& record = collection.getRecord (i);
|
||||||
|
|
||||||
|
if (!std::binary_search (mSelection.begin(), mSelection.end(),
|
||||||
|
Misc::StringUtils::lowerCase (record.get().mCell)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mDocument.getUndoStack().push (
|
||||||
|
new CSMWorld::RevertCommand (model, record.get().mId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mExtendedTypes.size()>1)
|
||||||
|
mDocument.getUndoStack().endMacro();
|
||||||
|
}
|
69
apps/opencs/model/world/commanddispatcher.hpp
Normal file
69
apps/opencs/model/world/commanddispatcher.hpp
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#ifndef CSM_WOLRD_COMMANDDISPATCHER_H
|
||||||
|
#define CSM_WOLRD_COMMANDDISPATCHER_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "universalid.hpp"
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Document;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class CommandDispatcher : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
bool mLocked;
|
||||||
|
CSMDoc::Document& mDocument;
|
||||||
|
UniversalId mId;
|
||||||
|
std::vector<std::string> mSelection;
|
||||||
|
std::vector<UniversalId> mExtendedTypes;
|
||||||
|
|
||||||
|
std::vector<std::string> getDeletableRecords() const;
|
||||||
|
|
||||||
|
std::vector<std::string> getRevertableRecords() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CommandDispatcher (CSMDoc::Document& document, const CSMWorld::UniversalId& id,
|
||||||
|
QObject *parent = 0);
|
||||||
|
///< \param id ID of the table the commands should operate on primarily.
|
||||||
|
|
||||||
|
void setEditLock (bool locked);
|
||||||
|
|
||||||
|
void setSelection (const std::vector<std::string>& selection);
|
||||||
|
|
||||||
|
void setExtendedTypes (const std::vector<UniversalId>& types);
|
||||||
|
///< Set record lists selected by the user for extended operations.
|
||||||
|
|
||||||
|
bool canDelete() const;
|
||||||
|
|
||||||
|
bool canRevert() const;
|
||||||
|
|
||||||
|
/// Return IDs of the record collection that can also be affected when
|
||||||
|
/// operating on the record collection this dispatcher is used for.
|
||||||
|
///
|
||||||
|
/// \note The returned collection contains the ID of the record collection this
|
||||||
|
/// dispatcher is used for. However if that record collection does not support
|
||||||
|
/// the extended mode, the returned vector will be empty instead.
|
||||||
|
std::vector<UniversalId> getExtendedTypes() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void executeDelete();
|
||||||
|
|
||||||
|
void executeRevert();
|
||||||
|
|
||||||
|
void executeExtendedDelete();
|
||||||
|
|
||||||
|
void executeExtendedRevert();
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -16,11 +16,12 @@
|
||||||
#include "regionmap.hpp"
|
#include "regionmap.hpp"
|
||||||
#include "columns.hpp"
|
#include "columns.hpp"
|
||||||
|
|
||||||
void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type, bool update)
|
||||||
UniversalId::Type type2, bool update)
|
|
||||||
{
|
{
|
||||||
mModels.push_back (model);
|
mModels.push_back (model);
|
||||||
mModelIndex.insert (std::make_pair (type1, model));
|
mModelIndex.insert (std::make_pair (type, model));
|
||||||
|
|
||||||
|
UniversalId::Type type2 = UniversalId::getParentType (type);
|
||||||
|
|
||||||
if (type2!=UniversalId::Type_None)
|
if (type2!=UniversalId::Type_None)
|
||||||
mModelIndex.insert (std::make_pair (type2, model));
|
mModelIndex.insert (std::make_pair (type2, model));
|
||||||
|
@ -235,26 +236,26 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding)
|
||||||
mFilters.addColumn (new DescriptionColumn<CSMFilter::Filter>);
|
mFilters.addColumn (new DescriptionColumn<CSMFilter::Filter>);
|
||||||
mFilters.addColumn (new ScopeColumn<CSMFilter::Filter>);
|
mFilters.addColumn (new ScopeColumn<CSMFilter::Filter>);
|
||||||
|
|
||||||
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);
|
addModel (new IdTable (&mGlobals), UniversalId::Type_Global);
|
||||||
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst);
|
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmst);
|
||||||
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill, false);
|
addModel (new IdTable (&mSkills), UniversalId::Type_Skill);
|
||||||
addModel (new IdTable (&mClasses), UniversalId::Type_Classes, UniversalId::Type_Class);
|
addModel (new IdTable (&mClasses), UniversalId::Type_Class);
|
||||||
addModel (new IdTable (&mFactions), UniversalId::Type_Factions, UniversalId::Type_Faction);
|
addModel (new IdTable (&mFactions), UniversalId::Type_Faction);
|
||||||
addModel (new IdTable (&mRaces), UniversalId::Type_Races, UniversalId::Type_Race);
|
addModel (new IdTable (&mRaces), UniversalId::Type_Race);
|
||||||
addModel (new IdTable (&mSounds), UniversalId::Type_Sounds, UniversalId::Type_Sound);
|
addModel (new IdTable (&mSounds), UniversalId::Type_Sound);
|
||||||
addModel (new IdTable (&mScripts), UniversalId::Type_Scripts, UniversalId::Type_Script);
|
addModel (new IdTable (&mScripts), UniversalId::Type_Script);
|
||||||
addModel (new IdTable (&mRegions), UniversalId::Type_Regions, UniversalId::Type_Region);
|
addModel (new IdTable (&mRegions), UniversalId::Type_Region);
|
||||||
addModel (new IdTable (&mBirthsigns), UniversalId::Type_Birthsigns, UniversalId::Type_Birthsign);
|
addModel (new IdTable (&mBirthsigns), UniversalId::Type_Birthsign);
|
||||||
addModel (new IdTable (&mSpells), UniversalId::Type_Spells, UniversalId::Type_Spell);
|
addModel (new IdTable (&mSpells), UniversalId::Type_Spell);
|
||||||
addModel (new IdTable (&mTopics), UniversalId::Type_Topics, UniversalId::Type_Topic);
|
addModel (new IdTable (&mTopics), UniversalId::Type_Topic);
|
||||||
addModel (new IdTable (&mJournals), UniversalId::Type_Journals, UniversalId::Type_Journal);
|
addModel (new IdTable (&mJournals), UniversalId::Type_Journal);
|
||||||
addModel (new IdTable (&mTopicInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_TopicInfos, UniversalId::Type_TopicInfo);
|
addModel (new IdTable (&mTopicInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_TopicInfo);
|
||||||
addModel (new IdTable (&mJournalInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_JournalInfos, UniversalId::Type_JournalInfo);
|
addModel (new IdTable (&mJournalInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_JournalInfo);
|
||||||
addModel (new IdTable (&mCells, IdTable::Reordering_None, IdTable::Viewing_Id), UniversalId::Type_Cells, UniversalId::Type_Cell);
|
addModel (new IdTable (&mCells, IdTable::Feature_ViewId), UniversalId::Type_Cell);
|
||||||
addModel (new IdTable (&mReferenceables, IdTable::Reordering_None, IdTable::Viewing_None, true),
|
addModel (new IdTable (&mReferenceables, IdTable::Feature_Preview),
|
||||||
UniversalId::Type_Referenceables, UniversalId::Type_Referenceable);
|
UniversalId::Type_Referenceable);
|
||||||
addModel (new IdTable (&mRefs, IdTable::Reordering_None, IdTable::Viewing_Cell, true), UniversalId::Type_References, UniversalId::Type_Reference, false);
|
addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference);
|
||||||
addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter, false);
|
addModel (new IdTable (&mFilters), UniversalId::Type_Filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::Data::~Data()
|
CSMWorld::Data::~Data()
|
||||||
|
@ -469,8 +470,7 @@ QAbstractItemModel *CSMWorld::Data::getTableModel (const CSMWorld::UniversalId&
|
||||||
if (id.getType()==UniversalId::Type_RegionMap)
|
if (id.getType()==UniversalId::Type_RegionMap)
|
||||||
{
|
{
|
||||||
RegionMap *table = 0;
|
RegionMap *table = 0;
|
||||||
addModel (table = new RegionMap (*this), UniversalId::Type_RegionMap,
|
addModel (table = new RegionMap (*this), UniversalId::Type_RegionMap, false);
|
||||||
UniversalId::Type_None, false);
|
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
throw std::logic_error ("No table model available for " + id.toString());
|
throw std::logic_error ("No table model available for " + id.toString());
|
||||||
|
|
|
@ -83,8 +83,8 @@ namespace CSMWorld
|
||||||
Data (const Data&);
|
Data (const Data&);
|
||||||
Data& operator= (const Data&);
|
Data& operator= (const Data&);
|
||||||
|
|
||||||
void addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
void addModel (QAbstractItemModel *model, UniversalId::Type type,
|
||||||
UniversalId::Type type2 = UniversalId::Type_None, bool update = true);
|
bool update = true);
|
||||||
|
|
||||||
static void appendIds (std::vector<std::string>& ids, const CollectionBase& collection,
|
static void appendIds (std::vector<std::string>& ids, const CollectionBase& collection,
|
||||||
bool listDeleted);
|
bool listDeleted);
|
||||||
|
|
|
@ -4,9 +4,8 @@
|
||||||
#include "collectionbase.hpp"
|
#include "collectionbase.hpp"
|
||||||
#include "columnbase.hpp"
|
#include "columnbase.hpp"
|
||||||
|
|
||||||
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, Reordering reordering,
|
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features)
|
||||||
Viewing viewing, bool preview)
|
: mIdCollection (idCollection), mFeatures (features)
|
||||||
: mIdCollection (idCollection), mReordering (reordering), mViewing (viewing), mPreview (preview)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CSMWorld::IdTable::~IdTable()
|
CSMWorld::IdTable::~IdTable()
|
||||||
|
@ -186,19 +185,9 @@ void CSMWorld::IdTable::reorderRows (int baseIndex, const std::vector<int>& newO
|
||||||
index (baseIndex+newOrder.size()-1, mIdCollection->getColumns()-1));
|
index (baseIndex+newOrder.size()-1, mIdCollection->getColumns()-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::IdTable::Reordering CSMWorld::IdTable::getReordering() const
|
unsigned int CSMWorld::IdTable::getFeatures() const
|
||||||
{
|
{
|
||||||
return mReordering;
|
return mFeatures;
|
||||||
}
|
|
||||||
|
|
||||||
CSMWorld::IdTable::Viewing CSMWorld::IdTable::getViewing() const
|
|
||||||
{
|
|
||||||
return mViewing;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSMWorld::IdTable::hasPreview() const
|
|
||||||
{
|
|
||||||
return mPreview;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const
|
std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const
|
||||||
|
@ -206,7 +195,7 @@ std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row)
|
||||||
std::string id;
|
std::string id;
|
||||||
std::string hint;
|
std::string hint;
|
||||||
|
|
||||||
if (mViewing==Viewing_Cell)
|
if (mFeatures & Feature_ViewCell)
|
||||||
{
|
{
|
||||||
int cellColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Cell);
|
int cellColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Cell);
|
||||||
int idColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Id);
|
int idColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Id);
|
||||||
|
@ -217,7 +206,7 @@ std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row)
|
||||||
hint = "r:" + std::string (mIdCollection->getData (row, idColumn).toString().toUtf8().constData());
|
hint = "r:" + std::string (mIdCollection->getData (row, idColumn).toString().toUtf8().constData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mViewing==Viewing_Id)
|
else if (mFeatures & Feature_ViewId)
|
||||||
{
|
{
|
||||||
int column = mIdCollection->searchColumnIndex (Columns::ColumnId_Id);
|
int column = mIdCollection->searchColumnIndex (Columns::ColumnId_Id);
|
||||||
|
|
||||||
|
|
|
@ -19,26 +19,27 @@ namespace CSMWorld
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Reordering
|
enum Features
|
||||||
{
|
{
|
||||||
Reordering_None,
|
Feature_ReorderWithinTopic = 1,
|
||||||
Reordering_WithinTopic
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Viewing
|
/// Use ID column to generate view request (ID is transformed into
|
||||||
{
|
/// worldspace and original ID is passed as hint with c: prefix).
|
||||||
Viewing_None,
|
Feature_ViewId = 2,
|
||||||
Viewing_Id, // use ID column to generate view request (ID is transformed into
|
|
||||||
// worldspace and original ID is passed as hint with c: prefix)
|
/// Use cell column to generate view request (cell ID is transformed
|
||||||
Viewing_Cell // use cell column to generate view request (cell ID is transformed
|
/// into worldspace and record ID is passed as hint with r: prefix).
|
||||||
// into worldspace and record ID is passed as hint with r: prefix)
|
Feature_ViewCell = 4,
|
||||||
|
|
||||||
|
Feature_View = Feature_ViewId | Feature_ViewCell,
|
||||||
|
|
||||||
|
Feature_Preview = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
CollectionBase *mIdCollection;
|
CollectionBase *mIdCollection;
|
||||||
Reordering mReordering;
|
unsigned int mFeatures;
|
||||||
Viewing mViewing;
|
|
||||||
bool mPreview;
|
bool mPreview;
|
||||||
|
|
||||||
// not implemented
|
// not implemented
|
||||||
|
@ -47,8 +48,7 @@ namespace CSMWorld
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
IdTable (CollectionBase *idCollection, Reordering reordering = Reordering_None,
|
IdTable (CollectionBase *idCollection, unsigned int features = 0);
|
||||||
Viewing viewing = Viewing_None, bool preview = false);
|
|
||||||
///< The ownership of \a idCollection is not transferred.
|
///< The ownership of \a idCollection is not transferred.
|
||||||
|
|
||||||
virtual ~IdTable();
|
virtual ~IdTable();
|
||||||
|
@ -97,11 +97,7 @@ namespace CSMWorld
|
||||||
///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices
|
///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices
|
||||||
/// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex).
|
/// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex).
|
||||||
|
|
||||||
Reordering getReordering() const;
|
unsigned int getFeatures() const;
|
||||||
|
|
||||||
Viewing getViewing() const;
|
|
||||||
|
|
||||||
bool hasPreview() const;
|
|
||||||
|
|
||||||
std::pair<UniversalId, std::string> view (int row) const;
|
std::pair<UniversalId, std::string> view (int row) const;
|
||||||
///< Return the UniversalId and the hint for viewing \a row. If viewing is not
|
///< Return the UniversalId and the hint for viewing \a row. If viewing is not
|
||||||
|
|
|
@ -61,8 +61,8 @@ namespace
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell", ":./spell.png" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell", ":./spell.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Topic, "Topic", 0 },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Topic, "Topic", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Journal, "Journal", 0 },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Journal, "Journal", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_TopicInfo, "TopicInfo", 0 },
|
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_TopicInfo, "TopicInfo", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_JournalInfo, "JournalInfo", 0 },
|
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_JournalInfo, "JournalInfo", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", ":./cell.png" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", ":./cell.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell_Missing, "Cell", ":./cell.png" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell_Missing, "Cell", ":./cell.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables", 0 },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables", 0 },
|
||||||
|
@ -90,7 +90,7 @@ namespace
|
||||||
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Static, "Static", ":./static.png" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Static, "Static", ":./static.png" },
|
||||||
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Weapon, "Weapon", ":./weapon.png" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Weapon, "Weapon", ":./weapon.png" },
|
||||||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Reference", 0 },
|
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Reference", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 },
|
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 },
|
||||||
|
|
||||||
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Preview, "Preview", 0 },
|
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Preview, "Preview", 0 },
|
||||||
|
@ -320,6 +320,28 @@ std::vector<CSMWorld::UniversalId::Type> CSMWorld::UniversalId::listReferenceabl
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSMWorld::UniversalId::Type CSMWorld::UniversalId::getParentType (Type type)
|
||||||
|
{
|
||||||
|
for (int i=0; sIdArg[i].mType; ++i)
|
||||||
|
if (type==sIdArg[i].mType)
|
||||||
|
{
|
||||||
|
if (sIdArg[i].mClass==Class_RefRecord)
|
||||||
|
return Type_Referenceables;
|
||||||
|
|
||||||
|
if (sIdArg[i].mClass==Class_SubRecord || sIdArg[i].mClass==Class_Record)
|
||||||
|
{
|
||||||
|
if (type==Type_Cell_Missing)
|
||||||
|
return Type_Cells;
|
||||||
|
|
||||||
|
return static_cast<Type> (type-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Type_None;
|
||||||
|
}
|
||||||
|
|
||||||
bool CSMWorld::operator== (const CSMWorld::UniversalId& left, const CSMWorld::UniversalId& right)
|
bool CSMWorld::operator== (const CSMWorld::UniversalId& left, const CSMWorld::UniversalId& right)
|
||||||
{
|
{
|
||||||
return left.isEqual (right);
|
return left.isEqual (right);
|
||||||
|
|
|
@ -32,6 +32,8 @@ namespace CSMWorld
|
||||||
ArgumentType_Index
|
ArgumentType_Index
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \note A record list type must always be immediately followed by the matching
|
||||||
|
/// record type, if this type is of class SubRecord or Record.
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
Type_None = 0,
|
Type_None = 0,
|
||||||
|
@ -86,8 +88,8 @@ namespace CSMWorld
|
||||||
Type_References,
|
Type_References,
|
||||||
Type_Reference,
|
Type_Reference,
|
||||||
Type_RegionMap,
|
Type_RegionMap,
|
||||||
Type_Filter,
|
|
||||||
Type_Filters,
|
Type_Filters,
|
||||||
|
Type_Filter,
|
||||||
Type_Topics,
|
Type_Topics,
|
||||||
Type_Topic,
|
Type_Topic,
|
||||||
Type_Journals,
|
Type_Journals,
|
||||||
|
@ -147,6 +149,11 @@ namespace CSMWorld
|
||||||
///< Will return an empty string, if no icon is available.
|
///< Will return an empty string, if no icon is available.
|
||||||
|
|
||||||
static std::vector<Type> listReferenceableTypes();
|
static std::vector<Type> listReferenceableTypes();
|
||||||
|
|
||||||
|
/// If \a type is a SubRecord, RefRecord or Record type return the type of the table
|
||||||
|
/// that contains records of type \a type.
|
||||||
|
/// Otherwise return Type_None.
|
||||||
|
static Type getParentType (Type type);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator== (const UniversalId& left, const UniversalId& right);
|
bool operator== (const UniversalId& left, const UniversalId& right);
|
||||||
|
|
|
@ -332,6 +332,7 @@ void CSVWorld::EditWidget::remake(int row)
|
||||||
if (mMainWidget)
|
if (mMainWidget)
|
||||||
{
|
{
|
||||||
delete mMainWidget;
|
delete mMainWidget;
|
||||||
|
mMainWidget = 0;
|
||||||
}
|
}
|
||||||
mMainWidget = new QWidget (this);
|
mMainWidget = new QWidget (this);
|
||||||
|
|
||||||
|
@ -339,6 +340,7 @@ void CSVWorld::EditWidget::remake(int row)
|
||||||
if (mWidgetMapper)
|
if (mWidgetMapper)
|
||||||
{
|
{
|
||||||
delete mWidgetMapper;
|
delete mWidgetMapper;
|
||||||
|
mWidgetMapper = 0;
|
||||||
}
|
}
|
||||||
mWidgetMapper = new QDataWidgetMapper (this);
|
mWidgetMapper = new QDataWidgetMapper (this);
|
||||||
mWidgetMapper->setModel(mTable);
|
mWidgetMapper->setModel(mTable);
|
||||||
|
@ -396,7 +398,7 @@ void CSVWorld::EditWidget::remake(int row)
|
||||||
|
|
||||||
mWidgetMapper->setCurrentModelIndex(mTable->index(row, 0));
|
mWidgetMapper->setCurrentModelIndex(mTable->index(row, 0));
|
||||||
|
|
||||||
this->setMinimumWidth(325); //TODO find better way to set the width or make it customizable
|
this->setMinimumWidth(325); /// \todo replace hardcoded value with a user setting
|
||||||
this->setWidget(mMainWidget);
|
this->setWidget(mMainWidget);
|
||||||
this->setWidgetResizable(true);
|
this->setWidgetResizable(true);
|
||||||
}
|
}
|
||||||
|
@ -407,7 +409,6 @@ void CSVWorld::EditWidget::remake(int row)
|
||||||
|
|
||||||
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
|
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
|
||||||
const CreatorFactoryBase& creatorFactory, bool sorting) :
|
const CreatorFactoryBase& creatorFactory, bool sorting) :
|
||||||
|
|
||||||
SubView (id),
|
SubView (id),
|
||||||
mEditWidget(0),
|
mEditWidget(0),
|
||||||
mMainLayout(NULL),
|
mMainLayout(NULL),
|
||||||
|
@ -415,8 +416,8 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
|
||||||
mTable(dynamic_cast<CSMWorld::IdTable*>(document.getData().getTableModel(id))),
|
mTable(dynamic_cast<CSMWorld::IdTable*>(document.getData().getTableModel(id))),
|
||||||
mRow (-1),
|
mRow (-1),
|
||||||
mLocked(false),
|
mLocked(false),
|
||||||
mDocument(document)
|
mDocument(document),
|
||||||
|
mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType()))
|
||||||
{
|
{
|
||||||
connect(mTable, SIGNAL(dataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT(dataChanged(const QModelIndex&)));
|
connect(mTable, SIGNAL(dataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT(dataChanged(const QModelIndex&)));
|
||||||
mRow = mTable->getModelIndex (id.getId(), 0).row();
|
mRow = mTable->getModelIndex (id.getId(), 0).row();
|
||||||
|
@ -440,7 +441,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
|
||||||
QToolButton* revertButton = new QToolButton(mainWidget);
|
QToolButton* revertButton = new QToolButton(mainWidget);
|
||||||
revertButton->setIcon(QIcon(":/edit-undo.png"));
|
revertButton->setIcon(QIcon(":/edit-undo.png"));
|
||||||
|
|
||||||
if (mTable->hasPreview())
|
if (mTable->getFeatures() & CSMWorld::IdTable::Feature_Preview)
|
||||||
{
|
{
|
||||||
QToolButton* previewButton = new QToolButton(mainWidget);
|
QToolButton* previewButton = new QToolButton(mainWidget);
|
||||||
previewButton->setIcon(QIcon(":/edit-preview.png"));
|
previewButton->setIcon(QIcon(":/edit-preview.png"));
|
||||||
|
@ -448,7 +449,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
|
||||||
connect(previewButton, SIGNAL(clicked()), this, SLOT(showPreview()));
|
connect(previewButton, SIGNAL(clicked()), this, SLOT(showPreview()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTable->getViewing()!=CSMWorld::IdTable::Viewing_None)
|
if (mTable->getFeatures() & CSMWorld::IdTable::Feature_View)
|
||||||
{
|
{
|
||||||
QToolButton* viewButton = new QToolButton(mainWidget);
|
QToolButton* viewButton = new QToolButton(mainWidget);
|
||||||
viewButton->setIcon(QIcon(":/cell.png"));
|
viewButton->setIcon(QIcon(":/cell.png"));
|
||||||
|
@ -560,14 +561,12 @@ void CSVWorld::DialogueSubView::nextId()
|
||||||
void CSVWorld::DialogueSubView::setEditLock (bool locked)
|
void CSVWorld::DialogueSubView::setEditLock (bool locked)
|
||||||
{
|
{
|
||||||
mLocked = locked;
|
mLocked = locked;
|
||||||
|
|
||||||
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (mRow, 1)).toInt());
|
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (mRow, 1)).toInt());
|
||||||
if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased)
|
|
||||||
{
|
mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || locked);
|
||||||
mEditWidget->setDisabled(true);
|
|
||||||
} else
|
mCommandDispatcher.setEditLock (locked);
|
||||||
{
|
|
||||||
mEditWidget->setDisabled(mLocked);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::DialogueSubView::dataChanged(const QModelIndex & index)
|
void CSVWorld::DialogueSubView::dataChanged(const QModelIndex & index)
|
||||||
|
@ -575,13 +574,8 @@ void CSVWorld::DialogueSubView::dataChanged(const QModelIndex & index)
|
||||||
if (index.row() == mRow)
|
if (index.row() == mRow)
|
||||||
{
|
{
|
||||||
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (mRow, 1)).toInt());
|
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (mRow, 1)).toInt());
|
||||||
if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased)
|
|
||||||
{
|
mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || mLocked);
|
||||||
mEditWidget->setDisabled(true);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
mEditWidget->setDisabled(mLocked);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,7 +665,8 @@ void CSVWorld::DialogueSubView::cloneRequest ()
|
||||||
|
|
||||||
void CSVWorld::DialogueSubView::showPreview ()
|
void CSVWorld::DialogueSubView::showPreview ()
|
||||||
{
|
{
|
||||||
if (mTable->hasPreview() && mRow < mTable->rowCount())
|
if ((mTable->getFeatures() & CSMWorld::IdTable::Feature_Preview) &&
|
||||||
|
mRow < mTable->rowCount())
|
||||||
{
|
{
|
||||||
emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()), "");
|
emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()), "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,9 @@
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
|
|
||||||
#include "../doc/subview.hpp"
|
#include "../doc/subview.hpp"
|
||||||
|
|
||||||
#include "../../model/world/columnbase.hpp"
|
#include "../../model/world/columnbase.hpp"
|
||||||
|
#include "../../model/world/commanddispatcher.hpp"
|
||||||
|
|
||||||
class QDataWidgetMapper;
|
class QDataWidgetMapper;
|
||||||
class QSize;
|
class QSize;
|
||||||
|
@ -169,6 +171,7 @@ namespace CSVWorld
|
||||||
bool mLocked;
|
bool mLocked;
|
||||||
const CSMDoc::Document& mDocument;
|
const CSMDoc::Document& mDocument;
|
||||||
TableBottomBox* mBottom;
|
TableBottomBox* mBottom;
|
||||||
|
CSMWorld::CommandDispatcher mCommandDispatcher;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -80,49 +80,42 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory<SceneSubView>);
|
manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory<SceneSubView>);
|
||||||
|
|
||||||
//edit subviews
|
// Dialogue subviews
|
||||||
manager.add (CSMWorld::UniversalId::Type_Region,
|
static const CSMWorld::UniversalId::Type sTableTypes2[] =
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
{
|
||||||
|
CSMWorld::UniversalId::Type_Region,
|
||||||
|
CSMWorld::UniversalId::Type_Spell,
|
||||||
|
CSMWorld::UniversalId::Type_Birthsign,
|
||||||
|
CSMWorld::UniversalId::Type_Global,
|
||||||
|
CSMWorld::UniversalId::Type_Race,
|
||||||
|
CSMWorld::UniversalId::Type_Class,
|
||||||
|
CSMWorld::UniversalId::Type_Filter,
|
||||||
|
CSMWorld::UniversalId::Type_Sound,
|
||||||
|
CSMWorld::UniversalId::Type_Faction,
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Spell,
|
CSMWorld::UniversalId::Type_None // end marker
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
};
|
||||||
|
|
||||||
|
for (int i=0; sTableTypes2[i]!=CSMWorld::UniversalId::Type_None; ++i)
|
||||||
|
manager.add (sTableTypes2[i],
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView,
|
||||||
|
CreatorFactory<GenericCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Skill,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, NullCreatorFactory > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Gmst,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, NullCreatorFactory > (false));
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Referenceable,
|
manager.add (CSMWorld::UniversalId::Type_Referenceable,
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<ReferenceableCreator> > (false));
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<ReferenceableCreator> > (false));
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Birthsign,
|
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Global,
|
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Gmst,
|
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Race,
|
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Class,
|
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Reference,
|
manager.add (CSMWorld::UniversalId::Type_Reference,
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<ReferenceCreator> > (false));
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<ReferenceCreator> > (false));
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Cell,
|
manager.add (CSMWorld::UniversalId::Type_Cell,
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<CellCreator> > (false));
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<CellCreator> > (false));
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Filter,
|
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Sound,
|
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Faction,
|
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Skill,
|
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_JournalInfo,
|
manager.add (CSMWorld::UniversalId::Type_JournalInfo,
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<InfoCreator> > (false));
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<InfoCreator> > (false));
|
||||||
|
|
||||||
|
|
|
@ -19,14 +19,36 @@
|
||||||
#include "../../model/world/columns.hpp"
|
#include "../../model/world/columns.hpp"
|
||||||
#include "../../model/world/tablemimedata.hpp"
|
#include "../../model/world/tablemimedata.hpp"
|
||||||
#include "../../model/world/tablemimedata.hpp"
|
#include "../../model/world/tablemimedata.hpp"
|
||||||
|
#include "../../model/world/commanddispatcher.hpp"
|
||||||
|
|
||||||
#include "recordstatusdelegate.hpp"
|
#include "recordstatusdelegate.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
|
||||||
void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||||
{
|
{
|
||||||
|
// configure dispatcher
|
||||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||||
|
|
||||||
|
std::vector<std::string> records;
|
||||||
|
|
||||||
|
int columnIndex = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id);
|
||||||
|
|
||||||
|
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end();
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
int row = mProxyModel->mapToSource (mProxyModel->index (iter->row(), 0)).row();
|
||||||
|
|
||||||
|
records.push_back (mModel->data (
|
||||||
|
mModel->index (row, columnIndex)).toString().toUtf8().constData());
|
||||||
|
}
|
||||||
|
|
||||||
|
mDispatcher->setSelection (records);
|
||||||
|
|
||||||
|
std::vector<CSMWorld::UniversalId> extendedTypes = mDispatcher->getExtendedTypes();
|
||||||
|
|
||||||
|
mDispatcher->setExtendedTypes (extendedTypes);
|
||||||
|
|
||||||
|
// create context menu
|
||||||
QMenu menu (this);
|
QMenu menu (this);
|
||||||
|
|
||||||
/// \todo add menu items for select all and clear selection
|
/// \todo add menu items for select all and clear selection
|
||||||
|
@ -44,22 +66,27 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||||
if (mCreateAction)
|
if (mCreateAction)
|
||||||
menu.addAction (mCreateAction);
|
menu.addAction (mCreateAction);
|
||||||
|
|
||||||
/// \todo Reverting temporarily disabled on tables that support reordering, because
|
if (mDispatcher->canRevert())
|
||||||
/// revert logic currently can not handle reordering.
|
{
|
||||||
if (mModel->getReordering()==CSMWorld::IdTable::Reordering_None)
|
|
||||||
if (listRevertableSelectedIds().size()>0)
|
|
||||||
menu.addAction (mRevertAction);
|
menu.addAction (mRevertAction);
|
||||||
|
|
||||||
if (listDeletableSelectedIds().size()>0)
|
if (!extendedTypes.empty())
|
||||||
|
menu.addAction (mExtendedRevertAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mDispatcher->canDelete())
|
||||||
|
{
|
||||||
menu.addAction (mDeleteAction);
|
menu.addAction (mDeleteAction);
|
||||||
|
|
||||||
if (mModel->getReordering()==CSMWorld::IdTable::Reordering_WithinTopic)
|
if (!extendedTypes.empty())
|
||||||
|
menu.addAction (mExtendedDeleteAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mModel->getFeatures() & CSMWorld::IdTable::Feature_ReorderWithinTopic)
|
||||||
{
|
{
|
||||||
/// \todo allow reordering of multiple rows
|
/// \todo allow reordering of multiple rows
|
||||||
if (selectedRows.size()==1)
|
if (selectedRows.size()==1)
|
||||||
{
|
{
|
||||||
int row =selectedRows.begin()->row();
|
|
||||||
|
|
||||||
int column = mModel->searchColumnIndex (CSMWorld::Columns::ColumnId_Topic);
|
int column = mModel->searchColumnIndex (CSMWorld::Columns::ColumnId_Topic);
|
||||||
|
|
||||||
if (column==-1)
|
if (column==-1)
|
||||||
|
@ -67,14 +94,17 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||||
|
|
||||||
if (column!=-1)
|
if (column!=-1)
|
||||||
{
|
{
|
||||||
if (row>0 && mProxyModel->data (mProxyModel->index (row, column))==
|
int row = mProxyModel->mapToSource (
|
||||||
mProxyModel->data (mProxyModel->index (row-1, column)))
|
mProxyModel->index (selectedRows.begin()->row(), 0)).row();
|
||||||
|
|
||||||
|
if (row>0 && mModel->data (mModel->index (row, column))==
|
||||||
|
mModel->data (mModel->index (row-1, column)))
|
||||||
{
|
{
|
||||||
menu.addAction (mMoveUpAction);
|
menu.addAction (mMoveUpAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (row<mProxyModel->rowCount()-1 && mProxyModel->data (mProxyModel->index (row, column))==
|
if (row<mModel->rowCount()-1 && mModel->data (mModel->index (row, column))==
|
||||||
mProxyModel->data (mProxyModel->index (row+1, column)))
|
mModel->data (mModel->index (row+1, column)))
|
||||||
{
|
{
|
||||||
menu.addAction (mMoveDownAction);
|
menu.addAction (mMoveDownAction);
|
||||||
}
|
}
|
||||||
|
@ -85,7 +115,7 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||||
|
|
||||||
if (selectedRows.size()==1)
|
if (selectedRows.size()==1)
|
||||||
{
|
{
|
||||||
if (mModel->getViewing()!=CSMWorld::IdTable::Viewing_None)
|
if (mModel->getFeatures() & CSMWorld::IdTable::Feature_View)
|
||||||
{
|
{
|
||||||
int row = selectedRows.begin()->row();
|
int row = selectedRows.begin()->row();
|
||||||
|
|
||||||
|
@ -101,91 +131,13 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||||
menu.addAction (mViewAction);
|
menu.addAction (mViewAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mModel->hasPreview())
|
if (mModel->getFeatures() & CSMWorld::IdTable::Feature_Preview)
|
||||||
menu.addAction (mPreviewAction);
|
menu.addAction (mPreviewAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.exec (event->globalPos());
|
menu.exec (event->globalPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> CSVWorld::Table::listRevertableSelectedIds() const
|
|
||||||
{
|
|
||||||
std::vector<std::string> revertableIds;
|
|
||||||
|
|
||||||
if (mProxyModel->columnCount()>0)
|
|
||||||
{
|
|
||||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
|
||||||
|
|
||||||
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end();
|
|
||||||
++iter)
|
|
||||||
{
|
|
||||||
QModelIndex index = mProxyModel->mapToSource (mProxyModel->index (iter->row(), 0));
|
|
||||||
|
|
||||||
CSMWorld::RecordBase::State state =
|
|
||||||
static_cast<CSMWorld::RecordBase::State> (
|
|
||||||
mModel->data (mModel->index (index.row(), 1)).toInt());
|
|
||||||
|
|
||||||
if (state!=CSMWorld::RecordBase::State_BaseOnly)
|
|
||||||
{
|
|
||||||
int columnIndex = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id);
|
|
||||||
|
|
||||||
std::string id = mModel->data (mModel->index (index.row(), columnIndex)).
|
|
||||||
toString().toUtf8().constData();
|
|
||||||
|
|
||||||
revertableIds.push_back (id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return revertableIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> CSVWorld::Table::listDeletableSelectedIds() const
|
|
||||||
{
|
|
||||||
std::vector<std::string> deletableIds;
|
|
||||||
|
|
||||||
if (mProxyModel->columnCount()>0)
|
|
||||||
{
|
|
||||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
|
||||||
|
|
||||||
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end();
|
|
||||||
++iter)
|
|
||||||
{
|
|
||||||
QModelIndex index = mProxyModel->mapToSource (mProxyModel->index (iter->row(), 0));
|
|
||||||
|
|
||||||
// check record state
|
|
||||||
CSMWorld::RecordBase::State state =
|
|
||||||
static_cast<CSMWorld::RecordBase::State> (
|
|
||||||
mModel->data (mModel->index (index.row(), 1)).toInt());
|
|
||||||
|
|
||||||
if (state==CSMWorld::RecordBase::State_Deleted)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// check other columns (only relevant for a subset of the tables)
|
|
||||||
int dialogueTypeIndex =
|
|
||||||
mModel->searchColumnIndex (CSMWorld::Columns::ColumnId_DialogueType);
|
|
||||||
|
|
||||||
if (dialogueTypeIndex!=-1)
|
|
||||||
{
|
|
||||||
int type = mModel->data (mModel->index (index.row(), dialogueTypeIndex)).toInt();
|
|
||||||
|
|
||||||
if (type!=ESM::Dialogue::Topic && type!=ESM::Dialogue::Journal)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the id to the collection
|
|
||||||
int columnIndex = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id);
|
|
||||||
|
|
||||||
std::string id = mModel->data (mModel->index (index.row(), columnIndex)).
|
|
||||||
toString().toUtf8().constData();
|
|
||||||
|
|
||||||
deletableIds.push_back (id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return deletableIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
||||||
bool createAndDelete, bool sorting, CSMDoc::Document& document)
|
bool createAndDelete, bool sorting, CSMDoc::Document& document)
|
||||||
: mCreateAction (0), mCloneAction(0), mRecordStatusDisplay (0),
|
: mCreateAction (0), mCloneAction(0), mRecordStatusDisplay (0),
|
||||||
|
@ -196,6 +148,8 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
||||||
mProxyModel = new CSMWorld::IdTableProxyModel (this);
|
mProxyModel = new CSMWorld::IdTableProxyModel (this);
|
||||||
mProxyModel->setSourceModel (mModel);
|
mProxyModel->setSourceModel (mModel);
|
||||||
|
|
||||||
|
mDispatcher = new CSMWorld::CommandDispatcher (document, id, this);
|
||||||
|
|
||||||
setModel (mProxyModel);
|
setModel (mProxyModel);
|
||||||
horizontalHeader()->setResizeMode (QHeaderView::Interactive);
|
horizontalHeader()->setResizeMode (QHeaderView::Interactive);
|
||||||
verticalHeader()->hide();
|
verticalHeader()->hide();
|
||||||
|
@ -240,11 +194,11 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
||||||
}
|
}
|
||||||
|
|
||||||
mRevertAction = new QAction (tr ("Revert Record"), this);
|
mRevertAction = new QAction (tr ("Revert Record"), this);
|
||||||
connect (mRevertAction, SIGNAL (triggered()), this, SLOT (revertRecord()));
|
connect (mRevertAction, SIGNAL (triggered()), mDispatcher, SLOT (executeRevert()));
|
||||||
addAction (mRevertAction);
|
addAction (mRevertAction);
|
||||||
|
|
||||||
mDeleteAction = new QAction (tr ("Delete Record"), this);
|
mDeleteAction = new QAction (tr ("Delete Record"), this);
|
||||||
connect (mDeleteAction, SIGNAL (triggered()), this, SLOT (deleteRecord()));
|
connect (mDeleteAction, SIGNAL (triggered()), mDispatcher, SLOT (executeDelete()));
|
||||||
addAction (mDeleteAction);
|
addAction (mDeleteAction);
|
||||||
|
|
||||||
mMoveUpAction = new QAction (tr ("Move Up"), this);
|
mMoveUpAction = new QAction (tr ("Move Up"), this);
|
||||||
|
@ -263,6 +217,18 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
||||||
connect (mPreviewAction, SIGNAL (triggered()), this, SLOT (previewRecord()));
|
connect (mPreviewAction, SIGNAL (triggered()), this, SLOT (previewRecord()));
|
||||||
addAction (mPreviewAction);
|
addAction (mPreviewAction);
|
||||||
|
|
||||||
|
/// \todo add a user option, that redirects the extended action to an input panel (in
|
||||||
|
/// the bottom bar) that lets the user select which record collections should be
|
||||||
|
/// modified.
|
||||||
|
|
||||||
|
mExtendedDeleteAction = new QAction (tr ("Extended Delete Record"), this);
|
||||||
|
connect (mExtendedDeleteAction, SIGNAL (triggered()), mDispatcher, SLOT (executeExtendedDelete()));
|
||||||
|
addAction (mExtendedDeleteAction);
|
||||||
|
|
||||||
|
mExtendedRevertAction = new QAction (tr ("Extended Revert Record"), this);
|
||||||
|
connect (mExtendedRevertAction, SIGNAL (triggered()), mDispatcher, SLOT (executeExtendedRevert()));
|
||||||
|
addAction (mExtendedRevertAction);
|
||||||
|
|
||||||
connect (mProxyModel, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
connect (mProxyModel, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
||||||
this, SLOT (tableSizeUpdate()));
|
this, SLOT (tableSizeUpdate()));
|
||||||
|
|
||||||
|
@ -283,53 +249,19 @@ void CSVWorld::Table::setEditLock (bool locked)
|
||||||
(*iter)->setEditLock (locked);
|
(*iter)->setEditLock (locked);
|
||||||
|
|
||||||
DragRecordTable::setEditLock(locked);
|
DragRecordTable::setEditLock(locked);
|
||||||
|
mDispatcher->setEditLock (locked);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const
|
CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const
|
||||||
{
|
{
|
||||||
|
row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row();
|
||||||
|
|
||||||
|
int idColumn = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id);
|
||||||
|
int typeColumn = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_RecordType);
|
||||||
|
|
||||||
return CSMWorld::UniversalId (
|
return CSMWorld::UniversalId (
|
||||||
static_cast<CSMWorld::UniversalId::Type> (mProxyModel->data (mProxyModel->index (row, 2)).toInt()),
|
static_cast<CSMWorld::UniversalId::Type> (mModel->data (mModel->index (row, typeColumn)).toInt()),
|
||||||
mProxyModel->data (mProxyModel->index (row, 0)).toString().toUtf8().constData());
|
mModel->data (mModel->index (row, idColumn)).toString().toUtf8().constData());
|
||||||
}
|
|
||||||
|
|
||||||
void CSVWorld::Table::revertRecord()
|
|
||||||
{
|
|
||||||
if (!mEditLock)
|
|
||||||
{
|
|
||||||
std::vector<std::string> revertableIds = listRevertableSelectedIds();
|
|
||||||
|
|
||||||
if (!revertableIds.empty())
|
|
||||||
{
|
|
||||||
if (revertableIds.size()>1)
|
|
||||||
mDocument.getUndoStack().beginMacro (tr ("Revert multiple records"));
|
|
||||||
|
|
||||||
for (std::vector<std::string>::const_iterator iter (revertableIds.begin()); iter!=revertableIds.end(); ++iter)
|
|
||||||
mDocument.getUndoStack().push (new CSMWorld::RevertCommand (*mModel, *iter));
|
|
||||||
|
|
||||||
if (revertableIds.size()>1)
|
|
||||||
mDocument.getUndoStack().endMacro();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSVWorld::Table::deleteRecord()
|
|
||||||
{
|
|
||||||
if (!mEditLock)
|
|
||||||
{
|
|
||||||
std::vector<std::string> deletableIds = listDeletableSelectedIds();
|
|
||||||
|
|
||||||
if (!deletableIds.empty())
|
|
||||||
{
|
|
||||||
if (deletableIds.size()>1)
|
|
||||||
mDocument.getUndoStack().beginMacro (tr ("Delete multiple records"));
|
|
||||||
|
|
||||||
for (std::vector<std::string>::const_iterator iter (deletableIds.begin()); iter!=deletableIds.end(); ++iter)
|
|
||||||
mDocument.getUndoStack().push (new CSMWorld::DeleteCommand (*mModel, *iter));
|
|
||||||
|
|
||||||
if (deletableIds.size()>1)
|
|
||||||
mDocument.getUndoStack().endMacro();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::Table::editRecord()
|
void CSVWorld::Table::editRecord()
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace CSMWorld
|
||||||
class UniversalId;
|
class UniversalId;
|
||||||
class IdTableProxyModel;
|
class IdTableProxyModel;
|
||||||
class IdTable;
|
class IdTable;
|
||||||
|
class CommandDispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSVWorld
|
namespace CSVWorld
|
||||||
|
@ -45,18 +46,17 @@ namespace CSVWorld
|
||||||
QAction *mMoveDownAction;
|
QAction *mMoveDownAction;
|
||||||
QAction *mViewAction;
|
QAction *mViewAction;
|
||||||
QAction *mPreviewAction;
|
QAction *mPreviewAction;
|
||||||
|
QAction *mExtendedDeleteAction;
|
||||||
|
QAction *mExtendedRevertAction;
|
||||||
CSMWorld::IdTableProxyModel *mProxyModel;
|
CSMWorld::IdTableProxyModel *mProxyModel;
|
||||||
CSMWorld::IdTable *mModel;
|
CSMWorld::IdTable *mModel;
|
||||||
int mRecordStatusDisplay;
|
int mRecordStatusDisplay;
|
||||||
|
CSMWorld::CommandDispatcher *mDispatcher;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void contextMenuEvent (QContextMenuEvent *event);
|
void contextMenuEvent (QContextMenuEvent *event);
|
||||||
|
|
||||||
std::vector<std::string> listRevertableSelectedIds() const;
|
|
||||||
|
|
||||||
std::vector<std::string> listDeletableSelectedIds() const;
|
|
||||||
|
|
||||||
void mouseMoveEvent(QMouseEvent *event);
|
void mouseMoveEvent(QMouseEvent *event);
|
||||||
|
|
||||||
void dropEvent(QDropEvent *event);
|
void dropEvent(QDropEvent *event);
|
||||||
|
@ -93,10 +93,6 @@ namespace CSVWorld
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void revertRecord();
|
|
||||||
|
|
||||||
void deleteRecord();
|
|
||||||
|
|
||||||
void editRecord();
|
void editRecord();
|
||||||
|
|
||||||
void cloneRecord();
|
void cloneRecord();
|
||||||
|
|
|
@ -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
|
||||||
|
@ -142,10 +142,6 @@ if(APPLE)
|
||||||
endif()
|
endif()
|
||||||
endif(APPLE)
|
endif(APPLE)
|
||||||
|
|
||||||
if(DPKG_PROGRAM)
|
|
||||||
INSTALL(TARGETS openmw RUNTIME DESTINATION games COMPONENT openmw)
|
|
||||||
endif(DPKG_PROGRAM)
|
|
||||||
|
|
||||||
if (BUILD_WITH_CODE_COVERAGE)
|
if (BUILD_WITH_CODE_COVERAGE)
|
||||||
add_definitions (--coverage)
|
add_definitions (--coverage)
|
||||||
target_link_libraries(openmw gcov)
|
target_link_libraries(openmw gcov)
|
||||||
|
|
|
@ -4,19 +4,19 @@
|
||||||
#include <components/version/version.hpp>
|
#include <components/version/version.hpp>
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL_messagebox.h>
|
||||||
|
#include <SDL_main.h>
|
||||||
#include "engine.hpp"
|
#include "engine.hpp"
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(_CONSOLE)
|
|
||||||
#include <boost/iostreams/concepts.hpp>
|
#include <boost/iostreams/concepts.hpp>
|
||||||
#include <boost/iostreams/stream_buffer.hpp>
|
#include <boost/iostreams/stream_buffer.hpp>
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
// For OutputDebugString
|
// For OutputDebugString
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
// makes __argc and __argv available on windows
|
// makes __argc and __argv available on windows
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -253,58 +253,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char**argv)
|
#if defined(_WIN32) && defined(_DEBUG)
|
||||||
{
|
|
||||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
|
||||||
// Unix crash catcher
|
|
||||||
if ((argc == 2 && strcmp(argv[1], "--cc-handle-crash") == 0) || !is_debugger_attached())
|
|
||||||
{
|
|
||||||
int s[5] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGABRT };
|
|
||||||
cc_install_handlers(argc, argv, 5, s, "crash.log", NULL);
|
|
||||||
std::cout << "Installing crash catcher" << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
std::cout << "Running in a debugger, not installing crash catcher" << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
|
||||||
// set current dir to bundle path
|
|
||||||
boost::filesystem::path bundlePath = boost::filesystem::path(Ogre::macBundlePath()).parent_path();
|
|
||||||
boost::filesystem::current_path(bundlePath);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Files::ConfigurationManager cfgMgr;
|
|
||||||
OMW::Engine engine(cfgMgr);
|
|
||||||
|
|
||||||
if (parseOptions(argc, argv, engine, cfgMgr))
|
|
||||||
{
|
|
||||||
engine.go();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception &e)
|
|
||||||
{
|
|
||||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
|
||||||
if (isatty(fileno(stdin)) || !SDL_WasInit(SDL_INIT_VIDEO))
|
|
||||||
std::cerr << "\nERROR: " << e.what() << std::endl;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
SDL_ShowSimpleMessageBox(0, "OpenMW: Fatal error", e.what(), NULL);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Platform specific for Windows when there is no console built into the executable.
|
|
||||||
// Windows will call the WinMain function instead of main in this case, the normal
|
|
||||||
// main function is then called with the __argc and __argv parameters.
|
|
||||||
// In addition if it is a debug build it will redirect cout to the debug console in Visual Studio
|
|
||||||
#if defined(_WIN32) && !defined(_CONSOLE)
|
|
||||||
|
|
||||||
#if defined(_DEBUG)
|
|
||||||
class DebugOutput : public boost::iostreams::sink
|
class DebugOutput : public boost::iostreams::sink
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -318,11 +268,11 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
class Logger : public boost::iostreams::sink
|
class Tee : public boost::iostreams::sink
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Logger(std::ofstream &stream)
|
Tee(std::ostream &stream, std::ostream &stream2)
|
||||||
: out(stream)
|
: out(stream), out2(stream2)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,38 +280,98 @@ public:
|
||||||
{
|
{
|
||||||
out.write (str, size);
|
out.write (str, size);
|
||||||
out.flush();
|
out.flush();
|
||||||
|
out2.write (str, size);
|
||||||
|
out2.flush();
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::ofstream &out;
|
std::ostream &out;
|
||||||
|
std::ostream &out2;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
int main(int argc, char**argv)
|
||||||
{
|
{
|
||||||
std::streambuf* old_rdbuf = std::cout.rdbuf ();
|
std::streambuf* cout_rdbuf = std::cout.rdbuf ();
|
||||||
|
std::streambuf* cerr_rdbuf = std::cerr.rdbuf ();
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
#if defined(_DEBUG)
|
try
|
||||||
// Redirect cout to VS debug output when running in debug mode
|
|
||||||
{
|
{
|
||||||
|
Files::ConfigurationManager cfgMgr;
|
||||||
|
|
||||||
|
#if defined(_WIN32) && defined(_DEBUG)
|
||||||
|
// Redirect cout and cerr to VS debug output when running in debug mode
|
||||||
boost::iostreams::stream_buffer<DebugOutput> sb;
|
boost::iostreams::stream_buffer<DebugOutput> sb;
|
||||||
sb.open(DebugOutput());
|
sb.open(DebugOutput());
|
||||||
#else
|
|
||||||
// Redirect cout to openmw.log
|
|
||||||
std::ofstream logfile ("openmw.log");
|
|
||||||
{
|
|
||||||
boost::iostreams::stream_buffer<Logger> sb;
|
|
||||||
sb.open (Logger (logfile));
|
|
||||||
#endif
|
|
||||||
std::cout.rdbuf (&sb);
|
std::cout.rdbuf (&sb);
|
||||||
|
std::cerr.rdbuf (&sb);
|
||||||
|
#else
|
||||||
|
// Redirect cout and cerr to openmw.log
|
||||||
|
std::ofstream logfile (std::string(cfgMgr.getLogPath().string() + "/openmw.log").c_str());
|
||||||
|
|
||||||
ret = main (__argc, __argv);
|
boost::iostreams::stream_buffer<Tee> coutsb;
|
||||||
|
std::ostream oldcout(cout_rdbuf);
|
||||||
|
coutsb.open (Tee(logfile, oldcout));
|
||||||
|
std::cout.rdbuf (&coutsb);
|
||||||
|
|
||||||
std::cout.rdbuf(old_rdbuf);
|
boost::iostreams::stream_buffer<Tee> cerrsb;
|
||||||
|
std::ostream oldcerr(cerr_rdbuf);
|
||||||
|
cerrsb.open (Tee(logfile, oldcerr));
|
||||||
|
std::cerr.rdbuf (&cerrsb);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||||
|
// Unix crash catcher
|
||||||
|
if ((argc == 2 && strcmp(argv[1], "--cc-handle-crash") == 0) || !is_debugger_attached())
|
||||||
|
{
|
||||||
|
int s[5] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGABRT };
|
||||||
|
cc_install_handlers(argc, argv, 5, s, std::string(cfgMgr.getLogPath().string() + "/crash.log").c_str(), NULL);
|
||||||
|
std::cout << "Installing crash catcher" << std::endl;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
std::cout << "Running in a debugger, not installing crash catcher" << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||||
|
// set current dir to bundle path
|
||||||
|
boost::filesystem::path bundlePath = boost::filesystem::path(Ogre::macBundlePath()).parent_path();
|
||||||
|
boost::filesystem::current_path(bundlePath);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
OMW::Engine engine(cfgMgr);
|
||||||
|
|
||||||
|
if (parseOptions(argc, argv, engine, cfgMgr))
|
||||||
|
{
|
||||||
|
engine.go();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception &e)
|
||||||
|
{
|
||||||
|
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||||
|
if (isatty(fileno(stdin)))
|
||||||
|
std::cerr << "\nERROR: " << e.what() << std::endl;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
SDL_ShowSimpleMessageBox(0, "OpenMW: Fatal error", e.what(), NULL);
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore cout and cerr
|
||||||
|
std::cout.rdbuf(cout_rdbuf);
|
||||||
|
std::cerr.rdbuf(cerr_rdbuf);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Platform specific for Windows when there is no console built into the executable.
|
||||||
|
// Windows will call the WinMain function instead of main in this case, the normal
|
||||||
|
// main function is then called with the __argc and __argv parameters.
|
||||||
|
#if defined(_WIN32) && !defined(_CONSOLE)
|
||||||
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
||||||
|
{
|
||||||
|
return main(__argc, __argv);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -76,6 +76,9 @@ namespace MWBase
|
||||||
|
|
||||||
/// @return faction1's opinion of faction2
|
/// @return faction1's opinion of faction2
|
||||||
virtual int getFactionReaction (const std::string& faction1, const std::string& faction2) const = 0;
|
virtual int getFactionReaction (const std::string& faction1, const std::string& faction2) const = 0;
|
||||||
|
|
||||||
|
/// Removes the last added topic response for the given actor from the journal
|
||||||
|
virtual void clearInfoActor (const MWWorld::Ptr& actor) const = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,12 @@ namespace MWBase
|
||||||
virtual int getJournalIndex (const std::string& id) const = 0;
|
virtual int getJournalIndex (const std::string& id) const = 0;
|
||||||
///< Get the journal index.
|
///< Get the journal index.
|
||||||
|
|
||||||
virtual void addTopic (const std::string& topicId, const std::string& infoId, const std::string& actorName) = 0;
|
virtual void addTopic (const std::string& topicId, const std::string& infoId, const MWWorld::Ptr& actor) = 0;
|
||||||
|
/// \note topicId must be lowercase
|
||||||
|
|
||||||
|
virtual void removeLastAddedTopicResponse (const std::string& topicId, const std::string& actorName) = 0;
|
||||||
|
///< Removes the last topic response added for the given topicId and actor name.
|
||||||
|
/// \note topicId must be lowercase
|
||||||
|
|
||||||
virtual TEntryIter begin() const = 0;
|
virtual TEntryIter begin() const = 0;
|
||||||
///< Iterator pointing to the begin of the main journal.
|
///< Iterator pointing to the begin of the main journal.
|
||||||
|
|
|
@ -328,6 +328,8 @@ namespace MWBase
|
||||||
/** Used when one Modal adds another Modal
|
/** Used when one Modal adds another Modal
|
||||||
\param input Pointer to the current modal, to ensure proper modal is removed **/
|
\param input Pointer to the current modal, to ensure proper modal is removed **/
|
||||||
virtual void removeCurrentModal(MWGui::WindowModal* input) = 0;
|
virtual void removeCurrentModal(MWGui::WindowModal* input) = 0;
|
||||||
|
|
||||||
|
virtual void pinWindow (MWGui::GuiWindow window) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -345,7 +345,9 @@ namespace MWClass
|
||||||
getCreatureStats(ptr).setAttacked(true);
|
getCreatureStats(ptr).setAttacked(true);
|
||||||
|
|
||||||
// Self defense
|
// Self defense
|
||||||
if (!attacker.isEmpty() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() < 80)
|
if (!attacker.isEmpty() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() < 80
|
||||||
|
&& (canWalk(ptr) || canFly(ptr) || canSwim(ptr))) // No retaliation for totally static creatures
|
||||||
|
// (they have no movement or attacks anyway)
|
||||||
MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, attacker);
|
MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, attacker);
|
||||||
|
|
||||||
if(!successful)
|
if(!successful)
|
||||||
|
|
|
@ -680,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%
|
||||||
|
|
|
@ -14,9 +14,12 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
void Static::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Static::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
|
MWWorld::LiveCellRef<ESM::Static> *ref =
|
||||||
|
ptr.get<ESM::Static>();
|
||||||
|
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
if (!model.empty()) {
|
if (!model.empty()) {
|
||||||
renderingInterface.getObjects().insertModel(ptr, model);
|
renderingInterface.getObjects().insertModel(ptr, model, !ref->mBase->mPersistent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,11 @@ namespace MWDialogue
|
||||||
mActorKnownTopics.clear();
|
mActorKnownTopics.clear();
|
||||||
|
|
||||||
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
||||||
win->startDialogue(actor, actor.getClass().getName (actor));
|
|
||||||
|
// If the dialogue window was already open, keep the existing history
|
||||||
|
bool resetHistory = (!MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_Dialogue));
|
||||||
|
|
||||||
|
win->startDialogue(actor, actor.getClass().getName (actor), resetHistory);
|
||||||
|
|
||||||
//setup the list of topics known by the actor. Topics who are also on the knownTopics list will be added to the GUI
|
//setup the list of topics known by the actor. Topics who are also on the knownTopics list will be added to the GUI
|
||||||
updateTopics();
|
updateTopics();
|
||||||
|
@ -294,7 +298,7 @@ namespace MWDialogue
|
||||||
{
|
{
|
||||||
if (iter->mId == info->mId)
|
if (iter->mId == info->mId)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getJournal()->addTopic (topic, info->mId, mActor.getClass().getName(mActor));
|
MWBase::Environment::get().getJournal()->addTopic (topic, info->mId, mActor);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -472,7 +476,7 @@ namespace MWDialogue
|
||||||
{
|
{
|
||||||
if (iter->mId == info->mId)
|
if (iter->mId == info->mId)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getJournal()->addTopic (mLastTopic, info->mId, mActor.getClass().getName(mActor));
|
MWBase::Environment::get().getJournal()->addTopic (mLastTopic, info->mId, mActor);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -694,6 +698,15 @@ namespace MWDialogue
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogueManager::clearInfoActor(const MWWorld::Ptr &actor) const
|
||||||
|
{
|
||||||
|
if (actor == mActor && !mLastTopic.empty())
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getJournal()->removeLastAddedTopicResponse(
|
||||||
|
mLastTopic, actor.getClass().getName(actor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<HyperTextToken> ParseHyperText(const std::string& text)
|
std::vector<HyperTextToken> ParseHyperText(const std::string& text)
|
||||||
{
|
{
|
||||||
std::vector<HyperTextToken> result;
|
std::vector<HyperTextToken> result;
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace MWDialogue
|
||||||
bool mTalkedTo;
|
bool mTalkedTo;
|
||||||
|
|
||||||
int mChoice;
|
int mChoice;
|
||||||
std::string mLastTopic;
|
std::string mLastTopic; // last topic ID, lowercase
|
||||||
bool mIsInChoice;
|
bool mIsInChoice;
|
||||||
|
|
||||||
float mTemporaryDispositionChange;
|
float mTemporaryDispositionChange;
|
||||||
|
@ -99,6 +99,9 @@ namespace MWDialogue
|
||||||
|
|
||||||
/// @return faction1's opinion of faction2
|
/// @return faction1's opinion of faction2
|
||||||
virtual int getFactionReaction (const std::string& faction1, const std::string& faction2) const;
|
virtual int getFactionReaction (const std::string& faction1, const std::string& faction2) const;
|
||||||
|
|
||||||
|
/// Removes the last added topic response for the given actor from the journal
|
||||||
|
virtual void clearInfoActor (const MWWorld::Ptr& actor) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,16 +5,21 @@
|
||||||
|
|
||||||
#include <components/esm/journalentry.hpp>
|
#include <components/esm/journalentry.hpp>
|
||||||
|
|
||||||
|
#include <components/interpreter/defines.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
|
||||||
|
#include "../mwscript/interpretercontext.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace MWDialogue
|
namespace MWDialogue
|
||||||
{
|
{
|
||||||
Entry::Entry() {}
|
Entry::Entry() {}
|
||||||
|
|
||||||
Entry::Entry (const std::string& topic, const std::string& infoId)
|
Entry::Entry (const std::string& topic, const std::string& infoId, const MWWorld::Ptr& actor)
|
||||||
: mInfoId (infoId)
|
: mInfoId (infoId)
|
||||||
{
|
{
|
||||||
const ESM::Dialogue *dialogue =
|
const ESM::Dialogue *dialogue =
|
||||||
|
@ -24,8 +29,17 @@ namespace MWDialogue
|
||||||
iter!=dialogue->mInfo.end(); ++iter)
|
iter!=dialogue->mInfo.end(); ++iter)
|
||||||
if (iter->mId == mInfoId)
|
if (iter->mId == mInfoId)
|
||||||
{
|
{
|
||||||
/// \todo text replacement
|
if (actor.isEmpty())
|
||||||
mText = iter->mResponse;
|
{
|
||||||
|
MWScript::InterpreterContext interpreterContext(NULL,MWWorld::Ptr());
|
||||||
|
mText = Interpreter::fixDefinesDialog(iter->mResponse, interpreterContext);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MWScript::InterpreterContext interpreterContext(&actor.getRefData().getLocals(),actor);
|
||||||
|
mText = Interpreter::fixDefinesDialog(iter->mResponse, interpreterContext);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,8 +63,8 @@ namespace MWDialogue
|
||||||
|
|
||||||
JournalEntry::JournalEntry() {}
|
JournalEntry::JournalEntry() {}
|
||||||
|
|
||||||
JournalEntry::JournalEntry (const std::string& topic, const std::string& infoId)
|
JournalEntry::JournalEntry (const std::string& topic, const std::string& infoId, const MWWorld::Ptr& actor)
|
||||||
: Entry (topic, infoId), mTopic (topic)
|
: Entry (topic, infoId, actor), mTopic (topic)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
JournalEntry::JournalEntry (const ESM::JournalEntry& record)
|
JournalEntry::JournalEntry (const ESM::JournalEntry& record)
|
||||||
|
@ -65,7 +79,7 @@ namespace MWDialogue
|
||||||
|
|
||||||
JournalEntry JournalEntry::makeFromQuest (const std::string& topic, int index)
|
JournalEntry JournalEntry::makeFromQuest (const std::string& topic, int index)
|
||||||
{
|
{
|
||||||
return JournalEntry (topic, idFromIndex (topic, index));
|
return JournalEntry (topic, idFromIndex (topic, index), MWWorld::Ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string JournalEntry::idFromIndex (const std::string& topic, int index)
|
std::string JournalEntry::idFromIndex (const std::string& topic, int index)
|
||||||
|
@ -90,7 +104,7 @@ namespace MWDialogue
|
||||||
|
|
||||||
StampedJournalEntry::StampedJournalEntry (const std::string& topic, const std::string& infoId,
|
StampedJournalEntry::StampedJournalEntry (const std::string& topic, const std::string& infoId,
|
||||||
int day, int month, int dayOfMonth)
|
int day, int month, int dayOfMonth)
|
||||||
: JournalEntry (topic, infoId), mDay (day), mMonth (month), mDayOfMonth (dayOfMonth)
|
: JournalEntry (topic, infoId, MWWorld::Ptr()), mDay (day), mMonth (month), mDayOfMonth (dayOfMonth)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
StampedJournalEntry::StampedJournalEntry (const ESM::JournalEntry& record)
|
StampedJournalEntry::StampedJournalEntry (const ESM::JournalEntry& record)
|
||||||
|
|
|
@ -8,6 +8,11 @@ namespace ESM
|
||||||
struct JournalEntry;
|
struct JournalEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace MWWorld
|
||||||
|
{
|
||||||
|
class Ptr;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWDialogue
|
namespace MWDialogue
|
||||||
{
|
{
|
||||||
/// \brief Basic quest/dialogue/topic entry
|
/// \brief Basic quest/dialogue/topic entry
|
||||||
|
@ -19,7 +24,8 @@ namespace MWDialogue
|
||||||
|
|
||||||
Entry();
|
Entry();
|
||||||
|
|
||||||
Entry (const std::string& topic, const std::string& infoId);
|
/// actor is optional
|
||||||
|
Entry (const std::string& topic, const std::string& infoId, const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
Entry (const ESM::JournalEntry& record);
|
Entry (const ESM::JournalEntry& record);
|
||||||
|
|
||||||
|
@ -37,7 +43,7 @@ namespace MWDialogue
|
||||||
|
|
||||||
JournalEntry();
|
JournalEntry();
|
||||||
|
|
||||||
JournalEntry (const std::string& topic, const std::string& infoId);
|
JournalEntry (const std::string& topic, const std::string& infoId, const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
JournalEntry (const ESM::JournalEntry& record);
|
JournalEntry (const ESM::JournalEntry& record);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <components/esm/journalentry.hpp>
|
#include <components/esm/journalentry.hpp>
|
||||||
|
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
@ -103,15 +104,25 @@ namespace MWDialogue
|
||||||
quest.setIndex (index);
|
quest.setIndex (index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Journal::addTopic (const std::string& topicId, const std::string& infoId, const std::string& actorName)
|
void Journal::addTopic (const std::string& topicId, const std::string& infoId, const MWWorld::Ptr& actor)
|
||||||
{
|
{
|
||||||
Topic& topic = getTopic (topicId);
|
Topic& topic = getTopic (topicId);
|
||||||
|
|
||||||
JournalEntry entry(topicId, infoId);
|
JournalEntry entry(topicId, infoId, actor);
|
||||||
entry.mActorName = actorName;
|
entry.mActorName = actor.getClass().getName(actor);
|
||||||
topic.addEntry (entry);
|
topic.addEntry (entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Journal::removeLastAddedTopicResponse(const std::string &topicId, const std::string &actorName)
|
||||||
|
{
|
||||||
|
Topic& topic = getTopic (topicId);
|
||||||
|
|
||||||
|
topic.removeLastAddedResponse(actorName);
|
||||||
|
|
||||||
|
if (topic.begin() == topic.end())
|
||||||
|
mTopics.erase(mTopics.find(topicId)); // All responses removed -> remove topic
|
||||||
|
}
|
||||||
|
|
||||||
int Journal::getJournalIndex (const std::string& id) const
|
int Journal::getJournalIndex (const std::string& id) const
|
||||||
{
|
{
|
||||||
TQuestContainer::const_iterator iter = mQuests.find (id);
|
TQuestContainer::const_iterator iter = mQuests.find (id);
|
||||||
|
|
|
@ -38,7 +38,12 @@ namespace MWDialogue
|
||||||
virtual int getJournalIndex (const std::string& id) const;
|
virtual int getJournalIndex (const std::string& id) const;
|
||||||
///< Get the journal index.
|
///< Get the journal index.
|
||||||
|
|
||||||
virtual void addTopic (const std::string& topicId, const std::string& infoId, const std::string& actorName);
|
virtual void addTopic (const std::string& topicId, const std::string& infoId, const MWWorld::Ptr& actor);
|
||||||
|
/// \note topicId must be lowercase
|
||||||
|
|
||||||
|
virtual void removeLastAddedTopicResponse (const std::string& topicId, const std::string& actorName);
|
||||||
|
///< Removes the last topic response added for the given topicId and actor name.
|
||||||
|
/// \note topicId must be lowercase
|
||||||
|
|
||||||
virtual TEntryIter begin() const;
|
virtual TEntryIter begin() const;
|
||||||
///< Iterator pointing to the begin of the main journal.
|
///< Iterator pointing to the begin of the main journal.
|
||||||
|
|
|
@ -59,8 +59,16 @@ namespace MWDialogue
|
||||||
return mEntries.end();
|
return mEntries.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
JournalEntry Topic::getEntry (const std::string& infoId) const
|
void Topic::removeLastAddedResponse (const std::string& actorName)
|
||||||
{
|
{
|
||||||
return JournalEntry (mTopic, infoId);
|
for (std::vector<MWDialogue::Entry>::reverse_iterator it = mEntries.rbegin();
|
||||||
|
it != mEntries.rend(); ++it)
|
||||||
|
{
|
||||||
|
if (it->mActorName == actorName)
|
||||||
|
{
|
||||||
|
mEntries.erase( (++it).base() ); // erase doesn't take a reverse_iterator
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,13 +48,13 @@ namespace MWDialogue
|
||||||
|
|
||||||
virtual std::string getName() const;
|
virtual std::string getName() const;
|
||||||
|
|
||||||
|
void removeLastAddedResponse (const std::string& actorName);
|
||||||
|
|
||||||
TEntryIter begin() const;
|
TEntryIter begin() const;
|
||||||
///< Iterator pointing to the begin of the journal for this topic.
|
///< Iterator pointing to the begin of the journal for this topic.
|
||||||
|
|
||||||
TEntryIter end() const;
|
TEntryIter end() const;
|
||||||
///< Iterator pointing past the end of the journal for this topic.
|
///< Iterator pointing past the end of the journal for this topic.
|
||||||
|
|
||||||
JournalEntry getEntry (const std::string& infoId) const;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -149,7 +136,7 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,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 ())
|
||||||
|
@ -204,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);
|
||||||
|
|
|
@ -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
|
||||||
|
@ -44,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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,9 @@ namespace MWGui
|
||||||
|
|
||||||
void ConfirmationDialog::exit()
|
void ConfirmationDialog::exit()
|
||||||
{
|
{
|
||||||
eventCancelClicked();
|
|
||||||
|
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
|
|
||||||
|
eventCancelClicked();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfirmationDialog::onCancelButtonClicked(MyGUI::Widget* _sender)
|
void ConfirmationDialog::onCancelButtonClicked(MyGUI::Widget* _sender)
|
||||||
|
@ -42,8 +42,8 @@ namespace MWGui
|
||||||
|
|
||||||
void ConfirmationDialog::onOkButtonClicked(MyGUI::Widget* _sender)
|
void ConfirmationDialog::onOkButtonClicked(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
eventOkClicked();
|
|
||||||
|
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
|
|
||||||
|
eventOkClicked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -366,10 +366,11 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
|
void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName, bool resetHistory)
|
||||||
{
|
{
|
||||||
mGoodbye = false;
|
mGoodbye = false;
|
||||||
mEnabled = true;
|
mEnabled = true;
|
||||||
|
bool sameActor = (mPtr == actor);
|
||||||
mPtr = actor;
|
mPtr = actor;
|
||||||
mTopicsList->setEnabled(true);
|
mTopicsList->setEnabled(true);
|
||||||
setTitle(npcName);
|
setTitle(npcName);
|
||||||
|
@ -378,9 +379,12 @@ namespace MWGui
|
||||||
|
|
||||||
mTopicsList->clear();
|
mTopicsList->clear();
|
||||||
|
|
||||||
|
if (resetHistory || !sameActor)
|
||||||
|
{
|
||||||
for (std::vector<DialogueText*>::iterator it = mHistoryContents.begin(); it != mHistoryContents.end(); ++it)
|
for (std::vector<DialogueText*>::iterator it = mHistoryContents.begin(); it != mHistoryContents.end(); ++it)
|
||||||
delete (*it);
|
delete (*it);
|
||||||
mHistoryContents.clear();
|
mHistoryContents.clear();
|
||||||
|
}
|
||||||
|
|
||||||
for (std::vector<Link*>::iterator it = mLinks.begin(); it != mLinks.end(); ++it)
|
for (std::vector<Link*>::iterator it = mLinks.begin(); it != mLinks.end(); ++it)
|
||||||
delete (*it);
|
delete (*it);
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace MWGui
|
||||||
|
|
||||||
void notifyLinkClicked (TypesetBook::InteractiveId link);
|
void notifyLinkClicked (TypesetBook::InteractiveId link);
|
||||||
|
|
||||||
void startDialogue(MWWorld::Ptr actor, std::string npcName);
|
void startDialogue(MWWorld::Ptr actor, std::string npcName, bool resetHistory);
|
||||||
void setKeywords(std::list<std::string> keyWord);
|
void setKeywords(std::list<std::string> keyWord);
|
||||||
|
|
||||||
void addResponse (const std::string& text, const std::string& title="");
|
void addResponse (const std::string& text, const std::string& title="");
|
||||||
|
|
|
@ -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,45 @@ 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()
|
void EnchantingDialog::exit()
|
||||||
|
@ -122,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);
|
||||||
|
@ -150,6 +179,8 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnchantingDialog::onSelectItem(MyGUI::Widget *sender)
|
void EnchantingDialog::onSelectItem(MyGUI::Widget *sender)
|
||||||
|
{
|
||||||
|
if (mEnchanting.getOldItem().isEmpty())
|
||||||
{
|
{
|
||||||
delete mItemSelectionDialog;
|
delete mItemSelectionDialog;
|
||||||
mItemSelectionDialog = new ItemSelectionDialog("#{sEnchantItems}");
|
mItemSelectionDialog = new ItemSelectionDialog("#{sEnchantItems}");
|
||||||
|
@ -159,38 +190,21 @@ namespace MWGui
|
||||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr());
|
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||||
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyEnchantable);
|
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);
|
||||||
|
@ -207,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()
|
||||||
|
@ -237,6 +230,8 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnchantingDialog::onSelectSoul(MyGUI::Widget *sender)
|
void EnchantingDialog::onSelectSoul(MyGUI::Widget *sender)
|
||||||
|
{
|
||||||
|
if (mEnchanting.getGem().isEmpty())
|
||||||
{
|
{
|
||||||
delete mItemSelectionDialog;
|
delete mItemSelectionDialog;
|
||||||
mItemSelectionDialog = new ItemSelectionDialog("#{sSoulGemsWithSouls}");
|
mItemSelectionDialog = new ItemSelectionDialog("#{sSoulGemsWithSouls}");
|
||||||
|
@ -248,6 +243,11 @@ namespace MWGui
|
||||||
|
|
||||||
//MWBase::Environment::get().getWindowManager()->messageBox("#{sInventorySelectNoSoul}");
|
//MWBase::Environment::get().getWindowManager()->messageBox("#{sInventorySelectNoSoul}");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setSoulGem(MWWorld::Ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EnchantingDialog::notifyEffectsChanged ()
|
void EnchantingDialog::notifyEffectsChanged ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -22,6 +23,9 @@ namespace MWGui
|
||||||
|
|
||||||
virtual void exit();
|
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);
|
||||||
|
|
||||||
|
@ -32,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();
|
||||||
|
@ -46,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;
|
||||||
|
|
|
@ -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,25 @@ 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 several win1252 characters that are not included
|
||||||
|
// in the cp437 encoding of the font. Fall back to similar available characters.
|
||||||
|
// Same for U+2013
|
||||||
|
std::map<int, int> additional;
|
||||||
|
additional[39] = 0x2019; // apostrophe
|
||||||
|
additional[45] = 0x2013; // dash
|
||||||
|
if (additional.find(i) != additional.end() && mEncoding == ToUTF8::CP437)
|
||||||
|
{
|
||||||
|
MyGUI::xml::ElementPtr code = codes->createChild("Code");
|
||||||
|
code->addAttribute("index", additional[i]);
|
||||||
|
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 +290,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);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "container.hpp"
|
#include "container.hpp"
|
||||||
|
|
||||||
#include "itemmodel.hpp"
|
#include "itemmodel.hpp"
|
||||||
|
#include "itemwidget.hpp"
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
105
apps/openmw/mwgui/itemwidget.cpp
Normal file
105
apps/openmw/mwgui/itemwidget.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
49
apps/openmw/mwgui/itemwidget.hpp
Normal file
49
apps/openmw/mwgui/itemwidget.hpp
Normal 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
|
|
@ -136,7 +136,7 @@ namespace MWGui
|
||||||
Ogre::StringVector groups = Ogre::ResourceGroupManager::getSingleton().getResourceGroups ();
|
Ogre::StringVector groups = Ogre::ResourceGroupManager::getSingleton().getResourceGroups ();
|
||||||
for (Ogre::StringVector::iterator it = groups.begin(); it != groups.end(); ++it)
|
for (Ogre::StringVector::iterator it = groups.begin(); it != groups.end(); ++it)
|
||||||
{
|
{
|
||||||
Ogre::StringVectorPtr resourcesInThisGroup = Ogre::ResourceGroupManager::getSingleton ().findResourceNames (*it, "Splash_*.tga");
|
Ogre::StringVectorPtr resourcesInThisGroup = Ogre::ResourceGroupManager::getSingleton ().findResourceNames (*it, "Splash/*.tga");
|
||||||
mResources.insert(mResources.end(), resourcesInThisGroup->begin(), resourcesInThisGroup->end());
|
mResources.insert(mResources.end(), resourcesInThisGroup->begin(), resourcesInThisGroup->end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
if (visible)
|
if (visible)
|
||||||
updateMenu();
|
updateMenu();
|
||||||
else
|
|
||||||
showBackground(
|
showBackground(
|
||||||
MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu) &&
|
MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu) &&
|
||||||
MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame);
|
MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame);
|
||||||
|
@ -167,7 +167,7 @@ namespace MWGui
|
||||||
mVideo = mVideoBackground->createWidget<VideoWidget>("ImageBox", 0,0,1,1,
|
mVideo = mVideoBackground->createWidget<VideoWidget>("ImageBox", 0,0,1,1,
|
||||||
MyGUI::Align::Stretch, "Menu");
|
MyGUI::Align::Stretch, "Menu");
|
||||||
|
|
||||||
mVideo->playVideo("video\\menu_background.bik", false);
|
mVideo->playVideo("video\\menu_background.bik");
|
||||||
}
|
}
|
||||||
|
|
||||||
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||||
|
@ -204,7 +204,7 @@ namespace MWGui
|
||||||
if (!mVideo->update())
|
if (!mVideo->update())
|
||||||
{
|
{
|
||||||
// If finished playing, start again
|
// If finished playing, start again
|
||||||
mVideo->playVideo("video\\menu_background.bik", 0);
|
mVideo->playVideo("video\\menu_background.bik");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,6 @@ namespace MWGui
|
||||||
|
|
||||||
MWBase::StateManager::State state = MWBase::Environment::get().getStateManager()->getState();
|
MWBase::StateManager::State state = MWBase::Environment::get().getStateManager()->getState();
|
||||||
|
|
||||||
showBackground(state == MWBase::StateManager::State_NoGame);
|
|
||||||
mVersionText->setVisible(state == MWBase::StateManager::State_NoGame);
|
mVersionText->setVisible(state == MWBase::StateManager::State_NoGame);
|
||||||
|
|
||||||
std::vector<std::string> buttons;
|
std::vector<std::string> buttons;
|
||||||
|
|
|
@ -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,54 +231,6 @@ namespace MWGui
|
||||||
buttonsWidth += buttonLeftPadding;
|
buttonsWidth += buttonLeftPadding;
|
||||||
|
|
||||||
MyGUI::IntSize mainWidgetSize;
|
MyGUI::IntSize mainWidgetSize;
|
||||||
if(buttonsWidth < fixedWidth)
|
|
||||||
{
|
|
||||||
// on one line
|
|
||||||
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
|
|
||||||
{
|
|
||||||
// among each other
|
// among each other
|
||||||
if(biggestButtonWidth > textSize.width) {
|
if(biggestButtonWidth > textSize.width) {
|
||||||
mainWidgetSize.width = biggestButtonWidth + buttonTopPadding;
|
mainWidgetSize.width = biggestButtonWidth + buttonTopPadding;
|
||||||
|
@ -323,11 +274,9 @@ namespace MWGui
|
||||||
messageWidgetCoord.width = textSize.width;
|
messageWidgetCoord.width = textSize.width;
|
||||||
messageWidgetCoord.height = textSize.height;
|
messageWidgetCoord.height = textSize.height;
|
||||||
mMessageWidget->setCoord(messageWidgetCoord);
|
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))
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
|
|
||||||
#include "spellwindow.hpp"
|
#include "spellwindow.hpp"
|
||||||
|
|
||||||
|
#include "itemwidget.hpp"
|
||||||
|
#include "sortfilteritemmodel.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
@ -46,14 +49,16 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,12 +82,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);
|
||||||
|
@ -128,6 +135,7 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
mItemSelectionDialog->setVisible(true);
|
mItemSelectionDialog->setVisible(true);
|
||||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr());
|
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||||
|
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyUsableItems);
|
||||||
|
|
||||||
mAssignDialog->setVisible (false);
|
mAssignDialog->setVisible (false);
|
||||||
}
|
}
|
||||||
|
@ -156,27 +164,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);
|
||||||
|
@ -189,28 +186,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);
|
||||||
|
@ -218,21 +205,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();
|
||||||
|
@ -251,8 +233,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);
|
||||||
|
@ -265,16 +247,17 @@ 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)
|
||||||
{
|
{
|
||||||
|
@ -286,7 +269,7 @@ namespace MWGui
|
||||||
if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), id))
|
if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), id))
|
||||||
{
|
{
|
||||||
item = *it;
|
item = *it;
|
||||||
button->getChildAt(0)->setUserData(item);
|
button->setUserData(item);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -303,7 +286,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);
|
||||||
|
@ -315,13 +298,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();
|
||||||
|
@ -403,9 +386,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;
|
||||||
|
@ -417,12 +400,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().getRefId();
|
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;
|
||||||
}
|
}
|
||||||
|
@ -452,7 +435,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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace MWGui
|
||||||
class QuickKeysMenuAssign;
|
class QuickKeysMenuAssign;
|
||||||
class ItemSelectionDialog;
|
class ItemSelectionDialog;
|
||||||
class MagicSelectionDialog;
|
class MagicSelectionDialog;
|
||||||
|
class ItemWidget;
|
||||||
|
|
||||||
class QuickKeysMenu : public WindowBase
|
class QuickKeysMenu : public WindowBase
|
||||||
{
|
{
|
||||||
|
@ -51,7 +52,8 @@ namespace MWGui
|
||||||
MyGUI::EditBox* mInstructionLabel;
|
MyGUI::EditBox* mInstructionLabel;
|
||||||
MyGUI::Button* mOkButton;
|
MyGUI::Button* mOkButton;
|
||||||
|
|
||||||
std::vector<MyGUI::Button*> mQuickKeyButtons;
|
std::vector<ItemWidget*> mQuickKeyButtons;
|
||||||
|
std::vector<QuickKeyType> mAssigned;
|
||||||
|
|
||||||
QuickKeysMenuAssign* mAssignDialog;
|
QuickKeysMenuAssign* mAssignDialog;
|
||||||
ItemSelectionDialog* mItemSelectionDialog;
|
ItemSelectionDialog* mItemSelectionDialog;
|
||||||
|
@ -63,7 +65,7 @@ namespace MWGui
|
||||||
void onQuickKeyButtonClicked(MyGUI::Widget* sender);
|
void onQuickKeyButtonClicked(MyGUI::Widget* sender);
|
||||||
void onOkButtonClicked(MyGUI::Widget* sender);
|
void onOkButtonClicked(MyGUI::Widget* sender);
|
||||||
|
|
||||||
void unassign(MyGUI::Widget* key, int index);
|
void unassign(ItemWidget* key, int index);
|
||||||
};
|
};
|
||||||
|
|
||||||
class QuickKeysMenuAssign : public WindowModal
|
class QuickKeysMenuAssign : public WindowModal
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "../mwmechanics/npcstats.hpp"
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
#include "widgets.hpp"
|
#include "widgets.hpp"
|
||||||
|
#include "itemwidget.hpp"
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
@ -45,12 +46,7 @@ void Recharge::exit()
|
||||||
|
|
||||||
void Recharge::start (const MWWorld::Ptr &item)
|
void Recharge::start (const MWWorld::Ptr &item)
|
||||||
{
|
{
|
||||||
std::string path = std::string("icons\\");
|
mGemIcon->setItem(item);
|
||||||
path += item.getClass().getInventoryIcon(item);
|
|
||||||
int pos = path.rfind(".");
|
|
||||||
path.erase(pos);
|
|
||||||
path.append(".dds");
|
|
||||||
mGemIcon->setImageTexture (path);
|
|
||||||
mGemIcon->setUserString("ToolTipType", "ItemPtr");
|
mGemIcon->setUserString("ToolTipType", "ItemPtr");
|
||||||
mGemIcon->setUserData(item);
|
mGemIcon->setUserData(item);
|
||||||
|
|
||||||
|
@ -108,14 +104,9 @@ void Recharge::updateView()
|
||||||
text->setNeedMouseFocus(false);
|
text->setNeedMouseFocus(false);
|
||||||
currentY += 19;
|
currentY += 19;
|
||||||
|
|
||||||
MyGUI::ImageBox* icon = mView->createWidget<MyGUI::ImageBox> (
|
ItemWidget* icon = mView->createWidget<ItemWidget> (
|
||||||
"ImageBox", MyGUI::IntCoord(16, currentY, 32, 32), MyGUI::Align::Default);
|
"MW_ItemIconSmall", MyGUI::IntCoord(16, currentY, 32, 32), MyGUI::Align::Default);
|
||||||
std::string path = std::string("icons\\");
|
icon->setItem(*iter);
|
||||||
path += iter->getClass().getInventoryIcon(*iter);
|
|
||||||
int pos = path.rfind(".");
|
|
||||||
path.erase(pos);
|
|
||||||
path.append(".dds");
|
|
||||||
icon->setImageTexture (path);
|
|
||||||
icon->setUserString("ToolTipType", "ItemPtr");
|
icon->setUserString("ToolTipType", "ItemPtr");
|
||||||
icon->setUserData(*iter);
|
icon->setUserData(*iter);
|
||||||
icon->eventMouseButtonClick += MyGUI::newDelegate(this, &Recharge::onItemClicked);
|
icon->eventMouseButtonClick += MyGUI::newDelegate(this, &Recharge::onItemClicked);
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class ItemWidget;
|
||||||
|
|
||||||
class Recharge : public WindowBase
|
class Recharge : public WindowBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -25,7 +27,7 @@ protected:
|
||||||
|
|
||||||
MyGUI::Widget* mGemBox;
|
MyGUI::Widget* mGemBox;
|
||||||
|
|
||||||
MyGUI::ImageBox* mGemIcon;
|
ItemWidget* mGemIcon;
|
||||||
|
|
||||||
MyGUI::TextBox* mChargeLabel;
|
MyGUI::TextBox* mChargeLabel;
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
#include "widgets.hpp"
|
#include "widgets.hpp"
|
||||||
|
|
||||||
|
#include "itemwidget.hpp"
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -44,12 +46,7 @@ void Repair::startRepairItem(const MWWorld::Ptr &item)
|
||||||
{
|
{
|
||||||
mRepair.setTool(item);
|
mRepair.setTool(item);
|
||||||
|
|
||||||
std::string path = std::string("icons\\");
|
mToolIcon->setItem(item);
|
||||||
path += item.getClass().getInventoryIcon(item);
|
|
||||||
int pos = path.rfind(".");
|
|
||||||
path.erase(pos);
|
|
||||||
path.append(".dds");
|
|
||||||
mToolIcon->setImageTexture (path);
|
|
||||||
mToolIcon->setUserString("ToolTipType", "ItemPtr");
|
mToolIcon->setUserString("ToolTipType", "ItemPtr");
|
||||||
mToolIcon->setUserData(item);
|
mToolIcon->setUserData(item);
|
||||||
|
|
||||||
|
@ -113,14 +110,9 @@ void Repair::updateRepairView()
|
||||||
text->setNeedMouseFocus(false);
|
text->setNeedMouseFocus(false);
|
||||||
currentY += 19;
|
currentY += 19;
|
||||||
|
|
||||||
MyGUI::ImageBox* icon = mRepairView->createWidget<MyGUI::ImageBox> (
|
ItemWidget* icon = mRepairView->createWidget<ItemWidget> (
|
||||||
"ImageBox", MyGUI::IntCoord(16, currentY, 32, 32), MyGUI::Align::Default);
|
"MW_ItemIconSmall", MyGUI::IntCoord(16, currentY, 32, 32), MyGUI::Align::Default);
|
||||||
std::string path = std::string("icons\\");
|
icon->setItem(*iter);
|
||||||
path += iter->getClass().getInventoryIcon(*iter);
|
|
||||||
int pos = path.rfind(".");
|
|
||||||
path.erase(pos);
|
|
||||||
path.append(".dds");
|
|
||||||
icon->setImageTexture (path);
|
|
||||||
icon->setUserString("ToolTipType", "ItemPtr");
|
icon->setUserString("ToolTipType", "ItemPtr");
|
||||||
icon->setUserData(*iter);
|
icon->setUserData(*iter);
|
||||||
icon->eventMouseButtonClick += MyGUI::newDelegate(this, &Repair::onRepairItem);
|
icon->eventMouseButtonClick += MyGUI::newDelegate(this, &Repair::onRepairItem);
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class ItemWidget;
|
||||||
|
|
||||||
class Repair : public WindowBase
|
class Repair : public WindowBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -25,7 +27,7 @@ protected:
|
||||||
|
|
||||||
MyGUI::Widget* mToolBox;
|
MyGUI::Widget* mToolBox;
|
||||||
|
|
||||||
MyGUI::ImageBox* mToolIcon;
|
ItemWidget* mToolIcon;
|
||||||
|
|
||||||
MyGUI::TextBox* mUsesLabel;
|
MyGUI::TextBox* mUsesLabel;
|
||||||
MyGUI::TextBox* mQualityLabel;
|
MyGUI::TextBox* mQualityLabel;
|
||||||
|
|
|
@ -30,11 +30,13 @@ namespace MWGui
|
||||||
getWidget(mInfoText, "InfoText");
|
getWidget(mInfoText, "InfoText");
|
||||||
getWidget(mOkButton, "OkButton");
|
getWidget(mOkButton, "OkButton");
|
||||||
getWidget(mCancelButton, "CancelButton");
|
getWidget(mCancelButton, "CancelButton");
|
||||||
|
getWidget(mDeleteButton, "DeleteButton");
|
||||||
getWidget(mSaveList, "SaveList");
|
getWidget(mSaveList, "SaveList");
|
||||||
getWidget(mSaveNameEdit, "SaveNameEdit");
|
getWidget(mSaveNameEdit, "SaveNameEdit");
|
||||||
getWidget(mSpacer, "Spacer");
|
getWidget(mSpacer, "Spacer");
|
||||||
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onOkButtonClicked);
|
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onOkButtonClicked);
|
||||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onCancelButtonClicked);
|
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onCancelButtonClicked);
|
||||||
|
mDeleteButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onDeleteButtonClicked);
|
||||||
mCharacterSelection->eventComboChangePosition += MyGUI::newDelegate(this, &SaveGameDialog::onCharacterSelected);
|
mCharacterSelection->eventComboChangePosition += MyGUI::newDelegate(this, &SaveGameDialog::onCharacterSelected);
|
||||||
mSaveList->eventListChangePosition += MyGUI::newDelegate(this, &SaveGameDialog::onSlotSelected);
|
mSaveList->eventListChangePosition += MyGUI::newDelegate(this, &SaveGameDialog::onSlotSelected);
|
||||||
mSaveList->eventListMouseItemActivate += MyGUI::newDelegate(this, &SaveGameDialog::onSlotMouseClick);
|
mSaveList->eventListMouseItemActivate += MyGUI::newDelegate(this, &SaveGameDialog::onSlotMouseClick);
|
||||||
|
@ -54,6 +56,10 @@ namespace MWGui
|
||||||
onSlotSelected(sender, pos);
|
onSlotSelected(sender, pos);
|
||||||
|
|
||||||
if (pos != MyGUI::ITEM_NONE && MyGUI::InputManager::getInstance().isShiftPressed())
|
if (pos != MyGUI::ITEM_NONE && MyGUI::InputManager::getInstance().isShiftPressed())
|
||||||
|
confirmDeleteSave();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveGameDialog::confirmDeleteSave()
|
||||||
{
|
{
|
||||||
ConfirmationDialog* dialog = MWBase::Environment::get().getWindowManager()->getConfirmationDialog();
|
ConfirmationDialog* dialog = MWBase::Environment::get().getWindowManager()->getConfirmationDialog();
|
||||||
dialog->open("#{sMessage3}");
|
dialog->open("#{sMessage3}");
|
||||||
|
@ -61,7 +67,6 @@ namespace MWGui
|
||||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &SaveGameDialog::onDeleteSlotConfirmed);
|
dialog->eventOkClicked += MyGUI::newDelegate(this, &SaveGameDialog::onDeleteSlotConfirmed);
|
||||||
dialog->eventCancelClicked.clear();
|
dialog->eventCancelClicked.clear();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void SaveGameDialog::onDeleteSlotConfirmed()
|
void SaveGameDialog::onDeleteSlotConfirmed()
|
||||||
{
|
{
|
||||||
|
@ -107,6 +112,7 @@ namespace MWGui
|
||||||
mCurrentCharacter = NULL;
|
mCurrentCharacter = NULL;
|
||||||
mCurrentSlot = NULL;
|
mCurrentSlot = NULL;
|
||||||
mSaveList->removeAllItems();
|
mSaveList->removeAllItems();
|
||||||
|
onSlotSelected(mSaveList, MyGUI::ITEM_NONE);
|
||||||
|
|
||||||
MWBase::StateManager* mgr = MWBase::Environment::get().getStateManager();
|
MWBase::StateManager* mgr = MWBase::Environment::get().getStateManager();
|
||||||
if (mgr->characterBegin() == mgr->characterEnd())
|
if (mgr->characterBegin() == mgr->characterEnd())
|
||||||
|
@ -157,6 +163,8 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
mCharacterSelection->setIndexSelected(selectedIndex);
|
mCharacterSelection->setIndexSelected(selectedIndex);
|
||||||
|
if (selectedIndex == MyGUI::ITEM_NONE)
|
||||||
|
mCharacterSelection->setCaption("Select Character ...");
|
||||||
|
|
||||||
fillSaveList();
|
fillSaveList();
|
||||||
|
|
||||||
|
@ -175,6 +183,9 @@ namespace MWGui
|
||||||
mCharacterSelection->setVisible(load);
|
mCharacterSelection->setVisible(load);
|
||||||
mSpacer->setUserString("Hidden", load ? "false" : "true");
|
mSpacer->setUserString("Hidden", load ? "false" : "true");
|
||||||
|
|
||||||
|
mDeleteButton->setUserString("Hidden", load ? "false" : "true");
|
||||||
|
mDeleteButton->setVisible(load);
|
||||||
|
|
||||||
if (!load)
|
if (!load)
|
||||||
{
|
{
|
||||||
mCurrentCharacter = MWBase::Environment::get().getStateManager()->getCurrentCharacter (false);
|
mCurrentCharacter = MWBase::Environment::get().getStateManager()->getCurrentCharacter (false);
|
||||||
|
@ -188,6 +199,12 @@ namespace MWGui
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SaveGameDialog::onDeleteButtonClicked(MyGUI::Widget *sender)
|
||||||
|
{
|
||||||
|
if (mCurrentSlot)
|
||||||
|
confirmDeleteSave();
|
||||||
|
}
|
||||||
|
|
||||||
void SaveGameDialog::onConfirmationGiven()
|
void SaveGameDialog::onConfirmationGiven()
|
||||||
{
|
{
|
||||||
accept(true);
|
accept(true);
|
||||||
|
@ -225,12 +242,10 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mCurrentCharacter && mCurrentSlot)
|
assert (mCurrentCharacter && mCurrentSlot);
|
||||||
{
|
|
||||||
MWBase::Environment::get().getStateManager()->loadGame (mCurrentCharacter, mCurrentSlot);
|
MWBase::Environment::get().getStateManager()->loadGame (mCurrentCharacter, mCurrentSlot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void SaveGameDialog::onOkButtonClicked(MyGUI::Widget *sender)
|
void SaveGameDialog::onOkButtonClicked(MyGUI::Widget *sender)
|
||||||
{
|
{
|
||||||
|
@ -278,6 +293,9 @@ namespace MWGui
|
||||||
|
|
||||||
void SaveGameDialog::onSlotSelected(MyGUI::ListBox *sender, size_t pos)
|
void SaveGameDialog::onSlotSelected(MyGUI::ListBox *sender, size_t pos)
|
||||||
{
|
{
|
||||||
|
mOkButton->setEnabled(pos != MyGUI::ITEM_NONE || mSaving);
|
||||||
|
mDeleteButton->setEnabled(pos != MyGUI::ITEM_NONE);
|
||||||
|
|
||||||
if (pos == MyGUI::ITEM_NONE)
|
if (pos == MyGUI::ITEM_NONE)
|
||||||
{
|
{
|
||||||
mCurrentSlot = NULL;
|
mCurrentSlot = NULL;
|
||||||
|
|
|
@ -24,8 +24,11 @@ namespace MWGui
|
||||||
void setLoadOrSave(bool load);
|
void setLoadOrSave(bool load);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void confirmDeleteSave();
|
||||||
|
|
||||||
void onCancelButtonClicked (MyGUI::Widget* sender);
|
void onCancelButtonClicked (MyGUI::Widget* sender);
|
||||||
void onOkButtonClicked (MyGUI::Widget* sender);
|
void onOkButtonClicked (MyGUI::Widget* sender);
|
||||||
|
void onDeleteButtonClicked (MyGUI::Widget* sender);
|
||||||
void onCharacterSelected (MyGUI::ComboBox* sender, size_t pos);
|
void onCharacterSelected (MyGUI::ComboBox* sender, size_t pos);
|
||||||
// Slot selected (mouse click or arrow keys)
|
// Slot selected (mouse click or arrow keys)
|
||||||
void onSlotSelected (MyGUI::ListBox* sender, size_t pos);
|
void onSlotSelected (MyGUI::ListBox* sender, size_t pos);
|
||||||
|
@ -51,6 +54,7 @@ namespace MWGui
|
||||||
MyGUI::EditBox* mInfoText;
|
MyGUI::EditBox* mInfoText;
|
||||||
MyGUI::Button* mOkButton;
|
MyGUI::Button* mOkButton;
|
||||||
MyGUI::Button* mCancelButton;
|
MyGUI::Button* mCancelButton;
|
||||||
|
MyGUI::Button* mDeleteButton;
|
||||||
MyGUI::ListBox* mSaveList;
|
MyGUI::ListBox* mSaveList;
|
||||||
MyGUI::EditBox* mSaveNameEdit;
|
MyGUI::EditBox* mSaveNameEdit;
|
||||||
MyGUI::Widget* mSpacer;
|
MyGUI::Widget* mSpacer;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <components/esm/loadweap.hpp>
|
#include <components/esm/loadweap.hpp>
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
#include "../mwworld/nullaction.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -126,6 +127,10 @@ namespace MWGui
|
||||||
&& !base.get<ESM::Book>()->mBase->mData.mIsScroll)
|
&& !base.get<ESM::Book>()->mBase->mData.mIsScroll)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if ((mFilter & Filter_OnlyUsableItems) && typeid(*base.getClass().use(base)) == typeid(MWWorld::NullAction)
|
||||||
|
&& base.getClass().getScript(base).empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ namespace MWGui
|
||||||
static const int Filter_OnlyEnchanted = (1<<1);
|
static const int Filter_OnlyEnchanted = (1<<1);
|
||||||
static const int Filter_OnlyEnchantable = (1<<2);
|
static const int Filter_OnlyEnchantable = (1<<2);
|
||||||
static const int Filter_OnlyChargedSoulstones = (1<<3);
|
static const int Filter_OnlyChargedSoulstones = (1<<3);
|
||||||
|
static const int Filter_OnlyUsableItems = (1<<4); // Only items with a Use action
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -400,7 +400,7 @@ namespace MWGui
|
||||||
if (!info.effects.empty())
|
if (!info.effects.empty())
|
||||||
{
|
{
|
||||||
MyGUI::Widget* effectArea = mDynamicToolTipBox->createWidget<MyGUI::Widget>("",
|
MyGUI::Widget* effectArea = mDynamicToolTipBox->createWidget<MyGUI::Widget>("",
|
||||||
MyGUI::IntCoord(0, totalSize.height, 300, 300-totalSize.height),
|
MyGUI::IntCoord(padding.left, totalSize.height, 300-padding.left, 300-totalSize.height),
|
||||||
MyGUI::Align::Stretch, "ToolTipEffectArea");
|
MyGUI::Align::Stretch, "ToolTipEffectArea");
|
||||||
|
|
||||||
MyGUI::IntCoord coord(0, 6, totalSize.width, 24);
|
MyGUI::IntCoord coord(0, 6, totalSize.width, 24);
|
||||||
|
@ -419,7 +419,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
assert(enchant);
|
assert(enchant);
|
||||||
MyGUI::Widget* enchantArea = mDynamicToolTipBox->createWidget<MyGUI::Widget>("",
|
MyGUI::Widget* enchantArea = mDynamicToolTipBox->createWidget<MyGUI::Widget>("",
|
||||||
MyGUI::IntCoord(0, totalSize.height, 300, 300-totalSize.height),
|
MyGUI::IntCoord(padding.left, totalSize.height, 300-padding.left, 300-totalSize.height),
|
||||||
MyGUI::Align::Stretch, "ToolTipEnchantArea");
|
MyGUI::Align::Stretch, "ToolTipEnchantArea");
|
||||||
|
|
||||||
MyGUI::IntCoord coord(0, 6, totalSize.width, 24);
|
MyGUI::IntCoord coord(0, 6, totalSize.width, 24);
|
||||||
|
@ -512,7 +512,11 @@ namespace MWGui
|
||||||
std::string ToolTips::toString(const float value)
|
std::string ToolTips::toString(const float value)
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
stream << std::setprecision(3) << value;
|
|
||||||
|
if (value != int(value))
|
||||||
|
stream << std::setprecision(3);
|
||||||
|
|
||||||
|
stream << value;
|
||||||
return stream.str();
|
return stream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -345,7 +345,7 @@ namespace MWGui
|
||||||
x += abs(int(npcTerm - pcTerm));
|
x += abs(int(npcTerm - pcTerm));
|
||||||
|
|
||||||
int roll = std::rand()%100 + 1;
|
int roll = std::rand()%100 + 1;
|
||||||
if(roll > x) //trade refused
|
if(roll > x || (mCurrentMerchantOffer < 0) != (mCurrentBalance < 0)) //trade refused
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->
|
MWBase::Environment::get().getWindowManager()->
|
||||||
messageBox("#{sNotifyMessage9}");
|
messageBox("#{sNotifyMessage9}");
|
||||||
|
|
|
@ -16,6 +16,24 @@
|
||||||
|
|
||||||
#include "tooltips.hpp"
|
#include "tooltips.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// Sorts a container descending by skill value. If skill value is equal, sorts ascending by skill ID.
|
||||||
|
// pair <skill ID, skill value>
|
||||||
|
bool sortSkills (const std::pair<int, int>& left, const std::pair<int, int>& right)
|
||||||
|
{
|
||||||
|
if (left == right)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (left.second > right.second)
|
||||||
|
return true;
|
||||||
|
else if (left.second < right.second)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return left.first < right.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -52,29 +70,17 @@ namespace MWGui
|
||||||
MWMechanics::NpcStats& npcStats = actor.getClass().getNpcStats (actor);
|
MWMechanics::NpcStats& npcStats = actor.getClass().getNpcStats (actor);
|
||||||
|
|
||||||
// NPC can train you in his best 3 skills
|
// NPC can train you in his best 3 skills
|
||||||
std::vector< std::pair<int, int> > bestSkills;
|
std::vector< std::pair<int, int> > skills;
|
||||||
bestSkills.push_back (std::make_pair(-1, -1));
|
|
||||||
bestSkills.push_back (std::make_pair(-1, -1));
|
|
||||||
bestSkills.push_back (std::make_pair(-1, -1));
|
|
||||||
|
|
||||||
for (int i=0; i<ESM::Skill::Length; ++i)
|
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||||
{
|
{
|
||||||
int value = npcStats.getSkill (i).getBase ();
|
int value = npcStats.getSkill (i).getBase ();
|
||||||
|
|
||||||
for (int j=0; j<3; ++j)
|
skills.push_back(std::make_pair(i, value));
|
||||||
{
|
|
||||||
if (value > bestSkills[j].second)
|
|
||||||
{
|
|
||||||
if (j<2)
|
|
||||||
{
|
|
||||||
bestSkills[j+1] = bestSkills[j];
|
|
||||||
}
|
|
||||||
bestSkills[j] = std::make_pair(i, value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::sort(skills.begin(), skills.end(), sortSkills);
|
||||||
|
|
||||||
MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator ();
|
MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator ();
|
||||||
MyGUI::Gui::getInstance ().destroyWidgets (widgets);
|
MyGUI::Gui::getInstance ().destroyWidgets (widgets);
|
||||||
|
|
||||||
|
@ -86,20 +92,20 @@ namespace MWGui
|
||||||
for (int i=0; i<3; ++i)
|
for (int i=0; i<3; ++i)
|
||||||
{
|
{
|
||||||
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer
|
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer
|
||||||
(mPtr,pcStats.getSkill (bestSkills[i].first).getBase() * gmst.find("iTrainingMod")->getInt (),true);
|
(mPtr,pcStats.getSkill (skills[i].first).getBase() * gmst.find("iTrainingMod")->getInt (),true);
|
||||||
|
|
||||||
MyGUI::Button* button = mTrainingOptions->createWidget<MyGUI::Button>("SandTextButton",
|
MyGUI::Button* button = mTrainingOptions->createWidget<MyGUI::Button>("SandTextButton",
|
||||||
MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default);
|
MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default);
|
||||||
|
|
||||||
button->setEnabled(price <= playerGold);
|
button->setEnabled(price <= playerGold);
|
||||||
button->setUserData(bestSkills[i].first);
|
button->setUserData(skills[i].first);
|
||||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected);
|
button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected);
|
||||||
|
|
||||||
button->setCaptionWithReplacing("#{" + ESM::Skill::sSkillNameIds[bestSkills[i].first] + "} - " + boost::lexical_cast<std::string>(price));
|
button->setCaptionWithReplacing("#{" + ESM::Skill::sSkillNameIds[skills[i].first] + "} - " + boost::lexical_cast<std::string>(price));
|
||||||
|
|
||||||
button->setSize(button->getTextSize ().width+12, button->getSize().height);
|
button->setSize(button->getTextSize ().width+12, button->getSize().height);
|
||||||
|
|
||||||
ToolTips::createSkillToolTip (button, bestSkills[i].first);
|
ToolTips::createSkillToolTip (button, skills[i].first);
|
||||||
}
|
}
|
||||||
|
|
||||||
center();
|
center();
|
||||||
|
|
|
@ -4,17 +4,12 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
VideoWidget::VideoWidget()
|
VideoWidget::VideoWidget()
|
||||||
: mAllowSkipping(true)
|
|
||||||
{
|
{
|
||||||
eventKeyButtonPressed += MyGUI::newDelegate(this, &VideoWidget::onKeyPressed);
|
|
||||||
|
|
||||||
setNeedKeyFocus(true);
|
setNeedKeyFocus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoWidget::playVideo(const std::string &video, bool allowSkipping)
|
void VideoWidget::playVideo(const std::string &video)
|
||||||
{
|
{
|
||||||
mAllowSkipping = allowSkipping;
|
|
||||||
|
|
||||||
mPlayer.playVideo(video);
|
mPlayer.playVideo(video);
|
||||||
|
|
||||||
setImageTexture(mPlayer.getTextureName());
|
setImageTexture(mPlayer.getTextureName());
|
||||||
|
@ -30,16 +25,15 @@ int VideoWidget::getVideoHeight()
|
||||||
return mPlayer.getVideoHeight();
|
return mPlayer.getVideoHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoWidget::onKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char)
|
|
||||||
{
|
|
||||||
if (_key == MyGUI::KeyCode::Escape && mAllowSkipping)
|
|
||||||
mPlayer.stopVideo();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VideoWidget::update()
|
bool VideoWidget::update()
|
||||||
{
|
{
|
||||||
mPlayer.update();
|
mPlayer.update();
|
||||||
return mPlayer.isPlaying();
|
return mPlayer.isPlaying();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VideoWidget::stop()
|
||||||
|
{
|
||||||
|
mPlayer.close();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Widget that plays a video. Can be skipped by pressing Esc.
|
* Widget that plays a video.
|
||||||
*/
|
*/
|
||||||
class VideoWidget : public MyGUI::ImageBox
|
class VideoWidget : public MyGUI::ImageBox
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace MWGui
|
||||||
|
|
||||||
VideoWidget();
|
VideoWidget();
|
||||||
|
|
||||||
void playVideo (const std::string& video, bool allowSkipping);
|
void playVideo (const std::string& video);
|
||||||
|
|
||||||
int getVideoWidth();
|
int getVideoWidth();
|
||||||
int getVideoHeight();
|
int getVideoHeight();
|
||||||
|
@ -26,12 +26,11 @@ namespace MWGui
|
||||||
/// @return Is the video still playing?
|
/// @return Is the video still playing?
|
||||||
bool update();
|
bool update();
|
||||||
|
|
||||||
|
/// Stop video and free resources (done automatically on destruction)
|
||||||
|
void stop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mAllowSkipping;
|
|
||||||
|
|
||||||
MWRender::VideoPlayer mPlayer;
|
MWRender::VideoPlayer mPlayer;
|
||||||
|
|
||||||
void onKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
#include "fontloader.hpp"
|
#include "fontloader.hpp"
|
||||||
#include "videowidget.hpp"
|
#include "videowidget.hpp"
|
||||||
#include "backgroundimage.hpp"
|
#include "backgroundimage.hpp"
|
||||||
|
#include "itemwidget.hpp"
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
@ -166,6 +167,7 @@ namespace MWGui
|
||||||
MyGUI::FactoryManager::getInstance().registerFactory<BackgroundImage>("Widget");
|
MyGUI::FactoryManager::getInstance().registerFactory<BackgroundImage>("Widget");
|
||||||
BookPage::registerMyGUIComponents ();
|
BookPage::registerMyGUIComponents ();
|
||||||
ItemView::registerComponents();
|
ItemView::registerComponents();
|
||||||
|
ItemWidget::registerComponents();
|
||||||
|
|
||||||
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Controllers::ControllerRepeatClick>("Controller");
|
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Controllers::ControllerRepeatClick>("Controller");
|
||||||
|
|
||||||
|
@ -200,8 +202,12 @@ namespace MWGui
|
||||||
MyGUI::Align::Default, "Overlay");
|
MyGUI::Align::Default, "Overlay");
|
||||||
mVideoBackground->setImageTexture("black.png");
|
mVideoBackground->setImageTexture("black.png");
|
||||||
mVideoBackground->setVisible(false);
|
mVideoBackground->setVisible(false);
|
||||||
|
mVideoBackground->setNeedMouseFocus(true);
|
||||||
|
mVideoBackground->setNeedKeyFocus(true);
|
||||||
|
|
||||||
mVideoWidget = mVideoBackground->createWidgetReal<VideoWidget>("ImageBox", 0,0,1,1, MyGUI::Align::Default);
|
mVideoWidget = mVideoBackground->createWidgetReal<VideoWidget>("ImageBox", 0,0,1,1, MyGUI::Align::Default);
|
||||||
|
mVideoWidget->setNeedMouseFocus(true);
|
||||||
|
mVideoWidget->setNeedKeyFocus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowManager::initUI()
|
void WindowManager::initUI()
|
||||||
|
@ -261,7 +267,7 @@ namespace MWGui
|
||||||
mCompanionWindow = new CompanionWindow(mDragAndDrop, mMessageBoxManager);
|
mCompanionWindow = new CompanionWindow(mDragAndDrop, mMessageBoxManager);
|
||||||
trackWindow(mCompanionWindow, "companion");
|
trackWindow(mCompanionWindow, "companion");
|
||||||
|
|
||||||
mInputBlocker = mGui->createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Default,"Windows","");
|
mInputBlocker = mGui->createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Default,"Windows");
|
||||||
|
|
||||||
mHud->setVisible(mHudEnabled);
|
mHud->setVisible(mHudEnabled);
|
||||||
|
|
||||||
|
@ -1557,7 +1563,15 @@ namespace MWGui
|
||||||
|
|
||||||
void WindowManager::playVideo(const std::string &name, bool allowSkipping)
|
void WindowManager::playVideo(const std::string &name, bool allowSkipping)
|
||||||
{
|
{
|
||||||
mVideoWidget->playVideo("video\\" + name, allowSkipping);
|
mVideoWidget->playVideo("video\\" + name);
|
||||||
|
|
||||||
|
mVideoWidget->eventKeyButtonPressed.clear();
|
||||||
|
mVideoBackground->eventKeyButtonPressed.clear();
|
||||||
|
if (allowSkipping)
|
||||||
|
{
|
||||||
|
mVideoWidget->eventKeyButtonPressed += MyGUI::newDelegate(this, &WindowManager::onVideoKeyPressed);
|
||||||
|
mVideoBackground->eventKeyButtonPressed += MyGUI::newDelegate(this, &WindowManager::onVideoKeyPressed);
|
||||||
|
}
|
||||||
|
|
||||||
// Turn off all rendering except for the GUI
|
// Turn off all rendering except for the GUI
|
||||||
mRendering->getScene()->clearSpecialCaseRenderQueues();
|
mRendering->getScene()->clearSpecialCaseRenderQueues();
|
||||||
|
@ -1579,12 +1593,13 @@ namespace MWGui
|
||||||
bool cursorWasVisible = mCursorVisible;
|
bool cursorWasVisible = mCursorVisible;
|
||||||
setCursorVisible(false);
|
setCursorVisible(false);
|
||||||
|
|
||||||
while (mVideoWidget->update())
|
while (mVideoWidget->update() && !MWBase::Environment::get().getStateManager()->hasQuitRequest())
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getInputManager()->update(0, true, false);
|
MWBase::Environment::get().getInputManager()->update(0, true, false);
|
||||||
|
|
||||||
mRendering->getWindow()->update();
|
mRendering->getWindow()->update();
|
||||||
}
|
}
|
||||||
|
mVideoWidget->stop();
|
||||||
|
|
||||||
setCursorVisible(cursorWasVisible);
|
setCursorVisible(cursorWasVisible);
|
||||||
|
|
||||||
|
@ -1625,4 +1640,33 @@ namespace MWGui
|
||||||
if(input == mCurrentModals.top())
|
if(input == mCurrentModals.top())
|
||||||
mCurrentModals.pop();
|
mCurrentModals.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowManager::onVideoKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char)
|
||||||
|
{
|
||||||
|
if (_key == MyGUI::KeyCode::Escape)
|
||||||
|
mVideoWidget->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowManager::pinWindow(GuiWindow window)
|
||||||
|
{
|
||||||
|
switch (window)
|
||||||
|
{
|
||||||
|
case GW_Inventory:
|
||||||
|
mInventoryWindow->setPinned(true);
|
||||||
|
break;
|
||||||
|
case GW_Map:
|
||||||
|
mMap->setPinned(true);
|
||||||
|
break;
|
||||||
|
case GW_Magic:
|
||||||
|
mSpellWindow->setPinned(true);
|
||||||
|
break;
|
||||||
|
case GW_Stats:
|
||||||
|
mStatsWindow->setPinned(true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateVisible();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
|
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
|
#include <MyGUI_KeyCode.h>
|
||||||
|
#include <MyGUI_Types.h>
|
||||||
|
|
||||||
namespace MyGUI
|
namespace MyGUI
|
||||||
{
|
{
|
||||||
class Gui;
|
class Gui;
|
||||||
|
@ -316,6 +319,8 @@ namespace MWGui
|
||||||
\param input Pointer to the current modal, to ensure proper modal is removed **/
|
\param input Pointer to the current modal, to ensure proper modal is removed **/
|
||||||
virtual void removeCurrentModal(WindowModal* input);
|
virtual void removeCurrentModal(WindowModal* input);
|
||||||
|
|
||||||
|
virtual void pinWindow (MWGui::GuiWindow window);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mConsoleOnlyScripts;
|
bool mConsoleOnlyScripts;
|
||||||
|
|
||||||
|
@ -424,6 +429,9 @@ namespace MWGui
|
||||||
void onCursorChange(const std::string& name);
|
void onCursorChange(const std::string& name);
|
||||||
void onKeyFocusChanged(MyGUI::Widget* widget);
|
void onKeyFocusChanged(MyGUI::Widget* widget);
|
||||||
|
|
||||||
|
// Key pressed while playing a video
|
||||||
|
void onVideoKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char);
|
||||||
|
|
||||||
void sizeVideo(int screenWidth, int screenHeight);
|
void sizeVideo(int screenWidth, int screenHeight);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,12 @@ namespace MWGui
|
||||||
onPinToggled();
|
onPinToggled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowPinnableBase::setPinned(bool pinned)
|
||||||
|
{
|
||||||
|
if (pinned != mPinned)
|
||||||
|
onPinButtonClicked(mPinButton);
|
||||||
|
}
|
||||||
|
|
||||||
void WindowPinnableBase::setPinButtonVisible(bool visible)
|
void WindowPinnableBase::setPinButtonVisible(bool visible)
|
||||||
{
|
{
|
||||||
mPinButton->setVisible(visible);
|
mPinButton->setVisible(visible);
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace MWGui
|
||||||
public:
|
public:
|
||||||
WindowPinnableBase(const std::string& parLayout);
|
WindowPinnableBase(const std::string& parLayout);
|
||||||
bool pinned() { return mPinned; }
|
bool pinned() { return mPinned; }
|
||||||
|
void setPinned (bool pinned);
|
||||||
void setPinButtonVisible(bool visible);
|
void setPinButtonVisible(bool visible);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -117,7 +117,8 @@ namespace MWInput
|
||||||
, mPreviewPOVDelay(0.f)
|
, mPreviewPOVDelay(0.f)
|
||||||
, mTimeIdle(0.f)
|
, mTimeIdle(0.f)
|
||||||
, mOverencumberedMessageDelay(0.f)
|
, mOverencumberedMessageDelay(0.f)
|
||||||
, mAlwaysRunActive(false)
|
, mAlwaysRunActive(Settings::Manager::getBool("always run", "Input"))
|
||||||
|
, mAttemptJump(false)
|
||||||
, mControlsDisabled(false)
|
, mControlsDisabled(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -165,6 +166,21 @@ namespace MWInput
|
||||||
delete mInputManager;
|
delete mInputManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InputManager::setPlayerControlsEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
int nPlayerChannels = 17;
|
||||||
|
int playerChannels[] = {A_Activate, A_AutoMove, A_AlwaysRun, A_ToggleWeapon,
|
||||||
|
A_ToggleSpell, A_Rest, A_QuickKey1, A_QuickKey2,
|
||||||
|
A_QuickKey3, A_QuickKey4, A_QuickKey5, A_QuickKey6,
|
||||||
|
A_QuickKey7, A_QuickKey8, A_QuickKey9, A_QuickKey10,
|
||||||
|
A_Use};
|
||||||
|
|
||||||
|
for(int i = 0; i < nPlayerChannels; i++) {
|
||||||
|
int pc = playerChannels[i];
|
||||||
|
mInputBinder->getChannel(pc)->setEnabled(enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InputManager::channelChanged(ICS::Channel* channel, float currentValue, float previousValue)
|
void InputManager::channelChanged(ICS::Channel* channel, float currentValue, float previousValue)
|
||||||
{
|
{
|
||||||
if (mDragDrop)
|
if (mDragDrop)
|
||||||
|
@ -179,6 +195,11 @@ namespace MWInput
|
||||||
mPlayer->getPlayer().getClass().getCreatureStats(mPlayer->getPlayer()).setAttackingOrSpell(currentValue);
|
mPlayer->getPlayer().getClass().getCreatureStats(mPlayer->getPlayer()).setAttackingOrSpell(currentValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action == A_Jump)
|
||||||
|
{
|
||||||
|
mAttemptJump = (currentValue == 1.0 && previousValue == 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
if (currentValue == 1)
|
if (currentValue == 1)
|
||||||
{
|
{
|
||||||
// trigger action activated
|
// trigger action activated
|
||||||
|
@ -305,11 +326,9 @@ namespace MWInput
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable movement in Gui mode
|
// Disable movement in Gui mode
|
||||||
if (MWBase::Environment::get().getWindowManager()->isGuiMode()
|
if (!(MWBase::Environment::get().getWindowManager()->isGuiMode()
|
||||||
|| MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running)
|
|| MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running))
|
||||||
return;
|
{
|
||||||
|
|
||||||
|
|
||||||
// Configure player movement according to keyboard input. Actual movement will
|
// Configure player movement according to keyboard input. Actual movement will
|
||||||
// be done in the physics system.
|
// be done in the physics system.
|
||||||
if (mControlSwitch["playercontrols"])
|
if (mControlSwitch["playercontrols"])
|
||||||
|
@ -347,7 +366,7 @@ namespace MWInput
|
||||||
|
|
||||||
mPlayer->setSneak(actionIsActive(A_Sneak));
|
mPlayer->setSneak(actionIsActive(A_Sneak));
|
||||||
|
|
||||||
if (actionIsActive(A_Jump) && mControlSwitch["playerjumping"])
|
if (mAttemptJump && mControlSwitch["playerjumping"])
|
||||||
{
|
{
|
||||||
mPlayer->setUpDown (1);
|
mPlayer->setUpDown (1);
|
||||||
triedToMove = true;
|
triedToMove = true;
|
||||||
|
@ -407,6 +426,8 @@ namespace MWInput
|
||||||
updateIdleTime(dt);
|
updateIdleTime(dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mAttemptJump = false; // Can only jump on first frame input is on
|
||||||
|
}
|
||||||
|
|
||||||
void InputManager::setDragDrop(bool dragDrop)
|
void InputManager::setDragDrop(bool dragDrop)
|
||||||
{
|
{
|
||||||
|
@ -517,13 +538,15 @@ namespace MWInput
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mControlsDisabled)
|
|
||||||
mInputBinder->keyPressed (arg);
|
|
||||||
|
|
||||||
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
|
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
|
||||||
|
|
||||||
if (kc != OIS::KC_UNASSIGNED)
|
if (kc != OIS::KC_UNASSIGNED)
|
||||||
MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0);
|
{
|
||||||
|
bool guiFocus = MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0);
|
||||||
|
setPlayerControlsEnabled(!guiFocus);
|
||||||
|
}
|
||||||
|
if (!mControlsDisabled)
|
||||||
|
mInputBinder->keyPressed (arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputManager::textInput(const SDL_TextInputEvent &arg)
|
void InputManager::textInput(const SDL_TextInputEvent &arg)
|
||||||
|
@ -536,21 +559,20 @@ namespace MWInput
|
||||||
|
|
||||||
void InputManager::keyReleased(const SDL_KeyboardEvent &arg )
|
void InputManager::keyReleased(const SDL_KeyboardEvent &arg )
|
||||||
{
|
{
|
||||||
mInputBinder->keyReleased (arg);
|
|
||||||
|
|
||||||
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
|
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
|
||||||
|
|
||||||
MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc));
|
setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc)));
|
||||||
|
mInputBinder->keyReleased (arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputManager::mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id )
|
void InputManager::mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id )
|
||||||
{
|
{
|
||||||
mInputBinder->mousePressed (arg, id);
|
bool guiMode = false;
|
||||||
|
|
||||||
if (id != SDL_BUTTON_LEFT && id != SDL_BUTTON_RIGHT)
|
if (id == SDL_BUTTON_LEFT || id == SDL_BUTTON_RIGHT) // MyGUI only uses these mouse events
|
||||||
return; // MyGUI has no use for these events
|
{
|
||||||
|
guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode();
|
||||||
MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, sdlButtonToMyGUI(id));
|
guiMode = MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, sdlButtonToMyGUI(id)) && guiMode;
|
||||||
if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0)
|
if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0)
|
||||||
{
|
{
|
||||||
MyGUI::Button* b = MyGUI::InputManager::getInstance ().getMouseFocusWidget ()->castType<MyGUI::Button>(false);
|
MyGUI::Button* b = MyGUI::InputManager::getInstance ().getMouseFocusWidget ()->castType<MyGUI::Button>(false);
|
||||||
|
@ -561,11 +583,27 @@ namespace MWInput
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setPlayerControlsEnabled(!guiMode);
|
||||||
|
mInputBinder->mousePressed (arg, id);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void InputManager::mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id )
|
void InputManager::mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id )
|
||||||
{
|
{
|
||||||
mInputBinder->mouseReleased (arg, id);
|
|
||||||
|
|
||||||
MyGUI::InputManager::getInstance().injectMouseRelease(mMouseX, mMouseY, sdlButtonToMyGUI(id));
|
if(mInputBinder->detectingBindingState())
|
||||||
|
{
|
||||||
|
mInputBinder->mouseReleased (arg, id);
|
||||||
|
} else {
|
||||||
|
bool guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode();
|
||||||
|
guiMode = MyGUI::InputManager::getInstance().injectMouseRelease(mMouseX, mMouseY, sdlButtonToMyGUI(id)) && guiMode;
|
||||||
|
|
||||||
|
if(mInputBinder->detectingBindingState()) return; // don't allow same mouseup to bind as initiated bind
|
||||||
|
|
||||||
|
setPlayerControlsEnabled(!guiMode);
|
||||||
|
mInputBinder->mouseReleased (arg, id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputManager::mouseMoved(const SFO::MouseMotionEvent &arg )
|
void InputManager::mouseMoved(const SFO::MouseMotionEvent &arg )
|
||||||
|
@ -769,8 +807,9 @@ namespace MWInput
|
||||||
if (MyGUI::InputManager::getInstance ().isModalAny())
|
if (MyGUI::InputManager::getInstance ().isModalAny())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Toggle between game mode and journal mode
|
if((!MWBase::Environment::get().getWindowManager()->isGuiMode()
|
||||||
if(!MWBase::Environment::get().getWindowManager()->isGuiMode() && MWBase::Environment::get().getWindowManager ()->getJournalAllowed())
|
|| MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_Dialogue)
|
||||||
|
&& MWBase::Environment::get().getWindowManager ()->getJournalAllowed())
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0);
|
MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0);
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Journal);
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Journal);
|
||||||
|
@ -779,7 +818,6 @@ namespace MWInput
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode();
|
MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode();
|
||||||
}
|
}
|
||||||
// .. but don't touch any other mode.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputManager::quickKey (int index)
|
void InputManager::quickKey (int index)
|
||||||
|
@ -819,6 +857,8 @@ namespace MWInput
|
||||||
{
|
{
|
||||||
if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return;
|
if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return;
|
||||||
mAlwaysRunActive = !mAlwaysRunActive;
|
mAlwaysRunActive = !mAlwaysRunActive;
|
||||||
|
|
||||||
|
Settings::Manager::setBool("always run", "Input", mAlwaysRunActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputManager::resetIdleTime()
|
void InputManager::resetIdleTime()
|
||||||
|
@ -917,11 +957,6 @@ namespace MWInput
|
||||||
mInputBinder->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE);
|
mInputBinder->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Printscreen key should not be allowed because it's captured by system screenshot function
|
|
||||||
// We check this explicitely here to fix up pre-0.26 config files. Can be removed after a few versions
|
|
||||||
if (mInputBinder->getKeyBinding(mInputBinder->getControl(A_Screenshot), ICS::Control::INCREASE) == SDLK_PRINTSCREEN)
|
|
||||||
mInputBinder->addKeyBinding(mInputBinder->getControl(A_Screenshot), SDLK_F12, ICS::Control::INCREASE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string InputManager::getActionDescription (int action)
|
std::string InputManager::getActionDescription (int action)
|
||||||
|
|
|
@ -163,6 +163,7 @@ namespace MWInput
|
||||||
int mMouseWheel;
|
int mMouseWheel;
|
||||||
bool mUserFileExists;
|
bool mUserFileExists;
|
||||||
bool mAlwaysRunActive;
|
bool mAlwaysRunActive;
|
||||||
|
bool mAttemptJump;
|
||||||
|
|
||||||
std::map<std::string, bool> mControlSwitch;
|
std::map<std::string, bool> mControlSwitch;
|
||||||
|
|
||||||
|
@ -173,6 +174,8 @@ namespace MWInput
|
||||||
void resetIdleTime();
|
void resetIdleTime();
|
||||||
void updateIdleTime(float dt);
|
void updateIdleTime(float dt);
|
||||||
|
|
||||||
|
void setPlayerControlsEnabled(bool enabled);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void toggleMainMenu();
|
void toggleMainMenu();
|
||||||
void toggleSpell();
|
void toggleSpell();
|
||||||
|
|
|
@ -932,7 +932,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
for (std::list<MWWorld::Ptr>::iterator it = listGuards.begin(); it != listGuards.end(); ++it)
|
for (std::list<MWWorld::Ptr>::iterator it = listGuards.begin(); it != listGuards.end(); ++it)
|
||||||
{
|
{
|
||||||
engageCombat(iter->first, *it, false);
|
engageCombat(iter->first, *it, *it == player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1088,10 +1088,10 @@ namespace MWMechanics
|
||||||
|
|
||||||
CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
||||||
|
|
||||||
float healthHours = healthPerHour >= 0
|
float healthHours = healthPerHour > 0
|
||||||
? (stats.getHealth().getModified() - stats.getHealth().getCurrent()) / healthPerHour
|
? (stats.getHealth().getModified() - stats.getHealth().getCurrent()) / healthPerHour
|
||||||
: 1.0f;
|
: 1.0f;
|
||||||
float magickaHours = magickaPerHour >= 0
|
float magickaHours = magickaPerHour > 0
|
||||||
? (stats.getMagicka().getModified() - stats.getMagicka().getCurrent()) / magickaPerHour
|
? (stats.getMagicka().getModified() - stats.getMagicka().getCurrent()) / magickaPerHour
|
||||||
: 1.0f;
|
: 1.0f;
|
||||||
|
|
||||||
|
|
|
@ -395,7 +395,8 @@ int MWMechanics::Alchemy::addIngredient (const MWWorld::Ptr& ingredient)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (TIngredientsIterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter)
|
for (TIngredientsIterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter)
|
||||||
if (!iter->isEmpty() && ingredient.get<ESM::Ingredient>()==iter->get<ESM::Ingredient>())
|
if (!iter->isEmpty() && Misc::StringUtils::ciEqual(ingredient.getClass().getId(ingredient),
|
||||||
|
iter->getClass().getId(*iter)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
mIngredients[slot] = ingredient;
|
mIngredients[slot] = ingredient;
|
||||||
|
|
|
@ -409,6 +409,13 @@ MWWorld::ContainerStoreIterator getActiveWeapon(CreatureStats &stats, MWWorld::I
|
||||||
|
|
||||||
void CharacterController::playDeath(float startpoint, CharacterState death)
|
void CharacterController::playDeath(float startpoint, CharacterState death)
|
||||||
{
|
{
|
||||||
|
if (mPtr == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||||
|
{
|
||||||
|
// The first-person animations do not include death, so we need to
|
||||||
|
// force-switch to third person before playing the death animation.
|
||||||
|
MWBase::Environment::get().getWorld()->useDeathCamera();
|
||||||
|
}
|
||||||
|
|
||||||
switch (death)
|
switch (death)
|
||||||
{
|
{
|
||||||
case CharState_SwimDeath:
|
case CharState_SwimDeath:
|
||||||
|
@ -825,6 +832,8 @@ bool CharacterController::updateWeaponState()
|
||||||
MWRender::Animation::Group_UpperBody, false,
|
MWRender::Animation::Group_UpperBody, false,
|
||||||
weapSpeed, mAttackType+" max attack", mAttackType+" min hit",
|
weapSpeed, mAttackType+" max attack", mAttackType+" min hit",
|
||||||
1.0f-complete, 0);
|
1.0f-complete, 0);
|
||||||
|
|
||||||
|
complete = 0.f;
|
||||||
mUpperBodyState = UpperCharState_MaxAttackToMinHit;
|
mUpperBodyState = UpperCharState_MaxAttackToMinHit;
|
||||||
}
|
}
|
||||||
else if (mHitState == CharState_KnockDown)
|
else if (mHitState == CharState_KnockDown)
|
||||||
|
@ -968,7 +977,8 @@ bool CharacterController::updateWeaponState()
|
||||||
}
|
}
|
||||||
|
|
||||||
//if playing combat animation and lowerbody is not busy switch to whole body animation
|
//if playing combat animation and lowerbody is not busy switch to whole body animation
|
||||||
if((weaptype != WeapType_None || UpperCharState_UnEquipingWeap) && animPlaying)
|
if((weaptype != WeapType_None || mUpperBodyState == UpperCharState_UnEquipingWeap
|
||||||
|
|| mUpperBodyState == UpperCharState_EquipingWeap) && animPlaying)
|
||||||
{
|
{
|
||||||
if( mMovementState != CharState_None ||
|
if( mMovementState != CharState_None ||
|
||||||
mJumpState != JumpState_None ||
|
mJumpState != JumpState_None ||
|
||||||
|
|
|
@ -73,9 +73,16 @@ namespace MWMechanics
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MWMechanics::CreatureStats& blockerStats = blocker.getClass().getCreatureStats(blocker);
|
MWMechanics::CreatureStats& blockerStats = blocker.getClass().getCreatureStats(blocker);
|
||||||
|
|
||||||
|
// Don't block when in spellcasting state (shield is equipped, but not visible)
|
||||||
if (blockerStats.getDrawState() == DrawState_Spell)
|
if (blockerStats.getDrawState() == DrawState_Spell)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Don't block when in hand-to-hand combat (shield is equipped, but not visible)
|
||||||
|
if (blockerStats.getDrawState() == DrawState_Weapon &&
|
||||||
|
inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight) == inv.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
MWMechanics::CreatureStats& attackerStats = attacker.getClass().getCreatureStats(attacker);
|
MWMechanics::CreatureStats& attackerStats = attacker.getClass().getCreatureStats(attacker);
|
||||||
|
|
||||||
float blockTerm = blocker.getClass().getSkill(blocker, ESM::Skill::Block) + 0.2 * blockerStats.getAttribute(ESM::Attribute::Agility).getModified()
|
float blockTerm = blocker.getClass().getSkill(blocker, ESM::Skill::Block) + 0.2 * blockerStats.getAttribute(ESM::Attribute::Agility).getModified()
|
||||||
|
|
|
@ -929,7 +929,10 @@ namespace MWMechanics
|
||||||
else if (type == OT_Murder)
|
else if (type == OT_Murder)
|
||||||
arg = store.find("iCrimeKilling")->getInt();
|
arg = store.find("iCrimeKilling")->getInt();
|
||||||
else if (type == OT_Theft)
|
else if (type == OT_Theft)
|
||||||
|
{
|
||||||
arg *= store.find("fCrimeStealing")->getFloat();
|
arg *= store.find("fCrimeStealing")->getFloat();
|
||||||
|
arg = std::max(1, arg); // Minimum bounty of 1, in case items with zero value are stolen
|
||||||
|
}
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sCrimeMessage}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sCrimeMessage}");
|
||||||
ptr.getClass().getNpcStats(ptr).setBounty(ptr.getClass().getNpcStats(ptr).getBounty()
|
ptr.getClass().getNpcStats(ptr).setBounty(ptr.getClass().getNpcStats(ptr).getBounty()
|
||||||
|
|
|
@ -356,28 +356,40 @@ void Animation::addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectScene
|
||||||
objlist->mControllers.push_back(Ogre::Controller<Ogre::Real>(src, dest, func));
|
objlist->mControllers.push_back(Ogre::Controller<Ogre::Real>(src, dest, func));
|
||||||
|
|
||||||
bool interior = !(mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior());
|
bool interior = !(mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior());
|
||||||
bool quadratic = fallback->getFallbackBool("LightAttenuation_OutQuadInLin") ?
|
|
||||||
!interior : fallback->getFallbackBool("LightAttenuation_UseQuadratic");
|
static bool outQuadInLin = fallback->getFallbackBool("LightAttenuation_OutQuadInLin");
|
||||||
|
static bool useQuadratic = fallback->getFallbackBool("LightAttenuation_UseQuadratic");
|
||||||
|
static float quadraticValue = fallback->getFallbackFloat("LightAttenuation_QuadraticValue");
|
||||||
|
static float quadraticRadiusMult = fallback->getFallbackFloat("LightAttenuation_QuadraticRadiusMult");
|
||||||
|
static bool useLinear = fallback->getFallbackBool("LightAttenuation_UseLinear");
|
||||||
|
static float linearRadiusMult = fallback->getFallbackFloat("LightAttenuation_LinearRadiusMult");
|
||||||
|
static float linearValue = fallback->getFallbackFloat("LightAttenuation_LinearValue");
|
||||||
|
|
||||||
|
bool quadratic = useQuadratic && (!outQuadInLin || !interior);
|
||||||
|
|
||||||
|
|
||||||
// with the standard 1 / (c + d*l + d*d*q) equation the attenuation factor never becomes zero,
|
// with the standard 1 / (c + d*l + d*d*q) equation the attenuation factor never becomes zero,
|
||||||
// so we ignore lights if their attenuation falls below this factor.
|
// so we ignore lights if their attenuation falls below this factor.
|
||||||
const float threshold = 0.03;
|
const float threshold = 0.03;
|
||||||
|
|
||||||
if (!quadratic)
|
float quadraticAttenuation = 0;
|
||||||
|
float linearAttenuation = 0;
|
||||||
|
float activationRange = 0;
|
||||||
|
if (quadratic)
|
||||||
{
|
{
|
||||||
float r = radius * fallback->getFallbackFloat("LightAttenuation_LinearRadiusMult");
|
float r = radius * quadraticRadiusMult;
|
||||||
float attenuation = fallback->getFallbackFloat("LightAttenuation_LinearValue") / r;
|
quadraticAttenuation = quadraticValue / std::pow(r, 2);
|
||||||
float activationRange = 1.0f / (threshold * attenuation);
|
activationRange = std::sqrt(1.0f / (threshold * quadraticAttenuation));
|
||||||
olight->setAttenuation(activationRange, 0, attenuation, 0);
|
|
||||||
}
|
}
|
||||||
else
|
if (useLinear)
|
||||||
{
|
{
|
||||||
float r = radius * fallback->getFallbackFloat("LightAttenuation_QuadraticRadiusMult");
|
float r = radius * linearRadiusMult;
|
||||||
float attenuation = fallback->getFallbackFloat("LightAttenuation_QuadraticValue") / std::pow(r, 2);
|
linearAttenuation = linearValue / r;
|
||||||
float activationRange = std::sqrt(1.0f / (threshold * attenuation));
|
activationRange = std::max(activationRange, 1.0f / (threshold * linearAttenuation));
|
||||||
olight->setAttenuation(activationRange, 0, 0, attenuation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
olight->setAttenuation(activationRange, 0, linearAttenuation, quadraticAttenuation);
|
||||||
|
|
||||||
// If there's an AttachLight bone, attach the light to that, otherwise put it in the center,
|
// If there's an AttachLight bone, attach the light to that, otherwise put it in the center,
|
||||||
if(objlist->mSkelBase && objlist->mSkelBase->getSkeleton()->hasBone("AttachLight"))
|
if(objlist->mSkelBase && objlist->mSkelBase->getSkeleton()->hasBone("AttachLight"))
|
||||||
objlist->mSkelBase->attachObjectToBone("AttachLight", olight);
|
objlist->mSkelBase->attachObjectToBone("AttachLight", olight);
|
||||||
|
|
|
@ -140,11 +140,11 @@ namespace MWRender
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::toggleViewMode()
|
void Camera::toggleViewMode(bool force)
|
||||||
{
|
{
|
||||||
// Changing the view will stop all playing animations, so if we are playing
|
// Changing the view will stop all playing animations, so if we are playing
|
||||||
// anything important, queue the view change for later
|
// anything important, queue the view change for later
|
||||||
if (!mAnimation->allowSwitchViewMode())
|
if (!mAnimation->allowSwitchViewMode() && !force)
|
||||||
{
|
{
|
||||||
mViewModeToggleQueued = true;
|
mViewModeToggleQueued = true;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -75,7 +75,8 @@ namespace MWRender
|
||||||
/// Attach camera to object
|
/// Attach camera to object
|
||||||
void attachTo(const MWWorld::Ptr &);
|
void attachTo(const MWWorld::Ptr &);
|
||||||
|
|
||||||
void toggleViewMode();
|
/// @param Force view mode switch, even if currently not allowed by the animation.
|
||||||
|
void toggleViewMode(bool force=false);
|
||||||
|
|
||||||
bool toggleVanityMode(bool enable);
|
bool toggleVanityMode(bool enable);
|
||||||
void allowVanityMode(bool allow);
|
void allowVanityMode(bool allow);
|
||||||
|
|
|
@ -308,7 +308,7 @@ void NpcAnimation::updateParts()
|
||||||
ESM::PartReferenceType parts[] = {
|
ESM::PartReferenceType parts[] = {
|
||||||
ESM::PRT_Groin, ESM::PRT_Skirt, ESM::PRT_RLeg, ESM::PRT_LLeg,
|
ESM::PRT_Groin, ESM::PRT_Skirt, ESM::PRT_RLeg, ESM::PRT_LLeg,
|
||||||
ESM::PRT_RUpperarm, ESM::PRT_LUpperarm, ESM::PRT_RKnee, ESM::PRT_LKnee,
|
ESM::PRT_RUpperarm, ESM::PRT_LUpperarm, ESM::PRT_RKnee, ESM::PRT_LKnee,
|
||||||
ESM::PRT_RForearm, ESM::PRT_LForearm, ESM::PRT_RPauldron, ESM::PRT_LPauldron
|
ESM::PRT_RForearm, ESM::PRT_LForearm
|
||||||
};
|
};
|
||||||
size_t parts_size = sizeof(parts)/sizeof(parts[0]);
|
size_t parts_size = sizeof(parts)/sizeof(parts[0]);
|
||||||
for(size_t p = 0;p < parts_size;++p)
|
for(size_t p = 0;p < parts_size;++p)
|
||||||
|
@ -351,8 +351,6 @@ void NpcAnimation::updateParts()
|
||||||
// Remember body parts so we only have to search through the store once for each race/gender/viewmode combination
|
// Remember body parts so we only have to search through the store once for each race/gender/viewmode combination
|
||||||
static std::map< std::pair<std::string,int>,std::vector<const ESM::BodyPart*> > sRaceMapping;
|
static std::map< std::pair<std::string,int>,std::vector<const ESM::BodyPart*> > sRaceMapping;
|
||||||
|
|
||||||
static std::map <std::pair<std::string,int>, std::vector<const ESM::BodyPart*> > sVampireMapping;
|
|
||||||
|
|
||||||
static const int Flag_Female = 1<<0;
|
static const int Flag_Female = 1<<0;
|
||||||
static const int Flag_FirstPerson = 1<<1;
|
static const int Flag_FirstPerson = 1<<1;
|
||||||
|
|
||||||
|
@ -408,8 +406,6 @@ void NpcAnimation::updateParts()
|
||||||
if (bodypart.mData.mType != ESM::BodyPart::MT_Skin)
|
if (bodypart.mData.mType != ESM::BodyPart::MT_Skin)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!mNpc->isMale() != (bodypart.mData.mFlags & ESM::BodyPart::BPF_Female))
|
|
||||||
continue;
|
|
||||||
if (!Misc::StringUtils::ciEqual(bodypart.mRace, mNpc->mRace))
|
if (!Misc::StringUtils::ciEqual(bodypart.mRace, mNpc->mRace))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -435,6 +431,20 @@ void NpcAnimation::updateParts()
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mNpc->isMale() != (bodypart.mData.mFlags & ESM::BodyPart::BPF_Female))
|
||||||
|
{
|
||||||
|
// Allow opposite gender's parts as fallback if parts for our gender are missing
|
||||||
|
BodyPartMapType::const_iterator bIt = sBodyPartMap.lower_bound(BodyPartMapType::key_type(bodypart.mData.mPart));
|
||||||
|
while(bIt != sBodyPartMap.end() && bIt->first == bodypart.mData.mPart)
|
||||||
|
{
|
||||||
|
if(!parts[bIt->second])
|
||||||
|
parts[bIt->second] = &*it;
|
||||||
|
++bIt;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
BodyPartMapType::const_iterator bIt = sBodyPartMap.lower_bound(BodyPartMapType::key_type(bodypart.mData.mPart));
|
BodyPartMapType::const_iterator bIt = sBodyPartMap.lower_bound(BodyPartMapType::key_type(bodypart.mData.mPart));
|
||||||
while(bIt != sBodyPartMap.end() && bIt->first == bodypart.mData.mPart)
|
while(bIt != sBodyPartMap.end() && bIt->first == bodypart.mData.mPart)
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,7 +73,7 @@ void Objects::insertBegin(const MWWorld::Ptr& ptr)
|
||||||
ptr.getRefData().setBaseNode(insert);
|
ptr.getRefData().setBaseNode(insert);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh)
|
void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh, bool batch)
|
||||||
{
|
{
|
||||||
insertBegin(ptr);
|
insertBegin(ptr);
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh)
|
||||||
mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL;
|
mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL;
|
||||||
mBounds[ptr.getCell()].merge(bounds);
|
mBounds[ptr.getCell()].merge(bounds);
|
||||||
|
|
||||||
if(ptr.getTypeName() == typeid(ESM::Static).name() &&
|
if(batch &&
|
||||||
Settings::Manager::getBool("use static geometry", "Objects") &&
|
Settings::Manager::getBool("use static geometry", "Objects") &&
|
||||||
anim->canBatch())
|
anim->canBatch())
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
, mRootNode(NULL)
|
, mRootNode(NULL)
|
||||||
{}
|
{}
|
||||||
~Objects(){}
|
~Objects(){}
|
||||||
void insertModel(const MWWorld::Ptr& ptr, const std::string &model);
|
void insertModel(const MWWorld::Ptr& ptr, const std::string &model, bool batch=false);
|
||||||
|
|
||||||
ObjectAnimation* getAnimation(const MWWorld::Ptr &ptr);
|
ObjectAnimation* getAnimation(const MWWorld::Ptr &ptr);
|
||||||
|
|
||||||
|
|
|
@ -235,6 +235,18 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class R>
|
||||||
|
class OpClearInfoActor : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
|
||||||
|
MWBase::Environment::get().getDialogueManager()->clearInfoActor(ptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
{
|
{
|
||||||
|
@ -256,6 +268,8 @@ namespace MWScript
|
||||||
interpreter.installSegment5 (Compiler::Dialogue::opcodeSameFactionExplicit, new OpSameFaction<ExplicitRef>);
|
interpreter.installSegment5 (Compiler::Dialogue::opcodeSameFactionExplicit, new OpSameFaction<ExplicitRef>);
|
||||||
interpreter.installSegment5 (Compiler::Dialogue::opcodeModFactionReaction, new OpModFactionReaction);
|
interpreter.installSegment5 (Compiler::Dialogue::opcodeModFactionReaction, new OpModFactionReaction);
|
||||||
interpreter.installSegment5 (Compiler::Dialogue::opcodeGetFactionReaction, new OpGetFactionReaction);
|
interpreter.installSegment5 (Compiler::Dialogue::opcodeGetFactionReaction, new OpGetFactionReaction);
|
||||||
|
interpreter.installSegment5 (Compiler::Dialogue::opcodeClearInfoActor, new OpClearInfoActor<ImplicitRef>);
|
||||||
|
interpreter.installSegment5 (Compiler::Dialogue::opcodeClearInfoActorExplicit, new OpClearInfoActor<ExplicitRef>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,8 @@ op 0x20028: RemoveSoulGem, explicit reference
|
||||||
op 0x20029: PCRaiseRank, explicit reference
|
op 0x20029: PCRaiseRank, explicit reference
|
||||||
op 0x2002a: PCLowerRank, explicit reference
|
op 0x2002a: PCLowerRank, explicit reference
|
||||||
op 0x2002b: PCJoinFaction, explicit reference
|
op 0x2002b: PCJoinFaction, explicit reference
|
||||||
opcodes 0x2002c-0x3ffff unused
|
op 0x2002c: MenuTest
|
||||||
|
opcodes 0x2002d-0x3ffff unused
|
||||||
|
|
||||||
Segment 4:
|
Segment 4:
|
||||||
(not implemented yet)
|
(not implemented yet)
|
||||||
|
@ -393,5 +394,7 @@ op 0x2000241: onKnockoutExplicit
|
||||||
op 0x2000242: ModFactionReaction
|
op 0x2000242: ModFactionReaction
|
||||||
op 0x2000243: GetFactionReaction
|
op 0x2000243: GetFactionReaction
|
||||||
op 0x2000244: Activate, explicit
|
op 0x2000244: Activate, explicit
|
||||||
|
op 0x2000245: ClearInfoActor
|
||||||
|
op 0x2000246: ClearInfoActor, explicit
|
||||||
|
|
||||||
opcodes 0x2000245-0x3ffffff unused
|
opcodes 0x2000247-0x3ffffff unused
|
||||||
|
|
|
@ -162,6 +162,47 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class OpMenuTest : public Interpreter::Opcode1
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0)
|
||||||
|
{
|
||||||
|
int arg=0;
|
||||||
|
if(arg0>0)
|
||||||
|
{
|
||||||
|
arg = runtime[0].mInteger;
|
||||||
|
runtime.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (arg == 0)
|
||||||
|
{
|
||||||
|
MWGui::GuiMode modes[] = { MWGui::GM_Inventory, MWGui::GM_Container };
|
||||||
|
|
||||||
|
for (int i=0; i<2; ++i)
|
||||||
|
{
|
||||||
|
if (MWBase::Environment::get().getWindowManager()->containsMode(modes[i]))
|
||||||
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(modes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MWGui::GuiWindow gw = MWGui::GW_None;
|
||||||
|
if (arg == 3)
|
||||||
|
gw = MWGui::GW_Stats;
|
||||||
|
if (arg == 4)
|
||||||
|
gw = MWGui::GW_Inventory;
|
||||||
|
if (arg == 5)
|
||||||
|
gw = MWGui::GW_Magic;
|
||||||
|
if (arg == 6)
|
||||||
|
gw = MWGui::GW_Map;
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWindowManager()->pinWindow(gw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
{
|
{
|
||||||
|
@ -200,6 +241,7 @@ namespace MWScript
|
||||||
|
|
||||||
interpreter.installSegment5 (Compiler::Gui::opcodeShowMap, new OpShowMap);
|
interpreter.installSegment5 (Compiler::Gui::opcodeShowMap, new OpShowMap);
|
||||||
interpreter.installSegment5 (Compiler::Gui::opcodeFillMap, new OpFillMap);
|
interpreter.installSegment5 (Compiler::Gui::opcodeFillMap, new OpFillMap);
|
||||||
|
interpreter.installSegment3 (Compiler::Gui::opcodeMenuTest, new OpMenuTest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,9 +54,28 @@ void MWState::Character::addSlot (const ESM::SavedGame& profile)
|
||||||
Slot slot;
|
Slot slot;
|
||||||
|
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
stream << mNext++;
|
|
||||||
|
// The profile description is user-supplied, so we need to escape the path
|
||||||
|
for (std::string::const_iterator it = profile.mDescription.begin(); it != profile.mDescription.end(); ++it)
|
||||||
|
{
|
||||||
|
if (std::isalnum(*it)) // Ignores multibyte characters and non alphanumeric characters
|
||||||
|
stream << *it;
|
||||||
|
else
|
||||||
|
stream << "_";
|
||||||
|
}
|
||||||
|
|
||||||
slot.mPath = mPath / stream.str();
|
slot.mPath = mPath / stream.str();
|
||||||
|
|
||||||
|
// Append an index if necessary to ensure a unique file
|
||||||
|
int i=0;
|
||||||
|
while (boost::filesystem::exists(slot.mPath))
|
||||||
|
{
|
||||||
|
std::ostringstream test;
|
||||||
|
test << stream.str();
|
||||||
|
test << " - " << ++i;
|
||||||
|
slot.mPath = mPath / test.str();
|
||||||
|
}
|
||||||
|
|
||||||
slot.mProfile = profile;
|
slot.mProfile = profile;
|
||||||
slot.mTimeStamp = std::time (0);
|
slot.mTimeStamp = std::time (0);
|
||||||
|
|
||||||
|
@ -64,7 +83,7 @@ void MWState::Character::addSlot (const ESM::SavedGame& profile)
|
||||||
}
|
}
|
||||||
|
|
||||||
MWState::Character::Character (const boost::filesystem::path& saves, const std::string& game)
|
MWState::Character::Character (const boost::filesystem::path& saves, const std::string& game)
|
||||||
: mPath (saves), mNext (0)
|
: mPath (saves)
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::is_directory (mPath))
|
if (!boost::filesystem::is_directory (mPath))
|
||||||
{
|
{
|
||||||
|
@ -82,13 +101,6 @@ MWState::Character::Character (const boost::filesystem::path& saves, const std::
|
||||||
addSlot (slotPath, game);
|
addSlot (slotPath, game);
|
||||||
}
|
}
|
||||||
catch (...) {} // ignoring bad saved game files for now
|
catch (...) {} // ignoring bad saved game files for now
|
||||||
|
|
||||||
std::istringstream stream (slotPath.filename().string());
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
if ((stream >> index) && index>=mNext)
|
|
||||||
mNext = index+1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort (mSlots.begin(), mSlots.end());
|
std::sort (mSlots.begin(), mSlots.end());
|
||||||
|
|
|
@ -26,7 +26,6 @@ namespace MWState
|
||||||
|
|
||||||
boost::filesystem::path mPath;
|
boost::filesystem::path mPath;
|
||||||
std::vector<Slot> mSlots;
|
std::vector<Slot> mSlots;
|
||||||
int mNext;
|
|
||||||
|
|
||||||
void addSlot (const boost::filesystem::path& path, const std::string& game);
|
void addSlot (const boost::filesystem::path& path, const std::string& game);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
MWState::CharacterManager::CharacterManager (const boost::filesystem::path& saves,
|
MWState::CharacterManager::CharacterManager (const boost::filesystem::path& saves,
|
||||||
const std::string& game)
|
const std::string& game)
|
||||||
: mPath (saves), mNext (0), mCurrent (0), mGame (game)
|
: mPath (saves), mCurrent (0), mGame (game)
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::is_directory (mPath))
|
if (!boost::filesystem::is_directory (mPath))
|
||||||
{
|
{
|
||||||
|
@ -28,21 +28,14 @@ MWState::CharacterManager::CharacterManager (const boost::filesystem::path& save
|
||||||
if (character.begin()!=character.end())
|
if (character.begin()!=character.end())
|
||||||
mCharacters.push_back (character);
|
mCharacters.push_back (character);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istringstream stream (characterDir.filename().string());
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
if ((stream >> index) && index>=mNext)
|
|
||||||
mNext = index+1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MWState::Character *MWState::CharacterManager::getCurrentCharacter (bool create)
|
MWState::Character *MWState::CharacterManager::getCurrentCharacter (bool create, const std::string& name)
|
||||||
{
|
{
|
||||||
if (!mCurrent && create)
|
if (!mCurrent && create)
|
||||||
createCharacter();
|
createCharacter(name);
|
||||||
|
|
||||||
return mCurrent;
|
return mCurrent;
|
||||||
}
|
}
|
||||||
|
@ -63,13 +56,31 @@ void MWState::CharacterManager::deleteSlot(const MWState::Character *character,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWState::CharacterManager::createCharacter()
|
void MWState::CharacterManager::createCharacter(const std::string& name)
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
stream << mNext++;
|
|
||||||
|
// The character name is user-supplied, so we need to escape the path
|
||||||
|
for (std::string::const_iterator it = name.begin(); it != name.end(); ++it)
|
||||||
|
{
|
||||||
|
if (std::isalnum(*it)) // Ignores multibyte characters and non alphanumeric characters
|
||||||
|
stream << *it;
|
||||||
|
else
|
||||||
|
stream << "_";
|
||||||
|
}
|
||||||
|
|
||||||
boost::filesystem::path path = mPath / stream.str();
|
boost::filesystem::path path = mPath / stream.str();
|
||||||
|
|
||||||
|
// Append an index if necessary to ensure a unique directory
|
||||||
|
int i=0;
|
||||||
|
while (boost::filesystem::exists(path))
|
||||||
|
{
|
||||||
|
std::ostringstream test;
|
||||||
|
test << stream.str();
|
||||||
|
test << " - " << ++i;
|
||||||
|
path = mPath / test.str();
|
||||||
|
}
|
||||||
|
|
||||||
mCharacters.push_back (Character (path, mGame));
|
mCharacters.push_back (Character (path, mGame));
|
||||||
|
|
||||||
mCurrent = &mCharacters.back();
|
mCurrent = &mCharacters.back();
|
||||||
|
|
|
@ -10,7 +10,6 @@ namespace MWState
|
||||||
class CharacterManager
|
class CharacterManager
|
||||||
{
|
{
|
||||||
boost::filesystem::path mPath;
|
boost::filesystem::path mPath;
|
||||||
int mNext;
|
|
||||||
|
|
||||||
// Uses std::list, so that mCurrent stays valid when characters are deleted
|
// Uses std::list, so that mCurrent stays valid when characters are deleted
|
||||||
std::list<Character> mCharacters;
|
std::list<Character> mCharacters;
|
||||||
|
@ -32,13 +31,15 @@ namespace MWState
|
||||||
|
|
||||||
CharacterManager (const boost::filesystem::path& saves, const std::string& game);
|
CharacterManager (const boost::filesystem::path& saves, const std::string& game);
|
||||||
|
|
||||||
Character *getCurrentCharacter (bool create = true);
|
Character *getCurrentCharacter (bool create, const std::string& name);
|
||||||
///< \param create Create a new character, if there is no current character.
|
///< \param create Create a new character, if there is no current character.
|
||||||
|
/// \param name The character name to use in case a new character is created.
|
||||||
|
|
||||||
void deleteSlot(const MWState::Character *character, const MWState::Slot *slot);
|
void deleteSlot(const MWState::Character *character, const MWState::Slot *slot);
|
||||||
|
|
||||||
void createCharacter();
|
void createCharacter(const std::string& name);
|
||||||
///< Create new character within saved game management
|
///< Create new character within saved game management
|
||||||
|
/// \param name Name for the character (does not need to be unique)
|
||||||
|
|
||||||
void setCurrentCharacter (const Character *character);
|
void setCurrentCharacter (const Character *character);
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,6 @@ void MWState::StateManager::newGame (bool bypass)
|
||||||
void MWState::StateManager::endGame()
|
void MWState::StateManager::endGame()
|
||||||
{
|
{
|
||||||
mState = State_Ended;
|
mState = State_Ended;
|
||||||
MWBase::Environment::get().getWorld()->useDeathCamera();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWState::StateManager::saveGame (const std::string& description, const Slot *slot)
|
void MWState::StateManager::saveGame (const std::string& description, const Slot *slot)
|
||||||
|
@ -185,9 +184,9 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
|
||||||
encoded->read(&profile.mScreenshot[0], encoded->size());
|
encoded->read(&profile.mScreenshot[0], encoded->size());
|
||||||
|
|
||||||
if (!slot)
|
if (!slot)
|
||||||
slot = mCharacterManager.getCurrentCharacter()->createSlot (profile);
|
slot = getCurrentCharacter()->createSlot (profile);
|
||||||
else
|
else
|
||||||
slot = mCharacterManager.getCurrentCharacter()->updateSlot (slot, profile);
|
slot = getCurrentCharacter()->updateSlot (slot, profile);
|
||||||
|
|
||||||
boost::filesystem::ofstream stream (slot->mPath, std::ios::binary);
|
boost::filesystem::ofstream stream (slot->mPath, std::ios::binary);
|
||||||
|
|
||||||
|
@ -234,6 +233,9 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
|
||||||
|
|
||||||
writer.close();
|
writer.close();
|
||||||
|
|
||||||
|
if (stream.fail())
|
||||||
|
throw std::runtime_error("Write operation failed");
|
||||||
|
|
||||||
Settings::Manager::setString ("character", "Saves",
|
Settings::Manager::setString ("character", "Saves",
|
||||||
slot->mPath.parent_path().filename().string());
|
slot->mPath.parent_path().filename().string());
|
||||||
}
|
}
|
||||||
|
@ -247,6 +249,10 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
|
||||||
std::vector<std::string> buttons;
|
std::vector<std::string> buttons;
|
||||||
buttons.push_back("#{sOk}");
|
buttons.push_back("#{sOk}");
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox(error.str(), buttons);
|
MWBase::Environment::get().getWindowManager()->messageBox(error.str(), buttons);
|
||||||
|
|
||||||
|
// If no file was written, clean up the slot
|
||||||
|
if (slot && !boost::filesystem::exists(slot->mPath))
|
||||||
|
getCurrentCharacter()->deleteSlot(slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,7 +419,10 @@ void MWState::StateManager::deleteGame(const MWState::Character *character, cons
|
||||||
|
|
||||||
MWState::Character *MWState::StateManager::getCurrentCharacter (bool create)
|
MWState::Character *MWState::StateManager::getCurrentCharacter (bool create)
|
||||||
{
|
{
|
||||||
return mCharacterManager.getCurrentCharacter (create);
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
|
std::string name = player.getClass().getName(player);
|
||||||
|
|
||||||
|
return mCharacterManager.getCurrentCharacter (create, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
MWState::StateManager::CharacterIterator MWState::StateManager::characterBegin()
|
MWState::StateManager::CharacterIterator MWState::StateManager::characterBegin()
|
||||||
|
@ -434,11 +443,12 @@ void MWState::StateManager::update (float duration)
|
||||||
if (mAskLoadRecent)
|
if (mAskLoadRecent)
|
||||||
{
|
{
|
||||||
int iButton = MWBase::Environment::get().getWindowManager()->readPressedButton();
|
int iButton = MWBase::Environment::get().getWindowManager()->readPressedButton();
|
||||||
if(iButton==0)
|
MWState::Character *curCharacter = getCurrentCharacter(false);
|
||||||
|
if(iButton==0 && curCharacter)
|
||||||
{
|
{
|
||||||
mAskLoadRecent = false;
|
mAskLoadRecent = false;
|
||||||
//Load last saved game for current character
|
//Load last saved game for current character
|
||||||
MWState::Character *curCharacter = getCurrentCharacter();
|
|
||||||
MWState::Slot lastSave = *curCharacter->begin();
|
MWState::Slot lastSave = *curCharacter->begin();
|
||||||
loadGame(curCharacter, &lastSave);
|
loadGame(curCharacter, &lastSave);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,8 @@ namespace MWWorld
|
||||||
|
|
||||||
// slots that this item can be equipped in
|
// slots that this item can be equipped in
|
||||||
std::pair<std::vector<int>, bool> slots_ = getTarget().getClass().getEquipmentSlots(getTarget());
|
std::pair<std::vector<int>, bool> slots_ = getTarget().getClass().getEquipmentSlots(getTarget());
|
||||||
|
if (slots_.first.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
// retrieve ContainerStoreIterator to the item
|
// retrieve ContainerStoreIterator to the item
|
||||||
MWWorld::ContainerStoreIterator it = invStore.begin();
|
MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||||
|
@ -55,20 +57,13 @@ namespace MWWorld
|
||||||
assert(it != invStore.end());
|
assert(it != invStore.end());
|
||||||
|
|
||||||
// equip the item in the first free slot
|
// equip the item in the first free slot
|
||||||
for (std::vector<int>::const_iterator slot=slots_.first.begin();
|
std::vector<int>::const_iterator slot=slots_.first.begin();
|
||||||
slot!=slots_.first.end(); ++slot)
|
for (;slot!=slots_.first.end(); ++slot)
|
||||||
{
|
{
|
||||||
// if the item is equipped already, nothing to do
|
// if the item is equipped already, nothing to do
|
||||||
if (invStore.getSlot(*slot) == it)
|
if (invStore.getSlot(*slot) == it)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// if all slots are occupied, replace the last slot
|
|
||||||
if (slot == --slots_.first.end())
|
|
||||||
{
|
|
||||||
invStore.equip(*slot, it, actor);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (invStore.getSlot(*slot) == invStore.end())
|
if (invStore.getSlot(*slot) == invStore.end())
|
||||||
{
|
{
|
||||||
// slot is not occupied
|
// slot is not occupied
|
||||||
|
@ -76,5 +71,19 @@ namespace MWWorld
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// all slots are occupied -> cycle
|
||||||
|
// move all slots one towards begin(), then equip the item in the slot that is now free
|
||||||
|
if (slot == slots_.first.end())
|
||||||
|
{
|
||||||
|
for (slot=slots_.first.begin();slot!=slots_.first.end(); ++slot)
|
||||||
|
{
|
||||||
|
invStore.unequipSlot(*slot, actor);
|
||||||
|
if (slot+1 != slots_.first.end())
|
||||||
|
invStore.equip(*slot, invStore.getSlot(*(slot+1)), actor);
|
||||||
|
else
|
||||||
|
invStore.equip(*slot, it, actor);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,13 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener)
|
||||||
}
|
}
|
||||||
it->second->load(esm, id);
|
it->second->load(esm, id);
|
||||||
|
|
||||||
|
// DELE can also occur after the usual subrecords
|
||||||
|
if (esm.isNextSub("DELE")) {
|
||||||
|
esm.skipRecord();
|
||||||
|
it->second->eraseStatic(id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (n.val==ESM::REC_DIAL) {
|
if (n.val==ESM::REC_DIAL) {
|
||||||
dialogue = const_cast<ESM::Dialogue*>(mDialogs.find(id));
|
dialogue = const_cast<ESM::Dialogue*>(mDialogs.find(id));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -193,6 +193,11 @@ namespace MWWorld
|
||||||
const ESM::Position &refpos = ptr.getRefData().getPosition();
|
const ESM::Position &refpos = ptr.getRefData().getPosition();
|
||||||
Ogre::Vector3 position(refpos.pos);
|
Ogre::Vector3 position(refpos.pos);
|
||||||
|
|
||||||
|
// Early-out for totally static creatures
|
||||||
|
// (Not sure if gravity should still apply?)
|
||||||
|
if (!ptr.getClass().canWalk(ptr) && !isFlying && !ptr.getClass().canSwim(ptr))
|
||||||
|
return position;
|
||||||
|
|
||||||
/* Anything to collide with? */
|
/* Anything to collide with? */
|
||||||
OEngine::Physic::PhysicActor *physicActor = engine->getCharacter(ptr.getRefData().getHandle());
|
OEngine::Physic::PhysicActor *physicActor = engine->getCharacter(ptr.getRefData().getHandle());
|
||||||
if(!physicActor || !physicActor->getCollisionMode())
|
if(!physicActor || !physicActor->getCollisionMode())
|
||||||
|
@ -299,6 +304,8 @@ namespace MWWorld
|
||||||
continue; // velocity updated, calculate nextpos again
|
continue; // velocity updated, calculate nextpos again
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!newPosition.positionCloses(nextpos, 0.00000001))
|
||||||
|
{
|
||||||
// trace to where character would go if there were no obstructions
|
// trace to where character would go if there were no obstructions
|
||||||
tracer.doTrace(colobj, newPosition, nextpos, engine);
|
tracer.doTrace(colobj, newPosition, nextpos, engine);
|
||||||
|
|
||||||
|
@ -309,6 +316,20 @@ namespace MWWorld
|
||||||
remainingTime *= (1.0f-tracer.mFraction); // FIXME: remainingTime is no longer used so don't set it?
|
remainingTime *= (1.0f-tracer.mFraction); // FIXME: remainingTime is no longer used so don't set it?
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The current position and next position are nearly the same, so just exit.
|
||||||
|
// Note: Bullet can trigger an assert in debug modes if the positions
|
||||||
|
// are the same, since that causes it to attempt to normalize a zero
|
||||||
|
// length vector (which can also happen with nearly identical vectors, since
|
||||||
|
// precision can be lost due to any math Bullet does internally). Since we
|
||||||
|
// aren't performing any collision detection, we want to reject the next
|
||||||
|
// position, so that we don't slowly move inside another object.
|
||||||
|
remainingTime *= (1.0f-tracer.mFraction); // FIXME: remainingTime is no longer used so don't set it?
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Ogre::Vector3 oldPosition = newPosition;
|
Ogre::Vector3 oldPosition = newPosition;
|
||||||
// We hit something. Try to step up onto it. (NOTE: stepMove does not allow stepping over)
|
// We hit something. Try to step up onto it. (NOTE: stepMove does not allow stepping over)
|
||||||
|
@ -492,7 +513,7 @@ namespace MWWorld
|
||||||
return std::make_pair(true, ray.getPoint(len * test.second));
|
return std::make_pair(true, ray.getPoint(len * test.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY, Ogre::Vector3* normal)
|
std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY, Ogre::Vector3* normal, std::string* hit)
|
||||||
{
|
{
|
||||||
Ogre::Ray ray = mRender.getCamera()->getCameraToViewportRay(
|
Ogre::Ray ray = mRender.getCamera()->getCameraToViewportRay(
|
||||||
mouseX,
|
mouseX,
|
||||||
|
@ -510,6 +531,8 @@ namespace MWWorld
|
||||||
return std::make_pair(false, Ogre::Vector3());
|
return std::make_pair(false, Ogre::Vector3());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (hit != NULL)
|
||||||
|
*hit = result.first;
|
||||||
return std::make_pair(true, ray.getPoint(200*result.second)); /// \todo make this distance (ray length) configurable
|
return std::make_pair(true, ray.getPoint(200*result.second)); /// \todo make this distance (ray length) configurable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,9 +70,10 @@ namespace MWWorld
|
||||||
std::pair<bool, Ogre::Vector3>
|
std::pair<bool, Ogre::Vector3>
|
||||||
castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len);
|
castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len);
|
||||||
|
|
||||||
std::pair<bool, Ogre::Vector3> castRay(float mouseX, float mouseY, Ogre::Vector3* normal = NULL);
|
std::pair<bool, Ogre::Vector3> castRay(float mouseX, float mouseY, Ogre::Vector3* normal = NULL, std::string* hit = NULL);
|
||||||
///< cast ray from the mouse, return true if it hit something and the first result
|
///< cast ray from the mouse, return true if it hit something and the first result
|
||||||
/// @param normal if non-NULL, the hit normal will be written there (if there is a hit)
|
/// @param normal if non-NULL, the hit normal will be written there (if there is a hit)
|
||||||
|
/// @param hit if non-NULL, the string handle of the hit object will be written there (if there is a hit)
|
||||||
|
|
||||||
OEngine::Physic::PhysicEngine* getEngine();
|
OEngine::Physic::PhysicEngine* getEngine();
|
||||||
|
|
||||||
|
|
|
@ -432,7 +432,7 @@ namespace MWWorld
|
||||||
mRendering->getCamera()->toggleVanityMode(false);
|
mRendering->getCamera()->toggleVanityMode(false);
|
||||||
}
|
}
|
||||||
if(mRendering->getCamera()->isFirstPerson())
|
if(mRendering->getCamera()->isFirstPerson())
|
||||||
togglePOV();
|
mRendering->getCamera()->toggleViewMode(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::Player& World::getPlayer()
|
MWWorld::Player& World::getPlayer()
|
||||||
|
@ -1624,12 +1624,20 @@ namespace MWWorld
|
||||||
bool World::canPlaceObject(float cursorX, float cursorY)
|
bool World::canPlaceObject(float cursorX, float cursorY)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 normal(0,0,0);
|
Ogre::Vector3 normal(0,0,0);
|
||||||
std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY, &normal);
|
std::string handle;
|
||||||
|
std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY, &normal, &handle);
|
||||||
|
|
||||||
if (result.first)
|
if (result.first)
|
||||||
{
|
{
|
||||||
// check if the wanted position is on a flat surface, and not e.g. against a vertical wall
|
// check if the wanted position is on a flat surface, and not e.g. against a vertical wall
|
||||||
return (normal.angleBetween(Ogre::Vector3(0.f,0.f,1.f)).valueDegrees() < 30);
|
if (normal.angleBetween(Ogre::Vector3(0.f,0.f,1.f)).valueDegrees() >= 30)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MWWorld::Ptr hitObject = searchPtrViaHandle(handle);
|
||||||
|
if (!hitObject.isEmpty() && hitObject.getClass().isActor())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@ -1695,13 +1703,14 @@ namespace MWWorld
|
||||||
|
|
||||||
Ogre::Vector3 orig =
|
Ogre::Vector3 orig =
|
||||||
Ogre::Vector3(pos.pos);
|
Ogre::Vector3(pos.pos);
|
||||||
|
orig.z += 20;
|
||||||
Ogre::Vector3 dir = Ogre::Vector3(0, 0, -1);
|
Ogre::Vector3 dir = Ogre::Vector3(0, 0, -1);
|
||||||
|
|
||||||
float len = (pos.pos[2] >= 0) ? pos.pos[2] : -pos.pos[2];
|
float len = 100.0;
|
||||||
len += 100.0;
|
|
||||||
|
|
||||||
std::pair<bool, Ogre::Vector3> hit =
|
std::pair<bool, Ogre::Vector3> hit =
|
||||||
mPhysics->castRay(orig, dir, len);
|
mPhysics->castRay(orig, dir, len);
|
||||||
|
if (hit.first)
|
||||||
pos.pos[2] = hit.second.z;
|
pos.pos[2] = hit.second.z;
|
||||||
|
|
||||||
// copy the object and set its count
|
// copy the object and set its count
|
||||||
|
@ -1851,7 +1860,12 @@ namespace MWWorld
|
||||||
if (!mPlayer)
|
if (!mPlayer)
|
||||||
mPlayer = new MWWorld::Player(player, *this);
|
mPlayer = new MWWorld::Player(player, *this);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
// Remove the old CharacterController
|
||||||
|
MWBase::Environment::get().getMechanicsManager()->remove(getPlayerPtr());
|
||||||
|
|
||||||
mPlayer->set(player);
|
mPlayer->set(player);
|
||||||
|
}
|
||||||
|
|
||||||
Ptr ptr = mPlayer->getPlayer();
|
Ptr ptr = mPlayer->getPlayer();
|
||||||
mRendering->setupPlayer(ptr);
|
mRendering->setupPlayer(ptr);
|
||||||
|
|
|
@ -181,6 +181,7 @@ namespace Compiler
|
||||||
opcodeSameFactionExplicit);
|
opcodeSameFactionExplicit);
|
||||||
extensions.registerInstruction("modfactionreaction", "ccl", opcodeModFactionReaction);
|
extensions.registerInstruction("modfactionreaction", "ccl", opcodeModFactionReaction);
|
||||||
extensions.registerFunction("getfactionreaction", 'l', "ccl", opcodeGetFactionReaction);
|
extensions.registerFunction("getfactionreaction", 'l', "ccl", opcodeGetFactionReaction);
|
||||||
|
extensions.registerInstruction("clearinfoactor", "", opcodeClearInfoActor, opcodeClearInfoActorExplicit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,6 +216,7 @@ namespace Compiler
|
||||||
|
|
||||||
extensions.registerInstruction ("showmap", "S", opcodeShowMap);
|
extensions.registerInstruction ("showmap", "S", opcodeShowMap);
|
||||||
extensions.registerInstruction ("fillmap", "", opcodeFillMap);
|
extensions.registerInstruction ("fillmap", "", opcodeFillMap);
|
||||||
|
extensions.registerInstruction ("menutest", "/l", opcodeMenuTest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,6 +154,8 @@ namespace Compiler
|
||||||
const int opcodeSameFactionExplicit = 0x20001b6;
|
const int opcodeSameFactionExplicit = 0x20001b6;
|
||||||
const int opcodeModFactionReaction = 0x2000242;
|
const int opcodeModFactionReaction = 0x2000242;
|
||||||
const int opcodeGetFactionReaction = 0x2000243;
|
const int opcodeGetFactionReaction = 0x2000243;
|
||||||
|
const int opcodeClearInfoActor = 0x2000245;
|
||||||
|
const int opcodeClearInfoActorExplicit = 0x2000246;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Gui
|
namespace Gui
|
||||||
|
@ -175,6 +177,7 @@ namespace Compiler
|
||||||
const int opcodeToggleFullHelp = 0x2000151;
|
const int opcodeToggleFullHelp = 0x2000151;
|
||||||
const int opcodeShowMap = 0x20001a0;
|
const int opcodeShowMap = 0x20001a0;
|
||||||
const int opcodeFillMap = 0x20001a1;
|
const int opcodeFillMap = 0x20001a1;
|
||||||
|
const int opcodeMenuTest = 0x2002c;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Misc
|
namespace Misc
|
||||||
|
|
|
@ -239,7 +239,7 @@ bool ContentSelectorModel::ContentModel::setData(const QModelIndex &index, const
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
EsmFile *file = item(index.row());
|
EsmFile *file = item(index.row());
|
||||||
QString fileName = file->filePath();
|
QString fileName = file->fileName();
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
switch(role)
|
switch(role)
|
||||||
|
@ -266,7 +266,7 @@ bool ContentSelectorModel::ContentModel::setData(const QModelIndex &index, const
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
success = setCheckState(fileName, value.toBool());
|
success = setCheckState(file->filePath(), value.toBool());
|
||||||
emit dataChanged(index, index);
|
emit dataChanged(index, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -277,19 +277,19 @@ bool ContentSelectorModel::ContentModel::setData(const QModelIndex &index, const
|
||||||
int checkValue = value.toInt();
|
int checkValue = value.toInt();
|
||||||
bool success = false;
|
bool success = false;
|
||||||
bool setState = false;
|
bool setState = false;
|
||||||
if ((checkValue==Qt::Checked) && !isChecked(fileName))
|
if ((checkValue==Qt::Checked) && !isChecked(file->filePath()))
|
||||||
{
|
{
|
||||||
setState = true;
|
setState = true;
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
else if ((checkValue == Qt::Checked) && isChecked (fileName))
|
else if ((checkValue == Qt::Checked) && isChecked (file->filePath()))
|
||||||
setState = true;
|
setState = true;
|
||||||
else if (checkValue == Qt::Unchecked)
|
else if (checkValue == Qt::Unchecked)
|
||||||
setState = true;
|
setState = true;
|
||||||
|
|
||||||
if (setState)
|
if (setState)
|
||||||
{
|
{
|
||||||
setCheckState(fileName, success);
|
setCheckState(file->filePath(), success);
|
||||||
emit dataChanged(index, index);
|
emit dataChanged(index, index);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -517,10 +517,10 @@ void ContentSelectorModel::ContentModel::sortFiles()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContentSelectorModel::ContentModel::isChecked(const QString& name) const
|
bool ContentSelectorModel::ContentModel::isChecked(const QString& filepath) const
|
||||||
{
|
{
|
||||||
if (mCheckStates.contains(name))
|
if (mCheckStates.contains(filepath))
|
||||||
return (mCheckStates[name] == Qt::Checked);
|
return (mCheckStates[filepath] == Qt::Checked);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -543,12 +543,12 @@ void ContentSelectorModel::ContentModel::refreshModel()
|
||||||
emit dataChanged (index(0,0), index(rowCount()-1,0));
|
emit dataChanged (index(0,0), index(rowCount()-1,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool checkState)
|
bool ContentSelectorModel::ContentModel::setCheckState(const QString &filepath, bool checkState)
|
||||||
{
|
{
|
||||||
if (name.isEmpty())
|
if (filepath.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const EsmFile *file = item(name);
|
const EsmFile *file = item(filepath);
|
||||||
|
|
||||||
if (!file)
|
if (!file)
|
||||||
return false;
|
return false;
|
||||||
|
@ -558,8 +558,8 @@ bool ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool
|
||||||
if (checkState)
|
if (checkState)
|
||||||
state = Qt::Checked;
|
state = Qt::Checked;
|
||||||
|
|
||||||
mCheckStates[name] = state;
|
mCheckStates[filepath] = state;
|
||||||
emit dataChanged(indexFromItem(item(name)), indexFromItem(item(name)));
|
emit dataChanged(indexFromItem(item(filepath)), indexFromItem(item(filepath)));
|
||||||
|
|
||||||
if (file->isGameFile())
|
if (file->isGameFile())
|
||||||
refreshModel();
|
refreshModel();
|
||||||
|
@ -586,7 +586,10 @@ bool ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool
|
||||||
{
|
{
|
||||||
foreach (const EsmFile *downstreamFile, mFiles)
|
foreach (const EsmFile *downstreamFile, mFiles)
|
||||||
{
|
{
|
||||||
if (downstreamFile->gameFiles().contains(name))
|
QFileInfo fileInfo(filepath);
|
||||||
|
QString filename = fileInfo.fileName();
|
||||||
|
|
||||||
|
if (downstreamFile->gameFiles().contains(filename))
|
||||||
{
|
{
|
||||||
if (mCheckStates.contains(downstreamFile->filePath()))
|
if (mCheckStates.contains(downstreamFile->filePath()))
|
||||||
mCheckStates[downstreamFile->filePath()] = Qt::Unchecked;
|
mCheckStates[downstreamFile->filePath()] = Qt::Unchecked;
|
||||||
|
|
|
@ -45,8 +45,8 @@ namespace ContentSelectorModel
|
||||||
const EsmFile *item(const QString &name) const;
|
const EsmFile *item(const QString &name) const;
|
||||||
|
|
||||||
bool isEnabled (QModelIndex index) const;
|
bool isEnabled (QModelIndex index) const;
|
||||||
bool isChecked(const QString &name) const;
|
bool isChecked(const QString &filepath) const;
|
||||||
bool setCheckState(const QString &name, bool isChecked);
|
bool setCheckState(const QString &filepath, bool isChecked);
|
||||||
void setCheckStates (const QStringList &fileList, bool isChecked);
|
void setCheckStates (const QStringList &fileList, bool isChecked);
|
||||||
ContentFileList checkedItems() const;
|
ContentFileList checkedItems() const;
|
||||||
void uncheckAll();
|
void uncheckAll();
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue