Merge remote-tracking branch 'upstream/master' into osx-ogre-19
|
@ -167,6 +167,7 @@ if(USE_SYSTEM_TINYXML)
|
|||
find_library(TINYXML_LIBRARIES tinyxml)
|
||||
find_path(TINYXML_INCLUDE_DIR tinyxml.h)
|
||||
message(STATUS "Found TinyXML: ${TINYXML_LIBRARIES} ${TINYXML_INCLUDE_DIR}")
|
||||
add_definitions (-DTIXML_USE_STL)
|
||||
if(TINYXML_LIBRARIES AND TINYXML_INCLUDE_DIR)
|
||||
include_directories(${TINYXML_INCLUDE_DIR})
|
||||
message(STATUS "Using system TinyXML library.")
|
||||
|
|
|
@ -77,6 +77,8 @@ namespace
|
|||
ini.insert(loc, setting + "=" + val + "\r\n");
|
||||
}
|
||||
|
||||
#define FIX(setting) add_setting(category, setting, get_setting(category, setting, inx), ini)
|
||||
|
||||
void bloodmoon_fix_ini(std::string& ini, const bfs::path inxPath)
|
||||
{
|
||||
std::string inx = read_to_string(inxPath);
|
||||
|
@ -88,95 +90,94 @@ namespace
|
|||
ini.erase(start, end-start);
|
||||
|
||||
std::string category;
|
||||
std::string setting;
|
||||
|
||||
category = "General";
|
||||
{
|
||||
setting = "Werewolf FOV"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
FIX("Werewolf FOV");
|
||||
}
|
||||
category = "Moons";
|
||||
{
|
||||
setting = "Script Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
FIX("Script Color");
|
||||
}
|
||||
category = "Weather";
|
||||
{
|
||||
setting = "Snow Ripples"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Ripple Radius"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Ripples Per Flake"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Ripple Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Ripple Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Gravity Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow High Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Low Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
FIX("Snow Ripples");
|
||||
FIX("Snow Ripple Radius");
|
||||
FIX("Snow Ripples Per Flake");
|
||||
FIX("Snow Ripple Scale");
|
||||
FIX("Snow Ripple Speed");
|
||||
FIX("Snow Gravity Scale");
|
||||
FIX("Snow High Kill");
|
||||
FIX("Snow Low Kill");
|
||||
}
|
||||
category = "Weather Blight";
|
||||
{
|
||||
setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
FIX("Ambient Loop Sound ID");
|
||||
}
|
||||
category = "Weather Snow";
|
||||
{
|
||||
setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Diameter"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Height Min"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Height Max"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Entrance Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Max Snowflakes"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
FIX("Sky Sunrise Color");
|
||||
FIX("Sky Day Color");
|
||||
FIX("Sky Sunset Color");
|
||||
FIX("Sky Night Color");
|
||||
FIX("Fog Sunrise Color");
|
||||
FIX("Fog Day Color");
|
||||
FIX("Fog Sunset Color");
|
||||
FIX("Fog Night Color");
|
||||
FIX("Ambient Sunrise Color");
|
||||
FIX("Ambient Day Color");
|
||||
FIX("Ambient Sunset Color");
|
||||
FIX("Ambient Night Color");
|
||||
FIX("Sun Sunrise Color");
|
||||
FIX("Sun Day Color");
|
||||
FIX("Sun Sunset Color");
|
||||
FIX("Sun Night Color");
|
||||
FIX("Sun Disc Sunset Color");
|
||||
FIX("Transition Delta");
|
||||
FIX("Land Fog Day Depth");
|
||||
FIX("Land Fog Night Depth");
|
||||
FIX("Clouds Maximum Percent");
|
||||
FIX("Wind Speed");
|
||||
FIX("Cloud Speed");
|
||||
FIX("Glare View");
|
||||
FIX("Cloud Texture");
|
||||
FIX("Ambient Loop Sound ID");
|
||||
FIX("Snow Threshold");
|
||||
FIX("Snow Diameter");
|
||||
FIX("Snow Height Min");
|
||||
FIX("Snow Height Max");
|
||||
FIX("Snow Entrance Speed");
|
||||
FIX("Max Snowflakes");
|
||||
}
|
||||
category = "Weather Blizzard";
|
||||
{
|
||||
setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Storm Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
FIX("Sky Sunrise Color");
|
||||
FIX("Sky Day Color");
|
||||
FIX("Sky Sunset Color");
|
||||
FIX("Sky Night Color");
|
||||
FIX("Fog Sunrise Color");
|
||||
FIX("Fog Day Color");
|
||||
FIX("Fog Sunset Color");
|
||||
FIX("Fog Night Color");
|
||||
FIX("Ambient Sunrise Color");
|
||||
FIX("Ambient Day Color");
|
||||
FIX("Ambient Sunset Color");
|
||||
FIX("Ambient Night Color");
|
||||
FIX("Sun Sunrise Color");
|
||||
FIX("Sun Day Color");
|
||||
FIX("Sun Sunset Color");
|
||||
FIX("Sun Night Color");
|
||||
FIX("Sun Disc Sunset Color");
|
||||
FIX("Transition Delta");
|
||||
FIX("Land Fog Day Depth");
|
||||
FIX("Land Fog Night Depth");
|
||||
FIX("Clouds Maximum Percent");
|
||||
FIX("Wind Speed");
|
||||
FIX("Cloud Speed");
|
||||
FIX("Glare View");
|
||||
FIX("Cloud Texture");
|
||||
FIX("Ambient Loop Sound ID");
|
||||
FIX("Storm Threshold");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,6 +269,27 @@ namespace
|
|||
strptime(time, "%d %B %Y", &tms);
|
||||
return mktime(&tms);
|
||||
}
|
||||
|
||||
// Some cds have cab files which have the Data Files subfolders outside the Data Files folder
|
||||
void install_dfiles_outside(const bfs::path& from, const bfs::path& dFiles)
|
||||
{
|
||||
bfs::path fonts = findFile(from, "fonts", false);
|
||||
if(fonts.string() != "")
|
||||
installToPath(fonts, dFiles / "Fonts");
|
||||
|
||||
bfs::path music = findFile(from, "music", false);
|
||||
if(music.string() != "")
|
||||
installToPath(music, dFiles / "Music");
|
||||
|
||||
bfs::path sound = findFile(from, "sound", false);
|
||||
if(sound.string() != "")
|
||||
installToPath(sound, dFiles / "Sound");
|
||||
|
||||
bfs::path splash = findFile(from, "splash", false);
|
||||
if(splash.string() != "")
|
||||
installToPath(splash, dFiles / "Splash");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool UnshieldThread::SetMorrowindPath(const std::string& path)
|
||||
|
@ -365,6 +387,8 @@ bool UnshieldThread::extract()
|
|||
|
||||
installToPath(dFilesDir, outputDataFilesDir);
|
||||
|
||||
install_dfiles_outside(mwExtractPath, outputDataFilesDir);
|
||||
|
||||
// Videos are often kept uncompressed on the cd
|
||||
bfs::path videosPath = findFile(mMorrowindPath.parent_path(), "video", false);
|
||||
if(videosPath.string() != "")
|
||||
|
@ -399,6 +423,8 @@ bool UnshieldThread::extract()
|
|||
|
||||
installToPath(dFilesDir, outputDataFilesDir);
|
||||
|
||||
install_dfiles_outside(tbExtractPath, outputDataFilesDir);
|
||||
|
||||
// Mt GOTY CD has Sounds in a seperate folder from the rest of the data files
|
||||
bfs::path soundsPath = findFile(tbExtractPath, "sounds", false);
|
||||
if(soundsPath.string() != "")
|
||||
|
@ -427,6 +453,8 @@ bool UnshieldThread::extract()
|
|||
|
||||
installToPath(dFilesDir, outputDataFilesDir);
|
||||
|
||||
install_dfiles_outside(bmExtractPath, outputDataFilesDir);
|
||||
|
||||
// My GOTY CD contains a folder within cab files called Tribunal patch,
|
||||
// which contains Tribunal.esm
|
||||
bfs::path tbPatchPath = findFile(bmExtractPath, "tribunal.esm");
|
||||
|
|
|
@ -18,12 +18,12 @@ opencs_hdrs_noqt (model/doc
|
|||
|
||||
|
||||
opencs_units (model/world
|
||||
idtable idtableproxymodel regionmap
|
||||
idtable idtableproxymodel regionmap data
|
||||
)
|
||||
|
||||
|
||||
opencs_units_noqt (model/world
|
||||
universalid data record commands columnbase scriptcontext cell refidcollection
|
||||
universalid record commands columnbase scriptcontext cell refidcollection
|
||||
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns
|
||||
)
|
||||
|
||||
|
@ -59,12 +59,13 @@ opencs_hdrs_noqt (view/doc
|
|||
|
||||
opencs_units (view/world
|
||||
table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator
|
||||
cellcreator referenceablecreator referencecreator
|
||||
cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool
|
||||
scenetoolmode
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/world
|
||||
dialoguesubview subviews
|
||||
enumdelegate vartypedelegate recordstatusdelegate refidtypedelegate datadisplaydelegate
|
||||
enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
|
||||
scripthighlighter idvalidator
|
||||
)
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row,
|
|||
{
|
||||
string = data.toString();
|
||||
}
|
||||
else if (data.type()==QVariant::Int || data.type()==QVariant::UInt ||
|
||||
else if ((data.type()==QVariant::Int || data.type()==QVariant::UInt) &&
|
||||
CSMWorld::Columns::hasEnums (static_cast<CSMWorld::Columns::ColumnId> (mColumnId)))
|
||||
{
|
||||
int value = data.toInt();
|
||||
|
@ -47,8 +47,10 @@ bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row,
|
|||
}
|
||||
else if (data.type()==QVariant::Bool)
|
||||
{
|
||||
string = data.toBool() ? "true" : " false";
|
||||
string = data.toBool() ? "true" : "false";
|
||||
}
|
||||
else if (mText.empty() && !data.isValid())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ bool CSMFilter::ValueNode::test (const CSMWorld::IdTable& table, int row,
|
|||
const std::map<int, int>::const_iterator iter = columns.find (mColumnId);
|
||||
|
||||
if (iter==columns.end())
|
||||
throw std::logic_error ("invalid column in test value test");
|
||||
throw std::logic_error ("invalid column in value node test");
|
||||
|
||||
if (iter->second==-1)
|
||||
return true;
|
||||
|
@ -27,7 +27,7 @@ bool CSMFilter::ValueNode::test (const CSMWorld::IdTable& table, int row,
|
|||
QVariant data = table.data (index);
|
||||
|
||||
if (data.type()!=QVariant::Double && data.type()!=QVariant::Bool && data.type()!=QVariant::Int &&
|
||||
data.type()!=QVariant::UInt)
|
||||
data.type()!=QVariant::UInt && data.type()!=static_cast<QVariant::Type> (QMetaType::Float))
|
||||
return false;
|
||||
|
||||
double value = data.toDouble();
|
||||
|
@ -68,7 +68,7 @@ std::string CSMFilter::ValueNode::toString (bool numericColumns) const
|
|||
<< CSMWorld::Columns::getName (static_cast<CSMWorld::Columns::ColumnId> (mColumnId))
|
||||
<< "\"";
|
||||
|
||||
stream << ", \"";
|
||||
stream << ", ";
|
||||
|
||||
if (mLower==mUpper && mLowerType!=Type_Infinite && mUpperType!=Type_Infinite)
|
||||
stream << mLower;
|
||||
|
|
|
@ -19,7 +19,12 @@ int CSMTools::BirthsignCheckStage::setup()
|
|||
|
||||
void CSMTools::BirthsignCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::BirthSign& birthsign = mBirthsigns.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::BirthSign>& record = mBirthsigns.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::BirthSign& birthsign = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Birthsign, birthsign.mId);
|
||||
|
||||
|
|
|
@ -20,7 +20,12 @@ int CSMTools::ClassCheckStage::setup()
|
|||
|
||||
void CSMTools::ClassCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Class& class_= mClasses.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::Class>& record = mClasses.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::Class& class_ = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Class, class_.mId);
|
||||
|
||||
|
|
|
@ -20,7 +20,12 @@ int CSMTools::FactionCheckStage::setup()
|
|||
|
||||
void CSMTools::FactionCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Faction& faction = mFactions.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::Faction>& record = mFactions.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::Faction& faction = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Faction, faction.mId);
|
||||
|
||||
|
|
|
@ -9,7 +9,12 @@
|
|||
|
||||
void CSMTools::RaceCheckStage::performPerRecord (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Race& race = mRaces.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::Race>& record = mRaces.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::Race& race = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Race, race.mId);
|
||||
|
||||
|
|
|
@ -19,7 +19,12 @@ int CSMTools::RegionCheckStage::setup()
|
|||
|
||||
void CSMTools::RegionCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Region& region = mRegions.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::Region>& record = mRegions.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::Region& region = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Region, region.mId);
|
||||
|
||||
|
|
|
@ -18,7 +18,12 @@ int CSMTools::SkillCheckStage::setup()
|
|||
|
||||
void CSMTools::SkillCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Skill& skill = mSkills.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::Skill>& record = mSkills.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::Skill& skill = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Skill, skill.mId);
|
||||
|
||||
|
|
|
@ -18,7 +18,12 @@ int CSMTools::SoundCheckStage::setup()
|
|||
|
||||
void CSMTools::SoundCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Sound& sound = mSounds.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::Sound>& record = mSounds.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::Sound& sound = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Sound, sound.mId);
|
||||
|
||||
|
|
|
@ -19,7 +19,12 @@ int CSMTools::SpellCheckStage::setup()
|
|||
|
||||
void CSMTools::SpellCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Spell& spell = mSpells.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::Spell>& record = mSpells.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::Spell& spell = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Spell, spell.mId);
|
||||
|
||||
|
|
|
@ -107,6 +107,11 @@ namespace CSMWorld
|
|||
virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const;
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
|
||||
virtual std::vector<std::string> getIds (bool listDeleted = true) const;
|
||||
///< Return a sorted collection of all IDs
|
||||
///
|
||||
/// \param listDeleted include deleted record in the list
|
||||
|
||||
void addColumn (Column<ESXRecordT> *column);
|
||||
|
||||
void setRecord (int index, const Record<ESXRecordT>& record);
|
||||
|
@ -293,6 +298,21 @@ namespace CSMWorld
|
|||
return static_cast<int> (mRecords.size());
|
||||
}
|
||||
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
std::vector<std::string> Collection<ESXRecordT, IdAccessorT>::getIds (bool listDeleted) const
|
||||
{
|
||||
std::vector<std::string> ids;
|
||||
|
||||
for (typename std::map<std::string, int>::const_iterator iter = mIndex.begin();
|
||||
iter!=mIndex.end(); ++iter)
|
||||
{
|
||||
if (listDeleted || !mRecords[iter->second].isDeleted())
|
||||
ids.push_back (IdAccessorT().getId (mRecords[iter->second].get()));
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
const Record<ESXRecordT>& Collection<ESXRecordT, IdAccessorT>::getRecord (const std::string& id) const
|
||||
{
|
||||
|
|
|
@ -78,8 +78,12 @@ namespace CSMWorld
|
|||
|
||||
virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const = 0;
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
};
|
||||
|
||||
virtual std::vector<std::string> getIds (bool listDeleted = true) const = 0;
|
||||
///< Return a sorted collection of all IDs
|
||||
///
|
||||
/// \param listDeleted include deleted record in the list
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1216,6 +1216,74 @@ namespace CSMWorld
|
|||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct PosColumn : public Column<ESXRecordT>
|
||||
{
|
||||
ESM::Position ESXRecordT::* mPosition;
|
||||
int mIndex;
|
||||
|
||||
PosColumn (ESM::Position ESXRecordT::* position, int index, bool door)
|
||||
: Column<ESXRecordT> (
|
||||
(door ? Columns::ColumnId_DoorPositionXPos : Columns::ColumnId_PositionXPos)+index,
|
||||
ColumnBase::Display_Float), mPosition (position), mIndex (index) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
const ESM::Position& position = record.get().*mPosition;
|
||||
return position.pos[mIndex];
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
ESM::Position& position = record.get().*mPosition;
|
||||
|
||||
position.pos[mIndex] = data.toFloat();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct RotColumn : public Column<ESXRecordT>
|
||||
{
|
||||
ESM::Position ESXRecordT::* mPosition;
|
||||
int mIndex;
|
||||
|
||||
RotColumn (ESM::Position ESXRecordT::* position, int index, bool door)
|
||||
: Column<ESXRecordT> (
|
||||
(door ? Columns::ColumnId_DoorPositionXRot : Columns::ColumnId_PositionXRot)+index,
|
||||
ColumnBase::Display_Float), mPosition (position), mIndex (index) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
const ESM::Position& position = record.get().*mPosition;
|
||||
return position.rot[mIndex];
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
ESM::Position& position = record.get().*mPosition;
|
||||
|
||||
position.rot[mIndex] = data.toFloat();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace CSMWorld
|
|||
{ ColumnId_FactionIndex, "Faction Index" },
|
||||
{ ColumnId_Charges, "Charges" },
|
||||
{ ColumnId_Enchantment, "Enchantment" },
|
||||
{ ColumnId_Value, "Coin Value" },
|
||||
{ ColumnId_CoinValue, "Coin Value" },
|
||||
{ ColumnId_Teleport, "Teleport" },
|
||||
{ ColumnId_TeleportCell, "Teleport Cell" },
|
||||
{ ColumnId_LockLevel, "Lock Level" },
|
||||
|
@ -147,6 +147,18 @@ namespace CSMWorld
|
|||
{ ColumnId_Magical, "Magical" },
|
||||
{ ColumnId_Silver, "Silver" },
|
||||
{ ColumnId_Filter, "Filter" },
|
||||
{ ColumnId_PositionXPos, "Pos X" },
|
||||
{ ColumnId_PositionYPos, "Pos Y" },
|
||||
{ ColumnId_PositionZPos, "Pos Z" },
|
||||
{ ColumnId_PositionXRot, "Rot X" },
|
||||
{ ColumnId_PositionYRot, "Rot Y" },
|
||||
{ ColumnId_PositionZRot, "Rot Z" },
|
||||
{ ColumnId_DoorPositionXPos, "Teleport Pos X" },
|
||||
{ ColumnId_DoorPositionYPos, "Teleport Pos Y" },
|
||||
{ ColumnId_DoorPositionZPos, "Teleport Pos Z" },
|
||||
{ ColumnId_DoorPositionXRot, "Teleport Rot X" },
|
||||
{ ColumnId_DoorPositionYRot, "Teleport Rot Y" },
|
||||
{ ColumnId_DoorPositionZRot, "Teleport Rot Z" },
|
||||
|
||||
{ ColumnId_UseValue1, "Use value 1" },
|
||||
{ ColumnId_UseValue2, "Use value 2" },
|
||||
|
|
|
@ -45,101 +45,113 @@ namespace CSMWorld
|
|||
ColumnId_Charges = 32,
|
||||
ColumnId_Enchantment = 33,
|
||||
ColumnId_CoinValue = 34,
|
||||
ColumnId_Teleport = 25,
|
||||
ColumnId_TeleportCell = 26,
|
||||
ColumnId_LockLevel = 27,
|
||||
ColumnId_Key = 28,
|
||||
ColumnId_Trap = 29,
|
||||
ColumnId_BeastRace = 30,
|
||||
ColumnId_AutoCalc = 31,
|
||||
ColumnId_StarterSpell = 32,
|
||||
ColumnId_AlwaysSucceeds = 33,
|
||||
ColumnId_SleepForbidden = 34,
|
||||
ColumnId_InteriorWater = 35,
|
||||
ColumnId_InteriorSky = 36,
|
||||
ColumnId_Model = 37,
|
||||
ColumnId_Script = 38,
|
||||
ColumnId_Icon = 39,
|
||||
ColumnId_Weight = 40,
|
||||
ColumnId_EnchantmentPoints = 31,
|
||||
ColumnId_Quality = 32,
|
||||
ColumnId_Ai = 33,
|
||||
ColumnId_AiHello = 34,
|
||||
ColumnId_AiFlee = 35,
|
||||
ColumnId_AiFight = 36,
|
||||
ColumnId_AiAlarm = 37,
|
||||
ColumnId_BuysWeapons = 38,
|
||||
ColumnId_BuysArmor = 39,
|
||||
ColumnId_BuysClothing = 40,
|
||||
ColumnId_BuysBooks = 41,
|
||||
ColumnId_BuysIngredients = 42,
|
||||
ColumnId_BuysLockpicks = 43,
|
||||
ColumnId_BuysProbes = 44,
|
||||
ColumnId_BuysLights = 45,
|
||||
ColumnId_BuysApparati = 46,
|
||||
ColumnId_BuysRepairItems = 47,
|
||||
ColumnId_BuysMiscItems = 48,
|
||||
ColumnId_BuysPotions = 49,
|
||||
ColumnId_BuysMagicItems = 50,
|
||||
ColumnId_SellsSpells = 51,
|
||||
ColumnId_Trainer = 52,
|
||||
ColumnId_Spellmaking = 53,
|
||||
ColumnId_EnchantingService = 54,
|
||||
ColumnId_RepairService = 55,
|
||||
ColumnId_ApparatusType = 56,
|
||||
ColumnId_ArmorType = 57,
|
||||
ColumnId_Health = 58,
|
||||
ColumnId_ArmorValue = 59,
|
||||
ColumnId_Scroll = 60,
|
||||
ColumnId_ClothingType = 61,
|
||||
ColumnId_WeightCapacity = 62,
|
||||
ColumnId_OrganicContainer = 63,
|
||||
ColumnId_Respawn = 64,
|
||||
ColumnId_CreatureType = 65,
|
||||
ColumnId_SoulPoints = 66,
|
||||
ColumnId_OriginalCreature = 67,
|
||||
ColumnId_Biped = 68,
|
||||
ColumnId_HasWeapon = 69,
|
||||
ColumnId_NoMovement = 70,
|
||||
ColumnId_Swims = 71,
|
||||
ColumnId_Flies = 72,
|
||||
ColumnId_Walks = 73,
|
||||
ColumnId_Essential = 74,
|
||||
ColumnId_SkeletonBlood = 75,
|
||||
ColumnId_MetalBlood = 76,
|
||||
ColumnId_OpenSound = 77,
|
||||
ColumnId_CloseSound = 78,
|
||||
ColumnId_Duration = 79,
|
||||
ColumnId_Radius = 80,
|
||||
ColumnId_Colour = 81,
|
||||
ColumnId_Sound = 82,
|
||||
ColumnId_Dynamic = 83,
|
||||
ColumnId_Portable = 84,
|
||||
ColumnId_NegativeLight = 85,
|
||||
ColumnId_Flickering = 86,
|
||||
ColumnId_SlowFlickering = 87,
|
||||
ColumnId_Pulsing = 88,
|
||||
ColumnId_SlowPulsing = 89,
|
||||
ColumnId_Fire = 90,
|
||||
ColumnId_OffByDefault = 91,
|
||||
ColumnId_IsKey = 92,
|
||||
ColumnId_Race = 93,
|
||||
ColumnId_Class = 94,
|
||||
Columnid_Hair = 95,
|
||||
ColumnId_Head = 96,
|
||||
ColumnId_Female = 97,
|
||||
ColumnId_WeaponType = 98,
|
||||
ColumnId_WeaponSpeed = 99,
|
||||
ColumnId_WeaponReach = 100,
|
||||
ColumnId_MinChop = 101,
|
||||
ColumnId_MaxChip = 102,
|
||||
Columnid_MinSlash = 103,
|
||||
ColumnId_MaxSlash = 104,
|
||||
ColumnId_MinThrust = 105,
|
||||
ColumnId_MaxThrust = 106,
|
||||
ColumnId_Magical = 107,
|
||||
ColumnId_Silver = 108,
|
||||
ColumnId_Filter = 109,
|
||||
ColumnId_Teleport = 35,
|
||||
ColumnId_TeleportCell = 36,
|
||||
ColumnId_LockLevel = 37,
|
||||
ColumnId_Key = 38,
|
||||
ColumnId_Trap = 39,
|
||||
ColumnId_BeastRace = 40,
|
||||
ColumnId_AutoCalc = 41,
|
||||
ColumnId_StarterSpell = 42,
|
||||
ColumnId_AlwaysSucceeds = 43,
|
||||
ColumnId_SleepForbidden = 44,
|
||||
ColumnId_InteriorWater = 45,
|
||||
ColumnId_InteriorSky = 46,
|
||||
ColumnId_Model = 47,
|
||||
ColumnId_Script = 48,
|
||||
ColumnId_Icon = 49,
|
||||
ColumnId_Weight = 50,
|
||||
ColumnId_EnchantmentPoints = 51,
|
||||
ColumnId_Quality = 52,
|
||||
ColumnId_Ai = 53,
|
||||
ColumnId_AiHello = 54,
|
||||
ColumnId_AiFlee = 55,
|
||||
ColumnId_AiFight = 56,
|
||||
ColumnId_AiAlarm = 57,
|
||||
ColumnId_BuysWeapons = 58,
|
||||
ColumnId_BuysArmor = 59,
|
||||
ColumnId_BuysClothing = 60,
|
||||
ColumnId_BuysBooks = 61,
|
||||
ColumnId_BuysIngredients = 62,
|
||||
ColumnId_BuysLockpicks = 63,
|
||||
ColumnId_BuysProbes = 64,
|
||||
ColumnId_BuysLights = 65,
|
||||
ColumnId_BuysApparati = 66,
|
||||
ColumnId_BuysRepairItems = 67,
|
||||
ColumnId_BuysMiscItems = 68,
|
||||
ColumnId_BuysPotions = 69,
|
||||
ColumnId_BuysMagicItems = 70,
|
||||
ColumnId_SellsSpells = 71,
|
||||
ColumnId_Trainer = 72,
|
||||
ColumnId_Spellmaking = 73,
|
||||
ColumnId_EnchantingService = 74,
|
||||
ColumnId_RepairService = 75,
|
||||
ColumnId_ApparatusType = 76,
|
||||
ColumnId_ArmorType = 77,
|
||||
ColumnId_Health = 78,
|
||||
ColumnId_ArmorValue = 79,
|
||||
ColumnId_Scroll = 80,
|
||||
ColumnId_ClothingType = 81,
|
||||
ColumnId_WeightCapacity = 82,
|
||||
ColumnId_OrganicContainer = 83,
|
||||
ColumnId_Respawn = 84,
|
||||
ColumnId_CreatureType = 85,
|
||||
ColumnId_SoulPoints = 86,
|
||||
ColumnId_OriginalCreature = 87,
|
||||
ColumnId_Biped = 88,
|
||||
ColumnId_HasWeapon = 89,
|
||||
ColumnId_NoMovement = 90,
|
||||
ColumnId_Swims = 91,
|
||||
ColumnId_Flies = 92,
|
||||
ColumnId_Walks = 93,
|
||||
ColumnId_Essential = 94,
|
||||
ColumnId_SkeletonBlood = 95,
|
||||
ColumnId_MetalBlood = 96,
|
||||
ColumnId_OpenSound = 97,
|
||||
ColumnId_CloseSound = 98,
|
||||
ColumnId_Duration = 99,
|
||||
ColumnId_Radius = 100,
|
||||
ColumnId_Colour = 101,
|
||||
ColumnId_Sound = 102,
|
||||
ColumnId_Dynamic = 103,
|
||||
ColumnId_Portable = 104,
|
||||
ColumnId_NegativeLight = 105,
|
||||
ColumnId_Flickering = 106,
|
||||
ColumnId_SlowFlickering = 107,
|
||||
ColumnId_Pulsing = 108,
|
||||
ColumnId_SlowPulsing = 109,
|
||||
ColumnId_Fire = 110,
|
||||
ColumnId_OffByDefault = 111,
|
||||
ColumnId_IsKey = 112,
|
||||
ColumnId_Race = 113,
|
||||
ColumnId_Class = 114,
|
||||
Columnid_Hair = 115,
|
||||
ColumnId_Head = 116,
|
||||
ColumnId_Female = 117,
|
||||
ColumnId_WeaponType = 118,
|
||||
ColumnId_WeaponSpeed = 119,
|
||||
ColumnId_WeaponReach = 120,
|
||||
ColumnId_MinChop = 121,
|
||||
ColumnId_MaxChip = 122,
|
||||
Columnid_MinSlash = 123,
|
||||
ColumnId_MaxSlash = 124,
|
||||
ColumnId_MinThrust = 125,
|
||||
ColumnId_MaxThrust = 126,
|
||||
ColumnId_Magical = 127,
|
||||
ColumnId_Silver = 128,
|
||||
ColumnId_Filter = 129,
|
||||
ColumnId_PositionXPos = 130,
|
||||
ColumnId_PositionYPos = 131,
|
||||
ColumnId_PositionZPos = 132,
|
||||
ColumnId_PositionXRot = 133,
|
||||
ColumnId_PositionYRot = 134,
|
||||
ColumnId_PositionZRot = 135,
|
||||
ColumnId_DoorPositionXPos = 136,
|
||||
ColumnId_DoorPositionYPos = 137,
|
||||
ColumnId_DoorPositionZPos = 138,
|
||||
ColumnId_DoorPositionXRot = 139,
|
||||
ColumnId_DoorPositionYRot = 140,
|
||||
ColumnId_DoorPositionZRot = 141,
|
||||
|
||||
// Allocated to a separate value range, so we don't get a collision should we ever need
|
||||
// to extend the number of use values.
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
#include "data.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
#include <components/esm/esmreader.hpp>
|
||||
#include <components/esm/defs.hpp>
|
||||
#include <components/esm/loadglob.hpp>
|
||||
#include <components/esm/cellref.hpp>
|
||||
|
||||
#include "idtable.hpp"
|
||||
#include "columnimp.hpp"
|
||||
|
@ -15,13 +17,31 @@
|
|||
#include "columns.hpp"
|
||||
|
||||
void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
||||
UniversalId::Type type2)
|
||||
UniversalId::Type type2, bool update)
|
||||
{
|
||||
mModels.push_back (model);
|
||||
mModelIndex.insert (std::make_pair (type1, model));
|
||||
|
||||
if (type2!=UniversalId::Type_None)
|
||||
mModelIndex.insert (std::make_pair (type2, model));
|
||||
|
||||
if (update)
|
||||
{
|
||||
connect (model, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||
this, SLOT (dataChanged (const QModelIndex&, const QModelIndex&)));
|
||||
connect (model, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
||||
this, SLOT (rowsChanged (const QModelIndex&, int, int)));
|
||||
connect (model, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
|
||||
this, SLOT (rowsChanged (const QModelIndex&, int, int)));
|
||||
}
|
||||
}
|
||||
|
||||
void CSMWorld::Data::appendIds (std::vector<std::string>& ids, const CollectionBase& collection,
|
||||
bool listDeleted)
|
||||
{
|
||||
std::vector<std::string> ids2 = collection.getIds (listDeleted);
|
||||
|
||||
ids.insert (ids.end(), ids2.begin(), ids2.end());
|
||||
}
|
||||
|
||||
CSMWorld::Data::Data() : mRefs (mCells)
|
||||
|
@ -134,6 +154,12 @@ CSMWorld::Data::Data() : mRefs (mCells)
|
|||
mRefs.addColumn (new RecordStateColumn<CellRef>);
|
||||
mRefs.addColumn (new CellColumn<CellRef>);
|
||||
mRefs.addColumn (new IdColumn<CellRef>);
|
||||
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mPos, 0, false));
|
||||
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mPos, 1, false));
|
||||
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mPos, 2, false));
|
||||
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mPos, 0, false));
|
||||
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mPos, 1, false));
|
||||
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mPos, 2, false));
|
||||
mRefs.addColumn (new ScaleColumn<CellRef>);
|
||||
mRefs.addColumn (new OwnerColumn<CellRef>);
|
||||
mRefs.addColumn (new SoulColumn<CellRef>);
|
||||
|
@ -144,6 +170,12 @@ CSMWorld::Data::Data() : mRefs (mCells)
|
|||
mRefs.addColumn (new GoldValueColumn<CellRef>);
|
||||
mRefs.addColumn (new TeleportColumn<CellRef>);
|
||||
mRefs.addColumn (new TeleportCellColumn<CellRef>);
|
||||
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mDoorDest, 0, true));
|
||||
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mDoorDest, 1, true));
|
||||
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mDoorDest, 2, true));
|
||||
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mDoorDest, 0, true));
|
||||
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mDoorDest, 1, true));
|
||||
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mDoorDest, 2, true));
|
||||
mRefs.addColumn (new LockLevelColumn<CellRef>);
|
||||
mRefs.addColumn (new KeyColumn<CellRef>);
|
||||
mRefs.addColumn (new TrapColumn<CellRef>);
|
||||
|
@ -155,7 +187,7 @@ CSMWorld::Data::Data() : mRefs (mCells)
|
|||
|
||||
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);
|
||||
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst);
|
||||
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill);
|
||||
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill, false);
|
||||
addModel (new IdTable (&mClasses), UniversalId::Type_Classes, UniversalId::Type_Class);
|
||||
addModel (new IdTable (&mFactions), UniversalId::Type_Factions, UniversalId::Type_Faction);
|
||||
addModel (new IdTable (&mRaces), UniversalId::Type_Races, UniversalId::Type_Race);
|
||||
|
@ -167,8 +199,8 @@ CSMWorld::Data::Data() : mRefs (mCells)
|
|||
addModel (new IdTable (&mCells), UniversalId::Type_Cells, UniversalId::Type_Cell);
|
||||
addModel (new IdTable (&mReferenceables), UniversalId::Type_Referenceables,
|
||||
UniversalId::Type_Referenceable);
|
||||
addModel (new IdTable (&mRefs), UniversalId::Type_References, UniversalId::Type_Reference);
|
||||
addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter);
|
||||
addModel (new IdTable (&mRefs), UniversalId::Type_References, UniversalId::Type_Reference, false);
|
||||
addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter, false);
|
||||
}
|
||||
|
||||
CSMWorld::Data::~Data()
|
||||
|
@ -341,7 +373,7 @@ QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id)
|
|||
{
|
||||
RegionMap *table = 0;
|
||||
addModel (table = new RegionMap (*this), UniversalId::Type_RegionMap,
|
||||
UniversalId::Type_None);
|
||||
UniversalId::Type_None, false);
|
||||
return table;
|
||||
}
|
||||
throw std::logic_error ("No table model available for " + id.toString());
|
||||
|
@ -440,3 +472,36 @@ bool CSMWorld::Data::hasId (const std::string& id) const
|
|||
getCells().searchId (id)!=-1 ||
|
||||
getReferenceables().searchId (id)!=-1;
|
||||
}
|
||||
|
||||
std::vector<std::string> CSMWorld::Data::getIds (bool listDeleted) const
|
||||
{
|
||||
std::vector<std::string> ids;
|
||||
|
||||
appendIds (ids, mGlobals, listDeleted);
|
||||
appendIds (ids, mGmsts, listDeleted);
|
||||
appendIds (ids, mClasses, listDeleted);
|
||||
appendIds (ids, mFactions, listDeleted);
|
||||
appendIds (ids, mRaces, listDeleted);
|
||||
appendIds (ids, mSounds, listDeleted);
|
||||
appendIds (ids, mScripts, listDeleted);
|
||||
appendIds (ids, mRegions, listDeleted);
|
||||
appendIds (ids, mBirthsigns, listDeleted);
|
||||
appendIds (ids, mSpells, listDeleted);
|
||||
appendIds (ids, mCells, listDeleted);
|
||||
appendIds (ids, mReferenceables, listDeleted);
|
||||
|
||||
std::sort (ids.begin(), ids.end());
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
void CSMWorld::Data::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
||||
{
|
||||
if (topLeft.column()<=0)
|
||||
emit idListChanged();
|
||||
}
|
||||
|
||||
void CSMWorld::Data::rowsChanged (const QModelIndex& parent, int start, int end)
|
||||
{
|
||||
emit idListChanged();
|
||||
}
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include <QObject>
|
||||
#include <QModelIndex>
|
||||
|
||||
#include <components/esm/loadglob.hpp>
|
||||
#include <components/esm/loadgmst.hpp>
|
||||
#include <components/esm/loadskil.hpp>
|
||||
|
@ -30,8 +33,10 @@ class QAbstractItemModel;
|
|||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class Data
|
||||
class Data : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
IdCollection<ESM::Global> mGlobals;
|
||||
IdCollection<ESM::GameSetting> mGmsts;
|
||||
IdCollection<ESM::Skill> mSkills;
|
||||
|
@ -55,13 +60,17 @@ namespace CSMWorld
|
|||
Data& operator= (const Data&);
|
||||
|
||||
void addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
||||
UniversalId::Type type2 = UniversalId::Type_None);
|
||||
UniversalId::Type type2 = UniversalId::Type_None, bool update = true);
|
||||
|
||||
static void appendIds (std::vector<std::string>& ids, const CollectionBase& collection,
|
||||
bool listDeleted);
|
||||
///< Append all IDs from collection to \a ids.
|
||||
|
||||
public:
|
||||
|
||||
Data();
|
||||
|
||||
~Data();
|
||||
virtual ~Data();
|
||||
|
||||
const IdCollection<ESM::Global>& getGlobals() const;
|
||||
|
||||
|
@ -136,6 +145,21 @@ namespace CSMWorld
|
|||
///< Merging content of a file into base or modified.
|
||||
|
||||
bool hasId (const std::string& id) const;
|
||||
|
||||
std::vector<std::string> getIds (bool listDeleted = true) const;
|
||||
///< Return a sorted collection of all IDs that are not internal to the editor.
|
||||
///
|
||||
/// \param listDeleted include deleted record in the list
|
||||
|
||||
signals:
|
||||
|
||||
void idListChanged();
|
||||
|
||||
private slots:
|
||||
|
||||
void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||
|
||||
void rowsChanged (const QModelIndex& parent, int start, int end);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -534,3 +534,8 @@ int CSMWorld::RefIdCollection::getAppendIndex (UniversalId::Type type) const
|
|||
{
|
||||
return mData.getAppendIndex (type);
|
||||
}
|
||||
|
||||
std::vector<std::string> CSMWorld::RefIdCollection::getIds (bool listDeleted) const
|
||||
{
|
||||
return mData.getIds (listDeleted);
|
||||
}
|
||||
|
|
|
@ -89,6 +89,11 @@ namespace CSMWorld
|
|||
|
||||
virtual int getAppendIndex (UniversalId::Type type) const;
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
|
||||
virtual std::vector<std::string> getIds (bool listDeleted) const;
|
||||
///< Return a sorted collection of all IDs
|
||||
///
|
||||
/// \param listDeleted include deleted record in the list
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -196,3 +196,25 @@ int CSMWorld::RefIdData::getSize() const
|
|||
{
|
||||
return mIndex.size();
|
||||
}
|
||||
|
||||
std::vector<std::string> CSMWorld::RefIdData::getIds (bool listDeleted) const
|
||||
{
|
||||
std::vector<std::string> ids;
|
||||
|
||||
for (std::map<std::string, LocalIndex>::const_iterator iter (mIndex.begin()); iter!=mIndex.end();
|
||||
++iter)
|
||||
{
|
||||
if (listDeleted || !getRecord (iter->second).isDeleted())
|
||||
{
|
||||
std::map<UniversalId::Type, RefIdDataContainerBase *>::const_iterator container =
|
||||
mRecordContainers.find (iter->second.second);
|
||||
|
||||
if (container==mRecordContainers.end())
|
||||
throw std::logic_error ("Invalid referenceable ID type");
|
||||
|
||||
ids.push_back (container->second->getId (iter->second.first));
|
||||
}
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
|
|
@ -182,6 +182,11 @@ namespace CSMWorld
|
|||
void load (const LocalIndex& index, ESM::ESMReader& reader, bool base);
|
||||
|
||||
int getSize() const;
|
||||
|
||||
std::vector<std::string> getIds (bool listDeleted = true) const;
|
||||
///< Return a sorted collection of all IDs
|
||||
///
|
||||
/// \param listDeleted include deleted record in the list
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
|
||||
#include "scriptcontext.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include "data.hpp"
|
||||
|
||||
CSMWorld::ScriptContext::ScriptContext (const Data& data) : mData (data), mIdsUpdated (false) {}
|
||||
|
||||
bool CSMWorld::ScriptContext::canDeclareLocals() const
|
||||
{
|
||||
return false;
|
||||
|
@ -18,5 +26,19 @@ char CSMWorld::ScriptContext::getMemberType (const std::string& name, const std:
|
|||
|
||||
bool CSMWorld::ScriptContext::isId (const std::string& name) const
|
||||
{
|
||||
return false;
|
||||
if (!mIdsUpdated)
|
||||
{
|
||||
mIds = mData.getIds();
|
||||
|
||||
std::for_each (mIds.begin(), mIds.end(), &Misc::StringUtils::lowerCase);
|
||||
|
||||
mIdsUpdated = true;
|
||||
}
|
||||
|
||||
return std::binary_search (mIds.begin(), mIds.end(), Misc::StringUtils::lowerCase (name));
|
||||
}
|
||||
|
||||
void CSMWorld::ScriptContext::invalidateIds()
|
||||
{
|
||||
mIdsUpdated = false;
|
||||
}
|
|
@ -1,14 +1,25 @@
|
|||
#ifndef CSM_WORLD_SCRIPTCONTEXT_H
|
||||
#define CSM_WORLD_SCRIPTCONTEXT_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <components/compiler/context.hpp>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class Data;
|
||||
|
||||
class ScriptContext : public Compiler::Context
|
||||
{
|
||||
const Data& mData;
|
||||
mutable std::vector<std::string> mIds;
|
||||
mutable bool mIdsUpdated;
|
||||
|
||||
public:
|
||||
|
||||
ScriptContext (const Data& data);
|
||||
|
||||
virtual bool canDeclareLocals() const;
|
||||
///< Is the compiler allowed to declare local variables?
|
||||
|
||||
|
@ -20,6 +31,8 @@ namespace CSMWorld
|
|||
|
||||
virtual bool isId (const std::string& name) const;
|
||||
///< Does \a name match an ID, that can be referenced?
|
||||
|
||||
void invalidateIds();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -43,18 +43,18 @@ namespace
|
|||
|
||||
static const TypeData sIdArg[] =
|
||||
{
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Faction, "Faction", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Race, "Race", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Sound, "Sound", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Script, "Script", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Region, "Region", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Birthsign, "Birthsign", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable", ":./globvar.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting", ":./GMST.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill", ":./skill.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class", ":./class.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Faction, "Faction", ":./faction.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Race, "Race", ":./race.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Sound, "Sound", ":./sound.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Script, "Script", ":./script.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Region, "Region", ":./land.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Birthsign, "Birthsign", ":./birthsign.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell", ":./spell.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", ":./cell.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables", 0 },
|
||||
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Activator, "Activator", ":./activator.png" },
|
||||
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Potion, "Potion", ":./potion.png" },
|
||||
|
@ -80,13 +80,14 @@ namespace
|
|||
{ 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_SubRecord, CSMWorld::UniversalId::Type_Reference, "Reference", 0 },
|
||||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Filter, "Filter", 0 },
|
||||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" },
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||
};
|
||||
|
||||
static const TypeData sIndexArg[] =
|
||||
{
|
||||
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||
};
|
||||
|
|
|
@ -86,10 +86,11 @@ namespace CSMWorld
|
|||
Type_Reference,
|
||||
Type_RegionMap,
|
||||
Type_Filter,
|
||||
Type_Filters
|
||||
Type_Filters,
|
||||
Type_Scene
|
||||
};
|
||||
|
||||
enum { NumberOfTypes = Type_Filters+1 };
|
||||
enum { NumberOfTypes = Type_Scene+1 };
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#include "ocspropertywidget.hpp"
|
||||
|
||||
OcsPropertyWidget::OcsPropertyWidget(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#ifndef OCSPROPERTYWIDGET_HPP
|
||||
#define OCSPROPERTYWIDGET_HPP
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class OcsPropertyWidget : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit OcsPropertyWidget(QObject *parent = 0);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // OCSPROPERTYWIDGET_HPP
|
|
@ -61,7 +61,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon)
|
|||
if (path.parent_path().string()==mLocalData.string())
|
||||
{
|
||||
// path already points to the local data directory
|
||||
message = QString::fromUtf8 (("Will be saved as: " + path.native()).c_str());
|
||||
message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str());
|
||||
mResultPath = path;
|
||||
mValid = true;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon)
|
|||
// path points somewhere else or is a leaf name.
|
||||
path = mLocalData / path.filename();
|
||||
|
||||
message = QString::fromUtf8 (("Will be saved as: " + path.native()).c_str());
|
||||
message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str());
|
||||
mResultPath = path;
|
||||
mValid = true;
|
||||
|
||||
|
|
|
@ -115,6 +115,10 @@ void CSVDoc::View::setupWorldMenu()
|
|||
|
||||
world->addSeparator(); // items that don't represent single record lists follow here
|
||||
|
||||
QAction *scene = new QAction (tr ("Scene"), this);
|
||||
connect (scene, SIGNAL (triggered()), this, SLOT (addSceneSubView()));
|
||||
world->addAction (scene);
|
||||
|
||||
QAction *regionMap = new QAction (tr ("Region Map"), this);
|
||||
connect (regionMap, SIGNAL (triggered()), this, SLOT (addRegionMapSubView()));
|
||||
world->addAction (regionMap);
|
||||
|
@ -403,6 +407,11 @@ void CSVDoc::View::addFiltersSubView()
|
|||
addSubView (CSMWorld::UniversalId::Type_Filters);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addSceneSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Scene);
|
||||
}
|
||||
|
||||
void CSVDoc::View::abortOperation (int type)
|
||||
{
|
||||
mDocument->abortOperation (type);
|
||||
|
|
|
@ -164,6 +164,8 @@ namespace CSVDoc
|
|||
|
||||
void addFiltersSubView();
|
||||
|
||||
void addSceneSubView();
|
||||
|
||||
void toggleShowStatusBar (bool show);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "../world/enumdelegate.hpp"
|
||||
#include "../world/vartypedelegate.hpp"
|
||||
#include "../world/recordstatusdelegate.hpp"
|
||||
#include "../world/refidtypedelegate.hpp"
|
||||
#include "../world/idtypedelegate.hpp"
|
||||
#include "../settings/usersettingsdialog.hpp"
|
||||
|
||||
#include "view.hpp"
|
||||
|
@ -56,7 +56,7 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
|
|||
new CSVWorld::RecordStatusDelegateFactory());
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_RefRecordType,
|
||||
new CSVWorld::RefIdTypeDelegateFactory());
|
||||
new CSVWorld::IdTypeDelegateFactory());
|
||||
|
||||
struct Mapping
|
||||
{
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "../../model/tools/reportmodel.hpp"
|
||||
|
||||
#include "../../view/world/idtypedelegate.hpp"
|
||||
|
||||
CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
||||
: CSVDoc::SubView (id), mModel (document.getReport (id))
|
||||
{
|
||||
|
@ -18,6 +20,11 @@ CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc:
|
|||
mTable->setSelectionBehavior (QAbstractItemView::SelectRows);
|
||||
mTable->setSelectionMode (QAbstractItemView::ExtendedSelection);
|
||||
|
||||
mIdTypeDelegate = CSVWorld::IdTypeDelegateFactory().makeDelegate (
|
||||
document.getUndoStack(), this);
|
||||
|
||||
mTable->setItemDelegateForColumn (0, mIdTypeDelegate);
|
||||
|
||||
connect (mTable, SIGNAL (doubleClicked (const QModelIndex&)), this, SLOT (show (const QModelIndex&)));
|
||||
}
|
||||
|
||||
|
@ -26,6 +33,11 @@ void CSVTools::ReportSubView::setEditLock (bool locked)
|
|||
// ignored. We don't change document state anyway.
|
||||
}
|
||||
|
||||
void CSVTools::ReportSubView::updateEditorSetting (const QString& key, const QString& value)
|
||||
{
|
||||
mIdTypeDelegate->updateEditorSetting (key, value);
|
||||
}
|
||||
|
||||
void CSVTools::ReportSubView::show (const QModelIndex& index)
|
||||
{
|
||||
focusId (mModel->getUniversalId (index.row()));
|
||||
|
|
|
@ -16,6 +16,11 @@ namespace CSMTools
|
|||
class ReportModel;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class CommandDelegate;
|
||||
}
|
||||
|
||||
namespace CSVTools
|
||||
{
|
||||
class Table;
|
||||
|
@ -26,6 +31,7 @@ namespace CSVTools
|
|||
|
||||
CSMTools::ReportModel *mModel;
|
||||
QTableView *mTable;
|
||||
CSVWorld::CommandDelegate *mIdTypeDelegate;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -33,6 +39,8 @@ namespace CSVTools
|
|||
|
||||
virtual void setEditLock (bool locked);
|
||||
|
||||
virtual void updateEditorSetting (const QString&, const QString&);
|
||||
|
||||
private slots:
|
||||
|
||||
void show (const QModelIndex& index);
|
||||
|
|
46
apps/opencs/view/world/idtypedelegate.cpp
Executable file
|
@ -0,0 +1,46 @@
|
|||
#include "idtypedelegate.hpp"
|
||||
|
||||
#include "../../model/world/universalid.hpp"
|
||||
|
||||
CSVWorld::IdTypeDelegate::IdTypeDelegate
|
||||
(const ValueList &values, const IconList &icons, QUndoStack& undoStack, QObject *parent)
|
||||
: DataDisplayDelegate (values, icons, undoStack, parent)
|
||||
{}
|
||||
|
||||
bool CSVWorld::IdTypeDelegate::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||
{
|
||||
/// \todo make the setting key a member variable, that is initialised from a constructor argument
|
||||
if (settingName == "Referenceable ID Type Display")
|
||||
{
|
||||
if (settingValue == "Icon and Text")
|
||||
mDisplayMode = Mode_IconAndText;
|
||||
|
||||
else if (settingValue == "Icon Only")
|
||||
mDisplayMode = Mode_IconOnly;
|
||||
|
||||
else if (settingValue == "Text Only")
|
||||
mDisplayMode = Mode_TextOnly;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
CSVWorld::IdTypeDelegateFactory::IdTypeDelegateFactory()
|
||||
{
|
||||
for (int i=0; i<CSMWorld::UniversalId::NumberOfTypes; ++i)
|
||||
{
|
||||
CSMWorld::UniversalId id (static_cast<CSMWorld::UniversalId::Type> (i));
|
||||
|
||||
DataDisplayDelegateFactory::add (id.getType(), QString::fromUtf8 (id.getTypeName().c_str()),
|
||||
QString::fromUtf8 (id.getIcon().c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
CSVWorld::CommandDelegate *CSVWorld::IdTypeDelegateFactory::makeDelegate (QUndoStack& undoStack,
|
||||
QObject *parent) const
|
||||
{
|
||||
return new IdTypeDelegate (mValues, mIcons, undoStack, parent);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef REFIDTYPEDELEGATE_HPP
|
||||
#define REFIDTYPEDELEGATE_HPP
|
||||
#ifndef IDTYPEDELEGATE_HPP
|
||||
#define IDTYPEDELEGATE_HPP
|
||||
|
||||
#include "enumdelegate.hpp"
|
||||
#include "util.hpp"
|
||||
|
@ -8,29 +8,23 @@
|
|||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class RefIdTypeDelegate : public DataDisplayDelegate
|
||||
class IdTypeDelegate : public DataDisplayDelegate
|
||||
{
|
||||
public:
|
||||
RefIdTypeDelegate (const ValueList &mValues, const IconList &icons, QUndoStack& undoStack, QObject *parent);
|
||||
IdTypeDelegate (const ValueList &mValues, const IconList &icons, QUndoStack& undoStack, QObject *parent);
|
||||
|
||||
virtual bool updateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||
|
||||
};
|
||||
|
||||
class RefIdTypeDelegateFactory : public DataDisplayDelegateFactory
|
||||
class IdTypeDelegateFactory : public DataDisplayDelegateFactory
|
||||
{
|
||||
|
||||
typedef std::vector < std::pair <CSMWorld::UniversalId::Type, QString> > UidTypeList;
|
||||
|
||||
public:
|
||||
RefIdTypeDelegateFactory();
|
||||
|
||||
IdTypeDelegateFactory();
|
||||
|
||||
virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const;
|
||||
///< The ownership of the returned CommandDelegate is transferred to the caller.
|
||||
|
||||
private:
|
||||
UidTypeList buildUidTypeList () const;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
#include "refidtypedelegate.hpp"
|
||||
|
||||
#include "../../model/world/universalid.hpp"
|
||||
|
||||
CSVWorld::RefIdTypeDelegate::RefIdTypeDelegate
|
||||
(const ValueList &values, const IconList &icons, QUndoStack& undoStack, QObject *parent)
|
||||
: DataDisplayDelegate (values, icons, undoStack, parent)
|
||||
{}
|
||||
|
||||
bool CSVWorld::RefIdTypeDelegate::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||
{
|
||||
if (settingName == "Referenceable ID Type Display")
|
||||
{
|
||||
if (settingValue == "Icon and Text")
|
||||
mDisplayMode = Mode_IconAndText;
|
||||
|
||||
else if (settingValue == "Icon Only")
|
||||
mDisplayMode = Mode_IconOnly;
|
||||
|
||||
else if (settingValue == "Text Only")
|
||||
mDisplayMode = Mode_TextOnly;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
CSVWorld::RefIdTypeDelegateFactory::RefIdTypeDelegateFactory()
|
||||
{
|
||||
UidTypeList uIdList = buildUidTypeList();
|
||||
|
||||
for (UidTypeList::const_iterator it = uIdList.begin(); it != uIdList.end(); it++)
|
||||
{
|
||||
int i = it->first;
|
||||
DataDisplayDelegateFactory::add (i, QString::fromStdString(CSMWorld::UniversalId(it->first, "").getTypeName()), it->second);
|
||||
}
|
||||
}
|
||||
|
||||
CSVWorld::CommandDelegate *CSVWorld::RefIdTypeDelegateFactory::makeDelegate (QUndoStack& undoStack,
|
||||
QObject *parent) const
|
||||
{
|
||||
return new RefIdTypeDelegate (mValues, mIcons, undoStack, parent);
|
||||
}
|
||||
|
||||
CSVWorld::RefIdTypeDelegateFactory::UidTypeList CSVWorld::RefIdTypeDelegateFactory::buildUidTypeList() const
|
||||
{
|
||||
UidTypeList list;
|
||||
|
||||
std::vector<CSMWorld::UniversalId::Type> types = CSMWorld::UniversalId::listReferenceableTypes();
|
||||
|
||||
for (std::vector<CSMWorld::UniversalId::Type>::const_iterator iter (types.begin());
|
||||
iter!=types.end(); ++iter)
|
||||
{
|
||||
CSMWorld::UniversalId id (*iter, "");
|
||||
|
||||
list.push_back (std::make_pair (id.getType(), id.getIcon().c_str()));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
82
apps/opencs/view/world/scenesubview.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
|
||||
#include "scenesubview.hpp"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../filter/filterbox.hpp"
|
||||
|
||||
#include "tablebottombox.hpp"
|
||||
#include "creator.hpp"
|
||||
#include "scenetoolbar.hpp"
|
||||
#include "scenetoolmode.hpp"
|
||||
|
||||
CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
||||
: SubView (id)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
|
||||
layout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||
|
||||
layout->addWidget (mBottom =
|
||||
new TableBottomBox (NullCreatorFactory(), document.getData(), document.getUndoStack(), id,
|
||||
this), 0);
|
||||
|
||||
QHBoxLayout *layout2 = new QHBoxLayout;
|
||||
|
||||
layout2->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||
|
||||
SceneToolbar *toolbar = new SceneToolbar (48, this);
|
||||
// test
|
||||
SceneToolMode *tool = new SceneToolMode (toolbar);
|
||||
tool->addButton (":door.png", "a");
|
||||
tool->addButton (":GMST.png", "b");
|
||||
tool->addButton (":Info.png", "c");
|
||||
toolbar->addTool (tool);
|
||||
toolbar->addTool (new SceneToolMode (toolbar));
|
||||
toolbar->addTool (new SceneToolMode (toolbar));
|
||||
toolbar->addTool (new SceneToolMode (toolbar));
|
||||
layout2->addWidget (toolbar, 0);
|
||||
|
||||
/// \todo replace with rendering widget
|
||||
QPalette palette2 (palette());
|
||||
palette2.setColor (QPalette::Background, Qt::white);
|
||||
QLabel *placeholder = new QLabel ("Here goes the 3D scene", this);
|
||||
placeholder->setAutoFillBackground (true);
|
||||
placeholder->setPalette (palette2);
|
||||
placeholder->setAlignment (Qt::AlignHCenter);
|
||||
|
||||
layout2->addWidget (placeholder, 1);
|
||||
|
||||
layout->insertLayout (0, layout2, 1);
|
||||
|
||||
CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this);
|
||||
|
||||
layout->insertWidget (0, filterBox);
|
||||
|
||||
QWidget *widget = new QWidget;
|
||||
|
||||
widget->setLayout (layout);
|
||||
|
||||
setWidget (widget);
|
||||
}
|
||||
|
||||
void CSVWorld::SceneSubView::setEditLock (bool locked)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CSVWorld::SceneSubView::updateEditorSetting(const QString &settingName, const QString &settingValue)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CSVWorld::SceneSubView::setStatusBar (bool show)
|
||||
{
|
||||
mBottom->setStatusBar (show);
|
||||
}
|
37
apps/opencs/view/world/scenesubview.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef CSV_WORLD_SCENESUBVIEW_H
|
||||
#define CSV_WORLD_SCENESUBVIEW_H
|
||||
|
||||
#include "../doc/subview.hpp"
|
||||
|
||||
class QModelIndex;
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class Table;
|
||||
class TableBottomBox;
|
||||
class CreatorFactoryBase;
|
||||
|
||||
class SceneSubView : public CSVDoc::SubView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
TableBottomBox *mBottom;
|
||||
|
||||
public:
|
||||
|
||||
SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
|
||||
|
||||
virtual void setEditLock (bool locked);
|
||||
|
||||
virtual void updateEditorSetting (const QString& key, const QString& value);
|
||||
|
||||
virtual void setStatusBar (bool show);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
17
apps/opencs/view/world/scenetool.cpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
#include "scenetool.hpp"
|
||||
|
||||
#include "scenetoolbar.hpp"
|
||||
|
||||
CSVWorld::SceneTool::SceneTool (SceneToolbar *parent) : QPushButton (parent)
|
||||
{
|
||||
setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||
setFixedSize (parent->getButtonSize(), parent->getButtonSize());
|
||||
|
||||
connect (this, SIGNAL (clicked()), this, SLOT (openRequest()));
|
||||
}
|
||||
|
||||
void CSVWorld::SceneTool::openRequest()
|
||||
{
|
||||
showPanel (parentWidget()->mapToGlobal (pos()));
|
||||
}
|
27
apps/opencs/view/world/scenetool.hpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef CSV_WORLD_SCENETOOL_H
|
||||
#define CSV_WORLD_SCENETOOL_H
|
||||
|
||||
#include <QPushButton>
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class SceneToolbar;
|
||||
|
||||
///< \brief Tool base class
|
||||
class SceneTool : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
SceneTool (SceneToolbar *parent);
|
||||
|
||||
virtual void showPanel (const QPoint& position) = 0;
|
||||
|
||||
private slots:
|
||||
|
||||
void openRequest();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
29
apps/opencs/view/world/scenetoolbar.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
|
||||
#include "scenetoolbar.hpp"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "scenetool.hpp"
|
||||
|
||||
CSVWorld::SceneToolbar::SceneToolbar (int buttonSize, QWidget *parent)
|
||||
: QWidget (parent), mButtonSize (buttonSize)
|
||||
{
|
||||
setFixedWidth (mButtonSize);
|
||||
|
||||
mLayout = new QVBoxLayout (this);
|
||||
mLayout->setAlignment (Qt::AlignTop);
|
||||
|
||||
mLayout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||
|
||||
setLayout (mLayout);
|
||||
}
|
||||
|
||||
void CSVWorld::SceneToolbar::addTool (SceneTool *tool)
|
||||
{
|
||||
mLayout->addWidget (tool, 0, Qt::AlignTop);
|
||||
}
|
||||
|
||||
int CSVWorld::SceneToolbar::getButtonSize() const
|
||||
{
|
||||
return mButtonSize;
|
||||
}
|
29
apps/opencs/view/world/scenetoolbar.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSV_WORLD_SCENETOOLBAR_H
|
||||
#define CSV_WORLD_SCENETOOLBAR_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QVBoxLayout;
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class SceneTool;
|
||||
|
||||
class SceneToolbar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QVBoxLayout *mLayout;
|
||||
int mButtonSize;
|
||||
|
||||
public:
|
||||
|
||||
SceneToolbar (int buttonSize, QWidget *parent = 0);
|
||||
|
||||
void addTool (SceneTool *tool);
|
||||
|
||||
int getButtonSize() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
56
apps/opencs/view/world/scenetoolmode.cpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
|
||||
#include "scenetoolmode.hpp"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QFrame>
|
||||
#include <QSignalMapper>
|
||||
|
||||
#include "scenetoolbar.hpp"
|
||||
|
||||
CSVWorld::SceneToolMode::SceneToolMode (SceneToolbar *parent)
|
||||
: SceneTool (parent), mButtonSize (parent->getButtonSize())
|
||||
{
|
||||
mPanel = new QFrame (this, Qt::Popup);
|
||||
|
||||
mLayout = new QHBoxLayout (mPanel);
|
||||
|
||||
mLayout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||
|
||||
mPanel->setLayout (mLayout);
|
||||
}
|
||||
|
||||
void CSVWorld::SceneToolMode::showPanel (const QPoint& position)
|
||||
{
|
||||
mPanel->move (position);
|
||||
mPanel->show();
|
||||
}
|
||||
|
||||
void CSVWorld::SceneToolMode::addButton (const std::string& icon, const std::string& id)
|
||||
{
|
||||
QPushButton *button = new QPushButton (QIcon (QPixmap (icon.c_str())), "", mPanel);
|
||||
button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||
button->setFixedSize (mButtonSize, mButtonSize);
|
||||
|
||||
mLayout->addWidget (button);
|
||||
|
||||
mButtons.insert (std::make_pair (button, id));
|
||||
|
||||
connect (button, SIGNAL (clicked()), this, SLOT (selected()));
|
||||
|
||||
if (mButtons.size()==1)
|
||||
setIcon (button->icon());
|
||||
}
|
||||
|
||||
void CSVWorld::SceneToolMode::selected()
|
||||
{
|
||||
std::map<QPushButton *, std::string>::const_iterator iter =
|
||||
mButtons.find (dynamic_cast<QPushButton *> (sender()));
|
||||
|
||||
if (iter!=mButtons.end())
|
||||
{
|
||||
mPanel->hide();
|
||||
|
||||
setIcon (iter->first->icon());
|
||||
emit modeChanged (iter->second);
|
||||
}
|
||||
}
|
42
apps/opencs/view/world/scenetoolmode.hpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
#ifndef CSV_WORLD_SCENETOOL_MODE_H
|
||||
#define CSV_WORLD_SCENETOOL_MODE_H
|
||||
|
||||
#include "scenetool.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
class QHBoxLayout;
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class SceneToolbar;
|
||||
|
||||
///< \brief Mode selector tool
|
||||
class SceneToolMode : public SceneTool
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QWidget *mPanel;
|
||||
QHBoxLayout *mLayout;
|
||||
std::map<QPushButton *, std::string> mButtons; // widget, id
|
||||
int mButtonSize;
|
||||
|
||||
public:
|
||||
|
||||
SceneToolMode (SceneToolbar *parent);
|
||||
|
||||
virtual void showPanel (const QPoint& position);
|
||||
|
||||
void addButton (const std::string& icon, const std::string& id);
|
||||
|
||||
signals:
|
||||
|
||||
void modeChanged (const std::string& id);
|
||||
|
||||
private slots:
|
||||
|
||||
void selected();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -4,6 +4,7 @@
|
|||
#include <sstream>
|
||||
|
||||
#include <components/compiler/scanner.hpp>
|
||||
#include <components/compiler/extensions0.hpp>
|
||||
|
||||
bool CSVWorld::ScriptHighlighter::parseInt (int value, const Compiler::TokenLoc& loc,
|
||||
Compiler::Scanner& scanner)
|
||||
|
@ -22,7 +23,7 @@ bool CSVWorld::ScriptHighlighter::parseFloat (float value, const Compiler::Token
|
|||
bool CSVWorld::ScriptHighlighter::parseName (const std::string& name, const Compiler::TokenLoc& loc,
|
||||
Compiler::Scanner& scanner)
|
||||
{
|
||||
highlight (loc, Type_Name);
|
||||
highlight (loc, mContext.isId (name) ? Type_Id : Type_Name);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -62,10 +63,10 @@ void CSVWorld::ScriptHighlighter::highlight (const Compiler::TokenLoc& loc, Type
|
|||
setFormat (index, length, mScheme[type]);
|
||||
}
|
||||
|
||||
CSVWorld::ScriptHighlighter::ScriptHighlighter (QTextDocument *parent)
|
||||
: QSyntaxHighlighter (parent), Compiler::Parser (mErrorHandler, mContext)
|
||||
CSVWorld::ScriptHighlighter::ScriptHighlighter (const CSMWorld::Data& data, QTextDocument *parent)
|
||||
: QSyntaxHighlighter (parent), Compiler::Parser (mErrorHandler, mContext), mContext (data)
|
||||
{
|
||||
/// \ŧodo replace this with user settings
|
||||
/// \todo replace this with user settings
|
||||
{
|
||||
QTextCharFormat format;
|
||||
format.setForeground (Qt::darkMagenta);
|
||||
|
@ -101,6 +102,16 @@ CSVWorld::ScriptHighlighter::ScriptHighlighter (QTextDocument *parent)
|
|||
format.setForeground (Qt::green);
|
||||
mScheme.insert (std::make_pair (Type_Comment, format));
|
||||
}
|
||||
|
||||
{
|
||||
QTextCharFormat format;
|
||||
format.setForeground (Qt::blue);
|
||||
mScheme.insert (std::make_pair (Type_Id, format));
|
||||
}
|
||||
|
||||
// configure compiler
|
||||
Compiler::registerExtensions (mExtensions);
|
||||
mContext.setExtensions (&mExtensions);
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptHighlighter::highlightBlock (const QString& text)
|
||||
|
@ -114,5 +125,9 @@ void CSVWorld::ScriptHighlighter::highlightBlock (const QString& text)
|
|||
scanner.scan (*this);
|
||||
}
|
||||
catch (...) {} // ignore syntax errors
|
||||
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptHighlighter::invalidateIds()
|
||||
{
|
||||
mContext.invalidateIds();
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <components/compiler/nullerrorhandler.hpp>
|
||||
#include <components/compiler/parser.hpp>
|
||||
#include <components/compiler/extensions.hpp>
|
||||
|
||||
#include "../../model/world/scriptcontext.hpp"
|
||||
|
||||
|
@ -23,12 +24,14 @@ namespace CSVWorld
|
|||
Type_Name,
|
||||
Type_Keyword,
|
||||
Type_Special,
|
||||
Type_Comment
|
||||
Type_Comment,
|
||||
Type_Id
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Compiler::NullErrorHandler mErrorHandler;
|
||||
Compiler::Extensions mExtensions;
|
||||
CSMWorld::ScriptContext mContext;
|
||||
std::map<Type, QTextCharFormat> mScheme;
|
||||
|
||||
|
@ -71,9 +74,11 @@ namespace CSVWorld
|
|||
|
||||
public:
|
||||
|
||||
ScriptHighlighter (QTextDocument *parent);
|
||||
ScriptHighlighter (const CSMWorld::Data& data, QTextDocument *parent);
|
||||
|
||||
virtual void highlightBlock (const QString& text);
|
||||
|
||||
void invalidateIds();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,13 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc:
|
|||
connect (mModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||
this, SLOT (rowsAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||
|
||||
new ScriptHighlighter (mEditor->document());
|
||||
connect (&document.getData(), SIGNAL (idListChanged()), this, SLOT (idListChanged()));
|
||||
|
||||
mHighlighter = new ScriptHighlighter (document.getData(), mEditor->document());
|
||||
|
||||
connect (&mUpdateTimer, SIGNAL (timeout()), this, SLOT (updateHighlighting()));
|
||||
|
||||
mUpdateTimer.setSingleShot (true);
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptSubView::setEditLock (bool locked)
|
||||
|
@ -66,8 +72,19 @@ void CSVWorld::ScriptSubView::setEditLock (bool locked)
|
|||
mEditor->setReadOnly (locked);
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptSubView::idListChanged()
|
||||
{
|
||||
mHighlighter->invalidateIds();
|
||||
|
||||
if (!mUpdateTimer.isActive())
|
||||
mUpdateTimer.start (0);
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptSubView::textChanged()
|
||||
{
|
||||
if (mChangeLocked)
|
||||
return;
|
||||
|
||||
ChangeLock lock (*this);
|
||||
|
||||
mDocument.getUndoStack().push (new CSMWorld::ModifyCommand (*mModel,
|
||||
|
@ -79,6 +96,8 @@ void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QMo
|
|||
if (mChangeLocked)
|
||||
return;
|
||||
|
||||
ChangeLock lock (*this);
|
||||
|
||||
QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn);
|
||||
|
||||
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row() &&
|
||||
|
@ -97,3 +116,13 @@ void CSVWorld::ScriptSubView::rowsAboutToBeRemoved (const QModelIndex& parent, i
|
|||
if (!parent.isValid() && index.row()>=start && index.row()<=end)
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptSubView::updateHighlighting()
|
||||
{
|
||||
if (mChangeLocked)
|
||||
return;
|
||||
|
||||
ChangeLock lock (*this);
|
||||
|
||||
mHighlighter->rehighlight();
|
||||
}
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include "../doc/subview.hpp"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
class QTextEdit;
|
||||
class QModelIndex;
|
||||
|
||||
|
@ -18,6 +20,8 @@ namespace CSMWorld
|
|||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class ScriptHighlighter;
|
||||
|
||||
class ScriptSubView : public CSVDoc::SubView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -27,6 +31,8 @@ namespace CSVWorld
|
|||
CSMWorld::IdTable *mModel;
|
||||
int mColumn;
|
||||
int mChangeLocked;
|
||||
ScriptHighlighter *mHighlighter;
|
||||
QTimer mUpdateTimer;
|
||||
|
||||
class ChangeLock
|
||||
{
|
||||
|
@ -49,13 +55,19 @@ namespace CSVWorld
|
|||
|
||||
virtual void setEditLock (bool locked);
|
||||
|
||||
private slots:
|
||||
public slots:
|
||||
|
||||
void idListChanged();
|
||||
|
||||
void textChanged();
|
||||
|
||||
void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||
|
||||
void rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||
|
||||
private slots:
|
||||
|
||||
void updateHighlighting();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "cellcreator.hpp"
|
||||
#include "referenceablecreator.hpp"
|
||||
#include "referencecreator.hpp"
|
||||
#include "scenesubview.hpp"
|
||||
|
||||
void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
||||
{
|
||||
|
@ -62,4 +63,5 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
|||
new CSVDoc::SubViewFactoryWithCreator<TableSubView,
|
||||
CreatorFactory<CSVFilter::FilterCreator> >);
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory<SceneSubView>);
|
||||
}
|
|
@ -12,8 +12,8 @@
|
|||
#include "../../model/world/idtableproxymodel.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/record.hpp"
|
||||
|
||||
#include "recordstatusdelegate.hpp"
|
||||
#include "refidtypedelegate.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||
|
|
|
@ -119,6 +119,10 @@ target_link_libraries(openmw
|
|||
components
|
||||
)
|
||||
|
||||
if (USE_SYSTEM_TINYXML)
|
||||
target_link_libraries(openmw ${TINYXML_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if (NOT UNIX)
|
||||
target_link_libraries(openmw ${SDL2MAIN_LIBRARY})
|
||||
endif()
|
||||
|
|
|
@ -399,8 +399,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||
mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
|
||||
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding);
|
||||
mEnvironment.setWindowManager (window);
|
||||
if (mNewGame)
|
||||
mEnvironment.getWindowManager()->setNewGame(true);
|
||||
|
||||
// Create the world
|
||||
mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mMaster, mPlugins,
|
||||
|
@ -410,6 +408,10 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||
input->setPlayer(&mEnvironment.getWorld()->getPlayer());
|
||||
|
||||
window->initUI();
|
||||
if (mNewGame)
|
||||
// still redundant work here: recreate CharacterCreation(),
|
||||
// double update visibility etc.
|
||||
window->setNewGame(true);
|
||||
window->renderWorldMap();
|
||||
|
||||
//Load translation data
|
||||
|
|
|
@ -324,6 +324,7 @@ namespace MWBase
|
|||
virtual void processChangedSettings (const Settings::CategorySettingVector& settings) = 0;
|
||||
|
||||
virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0;
|
||||
virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const = 0;
|
||||
virtual bool isSwimming(const MWWorld::Ptr &object) const = 0;
|
||||
///Is the head of the creature underwater?
|
||||
virtual bool isSubmerged(const MWWorld::Ptr &object) const = 0;
|
||||
|
@ -389,6 +390,12 @@ namespace MWBase
|
|||
/// Returns true if teleport spell effects are allowed.
|
||||
virtual bool isTeleportingEnabled() const = 0;
|
||||
|
||||
/// Enables or disables use of levitation spell effect.
|
||||
virtual void enableLevitation(bool enable) = 0;
|
||||
|
||||
/// Returns true if levitation spell effect is allowed.
|
||||
virtual bool isLevitationEnabled() const = 0;
|
||||
|
||||
/// Turn actor into werewolf or normal form.
|
||||
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0;
|
||||
|
||||
|
@ -396,6 +403,8 @@ namespace MWBase
|
|||
/// It only applies to the current form the NPC is in.
|
||||
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) = 0;
|
||||
|
||||
virtual bool getGodModeState() = 0;
|
||||
|
||||
virtual bool toggleGodMode() = 0;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <OgreSceneNode.h>
|
||||
|
||||
#include <components/esm/loadmgef.hpp>
|
||||
#include <components/esm/loadnpc.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
@ -396,9 +397,10 @@ namespace MWClass
|
|||
MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}");
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f);
|
||||
}
|
||||
weapon.getCellRef().mCharge -= std::min(std::max(1,
|
||||
(int)(damage * gmst.find("fWeaponDamageMult")->getFloat())),
|
||||
weapon.getCellRef().mCharge);
|
||||
|
||||
if (!MWBase::Environment::get().getWorld()->getGodModeState())
|
||||
weapon.getCellRef().mCharge -= std::min(std::max(1,
|
||||
(int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), weapon.getCellRef().mCharge);
|
||||
}
|
||||
healthdmg = true;
|
||||
}
|
||||
|
@ -769,6 +771,37 @@ namespace MWClass
|
|||
return x;
|
||||
}
|
||||
|
||||
float Npc::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const
|
||||
{
|
||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
||||
|
||||
const float fallDistanceMin = gmst.find("fFallDamageDistanceMin")->getFloat();
|
||||
|
||||
if (fallHeight >= fallDistanceMin)
|
||||
{
|
||||
const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill(ESM::Skill::Acrobatics).getModified();
|
||||
const CustomData *npcdata = static_cast<const CustomData*>(ptr.getRefData().getCustomData());
|
||||
const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Jump)).mMagnitude;
|
||||
const float fallAcroBase = gmst.find("fFallAcroBase")->getFloat();
|
||||
const float fallAcroMult = gmst.find("fFallAcroMult")->getFloat();
|
||||
const float fallDistanceBase = gmst.find("fFallDistanceBase")->getFloat();
|
||||
const float fallDistanceMult = gmst.find("fFallDistanceMult")->getFloat();
|
||||
|
||||
float x = fallHeight - fallDistanceMin;
|
||||
x -= (1.5 * acrobaticsSkill) + jumpSpellBonus;
|
||||
x = std::max(0.0f, x);
|
||||
|
||||
float a = fallAcroBase + fallAcroMult * (100 - acrobaticsSkill);
|
||||
x = fallDistanceBase + fallDistanceMult * x;
|
||||
x *= a;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ensureCustomData (ptr);
|
||||
|
|
|
@ -97,6 +97,9 @@ namespace MWClass
|
|||
virtual float getJump(const MWWorld::Ptr &ptr) const;
|
||||
///< Return jump velocity (not accounting for movement)
|
||||
|
||||
virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const;
|
||||
///< Return amount of health points lost when falling
|
||||
|
||||
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
|
||||
///< Return desired movement.
|
||||
|
||||
|
|
|
@ -250,6 +250,7 @@ namespace MWGui
|
|||
// remove object from the container it was coming from
|
||||
mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount);
|
||||
mDragAndDrop->finish();
|
||||
mDragAndDrop->mSourceModel->update();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace MWGui
|
|||
, mLastWallpaperChangeTime(0.f)
|
||||
, mFirstLoad(true)
|
||||
, mProgress(0)
|
||||
, mVSyncWasEnabled(false)
|
||||
{
|
||||
getWidget(mLoadingText, "LoadingText");
|
||||
getWidget(mProgressBar, "ProgressBar");
|
||||
|
@ -67,6 +68,14 @@ namespace MWGui
|
|||
|
||||
void LoadingScreen::loadingOn()
|
||||
{
|
||||
// Temporarily turn off VSync, we want to do actual loading rather than waiting for the screen to sync.
|
||||
// Threaded loading would be even better, of course - especially because some drivers force VSync to on and we can't change it.
|
||||
// In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged with GLX, nothing we can do :/
|
||||
mVSyncWasEnabled = mWindow->isVSyncEnabled();
|
||||
#if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0)
|
||||
mWindow->setVSyncEnabled(false);
|
||||
#endif
|
||||
|
||||
setVisible(true);
|
||||
|
||||
if (mFirstLoad)
|
||||
|
@ -83,6 +92,12 @@ namespace MWGui
|
|||
|
||||
void LoadingScreen::loadingOff()
|
||||
{
|
||||
// Re-enable vsync now.
|
||||
// In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged with GLX, nothing we can do :/
|
||||
#if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0)
|
||||
mWindow->setVSyncEnabled(mVSyncWasEnabled);
|
||||
#endif
|
||||
|
||||
setVisible(false);
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Loading);
|
||||
|
@ -212,7 +227,8 @@ namespace MWGui
|
|||
// caused a sync / flush and would be expensive).
|
||||
// We're doing this so we can do some actual loading while the GPU is busy with the render.
|
||||
// This means the render is lagging a frame behind, but this is hardly noticable.
|
||||
mWindow->swapBuffers(false); // never Vsync, makes no sense here
|
||||
mWindow->swapBuffers();
|
||||
|
||||
mWindow->update(false);
|
||||
|
||||
if (!hasCompositor)
|
||||
|
|
|
@ -57,6 +57,8 @@ namespace MWGui
|
|||
|
||||
Ogre::StringVector mResources;
|
||||
|
||||
bool mVSyncWasEnabled;
|
||||
|
||||
void changeWallpaper();
|
||||
|
||||
void draw();
|
||||
|
|
|
@ -70,7 +70,10 @@ namespace MWGui
|
|||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
|
||||
if (sender == mButtons["return"])
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager ()->resumeSounds (MWBase::SoundManager::Play_TypeSfx);
|
||||
MWBase::Environment::get().getWindowManager ()->removeGuiMode (GM_MainMenu);
|
||||
}
|
||||
else if (sender == mButtons["options"])
|
||||
MWBase::Environment::get().getWindowManager ()->pushGuiMode (GM_Settings);
|
||||
else if (sender == mButtons["exitgame"])
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace MWGui
|
|||
mMessageBoxSpeed = 0.1;
|
||||
mInterMessageBoxe = NULL;
|
||||
mStaticMessageBox = NULL;
|
||||
mLastButtonPressed = -1;
|
||||
}
|
||||
|
||||
void MessageBoxManager::onFrame (float frameDuration)
|
||||
|
@ -62,6 +63,7 @@ namespace MWGui
|
|||
}
|
||||
|
||||
if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) {
|
||||
mLastButtonPressed = mInterMessageBoxe->readPressedButton();
|
||||
delete mInterMessageBoxe;
|
||||
mInterMessageBoxe = NULL;
|
||||
MWBase::Environment::get().getInputManager()->changeInputMode(
|
||||
|
@ -107,6 +109,7 @@ namespace MWGui
|
|||
}
|
||||
|
||||
mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons);
|
||||
mLastButtonPressed = -1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -154,11 +157,9 @@ namespace MWGui
|
|||
|
||||
int MessageBoxManager::readPressedButton ()
|
||||
{
|
||||
if(mInterMessageBoxe != NULL)
|
||||
{
|
||||
return mInterMessageBoxe->readPressedButton();
|
||||
}
|
||||
return -1;
|
||||
int pressed = mLastButtonPressed;
|
||||
mLastButtonPressed = -1;
|
||||
return pressed;
|
||||
}
|
||||
|
||||
|
||||
|
@ -421,9 +422,7 @@ namespace MWGui
|
|||
|
||||
int InteractiveMessageBox::readPressedButton ()
|
||||
{
|
||||
int pressed = mButtonPressed;
|
||||
mButtonPressed = -1;
|
||||
return pressed;
|
||||
return mButtonPressed;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ namespace MWGui
|
|||
MessageBox* mStaticMessageBox;
|
||||
std::vector<MessageBoxManagerTimer> mTimers;
|
||||
float mMessageBoxSpeed;
|
||||
int mLastButtonPressed;
|
||||
};
|
||||
|
||||
class MessageBox : public OEngine::GUI::Layout
|
||||
|
|
|
@ -363,8 +363,12 @@ namespace MWGui
|
|||
else if (_sender == mVSyncButton)
|
||||
{
|
||||
Settings::Manager::setBool("vsync", "Video", newState);
|
||||
// Ogre::Window::setVSyncEnabled is bugged in 1.8
|
||||
#if OGRE_VERSION < (1 << 16 | 9 << 8 | 0)
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox("VSync will be applied after a restart", std::vector<std::string>());
|
||||
#endif
|
||||
apply();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
@ -169,13 +172,34 @@ namespace MWGui
|
|||
MWBase::Environment::get().getWindowManager()->getGameSettingString(
|
||||
ESM::Attribute::sGmstAttributeIds[effectIt->mKey.mArg], "") + ")";
|
||||
|
||||
if (!(effect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
|
||||
ESM::MagicEffect::MagnitudeDisplayType displayType = effect->getMagnitudeDisplayType();
|
||||
if (displayType == ESM::MagicEffect::MDT_TimesInt)
|
||||
{
|
||||
std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", "");
|
||||
std::stringstream formatter;
|
||||
formatter << std::fixed << std::setprecision(1) << " " << (effectIt->mMagnitude / 10.0f) << timesInt;
|
||||
sourcesDescription += formatter.str();
|
||||
}
|
||||
else if ( displayType != ESM::MagicEffect::MDT_None )
|
||||
{
|
||||
std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", "");
|
||||
std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", "");
|
||||
|
||||
sourcesDescription += ": " + boost::lexical_cast<std::string>(effectIt->mMagnitude);
|
||||
sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt);
|
||||
|
||||
if ( displayType == ESM::MagicEffect::MDT_Percentage )
|
||||
sourcesDescription += MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", "");
|
||||
else if ( displayType == ESM::MagicEffect::MDT_Feet )
|
||||
sourcesDescription += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sfeet", "");
|
||||
else if ( displayType == ESM::MagicEffect::MDT_Level )
|
||||
{
|
||||
sourcesDescription += " " + ((effectIt->mMagnitude > 1) ?
|
||||
MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevels", "") :
|
||||
MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevel", "") );
|
||||
}
|
||||
else // ESM::MagicEffect::MDT_Points
|
||||
{
|
||||
sourcesDescription += " " + ((effectIt->mMagnitude > 1) ?
|
||||
MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", "") :
|
||||
MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", "") );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <MyGUI_ProgressBar.h>
|
||||
#include <MyGUI_ImageBox.h>
|
||||
#include <MyGUI_ControllerManager.h>
|
||||
|
@ -405,6 +408,10 @@ namespace MWGui
|
|||
|
||||
std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", "");
|
||||
std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", "");
|
||||
std::string pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", "");
|
||||
std::string ft = MWBase::Environment::get().getWindowManager()->getGameSettingString("sfeet", "");
|
||||
std::string lvl = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevel", "");
|
||||
std::string lvls = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevels", "");
|
||||
std::string to = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sTo", "") + " ";
|
||||
std::string sec = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("ssecond", "");
|
||||
std::string secs = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sseconds", "");
|
||||
|
@ -421,13 +428,32 @@ namespace MWGui
|
|||
spellLine += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Attribute::sGmstAttributeIds[mEffectParams.mAttribute], "");
|
||||
}
|
||||
|
||||
if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
|
||||
{
|
||||
if (mEffectParams.mMagnMin == mEffectParams.mMagnMax)
|
||||
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + " " + ((mEffectParams.mMagnMin == 1) ? pt : pts);
|
||||
else
|
||||
{
|
||||
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + to + boost::lexical_cast<std::string>(mEffectParams.mMagnMax) + " " + pts;
|
||||
if (mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) {
|
||||
ESM::MagicEffect::MagnitudeDisplayType displayType = magicEffect->getMagnitudeDisplayType();
|
||||
if ( displayType == ESM::MagicEffect::MDT_TimesInt ) {
|
||||
std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", "");
|
||||
std::stringstream formatter;
|
||||
|
||||
formatter << std::fixed << std::setprecision(1) << " " << (mEffectParams.mMagnMin / 10.0f);
|
||||
if (mEffectParams.mMagnMin != mEffectParams.mMagnMax)
|
||||
formatter << to << (mEffectParams.mMagnMax / 10.0f);
|
||||
formatter << timesInt;
|
||||
|
||||
spellLine += formatter.str();
|
||||
}
|
||||
else if ( displayType != ESM::MagicEffect::MDT_None ) {
|
||||
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin);
|
||||
if (mEffectParams.mMagnMin != mEffectParams.mMagnMax)
|
||||
spellLine += to + boost::lexical_cast<std::string>(mEffectParams.mMagnMax);
|
||||
|
||||
if ( displayType == ESM::MagicEffect::MDT_Percentage )
|
||||
spellLine += pct;
|
||||
else if ( displayType == ESM::MagicEffect::MDT_Feet )
|
||||
spellLine += " " + ft;
|
||||
else if ( displayType == ESM::MagicEffect::MDT_Level )
|
||||
spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? lvl : lvls );
|
||||
else // ESM::MagicEffect::MDT_Points
|
||||
spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? pt : pts );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,20 +61,23 @@ namespace MWGui
|
|||
const Compiler::Extensions& extensions, int fpsLevel, OEngine::Render::OgreRenderer *ogre,
|
||||
const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts,
|
||||
Translation::Storage& translationDataStorage, ToUTF8::FromType encoding)
|
||||
: mGuiManager(NULL)
|
||||
, mConsoleOnlyScripts(consoleOnlyScripts)
|
||||
: mConsoleOnlyScripts(consoleOnlyScripts)
|
||||
, mGuiManager(NULL)
|
||||
, mRendering(ogre)
|
||||
, mHud(NULL)
|
||||
, mMap(NULL)
|
||||
, mMenu(NULL)
|
||||
, mStatsWindow(NULL)
|
||||
, mToolTips(NULL)
|
||||
, mStatsWindow(NULL)
|
||||
, mMessageBoxManager(NULL)
|
||||
, mConsole(NULL)
|
||||
, mJournal(NULL)
|
||||
, mDialogueWindow(NULL)
|
||||
, mBookWindow(NULL)
|
||||
, mContainerWindow(NULL)
|
||||
, mDragAndDrop(NULL)
|
||||
, mInventoryWindow(NULL)
|
||||
, mScrollWindow(NULL)
|
||||
, mBookWindow(NULL)
|
||||
, mCountDialog(NULL)
|
||||
, mTradeWindow(NULL)
|
||||
, mSpellBuyingWindow(NULL)
|
||||
|
@ -83,27 +86,37 @@ namespace MWGui
|
|||
, mConfirmationDialog(NULL)
|
||||
, mAlchemyWindow(NULL)
|
||||
, mSpellWindow(NULL)
|
||||
, mQuickKeysMenu(NULL)
|
||||
, mLoadingScreen(NULL)
|
||||
, mCharGen(NULL)
|
||||
, mLevelupDialog(NULL)
|
||||
, mWaitDialog(NULL)
|
||||
, mSpellCreationDialog(NULL)
|
||||
, mEnchantingDialog(NULL)
|
||||
, mTrainingWindow(NULL)
|
||||
, mMerchantRepair(NULL)
|
||||
, mRepair(NULL)
|
||||
, mSoulgemDialog(NULL)
|
||||
, mRepair(NULL)
|
||||
, mCompanionWindow(NULL)
|
||||
, mTranslationDataStorage (translationDataStorage)
|
||||
, mSoftwareCursor(NULL)
|
||||
, mCharGen(NULL)
|
||||
, mInputBlocker(NULL)
|
||||
, mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD"))
|
||||
, mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI"))
|
||||
, mHudEnabled(true)
|
||||
, mCursorVisible(true)
|
||||
, mPlayerName()
|
||||
, mPlayerRaceId()
|
||||
, mPlayerAttributes()
|
||||
, mPlayerMajorSkills()
|
||||
, mPlayerMinorSkills()
|
||||
, mPlayerMajorSkills()
|
||||
, mPlayerSkillValues()
|
||||
, mPlayerHealth()
|
||||
, mPlayerMagicka()
|
||||
, mPlayerFatigue()
|
||||
, mGui(NULL)
|
||||
, mGuiModes()
|
||||
, mCursorManager(NULL)
|
||||
, mGarbageDialogs()
|
||||
, mShown(GW_ALL)
|
||||
, mForceHidden(GW_None)
|
||||
|
@ -113,13 +126,7 @@ namespace MWGui
|
|||
, mFPS(0.0f)
|
||||
, mTriangleCount(0)
|
||||
, mBatchCount(0)
|
||||
, mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD"))
|
||||
, mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI"))
|
||||
, mHudEnabled(true)
|
||||
, mTranslationDataStorage (translationDataStorage)
|
||||
, mCursorManager(NULL)
|
||||
, mUseHardwareCursors(Settings::Manager::getBool("hardware cursors", "GUI"))
|
||||
, mCursorVisible(true)
|
||||
{
|
||||
// Set up the GUI system
|
||||
mGuiManager = new OEngine::GUI::MyGUIManager(mRendering->getWindow(), mRendering->getScene(), false, logpath);
|
||||
|
|
|
@ -585,7 +585,7 @@ namespace MWInput
|
|||
mPlayer->pitch(-y/scale);
|
||||
}
|
||||
|
||||
if (arg.zrel)
|
||||
if (arg.zrel && mControlSwitch["playerviewswitch"]) //Check to make sure you are allowed to zoomout and there is a change
|
||||
{
|
||||
MWBase::Environment::get().getWorld()->changeVanityModeScale(arg.zrel);
|
||||
MWBase::Environment::get().getWorld()->setCameraDistance(arg.zrel, true, true);
|
||||
|
@ -617,9 +617,15 @@ namespace MWInput
|
|||
if (MWBase::Environment::get().getWindowManager()->isGuiMode () && MWBase::Environment::get().getWindowManager()->getMode () == MWGui::GM_Video)
|
||||
MWBase::Environment::get().getWorld ()->stopVideo ();
|
||||
else if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu))
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
MWBase::Environment::get().getSoundManager()->resumeSounds (MWBase::SoundManager::Play_TypeSfx);
|
||||
}
|
||||
else
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
|
||||
MWBase::Environment::get().getSoundManager()->pauseSounds (MWBase::SoundManager::Play_TypeSfx);
|
||||
}
|
||||
}
|
||||
|
||||
void InputManager::toggleSpell()
|
||||
|
|
|
@ -31,11 +31,14 @@ namespace MWMechanics
|
|||
calculateDynamicStats (ptr);
|
||||
calculateCreatureStatModifiers (ptr);
|
||||
|
||||
// AI
|
||||
if(!MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
{
|
||||
// AI
|
||||
CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
|
||||
creatureStats.getAiSequence().execute (ptr);
|
||||
|
||||
// fatigue restoration
|
||||
calculateRestoration(ptr, duration);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,39 +96,29 @@ namespace MWMechanics
|
|||
void Actors::calculateRestoration (const MWWorld::Ptr& ptr, float duration)
|
||||
{
|
||||
CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
|
||||
const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
|
||||
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
|
||||
|
||||
float capacity = MWWorld::Class::get(ptr).getCapacity(ptr);
|
||||
float encumbrance = MWWorld::Class::get(ptr).getEncumbrance(ptr);
|
||||
float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity);
|
||||
if (normalizedEncumbrance > 1)
|
||||
normalizedEncumbrance = 1;
|
||||
|
||||
if (duration == 3600)
|
||||
{
|
||||
bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0;
|
||||
// the actor is sleeping, restore health and magicka
|
||||
|
||||
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
|
||||
bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0;
|
||||
|
||||
DynamicStat<float> health = stats.getHealth();
|
||||
health.setCurrent (health.getCurrent() + 0.1 * endurance);
|
||||
stats.setHealth (health);
|
||||
|
||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
float fFatigueReturnBase = store.get<ESM::GameSetting>().find("fFatigueReturnBase")->getFloat ();
|
||||
float fFatigueReturnMult = store.get<ESM::GameSetting>().find("fFatigueReturnMult")->getFloat ();
|
||||
float fEndFatigueMult = store.get<ESM::GameSetting>().find("fEndFatigueMult")->getFloat ();
|
||||
|
||||
float capacity = MWWorld::Class::get(ptr).getCapacity(ptr);
|
||||
float encumbrance = MWWorld::Class::get(ptr).getEncumbrance(ptr);
|
||||
float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity);
|
||||
if (normalizedEncumbrance > 1)
|
||||
normalizedEncumbrance = 1;
|
||||
|
||||
float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance);
|
||||
x *= fEndFatigueMult * endurance;
|
||||
|
||||
DynamicStat<float> fatigue = stats.getFatigue();
|
||||
fatigue.setCurrent (fatigue.getCurrent() + 3600 * x);
|
||||
stats.setFatigue (fatigue);
|
||||
|
||||
if (!stunted)
|
||||
{
|
||||
float fRestMagicMult = store.get<ESM::GameSetting>().find("fRestMagicMult")->getFloat ();
|
||||
float fRestMagicMult = settings.find("fRestMagicMult")->getFloat ();
|
||||
|
||||
DynamicStat<float> magicka = stats.getMagicka();
|
||||
magicka.setCurrent (magicka.getCurrent()
|
||||
|
@ -133,6 +126,19 @@ namespace MWMechanics
|
|||
stats.setMagicka (magicka);
|
||||
}
|
||||
}
|
||||
|
||||
// restore fatigue
|
||||
|
||||
float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat ();
|
||||
float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat ();
|
||||
float fEndFatigueMult = settings.find("fEndFatigueMult")->getFloat ();
|
||||
|
||||
float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance);
|
||||
x *= fEndFatigueMult * endurance;
|
||||
|
||||
DynamicStat<float> fatigue = stats.getFatigue();
|
||||
fatigue.setCurrent (fatigue.getCurrent() + duration * x);
|
||||
stats.setFatigue (fatigue);
|
||||
}
|
||||
|
||||
void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr)
|
||||
|
@ -275,9 +281,9 @@ namespace MWMechanics
|
|||
continue;
|
||||
}
|
||||
|
||||
// workaround: always keep player alive for now
|
||||
// \todo remove workaround, once player death can be handled
|
||||
if(iter->first.getRefData().getHandle()=="player")
|
||||
// If it's the player and God Mode is turned on, keep it alive
|
||||
if(iter->first.getRefData().getHandle()=="player" &&
|
||||
MWBase::Environment::get().getWorld()->getGodModeState())
|
||||
{
|
||||
MWMechanics::DynamicStat<float> stat(stats.getHealth());
|
||||
|
||||
|
|
|
@ -767,10 +767,25 @@ void CharacterController::update(float duration)
|
|||
}
|
||||
|
||||
if(sneak || inwater || flying)
|
||||
{
|
||||
vec.z = 0.0f;
|
||||
mFallHeight = mPtr.getRefData().getPosition().pos[2];
|
||||
}
|
||||
|
||||
if(!onground && !flying && !inwater)
|
||||
{
|
||||
// The player is in the air (either getting up —ascending part of jump— or falling).
|
||||
|
||||
if (world->isSlowFalling(mPtr))
|
||||
{
|
||||
// SlowFalling spell effect is active, do not keep previous fall height
|
||||
mFallHeight = mPtr.getRefData().getPosition().pos[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
mFallHeight = std::max(mFallHeight, mPtr.getRefData().getPosition().pos[2]);
|
||||
}
|
||||
|
||||
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
||||
|
||||
forcestateupdate = (mJumpState != JumpState_Falling);
|
||||
|
@ -794,6 +809,8 @@ void CharacterController::update(float duration)
|
|||
}
|
||||
else if(vec.z > 0.0f && mJumpState == JumpState_None)
|
||||
{
|
||||
// The player has started a jump.
|
||||
|
||||
float z = cls.getJump(mPtr);
|
||||
if(vec.x == 0 && vec.y == 0)
|
||||
vec = Ogre::Vector3(0.0f, 0.0f, z);
|
||||
|
@ -803,13 +820,49 @@ void CharacterController::update(float duration)
|
|||
vec = Ogre::Vector3(lat.x, lat.y, 1.0f) * z * 0.707f;
|
||||
}
|
||||
|
||||
//decrease fatigue by fFatigueJumpBase + (1 - normalizedEncumbrance) * fFatigueJumpMult;
|
||||
// advance acrobatics
|
||||
cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0);
|
||||
|
||||
// decrease fatigue
|
||||
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
||||
const float fatigueJumpBase = gmst.find("fFatigueJumpBase")->getFloat();
|
||||
const float fatigueJumpMult = gmst.find("fFatigueJumpMult")->getFloat();
|
||||
const float normalizedEncumbrance = cls.getEncumbrance(mPtr) / cls.getCapacity(mPtr);
|
||||
const int fatigueDecrease = fatigueJumpBase + (1 - normalizedEncumbrance) * fatigueJumpMult;
|
||||
DynamicStat<float> fatigue = cls.getCreatureStats(mPtr).getFatigue();
|
||||
fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease);
|
||||
cls.getCreatureStats(mPtr).setFatigue(fatigue);
|
||||
}
|
||||
else if(mJumpState == JumpState_Falling)
|
||||
{
|
||||
// The player is landing.
|
||||
|
||||
forcestateupdate = true;
|
||||
mJumpState = JumpState_Landing;
|
||||
vec.z = 0.0f;
|
||||
|
||||
float healthLost = cls.getFallDamage(mPtr, mFallHeight - mPtr.getRefData().getPosition().pos[2]);
|
||||
if (healthLost > 0.0f)
|
||||
{
|
||||
const float fatigueTerm = cls.getCreatureStats(mPtr).getFatigueTerm();
|
||||
|
||||
// inflict fall damages
|
||||
DynamicStat<float> health = cls.getCreatureStats(mPtr).getHealth();
|
||||
int realHealthLost = healthLost * (1.0f - 0.25 * fatigueTerm);
|
||||
health.setCurrent(health.getCurrent() - realHealthLost);
|
||||
cls.getCreatureStats(mPtr).setHealth(health);
|
||||
|
||||
// report acrobatics progression
|
||||
cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1);
|
||||
|
||||
const float acrobaticsSkill = cls.getNpcStats(mPtr).getSkill(ESM::Skill::Acrobatics).getModified();
|
||||
if (healthLost > (acrobaticsSkill * fatigueTerm))
|
||||
{
|
||||
//TODO: actor falls over
|
||||
}
|
||||
}
|
||||
|
||||
mFallHeight = mPtr.getRefData().getPosition().pos[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <OgreVector3.h>
|
||||
|
||||
#include <components/esm/loadmgef.hpp>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
|
@ -154,6 +156,9 @@ class CharacterController
|
|||
float mSecondsOfSwimming;
|
||||
float mSecondsOfRunning;
|
||||
|
||||
// used for acrobatics progress and fall damages
|
||||
float mFallHeight;
|
||||
|
||||
std::string mAttackType; // slash, chop or thrust
|
||||
|
||||
void refreshCurrentAnims(CharacterState idle, CharacterState movement, bool force=false);
|
||||
|
|
|
@ -151,8 +151,7 @@ namespace MWMechanics
|
|||
for (Collection::const_iterator iter (prev.begin()); iter!=prev.end(); ++iter)
|
||||
{
|
||||
Collection::const_iterator other = now.mCollection.find (iter->first);
|
||||
|
||||
if (other==prev.end())
|
||||
if (other==now.end())
|
||||
{
|
||||
result.add (iter->first, EffectParam() - iter->second);
|
||||
}
|
||||
|
|
|
@ -187,6 +187,12 @@ namespace MWRender
|
|||
rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false);
|
||||
}
|
||||
|
||||
void Camera::setSneakOffset()
|
||||
{
|
||||
if(mAnimation)
|
||||
mAnimation->addFirstPersonOffset(Ogre::Vector3(0.f, 0.f, -9.8f));
|
||||
}
|
||||
|
||||
float Camera::getYaw()
|
||||
{
|
||||
if(mVanity.enabled || mPreviewMode)
|
||||
|
|
|
@ -79,6 +79,12 @@ namespace MWRender
|
|||
|
||||
void togglePreviewMode(bool enable);
|
||||
|
||||
/// \brief Lowers the camera for sneak.
|
||||
/// As animation is tied to the camera, this needs
|
||||
/// to be set each frame after the animation is
|
||||
/// applied.
|
||||
void setSneakOffset();
|
||||
|
||||
bool isFirstPerson() const
|
||||
{ return !(mVanity.enabled || mPreviewMode || !mFirstPersonView); }
|
||||
|
||||
|
|
|
@ -84,7 +84,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
|
|||
mWeapon(inv.end()),
|
||||
mShield(inv.end()),
|
||||
mViewMode(viewMode),
|
||||
mShowWeapons(false)
|
||||
mShowWeapons(false),
|
||||
mFirstPersonOffset(0.f, 0.f, 0.f)
|
||||
{
|
||||
mNpc = mPtr.get<ESM::NPC>()->mBase;
|
||||
|
||||
|
@ -392,6 +393,11 @@ void NpcAnimation::updateParts(bool forceupdate)
|
|||
}
|
||||
}
|
||||
|
||||
void NpcAnimation::addFirstPersonOffset(const Ogre::Vector3 &offset)
|
||||
{
|
||||
mFirstPersonOffset += offset;
|
||||
}
|
||||
|
||||
class SetObjectGroup {
|
||||
int mGroup;
|
||||
|
||||
|
@ -448,7 +454,12 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed)
|
|||
float pitch = mCamera->getPitch();
|
||||
Ogre::Node *node = baseinst->getBone("Bip01 Neck");
|
||||
node->pitch(Ogre::Radian(pitch*0.75f), Ogre::Node::TS_WORLD);
|
||||
|
||||
// This has to be done before this function ends;
|
||||
// updateSkeletonInstance, below, touches the hands.
|
||||
node->translate(mFirstPersonOffset, Ogre::Node::TS_WORLD);
|
||||
}
|
||||
mFirstPersonOffset = 0.f; // reset the X, Y, Z offset for the next frame.
|
||||
|
||||
for(size_t i = 0;i < ESM::PRT_Count;i++)
|
||||
{
|
||||
|
|
|
@ -64,6 +64,8 @@ private:
|
|||
int mPartslots[ESM::PRT_Count]; //Each part slot is taken by clothing, armor, or is empty
|
||||
int mPartPriorities[ESM::PRT_Count];
|
||||
|
||||
Ogre::Vector3 mFirstPersonOffset;
|
||||
|
||||
void updateNpcBase();
|
||||
|
||||
NifOgre::ObjectList insertBoundedPart(const std::string &model, int group, const std::string &bonename);
|
||||
|
@ -89,6 +91,11 @@ public:
|
|||
|
||||
void updateParts(bool forceupdate = false);
|
||||
|
||||
/// \brief Applies a translation to the arms and hands.
|
||||
/// This may be called multiple times before the animation
|
||||
/// is updated to add additional offsets.
|
||||
void addFirstPersonOffset(const Ogre::Vector3 &offset);
|
||||
|
||||
/// Rebuilds the NPC, updating their root model, animation sources, and equipment.
|
||||
void rebuild();
|
||||
};
|
||||
|
|
|
@ -354,6 +354,15 @@ void RenderingManager::update (float duration, bool paused)
|
|||
mCamera->setCameraDistance(test.second * orig.distance(dest), false, false);
|
||||
}
|
||||
|
||||
// Sink the camera while sneaking
|
||||
bool isSneaking = MWWorld::Class::get(player).getStance(player, MWWorld::Class::Sneak);
|
||||
bool isInAir = !world->isOnGround(player);
|
||||
bool isSwimming = world->isSwimming(player);
|
||||
|
||||
if(isSneaking && !(isSwimming || isInAir))
|
||||
mCamera->setSneakOffset();
|
||||
|
||||
|
||||
mOcclusionQuery->update(duration);
|
||||
|
||||
mVideoPlayer->update ();
|
||||
|
@ -760,6 +769,13 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
|
|||
|| it->second == "resolution y"
|
||||
|| it->second == "fullscreen"))
|
||||
changeRes = true;
|
||||
else if (it->first == "Video" && it->second == "vsync")
|
||||
{
|
||||
// setVSyncEnabled is bugged in 1.8
|
||||
#if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0)
|
||||
mRendering.getWindow()->setVSyncEnabled(Settings::Manager::getBool("vsync", "Video"));
|
||||
#endif
|
||||
}
|
||||
else if (it->second == "field of view" && it->first == "General")
|
||||
mRendering.setFov(Settings::Manager::getFloat("field of view", "General"));
|
||||
else if ((it->second == "texture filtering" && it->first == "General")
|
||||
|
|
|
@ -352,5 +352,7 @@ op 0x200021c: SetWerewolfAcrobaticsExplicit
|
|||
op 0x200021d: ShowVars
|
||||
op 0x200021e: ShowVarsExplicit
|
||||
op 0x200021f: ToggleGodMode
|
||||
op 0x2000220: DisableLevitation
|
||||
op 0x2000221: EnableLevitation
|
||||
|
||||
opcodes 0x2000220-0x3ffffff unused
|
||||
opcodes 0x2000222-0x3ffffff unused
|
||||
|
|
|
@ -636,6 +636,17 @@ namespace MWScript
|
|||
}
|
||||
};
|
||||
|
||||
template <bool Enable>
|
||||
class OpEnableLevitation : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
world->enableLevitation(Enable);
|
||||
}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
class OpShowVars : public Interpreter::Opcode0
|
||||
|
@ -726,8 +737,7 @@ namespace MWScript
|
|||
|
||||
bool enabled = MWBase::Environment::get().getWorld()->toggleGodMode();
|
||||
|
||||
// context.report (enabled ? "God Mode -> On" : "God Mode -> Off");
|
||||
context.report("Unimplemented");
|
||||
context.report (enabled ? "God Mode -> On" : "God Mode -> Off");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -790,6 +800,8 @@ namespace MWScript
|
|||
interpreter.installSegment5 (Compiler::Misc::opcodeShowVars, new OpShowVars<ImplicitRef>);
|
||||
interpreter.installSegment5 (Compiler::Misc::opcodeShowVarsExplicit, new OpShowVars<ExplicitRef>);
|
||||
interpreter.installSegment5 (Compiler::Misc::opcodeToggleGodMode, new OpToggleGodMode);
|
||||
interpreter.installSegment5 (Compiler::Misc::opcodeDisableLevitation, new OpEnableLevitation<false>);
|
||||
interpreter.installSegment5 (Compiler::Misc::opcodeEnableLevitation, new OpEnableLevitation<true>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,6 +167,11 @@ namespace MWWorld
|
|||
throw std::runtime_error ("class does not support enchanting");
|
||||
}
|
||||
|
||||
float Class::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
MWMechanics::Movement& Class::getMovementSettings (const Ptr& ptr) const
|
||||
{
|
||||
throw std::runtime_error ("movement settings not supported by class");
|
||||
|
|
|
@ -175,6 +175,9 @@ namespace MWWorld
|
|||
virtual float getJump(const MWWorld::Ptr &ptr) const;
|
||||
///< Return jump velocity (not accounting for movement)
|
||||
|
||||
virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const;
|
||||
///< Return amount of health points lost when falling
|
||||
|
||||
virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const;
|
||||
///< Return desired movement.
|
||||
|
||||
|
|
|
@ -656,26 +656,38 @@ namespace MWWorld
|
|||
return iterator(mSharedExt.end());
|
||||
}
|
||||
|
||||
/// \todo implement appropriate index
|
||||
// Return the northernmost cell in the easternmost column.
|
||||
const ESM::Cell *searchExtByName(const std::string &id) const {
|
||||
ESM::Cell *cell = 0;
|
||||
std::vector<ESM::Cell *>::const_iterator it = mSharedExt.begin();
|
||||
for (; it != mSharedExt.end(); ++it) {
|
||||
if (Misc::StringUtils::ciEqual((*it)->mName, id)) {
|
||||
return *it;
|
||||
if ( cell == 0 ||
|
||||
( (*it)->mData.mX > cell->mData.mX ) ||
|
||||
( (*it)->mData.mX == cell->mData.mX && (*it)->mData.mY > cell->mData.mY ) )
|
||||
{
|
||||
cell = *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return cell;
|
||||
}
|
||||
|
||||
/// \todo implement appropriate index
|
||||
// Return the northernmost cell in the easternmost column.
|
||||
const ESM::Cell *searchExtByRegion(const std::string &id) const {
|
||||
ESM::Cell *cell = 0;
|
||||
std::vector<ESM::Cell *>::const_iterator it = mSharedExt.begin();
|
||||
for (; it != mSharedExt.end(); ++it) {
|
||||
if (Misc::StringUtils::ciEqual((*it)->mRegion, id)) {
|
||||
return *it;
|
||||
if ( cell == 0 ||
|
||||
( (*it)->mData.mX > cell->mData.mX ) ||
|
||||
( (*it)->mData.mX == cell->mData.mX && (*it)->mData.mY > cell->mData.mY ) )
|
||||
{
|
||||
cell = *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return cell;
|
||||
}
|
||||
|
||||
size_t getSize() const {
|
||||
|
|
|
@ -170,7 +170,7 @@ namespace MWWorld
|
|||
mSky (true), mCells (mStore, mEsm),
|
||||
mActivationDistanceOverride (mActivationDistanceOverride),
|
||||
mFallback(fallbackMap), mPlayIntro(0), mTeleportEnabled(true),
|
||||
mFacedDistance(FLT_MAX)
|
||||
mFacedDistance(FLT_MAX), mGodMode(false)
|
||||
{
|
||||
mPhysics = new PhysicsSystem(renderer);
|
||||
mPhysEngine = mPhysics->getEngine();
|
||||
|
@ -225,8 +225,8 @@ namespace MWWorld
|
|||
if (mEsm[0].getFormat() == 0)
|
||||
ensureNeededRecords();
|
||||
|
||||
mStore.movePlayerRecord();
|
||||
mStore.setUp();
|
||||
mStore.movePlayerRecord();
|
||||
|
||||
mGlobalVariables = new Globals (mStore);
|
||||
|
||||
|
@ -1582,6 +1582,19 @@ namespace MWWorld
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
World::isSlowFalling(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
if(!ptr.getClass().isActor())
|
||||
return false;
|
||||
|
||||
const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
|
||||
if(stats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::SlowFall)).mMagnitude > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool World::isSubmerged(const MWWorld::Ptr &object) const
|
||||
{
|
||||
float *fpos = object.getRefData().getPosition().pos;
|
||||
|
@ -1877,6 +1890,16 @@ namespace MWWorld
|
|||
return mTeleportEnabled;
|
||||
}
|
||||
|
||||
void World::enableLevitation(bool enable)
|
||||
{
|
||||
mLevitationEnabled = enable;
|
||||
}
|
||||
|
||||
bool World::isLevitationEnabled() const
|
||||
{
|
||||
return mLevitationEnabled;
|
||||
}
|
||||
|
||||
void World::setWerewolf(const MWWorld::Ptr& actor, bool werewolf)
|
||||
{
|
||||
MWMechanics::NpcStats& npcStats = Class::get(actor).getNpcStats(actor);
|
||||
|
@ -1948,9 +1971,16 @@ namespace MWWorld
|
|||
stats.getSkill(ESM::Skill::Acrobatics).setModified(gmst.find("fWerewolfAcrobatics")->getFloat(), 0);
|
||||
}
|
||||
|
||||
bool World::getGodModeState()
|
||||
{
|
||||
return mGodMode;
|
||||
}
|
||||
|
||||
bool World::toggleGodMode()
|
||||
{
|
||||
return false;
|
||||
mGodMode = !mGodMode;
|
||||
|
||||
return mGodMode;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -68,6 +68,8 @@ namespace MWWorld
|
|||
|
||||
OEngine::Physic::PhysicEngine* mPhysEngine;
|
||||
|
||||
bool mGodMode;
|
||||
|
||||
// not implemented
|
||||
World (const World&);
|
||||
World& operator= (const World&);
|
||||
|
@ -114,6 +116,7 @@ namespace MWWorld
|
|||
int mPlayIntro;
|
||||
|
||||
bool mTeleportEnabled;
|
||||
bool mLevitationEnabled;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -353,6 +356,7 @@ namespace MWWorld
|
|||
virtual void processChangedSettings(const Settings::CategorySettingVector& settings);
|
||||
|
||||
virtual bool isFlying(const MWWorld::Ptr &ptr) const;
|
||||
virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const;
|
||||
///Is the head of the creature underwater?
|
||||
virtual bool isSubmerged(const MWWorld::Ptr &object) const;
|
||||
virtual bool isSwimming(const MWWorld::Ptr &object) const;
|
||||
|
@ -436,10 +440,18 @@ namespace MWWorld
|
|||
/// Returns true if teleport spell effects are allowed.
|
||||
virtual bool isTeleportingEnabled() const;
|
||||
|
||||
/// Enables or disables use of levitation spell effect.
|
||||
virtual void enableLevitation(bool enable);
|
||||
|
||||
/// Returns true if levitation spell effect is allowed.
|
||||
virtual bool isLevitationEnabled() const;
|
||||
|
||||
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf);
|
||||
|
||||
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor);
|
||||
|
||||
virtual bool getGodModeState();
|
||||
|
||||
virtual bool toggleGodMode();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -260,6 +260,8 @@ namespace Compiler
|
|||
extensions.registerInstruction ("sv", "", opcodeShowVars, opcodeShowVarsExplicit);
|
||||
extensions.registerInstruction("tgm", "", opcodeToggleGodMode);
|
||||
extensions.registerInstruction("togglegodmode", "", opcodeToggleGodMode);
|
||||
extensions.registerInstruction ("disablelevitation", "", opcodeDisableLevitation);
|
||||
extensions.registerInstruction ("enablelevitation", "", opcodeEnableLevitation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -222,6 +222,8 @@ namespace Compiler
|
|||
const int opcodeShowVars = 0x200021d;
|
||||
const int opcodeShowVarsExplicit = 0x200021e;
|
||||
const int opcodeToggleGodMode = 0x200021f;
|
||||
const int opcodeDisableLevitation = 0x2000220;
|
||||
const int opcodeEnableLevitation = 0x2000221;
|
||||
}
|
||||
|
||||
namespace Sky
|
||||
|
|
|
@ -274,5 +274,23 @@ short MagicEffect::effectStringToId(const std::string &effect)
|
|||
return name->first;
|
||||
}
|
||||
|
||||
MagicEffect::MagnitudeDisplayType MagicEffect::getMagnitudeDisplayType() const {
|
||||
if ( mData.mFlags & NoMagnitude )
|
||||
return MDT_None;
|
||||
if ( mIndex == 84 )
|
||||
return MDT_TimesInt;
|
||||
if ( mIndex == 59 ||
|
||||
( mIndex >= 64 && mIndex <= 66) )
|
||||
return MDT_Feet;
|
||||
if ( mIndex == 118 || mIndex == 119 )
|
||||
return MDT_Level;
|
||||
if ( ( mIndex >= 28 && mIndex <= 36 )
|
||||
|| ( mIndex >= 90 && mIndex <= 99 )
|
||||
|| mIndex == 40 || mIndex == 47
|
||||
|| mIndex == 57 || mIndex == 68 )
|
||||
return MDT_Percentage;
|
||||
|
||||
return MDT_Points;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,15 @@ struct MagicEffect
|
|||
Negative = 0x0800 // A harmful effect. Will determine whether
|
||||
// eg. NPCs regard this spell as an attack. (same as 0x10?)
|
||||
};
|
||||
enum MagnitudeDisplayType
|
||||
{
|
||||
MDT_None,
|
||||
MDT_Feet,
|
||||
MDT_Level,
|
||||
MDT_Percentage,
|
||||
MDT_Points,
|
||||
MDT_TimesInt
|
||||
};
|
||||
|
||||
struct MEDTstruct
|
||||
{
|
||||
|
@ -47,6 +56,7 @@ struct MagicEffect
|
|||
|
||||
static const std::string &effectIdToString(short effectID);
|
||||
static short effectStringToId(const std::string &effect);
|
||||
MagnitudeDisplayType getMagnitudeDisplayType() const;
|
||||
|
||||
|
||||
MEDTstruct mData;
|
||||
|
|
|
@ -425,7 +425,7 @@ void Node::getProperties(const Nif::NiTexturingProperty *&texprop,
|
|||
|
||||
Ogre::Matrix4 Node::getLocalTransform() const
|
||||
{
|
||||
Ogre::Matrix4 mat4(Ogre::Matrix4::IDENTITY);
|
||||
Ogre::Matrix4 mat4 = Ogre::Matrix4(Ogre::Matrix4::IDENTITY);
|
||||
mat4.makeTransform(trafo.pos, Ogre::Vector3(trafo.scale), Ogre::Quaternion(trafo.rotation));
|
||||
return mat4;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ Marc Zinnschlag (Zini) - Lead Programmer/Project Manager
|
|||
|
||||
Adam Hogan (aurix)
|
||||
Aleksandar Jovanov
|
||||
Alex Haddad (rainChu)
|
||||
Alex McKibben (WeirdSexy)
|
||||
Alexander Nadeau (wareya)
|
||||
Alexander Olofsson (Ace)
|
||||
|
@ -47,6 +48,7 @@ Marc Bouvier (CramitDeFrog)
|
|||
Marcin Hulist (Gohan)
|
||||
Mark Siewert (mark76)
|
||||
Mateusz Kołaczek (PL_kolek)
|
||||
Michael Hogan (Xethik)
|
||||
Michael Mc Donnell
|
||||
Michael Papageorgiou (werdanith)
|
||||
Michał Bień (Glorf)
|
||||
|
@ -61,6 +63,7 @@ Roman Proskuryakov (humbug)
|
|||
Sandy Carter (bwrsandman)
|
||||
Sebastian Wick (swick)
|
||||
Sergey Shambir
|
||||
sir_herrbatka
|
||||
Sylvain Thesnieres (Garvek)
|
||||
Tom Mason (wheybags)
|
||||
Torben Leif Carrington (TorbenC)
|
||||
|
|
3
extern/sdl4ogre/sdlinputwrapper.cpp
vendored
|
@ -30,9 +30,6 @@ namespace SFO
|
|||
|
||||
InputWrapper::~InputWrapper()
|
||||
{
|
||||
if(mSDLWindow != NULL)
|
||||
SDL_DestroyWindow(mSDLWindow);
|
||||
mSDLWindow = NULL;
|
||||
}
|
||||
|
||||
void InputWrapper::capture(bool windowEventsOnly)
|
||||
|
|
BIN
files/opencs/GMST.png
Normal file
After Width: | Height: | Size: 820 B |
BIN
files/opencs/Info.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
files/opencs/LandTexture.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
files/opencs/PathGrid.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
files/opencs/activator.png
Executable file → Normal file
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 615 B |
0
files/opencs/apparatus.png
Executable file → Normal file
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
0
files/opencs/armor.png
Executable file → Normal file
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |