Conflicts:
	apps/openmw/mwdialogue/dialoguemanagerimp.cpp
	apps/openmw/mwworld/worldimp.cpp
	components/esm_store/reclists.hpp
	components/misc/stringops.hpp
actorid
eduard 12 years ago
commit c85400b809

1
.gitignore vendored

@ -14,3 +14,4 @@ Makefile
makefile
data
*.kdev4
CMakeLists.txt.user

4
.gitmodules vendored

@ -1,3 +1 @@
[submodule "extern/shiny"]
path = extern/shiny
url = git://github.com/scrawl/shiny.git

@ -15,7 +15,7 @@ include (OpenMWMacros)
# Version
set (OPENMW_VERSION_MAJOR 0)
set (OPENMW_VERSION_MINOR 19)
set (OPENMW_VERSION_MINOR 20)
set (OPENMW_VERSION_RELEASE 0)
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
@ -25,12 +25,14 @@ set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VE
configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp")
option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE)
option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE)
option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE)
option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE)
# Apps and tools
option(BUILD_ESMTOOL "build ESM inspector" ON)
option(BUILD_LAUNCHER "build Launcher" ON)
option(BUILD_MWINIIMPORTER "build MWiniImporter" ON)
option(BUILD_OPENCS "build OpenMW Construction Set" ON)
option(BUILD_WITH_CODE_COVERAGE "Enable code coverage with gconv" OFF)
option(BUILD_UNITTESTS "Enable Unittests with Google C++ Unittest ang GMock frameworks" OFF)
@ -167,9 +169,9 @@ if (WIN32)
set(PLATFORM_INCLUDE_DIR "platform")
add_definitions(-DBOOST_ALL_NO_LIB)
else (WIN32)
set(PLATFORM_INCLUDE_DIR "")
find_path (UUID_INCLUDE_DIR uuid/uuid.h)
include_directories(${UUID_INCLUDE_DIR})
set(PLATFORM_INCLUDE_DIR "")
find_path (UUID_INCLUDE_DIR uuid/uuid.h)
include_directories(${UUID_INCLUDE_DIR})
endif (WIN32)
if (MSVC10)
set(PLATFORM_INCLUDE_DIR "")
@ -183,7 +185,7 @@ endif (APPLE)
# Fix for not visible pthreads functions for linker with glibc 2.15
if (UNIX AND NOT APPLE)
find_package (Threads)
find_package (Threads)
endif()
# find boost without components so we can use Boost_VERSION
@ -196,6 +198,10 @@ if (Boost_VERSION LESS 104900)
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} wave)
endif()
IF(BOOST_STATIC)
set(Boost_USE_STATIC_LIBS ON)
endif()
find_package(OGRE REQUIRED)
find_package(MyGUI REQUIRED)
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
@ -244,7 +250,7 @@ if (APPLE)
else ()
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG})
endif ()
#set(OGRE_PLUGIN_DIR "${OGRE_PLUGIN_DIR}/")
configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist
@ -356,7 +362,7 @@ if(DPKG_PROGRAM)
SET(CPACK_DEBIAN_PACKAGE_NAME "openmw")
SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}")
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter")
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-filesystem1.46.1 (>= 1.46.1), libboost-program-options1.46.1 (>= 1.46.1), libboost-system1.46.1 (>= 1.46.1), libboost-thread1.46.1 (>= 1.46.1), libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)")
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)")
SET(CPACK_DEBIAN_PACKAGE_SECTION "Games")
@ -462,6 +468,10 @@ if (BUILD_MWINIIMPORTER)
add_subdirectory( apps/mwiniimporter )
endif()
if (BUILD_OPENCS)
add_subdirectory (apps/opencs)
endif()
# UnitTests
if (BUILD_UNITTESTS)
add_subdirectory( apps/openmw_test_suite )

@ -59,7 +59,7 @@ struct Arguments
std::string outname;
std::vector<std::string> types;
ESMData data;
ESM::ESMReader reader;
ESM::ESMWriter writer;
@ -74,7 +74,7 @@ bool parseOptions (int argc, char** argv, Arguments &info)
("version,v", "print version information and quit.")
("raw,r", "Show an unformatted list of all records and subrecords.")
// The intention is that this option would interact better
// with other modes including clone, dump, and raw.
// with other modes including clone, dump, and raw.
("type,t", bpo::value< std::vector<std::string> >(),
"Show only records of this type (four character record code). May "
"be specified multiple times. Only affects dump mode.")
@ -262,7 +262,7 @@ void printRaw(ESM::ESMReader &esm)
int load(Arguments& info)
{
ESM::ESMReader& esm = info.reader;
esm.setEncoding(info.encoding);
esm.setEncoding(ToUTF8::calculateEncoding(info.encoding));
std::string filename = info.filename;
std::cout << "Loading file: " << filename << std::endl;
@ -321,7 +321,7 @@ int load(Arguments& info)
if (info.types.size() > 0)
{
std::vector<std::string>::iterator match;
match = std::find(info.types.begin(), info.types.end(),
match = std::find(info.types.begin(), info.types.end(),
n.toString());
if (match == info.types.end()) interested = false;
}
@ -425,7 +425,7 @@ int clone(Arguments& info)
if (++i % 3 == 0)
std::cout << std::endl;
}
if (i % 3 != 0)
std::cout << std::endl;
@ -450,7 +450,7 @@ int clone(Arguments& info)
for (Records::iterator it = records.begin(); it != records.end() && i > 0; ++it)
{
EsmTool::RecordBase *record = *it;
name.val = record->getType().val;
esm.startRecord(name.toString(), record->getFlags());
@ -485,7 +485,7 @@ int clone(Arguments& info)
std::cerr << "\r" << perc << "%";
}
}
std::cout << "\rDone!" << std::endl;
esm.close();
@ -513,7 +513,7 @@ int comp(Arguments& info)
fileOne.encoding = info.encoding;
fileTwo.encoding = info.encoding;
fileOne.filename = info.filename;
fileTwo.filename = info.outname;
@ -534,9 +534,9 @@ int comp(Arguments& info)
std::cout << "Not equal, different amount of records." << std::endl;
return 1;
}
return 0;
}

@ -15,7 +15,7 @@ void printAIPackage(ESM::AIPackage p)
std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl;
if (p.mWander.mUnk != 1)
std::cout << " Unknown: " << (int)p.mWander.mUnk << std::endl;
std::cout << " Idle: ";
for (int i = 0; i != 8; i++)
std::cout << (int)p.mWander.mIdle[i] << " ";
@ -28,7 +28,7 @@ void printAIPackage(ESM::AIPackage p)
std::cout << " Travel Unknown: " << (int)p.mTravel.mUnk << std::endl;
}
else if (p.mType == ESM::AI_Follow || p.mType == ESM::AI_Escort)
{
{
std::cout << " Follow Coordinates: (" << p.mTarget.mX << ","
<< p.mTarget.mY << "," << p.mTarget.mZ << ")" << std::endl;
std::cout << " Duration: " << p.mTarget.mDuration << std::endl;
@ -43,7 +43,7 @@ void printAIPackage(ESM::AIPackage p)
else {
std::cout << " BadPackage: " << boost::format("0x%08x") % p.mType << std::endl;
}
if (p.mCellName != "")
std::cout << " Cell Name: " << p.mCellName << std::endl;
}
@ -51,13 +51,13 @@ void printAIPackage(ESM::AIPackage p)
std::string ruleString(ESM::DialInfo::SelectStruct ss)
{
std::string rule = ss.mSelectRule;
if (rule.length() < 5)
return "INVALID";
char type = rule[1];
char indicator = rule[2];
std::string type_str = "INVALID";
std::string func_str = str(boost::format("INVALID=%s") % rule.substr(1,3));
int func;
@ -71,14 +71,14 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
func_str = ruleFunction(func);
break;
case '2':
if (indicator == 's') type_str = "Global short";
else if (indicator == 'l') type_str = "Global long";
else if (indicator == 'f') type_str = "Global float";
if (indicator == 's') type_str = "Global short";
else if (indicator == 'l') type_str = "Global long";
else if (indicator == 'f') type_str = "Global float";
break;
case '3':
if (indicator == 's') type_str = "Local short";
else if (indicator == 'l') type_str = "Local long";
else if (indicator == 'f') type_str = "Local float";
if (indicator == 's') type_str = "Local short";
else if (indicator == 'l') type_str = "Local long";
else if (indicator == 'f') type_str = "Local float";
break;
case '4': if (indicator == 'J') type_str = "Journal"; break;
case '5': if (indicator == 'I') type_str = "Item type"; break;
@ -90,15 +90,15 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
case 'B': if (indicator == 'L') type_str = "Not Cell"; break;
case 'C': if (indicator == 's') type_str = "Not Local"; break;
}
// Append the variable name to the function string if any.
if (type != '1') func_str = rule.substr(5);
// In the previous switch, we assumed that the second char was X
// for all types not qual to one. If this wasn't true, go back to
// the error message.
if (type != '1' && rule[3] != 'X')
func_str = str(boost::format("INVALID=%s") % rule.substr(1,3));
func_str = str(boost::format("INVALID=%s") % rule.substr(1,3));
char oper = rule[4];
std::string oper_str = "??";
@ -117,8 +117,8 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
value_str = str(boost::format("%d") % ss.mI);
else if (ss.mType == ESM::VT_Float)
value_str = str(boost::format("%f") % ss.mF);
std::string result = str(boost::format("%-12s %-32s %2s %s")
std::string result = str(boost::format("%-12s %-32s %2s %s")
% type_str % func_str % oper_str % value_str);
return result;
}
@ -136,7 +136,7 @@ void printEffectList(ESM::EffectList effects)
<< " (" << (int)eit->mSkill << ")" << std::endl;
if (eit->mAttribute != -1)
std::cout << " Attribute: " << attributeLabel(eit->mAttribute)
<< " (" << (int)eit->mAttribute << ")" << std::endl;
<< " (" << (int)eit->mAttribute << ")" << std::endl;
std::cout << " Range: " << rangeTypeLabel(eit->mRange)
<< " (" << eit->mRange << ")" << std::endl;
// Area is always zero if range type is "Self"
@ -412,7 +412,7 @@ void Record<ESM::Armor>::print()
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
std::cout << " Value: " << mData.mData.mValue << std::endl;
std::cout << " Health: " << mData.mData.mHealth << std::endl;
std::cout << " Armor: " << mData.mData.mArmor << std::endl;
std::cout << " Armor: " << mData.mData.mArmor << std::endl;
std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl;
std::vector<ESM::PartReference>::iterator pit;
for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); pit++)
@ -483,7 +483,7 @@ void Record<ESM::BirthSign>::print()
std::cout << " Description: " << mData.mDescription << std::endl;
std::vector<std::string>::iterator pit;
for (pit = mData.mPowers.mList.begin(); pit != mData.mPowers.mList.end(); pit++)
std::cout << " Power: " << *pit << std::endl;
std::cout << " Power: " << *pit << std::endl;
}
template<>
@ -495,12 +495,12 @@ void Record<ESM::Cell>::print()
if (mData.mRegion != "")
std::cout << " Region: " << mData.mRegion << std::endl;
std::cout << " Flags: " << cellFlags(mData.mData.mFlags) << std::endl;
std::cout << " Coordinates: " << " (" << mData.getGridX() << ","
<< mData.getGridY() << ")" << std::endl;
if (mData.mData.mFlags & ESM::Cell::Interior &&
!(mData.mData.mFlags & ESM::Cell::QuasiEx))
if (mData.mData.mFlags & ESM::Cell::Interior &&
!(mData.mData.mFlags & ESM::Cell::QuasiEx))
{
std::cout << " Ambient Light Color: " << mData.mAmbi.mAmbient << std::endl;
std::cout << " Sunlight Color: " << mData.mAmbi.mSunlight << std::endl;
@ -508,7 +508,7 @@ void Record<ESM::Cell>::print()
std::cout << " Fog Density: " << mData.mAmbi.mFogDensity << std::endl;
std::cout << " Water Level: " << mData.mWater << std::endl;
}
else
else
std::cout << " Map Color: " << boost::format("0x%08X") % mData.mMapColor << std::endl;
std::cout << " Water Level Int: " << mData.mWaterInt << std::endl;
std::cout << " NAM0: " << mData.mNAM0 << std::endl;
@ -530,7 +530,7 @@ void Record<ESM::Class>::print()
<< " (" << mData.mData.mSpecialization << ")" << std::endl;
for (int i = 0; i != 5; i++)
std::cout << " Major Skill: " << skillLabel(mData.mData.mSkills[i][0])
<< " (" << mData.mData.mSkills[i][0] << ")" << std::endl;
<< " (" << mData.mData.mSkills[i][0] << ")" << std::endl;
for (int i = 0; i != 5; i++)
std::cout << " Minor Skill: " << skillLabel(mData.mData.mSkills[i][1])
<< " (" << mData.mData.mSkills[i][1] << ")" << std::endl;
@ -573,7 +573,7 @@ void Record<ESM::Container>::print()
std::cout << " Weight: " << mData.mWeight << std::endl;
std::vector<ESM::ContItem>::iterator cit;
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++)
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount
<< " Item: " << cit->mItem.toString() << std::endl;
}
@ -608,17 +608,17 @@ void Record<ESM::Creature>::print()
std::cout << " Combat: " << mData.mData.mCombat << std::endl;
std::cout << " Magic: " << mData.mData.mMagic << std::endl;
std::cout << " Stealth: " << mData.mData.mStealth << std::endl;
std::cout << " Attack1: " << mData.mData.mAttack[0]
std::cout << " Attack1: " << mData.mData.mAttack[0]
<< "-" << mData.mData.mAttack[1] << std::endl;
std::cout << " Attack2: " << mData.mData.mAttack[2]
std::cout << " Attack2: " << mData.mData.mAttack[2]
<< "-" << mData.mData.mAttack[3] << std::endl;
std::cout << " Attack3: " << mData.mData.mAttack[4]
std::cout << " Attack3: " << mData.mData.mAttack[4]
<< "-" << mData.mData.mAttack[5] << std::endl;
std::cout << " Gold: " << mData.mData.mGold << std::endl;
std::vector<ESM::ContItem>::iterator cit;
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++)
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount
<< " Item: " << cit->mItem.toString() << std::endl;
std::vector<std::string>::iterator sit;
@ -694,15 +694,15 @@ void Record<ESM::Faction>::print()
if (mData.mRanks[i] != "")
{
std::cout << " Rank: " << mData.mRanks[i] << std::endl;
std::cout << " Attribute1 Requirement: "
std::cout << " Attribute1 Requirement: "
<< mData.mData.mRankData[i].mAttribute1 << std::endl;
std::cout << " Attribute2 Requirement: "
std::cout << " Attribute2 Requirement: "
<< mData.mData.mRankData[i].mAttribute2 << std::endl;
std::cout << " One Skill at Level: "
<< mData.mData.mRankData[i].mSkill1 << std::endl;
std::cout << " Two Skills at Level: "
std::cout << " Two Skills at Level: "
<< mData.mData.mRankData[i].mSkill2 << std::endl;
std::cout << " Faction Reaction: "
std::cout << " Faction Reaction: "
<< mData.mData.mRankData[i].mFactReaction << std::endl;
}
std::vector<ESM::Faction::Reaction>::iterator rit;
@ -738,7 +738,6 @@ void Record<ESM::GameSetting>::print()
default:
std::cout << "unknown type";
}
std::cout << "\n Dirty: " << mData.mDirty << std::endl;
}
template<>
@ -849,7 +848,7 @@ void Record<ESM::CreatureLevList>::print()
std::cout << " Number of items: " << mData.mList.size() << std::endl;
std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++)
std::cout << " Creature: Level: " << iit->mLevel
std::cout << " Creature: Level: " << iit->mLevel
<< " Creature: " << iit->mId << std::endl;
}
@ -1012,11 +1011,11 @@ void Record<ESM::NPC>::print()
std::cout << " Disposition: " << (int)mData.mNpdt12.mDisposition << std::endl;
std::cout << " Faction: " << (int)mData.mNpdt52.mFactionID << std::endl;
std::cout << " Rank: " << (int)mData.mNpdt12.mRank << std::endl;
std::cout << " Unknown1: "
std::cout << " Unknown1: "
<< (unsigned int)((unsigned char)mData.mNpdt12.mUnknown1) << std::endl;
std::cout << " Unknown2: "
std::cout << " Unknown2: "
<< (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl;
std::cout << " Unknown3: "
std::cout << " Unknown3: "
<< (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl;
std::cout << " Gold: " << (int)mData.mNpdt12.mGold << std::endl;
}
@ -1038,9 +1037,9 @@ void Record<ESM::NPC>::print()
std::cout << " Skills:" << std::endl;
for (int i = 0; i != 27; i++)
std::cout << " " << skillLabel(i) << ": "
<< (int)((unsigned char)mData.mNpdt52.mSkills[i]) << std::endl;
std::cout << " " << skillLabel(i) << ": "
<< (int)((unsigned char)mData.mNpdt52.mSkills[i]) << std::endl;
std::cout << " Health: " << mData.mNpdt52.mHealth << std::endl;
std::cout << " Magicka: " << mData.mNpdt52.mMana << std::endl;
std::cout << " Fatigue: " << mData.mNpdt52.mFatigue << std::endl;
@ -1050,9 +1049,9 @@ void Record<ESM::NPC>::print()
std::vector<ESM::ContItem>::iterator cit;
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++)
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount
<< " Item: " << cit->mItem.toString() << std::endl;
std::vector<std::string>::iterator sit;
for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); sit++)
std::cout << " Spell: " << *sit << std::endl;
@ -1060,18 +1059,18 @@ void Record<ESM::NPC>::print()
std::vector<ESM::NPC::Dest>::iterator dit;
for (dit = mData.mTransport.begin(); dit != mData.mTransport.end(); dit++)
{
std::cout << " Destination Position: "
std::cout << " Destination Position: "
<< boost::format("%12.3f") % dit->mPos.pos[0] << ","
<< boost::format("%12.3f") % dit->mPos.pos[1] << ","
<< boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl;
std::cout << " Destination Rotation: "
std::cout << " Destination Rotation: "
<< boost::format("%9.6f") % dit->mPos.rot[0] << ","
<< boost::format("%9.6f") % dit->mPos.rot[1] << ","
<< boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl;
<< boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl;
if (dit->mCellName != "")
std::cout << " Destination Cell: " << dit->mCellName << std::endl;
}
std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl;
std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl;
std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl;
@ -1104,7 +1103,7 @@ void Record<ESM::Pathgrid>::print()
for (pit = mData.mPoints.begin(); pit != mData.mPoints.end(); pit++)
{
std::cout << " Point[" << i << "]:" << std::endl;
std::cout << " Coordinates: (" << pit->mX << ","
std::cout << " Coordinates: (" << pit->mX << ","
<< pit->mY << "," << pit->mZ << ")" << std::endl;
std::cout << " Auto-Generated: " << (int)pit->mAutogenerated << std::endl;
std::cout << " Connections: " << (int)pit->mConnectionNum << std::endl;
@ -1213,7 +1212,7 @@ void Record<ESM::Region>::print()
template<>
void Record<ESM::Script>::print()
{
std::cout << " Name: " << mData.mData.mName.toString() << std::endl;
std::cout << " Name: " << mData.mId << std::endl;
std::cout << " Num Shorts: " << mData.mData.mNumShorts << std::endl;
std::cout << " Num Longs: " << mData.mData.mNumLongs << std::endl;
@ -1267,7 +1266,7 @@ void Record<ESM::Sound>::print()
std::cout << " Sound: " << mData.mSound << std::endl;
std::cout << " Volume: " << (int)mData.mData.mVolume << std::endl;
if (mData.mData.mMinRange != 0 && mData.mData.mMaxRange != 0)
std::cout << " Range: " << (int)mData.mData.mMinRange << " - "
std::cout << " Range: " << (int)mData.mData.mMinRange << " - "
<< (int)mData.mData.mMaxRange << std::endl;
}
@ -1308,7 +1307,7 @@ void Record<ESM::Weapon>::print()
if (mData.mScript != "")
std::cout << " Script: " << mData.mScript << std::endl;
if (mData.mEnchant != "")
std::cout << " Enchantment: " << mData.mEnchant << std::endl;
std::cout << " Enchantment: " << mData.mEnchant << std::endl;
std::cout << " Type: " << weaponTypeLabel(mData.mData.mType)
<< " (" << mData.mData.mType << ")" << std::endl;
std::cout << " Flags: " << weaponFlags(mData.mData.mFlags) << std::endl;
@ -1319,23 +1318,14 @@ void Record<ESM::Weapon>::print()
std::cout << " Reach: " << mData.mData.mReach << std::endl;
std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl;
if (mData.mData.mChop[0] != 0 && mData.mData.mChop[1] != 0)
std::cout << " Chop: " << (int)mData.mData.mChop[0] << "-"
std::cout << " Chop: " << (int)mData.mData.mChop[0] << "-"
<< (int)mData.mData.mChop[1] << std::endl;
if (mData.mData.mSlash[0] != 0 && mData.mData.mSlash[1] != 0)
std::cout << " Slash: " << (int)mData.mData.mSlash[0] << "-"
<< (int)mData.mData.mSlash[1] << std::endl;
if (mData.mData.mThrust[0] != 0 && mData.mData.mThrust[1] != 0)
std::cout << " Thrust: " << (int)mData.mData.mThrust[0] << "-"
std::cout << " Thrust: " << (int)mData.mData.mThrust[0] << "-"
<< (int)mData.mData.mThrust[1] << std::endl;
}
template<>
void Record<ESM::CellRef>::print()
{
std::cout << " Refnum: " << mData.mRefnum << std::endl;
std::cout << " ID: '" << mData.mRefID << "'\n";
std::cout << " Owner: '" << mData.mOwner << "'\n";
std::cout << " INTV: " << mData.mIntv << " NAM9: " << mData.mIntv << std::endl;
}
} // end namespace

@ -2,6 +2,8 @@
#include <QFileInfo>
#include <QDir>
#include <stdexcept>
#include <components/esm/esmreader.hpp>
#include "esm/esmfile.hpp"
@ -270,7 +272,7 @@ void DataFilesModel::addMasters(const QString &path)
foreach (const QString &path, dir.entryList()) {
try {
ESM::ESMReader fileReader;
fileReader.setEncoding(mEncoding.toStdString());
fileReader.setEncoding(ToUTF8::calculateEncoding(mEncoding.toStdString()));
fileReader.open(dir.absoluteFilePath(path).toStdString());
ESM::ESMReader::MasterList mlist = fileReader.getMasters();
@ -333,7 +335,7 @@ void DataFilesModel::addPlugins(const QString &path)
try {
ESM::ESMReader fileReader;
fileReader.setEncoding(mEncoding.toStdString());
fileReader.setEncoding(ToUTF8::calculateEncoding(mEncoding.toStdString()));
fileReader.open(dir.absoluteFilePath(path).toStdString());
ESM::ESMReader::MasterList mlist = fileReader.getMasters();

@ -0,0 +1,76 @@
set (OPENCS_SRC
main.cpp editor.cpp
model/doc/documentmanager.cpp model/doc/document.cpp
model/world/universalid.cpp model/world/idcollection.cpp model/world/data.cpp model/world/idtable.cpp
model/world/commands.cpp model/world/idtableproxymodel.cpp model/world/record.cpp
model/world/columnbase.cpp
model/tools/tools.cpp model/tools/operation.cpp model/tools/stage.cpp model/tools/verifier.cpp
model/tools/mandatoryid.cpp model/tools/reportmodel.cpp
view/doc/viewmanager.cpp view/doc/view.cpp view/doc/operations.cpp view/doc/operation.cpp view/doc/subviewfactory.cpp
view/doc/subview.cpp
view/world/table.cpp view/world/tablesubview.cpp view/world/subviews.cpp view/world/util.cpp
view/world/dialoguesubview.cpp
view/tools/reportsubview.cpp view/tools/subviews.cpp
)
set (OPENCS_HDR
editor.hpp
model/doc/documentmanager.hpp model/doc/document.hpp model/doc/state.hpp
model/world/universalid.hpp model/world/record.hpp model/world/idcollection.hpp model/world/data.hpp
model/world/idtable.hpp model/world/columns.hpp model/world/idtableproxymodel.hpp
model/world/commands.hpp model/world/columnbase.hpp
model/tools/tools.hpp model/tools/operation.hpp model/tools/stage.hpp model/tools/verifier.hpp
model/tools/mandatoryid.hpp model/tools/reportmodel.hpp
view/doc/viewmanager.hpp view/doc/view.hpp view/doc/operations.hpp view/doc/operation.hpp view/doc/subviewfactory.hpp
view/doc/subview.hpp view/doc/subviewfactoryimp.hpp
view/world/table.hpp view/world/tablesubview.hpp view/world/subviews.hpp view/world/util.hpp
view/world/dialoguesubview.hpp
view/tools/reportsubview.hpp view/tools/subviews.hpp
)
set (OPENCS_US
)
set (OPENCS_RES
)
source_group (opencs FILES ${OPENCS_SRC} ${OPENCS_HDR})
if(WIN32)
set(QT_USE_QTMAIN TRUE)
endif(WIN32)
find_package(Qt4 COMPONENTS QtCore QtGui QtXml QtXmlPatterns REQUIRED)
include(${QT_USE_FILE})
qt4_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI})
qt4_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR})
qt4_add_resources(OPENCS_RES_SRC ${OPENCS_RES})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_executable(opencs
${OPENCS_SRC}
${OPENCS_UI_HDR}
${OPENCS_MOC_SRC}
${OPENCS_RES_SRC}
)
target_link_libraries(opencs
${Boost_LIBRARIES}
${QT_LIBRARIES}
components
)

@ -0,0 +1,49 @@
#include "editor.hpp"
#include <sstream>
#include <QtGui/QApplication>
#include "model/doc/document.hpp"
#include "model/world/data.hpp"
CS::Editor::Editor() : mViewManager (mDocumentManager), mNewDocumentIndex (0)
{
connect (&mViewManager, SIGNAL (newDocumentRequest ()), this, SLOT (createDocument ()));
}
void CS::Editor::createDocument()
{
std::ostringstream stream;
stream << "NewDocument" << (++mNewDocumentIndex);
CSMDoc::Document *document = mDocumentManager.addDocument (stream.str());
static const char *sGlobals[] =
{
"Day", "DaysPassed", "GameHour", "Month", "PCRace", "PCVampire", "PCWerewolf", "PCYear", 0
};
for (int i=0; sGlobals[i]; ++i)
{
ESM::Global record;
record.mId = sGlobals[i];
record.mValue = i==0 ? 1 : 0;
record.mType = ESM::VT_Float;
document->getData().getGlobals().add (record);
}
document->getData().merge(); /// \todo remove once proper ESX loading is implemented
mViewManager.addView (document);
}
int CS::Editor::run()
{
/// \todo Instead of creating an empty document, open a small welcome dialogue window with buttons for new/load/recent projects
createDocument();
return QApplication::exec();
}

@ -0,0 +1,37 @@
#ifndef CS_EDITOR_H
#define CS_EDITOR_H
#include <QObject>
#include "model/doc/documentmanager.hpp"
#include "view/doc/viewmanager.hpp"
namespace CS
{
class Editor : public QObject
{
Q_OBJECT
int mNewDocumentIndex; ///< \todo remove when the proper new document dialogue is implemented.
CSMDoc::DocumentManager mDocumentManager;
CSVDoc::ViewManager mViewManager;
// not implemented
Editor (const Editor&);
Editor& operator= (const Editor&);
public:
Editor();
int run();
///< \return error status
public slots:
void createDocument();
};
}
#endif

@ -0,0 +1,39 @@
#include "editor.hpp"
#include <exception>
#include <iostream>
#include <QtGui/QApplication>
class Application : public QApplication
{
private:
bool notify (QObject *receiver, QEvent *event)
{
try
{
return QApplication::notify (receiver, event);
}
catch (const std::exception& exception)
{
std::cerr << "An exception has been caught: " << exception.what() << std::endl;
}
return false;
}
public:
Application (int& argc, char *argv[]) : QApplication (argc, argv) {}
};
int main(int argc, char *argv[])
{
Application mApplication (argc, argv);
CS::Editor editor;
return editor.run();
}

@ -0,0 +1,114 @@
#include "document.hpp"
CSMDoc::Document::Document (const std::string& name)
: mTools (mData)
{
mName = name; ///< \todo replace with ESX list
connect (&mUndoStack, SIGNAL (cleanChanged (bool)), this, SLOT (modificationStateChanged (bool)));
connect (&mTools, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int)));
connect (&mTools, SIGNAL (done (int)), this, SLOT (operationDone (int)));
// dummy implementation -> remove when proper save is implemented.
mSaveCount = 0;
connect (&mSaveTimer, SIGNAL(timeout()), this, SLOT (saving()));
}
QUndoStack& CSMDoc::Document::getUndoStack()
{
return mUndoStack;
}
int CSMDoc::Document::getState() const
{
int state = 0;
if (!mUndoStack.isClean())
state |= State_Modified;
if (mSaveCount)
state |= State_Locked | State_Saving | State_Operation;
if (int operations = mTools.getRunningOperations())
state |= State_Locked | State_Operation | operations;
return state;
}
const std::string& CSMDoc::Document::getName() const
{
return mName;
}
void CSMDoc::Document::save()
{
mSaveCount = 1;
mSaveTimer.start (500);
emit stateChanged (getState(), this);
emit progress (1, 16, State_Saving, 1, this);
}
CSMWorld::UniversalId CSMDoc::Document::verify()
{
CSMWorld::UniversalId id = mTools.runVerifier();
emit stateChanged (getState(), this);
return id;
}
void CSMDoc::Document::abortOperation (int type)
{
mTools.abortOperation (type);
if (type==State_Saving)
{
mSaveTimer.stop();
emit stateChanged (getState(), this);
}
}
void CSMDoc::Document::modificationStateChanged (bool clean)
{
emit stateChanged (getState(), this);
}
void CSMDoc::Document::operationDone (int type)
{
emit stateChanged (getState(), this);
}
void CSMDoc::Document::saving()
{
++mSaveCount;
emit progress (mSaveCount, 16, State_Saving, 1, this);
if (mSaveCount>15)
{
mSaveCount = 0;
mSaveTimer.stop();
mUndoStack.setClean();
emit stateChanged (getState(), this);
}
}
const CSMWorld::Data& CSMDoc::Document::getData() const
{
return mData;
}
CSMWorld::Data& CSMDoc::Document::getData()
{
return mData;
}
CSMTools::ReportModel *CSMDoc::Document::getReport (const CSMWorld::UniversalId& id)
{
return mTools.getReport (id);
}
void CSMDoc::Document::progress (int current, int max, int type)
{
emit progress (current, max, type, 1, this);
}

@ -0,0 +1,87 @@
#ifndef CSM_DOC_DOCUMENT_H
#define CSM_DOC_DOCUMENT_H
#include <string>
#include <QUndoStack>
#include <QObject>
#include <QTimer>
#include "../world/data.hpp"
#include "../tools/tools.hpp"
#include "state.hpp"
class QAbstractItemModel;
namespace CSMDoc
{
class Document : public QObject
{
Q_OBJECT
private:
std::string mName; ///< \todo replace name with ESX list
CSMWorld::Data mData;
CSMTools::Tools mTools;
// It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is
// using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late.
QUndoStack mUndoStack;
int mSaveCount; ///< dummy implementation -> remove when proper save is implemented.
QTimer mSaveTimer; ///< dummy implementation -> remove when proper save is implemented.
// not implemented
Document (const Document&);
Document& operator= (const Document&);
public:
Document (const std::string& name);
///< \todo replace name with ESX list
QUndoStack& getUndoStack();
int getState() const;
const std::string& getName() const;
///< \todo replace with ESX list
void save();
CSMWorld::UniversalId verify();
void abortOperation (int type);
const CSMWorld::Data& getData() const;
CSMWorld::Data& getData();
CSMTools::ReportModel *getReport (const CSMWorld::UniversalId& id);
///< The ownership of the returned report is not transferred.
signals:
void stateChanged (int state, CSMDoc::Document *document);
void progress (int current, int max, int type, int threads, CSMDoc::Document *document);
private slots:
void modificationStateChanged (bool clean);
void operationDone (int type);
void saving();
///< dummy implementation -> remove when proper save is implemented.
public slots:
void progress (int current, int max, int type);
};
}
#endif

@ -0,0 +1,37 @@
#include "documentmanager.hpp"
#include <algorithm>
#include <stdexcept>
#include "document.hpp"
CSMDoc::DocumentManager::DocumentManager() {}
CSMDoc::DocumentManager::~DocumentManager()
{
for (std::vector<Document *>::iterator iter (mDocuments.begin()); iter!=mDocuments.end(); ++iter)
delete *iter;
}
CSMDoc::Document *CSMDoc::DocumentManager::addDocument (const std::string& name)
{
Document *document = new Document (name);
mDocuments.push_back (document);
return document;
}
bool CSMDoc::DocumentManager::removeDocument (Document *document)
{
std::vector<Document *>::iterator iter = std::find (mDocuments.begin(), mDocuments.end(), document);
if (iter==mDocuments.end())
throw std::runtime_error ("removing invalid document");
mDocuments.erase (iter);
delete document;
return mDocuments.empty();
}

@ -0,0 +1,32 @@
#ifndef CSM_DOC_DOCUMENTMGR_H
#define CSM_DOC_DOCUMENTMGR_H
#include <vector>
#include <string>
namespace CSMDoc
{
class Document;
class DocumentManager
{
std::vector<Document *> mDocuments;
DocumentManager (const DocumentManager&);
DocumentManager& operator= (const DocumentManager&);
public:
DocumentManager();
~DocumentManager();
Document *addDocument (const std::string& name);
///< The ownership of the returned document is not transferred to the caller.
bool removeDocument (Document *document);
///< \return last document removed?
};
}
#endif

@ -0,0 +1,19 @@
#ifndef CSM_DOC_STATE_H
#define CSM_DOC_STATE_H
namespace CSMDoc
{
enum State
{
State_Modified = 1,
State_Locked = 2,
State_Operation = 4,
State_Saving = 8,
State_Verifying = 16,
State_Compiling = 32, // not implemented yet
State_Searching = 64 // not implemented yet
};
}
#endif

@ -0,0 +1,21 @@
#include "mandatoryid.hpp"
#include "../world/idcollection.hpp"
CSMTools::MandatoryIdStage::MandatoryIdStage (const CSMWorld::IdCollectionBase& idCollection,
const CSMWorld::UniversalId& collectionId, const std::vector<std::string>& ids)
: mIdCollection (idCollection), mCollectionId (collectionId), mIds (ids)
{}
int CSMTools::MandatoryIdStage::setup()
{
return mIds.size();
}
void CSMTools::MandatoryIdStage::perform (int stage, std::vector<std::string>& messages)
{
if (mIdCollection.searchId (mIds.at (stage))==-1 ||
mIdCollection.getRecord (mIds.at (stage)).isDeleted())
messages.push_back (mCollectionId.toString() + "|Missing mandatory record: " + mIds.at (stage));
}

@ -0,0 +1,38 @@
#ifndef CSM_TOOLS_MANDATORYID_H
#define CSM_TOOLS_MANDATORYID_H
#include <string>
#include <vector>
#include "../world/universalid.hpp"
#include "stage.hpp"
namespace CSMWorld
{
class IdCollectionBase;
}
namespace CSMTools
{
/// \brief Verify stage: make sure that records with specific IDs exist.
class MandatoryIdStage : public Stage
{
const CSMWorld::IdCollectionBase& mIdCollection;
CSMWorld::UniversalId mCollectionId;
std::vector<std::string> mIds;
public:
MandatoryIdStage (const CSMWorld::IdCollectionBase& idCollection, const CSMWorld::UniversalId& collectionId,
const std::vector<std::string>& ids);
virtual int setup();
///< \return number of steps
virtual void perform (int stage, std::vector<std::string>& messages);
///< Messages resulting from this tage will be appended to \a messages.
};
}
#endif

@ -0,0 +1,84 @@
#include "operation.hpp"
#include <string>
#include <vector>
#include <QTimer>
#include "../doc/state.hpp"
#include "stage.hpp"
void CSMTools::Operation::prepareStages()
{
mCurrentStage = mStages.begin();
mCurrentStep = 0;
mCurrentStepTotal = 0;
mTotalSteps = 0;
for (std::vector<std::pair<Stage *, int> >::iterator iter (mStages.begin()); iter!=mStages.end(); ++iter)
{
iter->second = iter->first->setup();
mTotalSteps += iter->second;
}
}
CSMTools::Operation::Operation (int type) : mType (type) {}
CSMTools::Operation::~Operation()
{
for (std::vector<std::pair<Stage *, int> >::iterator iter (mStages.begin()); iter!=mStages.end(); ++iter)
delete iter->first;
}
void CSMTools::Operation::run()
{
prepareStages();
QTimer timer;
timer.connect (&timer, SIGNAL (timeout()), this, SLOT (verify()));
timer.start (0);
exec();
}
void CSMTools::Operation::appendStage (Stage *stage)
{
mStages.push_back (std::make_pair (stage, 0));
}
void CSMTools::Operation::abort()
{
exit();
}
void CSMTools::Operation::verify()
{
std::vector<std::string> messages;
while (mCurrentStage!=mStages.end())
{
if (mCurrentStep>=mCurrentStage->second)
{
mCurrentStep = 0;
++mCurrentStage;
}
else
{
mCurrentStage->first->perform (mCurrentStep++, messages);
++mCurrentStepTotal;
break;
}
}
emit progress (mCurrentStepTotal, mTotalSteps ? mTotalSteps : 1, mType);
for (std::vector<std::string>::const_iterator iter (messages.begin()); iter!=messages.end(); ++iter)
emit reportMessage (iter->c_str(), mType);
if (mCurrentStage==mStages.end())
exit();
}

@ -0,0 +1,54 @@
#ifndef CSM_TOOLS_OPERATION_H
#define CSM_TOOLS_OPERATION_H
#include <vector>
#include <QThread>
namespace CSMTools
{
class Stage;
class Operation : public QThread
{
Q_OBJECT
int mType;
std::vector<std::pair<Stage *, int> > mStages; // stage, number of steps
std::vector<std::pair<Stage *, int> >::iterator mCurrentStage;
int mCurrentStep;
int mCurrentStepTotal;
int mTotalSteps;
void prepareStages();
public:
Operation (int type);
virtual ~Operation();
virtual void run();
void appendStage (Stage *stage);
///< The ownership of \a stage is transferred to *this.
///
/// \attention Do no call this function while this Operation is running.
signals:
void progress (int current, int max, int type);
void reportMessage (const QString& message, int type);
public slots:
void abort();
private slots:
void verify();
};
}
#endif

@ -0,0 +1,71 @@
#include "reportmodel.hpp"
#include <stdexcept>
int CSMTools::ReportModel::rowCount (const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
return mRows.size();
}
int CSMTools::ReportModel::columnCount (const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
return 2;
}
QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const
{
if (role!=Qt::DisplayRole)
return QVariant();
if (index.column()==0)
return static_cast<int> (mRows.at (index.row()).first.getType());
else
return mRows.at (index.row()).second.c_str();
}
QVariant CSMTools::ReportModel::headerData (int section, Qt::Orientation orientation, int role) const
{
if (role!=Qt::DisplayRole)
return QVariant();
if (orientation==Qt::Vertical)
return QVariant();
return tr (section==0 ? "Type" : "Description");
}
bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& parent)
{
if (parent.isValid())
return false;
mRows.erase (mRows.begin()+row, mRows.begin()+row+count);
return true;
}
void CSMTools::ReportModel::add (const std::string& row)
{
std::string::size_type index = row.find ('|');
if (index==std::string::npos)
throw std::logic_error ("invalid report message");
beginInsertRows (QModelIndex(), mRows.size(), mRows.size());
mRows.push_back (std::make_pair (row.substr (0, index), row.substr (index+1)));
endInsertRows();
}
const CSMWorld::UniversalId& CSMTools::ReportModel::getUniversalId (int row) const
{
return mRows.at (row).first;
}

@ -0,0 +1,37 @@
#ifndef CSM_TOOLS_REPORTMODEL_H
#define CSM_TOOLS_REPORTMODEL_H
#include <vector>
#include <string>
#include <QAbstractTableModel>
#include "../world/universalid.hpp"
namespace CSMTools
{
class ReportModel : public QAbstractTableModel
{
Q_OBJECT
std::vector<std::pair<CSMWorld::UniversalId, std::string> > mRows;
public:
virtual int rowCount (const QModelIndex & parent = QModelIndex()) const;
virtual int columnCount (const QModelIndex & parent = QModelIndex()) const;
virtual QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const;
virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex());
void add (const std::string& row);
const CSMWorld::UniversalId& getUniversalId (int row) const;
};
}
#endif

@ -0,0 +1,4 @@
#include "stage.hpp"
CSMTools::Stage::~Stage() {}

@ -0,0 +1,24 @@
#ifndef CSM_TOOLS_STAGE_H
#define CSM_TOOLS_STAGE_H
#include <vector>
#include <string>
namespace CSMTools
{
class Stage
{
public:
virtual ~Stage();
virtual int setup() = 0;
///< \return number of steps
virtual void perform (int stage, std::vector<std::string>& messages) = 0;
///< Messages resulting from this tage will be appended to \a messages.
};
}
#endif

@ -0,0 +1,123 @@
#include "tools.hpp"
#include <QThreadPool>
#include "verifier.hpp"
#include "../doc/state.hpp"
#include "../world/data.hpp"
#include "../world/universalid.hpp"
#include "reportmodel.hpp"
#include "mandatoryid.hpp"
CSMTools::Operation *CSMTools::Tools::get (int type)
{
switch (type)
{
case CSMDoc::State_Verifying: return mVerifier;
}
return 0;
}
const CSMTools::Operation *CSMTools::Tools::get (int type) const
{
return const_cast<Tools *> (this)->get (type);
}
CSMTools::Verifier *CSMTools::Tools::getVerifier()
{
if (!mVerifier)
{
mVerifier = new Verifier;
connect (mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
connect (mVerifier, SIGNAL (finished()), this, SLOT (verifierDone()));
connect (mVerifier, SIGNAL (reportMessage (const QString&, int)),
this, SLOT (verifierMessage (const QString&, int)));
std::vector<std::string> mandatoryIds; // I want C++11, damn it!
mandatoryIds.push_back ("Day");
mandatoryIds.push_back ("DaysPassed");
mandatoryIds.push_back ("GameHour");
mandatoryIds.push_back ("Month");
mandatoryIds.push_back ("PCRace");
mandatoryIds.push_back ("PCVampire");
mandatoryIds.push_back ("PCWerewolf");
mandatoryIds.push_back ("PCYear");
mVerifier->appendStage (new MandatoryIdStage (mData.getGlobals(),
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds));
}
return mVerifier;
}
CSMTools::Tools::Tools (CSMWorld::Data& data) : mData (data), mVerifier (0), mNextReportNumber (0)
{
for (std::map<int, ReportModel *>::iterator iter (mReports.begin()); iter!=mReports.end(); ++iter)
delete iter->second;
}
CSMTools::Tools::~Tools()
{
delete mVerifier;
}
CSMWorld::UniversalId CSMTools::Tools::runVerifier()
{
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel));
mActiveReports[CSMDoc::State_Verifying] = mNextReportNumber-1;
getVerifier()->start();
return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_VerificationResults, mNextReportNumber-1);
}
void CSMTools::Tools::abortOperation (int type)
{
if (Operation *operation = get (type))
operation->abort();
}
int CSMTools::Tools::getRunningOperations() const
{
static const int sOperations[] =
{
CSMDoc::State_Verifying,
-1
};
int result = 0;
for (int i=0; sOperations[i]!=-1; ++i)
if (const Operation *operation = get (sOperations[i]))
if (operation->isRunning())
result |= sOperations[i];
return result;
}
CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId& id)
{
if (id.getType()!=CSMWorld::UniversalId::Type_VerificationResults)
throw std::logic_error ("invalid request for report model: " + id.toString());
return mReports.at (id.getIndex());
}
void CSMTools::Tools::verifierDone()
{
emit done (CSMDoc::State_Verifying);
}
void CSMTools::Tools::verifierMessage (const QString& message, int type)
{
std::map<int, int>::iterator iter = mActiveReports.find (type);
if (iter!=mActiveReports.end())
mReports[iter->second]->add (message.toStdString());
}

@ -0,0 +1,73 @@
#ifndef CSM_TOOLS_TOOLS_H
#define CSM_TOOLS_TOOLS_H
#include <QObject>
#include <map>
namespace CSMWorld
{
class Data;
class UniversalId;
}
namespace CSMTools
{
class Verifier;
class Operation;
class ReportModel;
class Tools : public QObject
{
Q_OBJECT
CSMWorld::Data& mData;
Verifier *mVerifier;
std::map<int, ReportModel *> mReports;
int mNextReportNumber;
std::map<int, int> mActiveReports; // type, report number
// not implemented
Tools (const Tools&);
Tools& operator= (const Tools&);
Verifier *getVerifier();
Operation *get (int type);
///< Returns a 0-pointer, if operation hasn't been used yet.
const Operation *get (int type) const;
///< Returns a 0-pointer, if operation hasn't been used yet.
public:
Tools (CSMWorld::Data& data);
virtual ~Tools();
CSMWorld::UniversalId runVerifier();
///< \return ID of the report for this verification run
void abortOperation (int type);
///< \attention The operation is not aborted immediately.
int getRunningOperations() const;
ReportModel *getReport (const CSMWorld::UniversalId& id);
///< The ownership of the returned report is not transferred.
private slots:
void verifierDone();
void verifierMessage (const QString& message, int type);
signals:
void progress (int current, int max, int type);
void done (int type);
};
}
#endif

@ -0,0 +1,7 @@
#include "verifier.hpp"
#include "../doc/state.hpp"
CSMTools::Verifier::Verifier() : Operation (CSMDoc::State_Verifying)
{}

@ -0,0 +1,17 @@
#ifndef CSM_TOOLS_VERIFIER_H
#define CSM_TOOLS_VERIFIER_H
#include "operation.hpp"
namespace CSMTools
{
class Verifier : public Operation
{
public:
Verifier();
};
}
#endif

@ -0,0 +1,13 @@
#include "columnbase.hpp"
CSMWorld::ColumnBase::ColumnBase (const std::string& title, int flags)
: mTitle (title), mFlags (flags)
{}
CSMWorld::ColumnBase::~ColumnBase() {}
bool CSMWorld::ColumnBase::isUserEditable() const
{
return isEditable();
}

@ -0,0 +1,57 @@
#ifndef CSM_WOLRD_COLUMNBASE_H
#define CSM_WOLRD_COLUMNBASE_H
#include <string>
#include <Qt>
#include <QVariant>
#include "record.hpp"
namespace CSMWorld
{
struct ColumnBase
{
enum Roles
{
Role_Flags = Qt::UserRole
};
enum Flags
{
Flag_Table = 1, // column should be displayed in table view
Flag_Dialogue = 2 // column should be displayed in dialogue view
};
std::string mTitle;
int mFlags;
ColumnBase (const std::string& title, int flag);
virtual ~ColumnBase();
virtual bool isEditable() const = 0;
virtual bool isUserEditable() const;
///< Can this column be edited directly by the user?
};
template<typename ESXRecordT>
struct Column : public ColumnBase
{
std::string mTitle;
int mFlags;
Column (const std::string& title, int flags = Flag_Table | Flag_Dialogue)
: ColumnBase (title, flags) {}
virtual QVariant get (const Record<ESXRecordT>& record) const = 0;
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
throw std::logic_error ("Column " + mTitle + " is not editable");
}
};
}
#endif

@ -0,0 +1,95 @@
#ifndef CSM_WOLRD_COLUMNS_H
#define CSM_WOLRD_COLUMNS_H
#include "idcollection.hpp"
namespace CSMWorld
{
template<typename ESXRecordT>
struct FloatValueColumn : public Column<ESXRecordT>
{
FloatValueColumn() : Column<ESXRecordT> ("Value") {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return record.get().mValue;
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT base = record.getBase();
base.mValue = data.toFloat();
record.setModified (base);
}
virtual bool isEditable() const
{
return true;
}
};
template<typename ESXRecordT>
struct StringIdColumn : public Column<ESXRecordT>
{
StringIdColumn() : Column<ESXRecordT> ("ID") {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return record.get().mId.c_str();
}
virtual bool isEditable() const
{
return false;
}
};
template<typename ESXRecordT>
struct RecordStateColumn : public Column<ESXRecordT>
{
RecordStateColumn() : Column<ESXRecordT> ("*") {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
if (record.mState==Record<ESXRecordT>::State_Erased)
return static_cast<int> (Record<ESXRecordT>::State_Deleted);
return static_cast<int> (record.mState);
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
record.mState = static_cast<RecordBase::State> (data.toInt());
}
virtual bool isEditable() const
{
return true;
}
virtual bool isUserEditable() const
{
return false;
}
};
template<typename ESXRecordT>
struct FixedRecordTypeColumn : public Column<ESXRecordT>
{
int mType;
FixedRecordTypeColumn (int type) : Column<ESXRecordT> ("Type", 0), mType (type) {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return mType;
}
virtual bool isEditable() const
{
return false;
}
};
}
#endif

@ -0,0 +1,108 @@
#include "commands.hpp"
#include <QAbstractTableModel>
#include "idtableproxymodel.hpp"
#include "idtable.hpp"
CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index,
const QVariant& new_, QUndoCommand *parent)
: QUndoCommand (parent), mModel (model), mIndex (index), mNew (new_)
{
mOld = mModel.data (mIndex, Qt::EditRole);
setText ("Modify " + mModel.headerData (mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString());
}
void CSMWorld::ModifyCommand::redo()
{
mModel.setData (mIndex, mNew);
}
void CSMWorld::ModifyCommand::undo()
{
mModel.setData (mIndex, mOld);
}
CSMWorld::CreateCommand::CreateCommand (IdTableProxyModel& model, const std::string& id, QUndoCommand *parent)
: QUndoCommand (parent), mModel (model), mId (id)
{
setText (("Create record " + id).c_str());
}
void CSMWorld::CreateCommand::redo()
{
mModel.addRecord (mId);
}
void CSMWorld::CreateCommand::undo()
{
mModel.removeRow (mModel.getModelIndex (mId, 0).row());
}
CSMWorld::RevertCommand::RevertCommand (IdTable& model, const std::string& id, QUndoCommand *parent)
: QUndoCommand (parent), mModel (model), mId (id), mOld (0)
{
setText (("Revert record " + id).c_str());
mOld = model.getRecord (id).clone();
}
CSMWorld::RevertCommand::~RevertCommand()
{
delete mOld;
}
void CSMWorld::RevertCommand::redo()
{
QModelIndex index = mModel.getModelIndex (mId, 1);
RecordBase::State state = static_cast<RecordBase::State> (mModel.data (index).toInt());
if (state==RecordBase::State_ModifiedOnly)
{
mModel.removeRows (index.row(), 1);
}
else
{
mModel.setData (index, static_cast<int> (RecordBase::State_BaseOnly));
}
}
void CSMWorld::RevertCommand::undo()
{
mModel.setRecord (*mOld);
}
CSMWorld::DeleteCommand::DeleteCommand (IdTable& model, const std::string& id, QUndoCommand *parent)
: QUndoCommand (parent), mModel (model), mId (id), mOld (0)
{
setText (("Delete record " + id).c_str());
mOld = model.getRecord (id).clone();
}
CSMWorld::DeleteCommand::~DeleteCommand()
{
delete mOld;
}
void CSMWorld::DeleteCommand::redo()
{
QModelIndex index = mModel.getModelIndex (mId, 1);
RecordBase::State state = static_cast<RecordBase::State> (mModel.data (index).toInt());
if (state==RecordBase::State_ModifiedOnly)
{
mModel.removeRows (index.row(), 1);
}
else
{
mModel.setData (index, static_cast<int> (RecordBase::State_Deleted));
}
}
void CSMWorld::DeleteCommand::undo()
{
mModel.setRecord (*mOld);
}

@ -0,0 +1,95 @@
#ifndef CSM_WOLRD_COMMANDS_H
#define CSM_WOLRD_COMMANDS_H
#include "record.hpp"
#include <string>
#include <QVariant>
#include <QUndoCommand>
#include <QModelIndex>
class QModelIndex;
class QAbstractItemModel;
namespace CSMWorld
{
class IdTableProxyModel;
class IdTable;
class RecordBase;
class ModifyCommand : public QUndoCommand
{
QAbstractItemModel& mModel;
QModelIndex mIndex;
QVariant mNew;
QVariant mOld;
public:
ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_,
QUndoCommand *parent = 0);
virtual void redo();
virtual void undo();
};
class CreateCommand : public QUndoCommand
{
IdTableProxyModel& mModel;
std::string mId;
public:
CreateCommand (IdTableProxyModel& model, const std::string& id, QUndoCommand *parent = 0);
virtual void redo();
virtual void undo();
};
class RevertCommand : public QUndoCommand
{
IdTable& mModel;
std::string mId;
RecordBase *mOld;
// not implemented
RevertCommand (const RevertCommand&);
RevertCommand& operator= (const RevertCommand&);
public:
RevertCommand (IdTable& model, const std::string& id, QUndoCommand *parent = 0);
virtual ~RevertCommand();
virtual void redo();
virtual void undo();
};
class DeleteCommand : public QUndoCommand
{
IdTable& mModel;
std::string mId;
RecordBase *mOld;
// not implemented
DeleteCommand (const DeleteCommand&);
DeleteCommand& operator= (const DeleteCommand&);
public:
DeleteCommand (IdTable& model, const std::string& id, QUndoCommand *parent = 0);
virtual ~DeleteCommand();
virtual void redo();
virtual void undo();
};
}
#endif

@ -0,0 +1,55 @@
#include "data.hpp"
#include <stdexcept>
#include <QAbstractTableModel>
#include <components/esm/loadglob.hpp>
#include "idtable.hpp"
#include "columns.hpp"
CSMWorld::Data::Data()
{
mGlobals.addColumn (new StringIdColumn<ESM::Global>);
mGlobals.addColumn (new RecordStateColumn<ESM::Global>);
mGlobals.addColumn (new FixedRecordTypeColumn<ESM::Global> (UniversalId::Type_Global));
mGlobals.addColumn (new FloatValueColumn<ESM::Global>);
mModels.insert (std::make_pair (
UniversalId (UniversalId::Type_Globals),
new IdTable (&mGlobals)
));
}
CSMWorld::Data::~Data()
{
for (std::map<UniversalId, QAbstractTableModel *>::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter)
delete iter->second;
}
const CSMWorld::IdCollection<ESM::Global>& CSMWorld::Data::getGlobals() const
{
return mGlobals;
}
CSMWorld::IdCollection<ESM::Global>& CSMWorld::Data::getGlobals()
{
return mGlobals;
}
QAbstractTableModel *CSMWorld::Data::getTableModel (const UniversalId& id)
{
std::map<UniversalId, QAbstractTableModel *>::iterator iter = mModels.find (id);
if (iter==mModels.end())
throw std::logic_error ("No table model available for " + id.toString());
return iter->second;
}
void CSMWorld::Data::merge()
{
mGlobals.merge();
}

@ -0,0 +1,42 @@
#ifndef CSM_WOLRD_IDLIST_H
#define CSM_WOLRD_IDLIST_H
#include <map>
#include <components/esm/loadglob.hpp>
#include "idcollection.hpp"
#include "universalid.hpp"
class QAbstractTableModel;
namespace CSMWorld
{
class Data
{
IdCollection<ESM::Global> mGlobals;
std::map<UniversalId, QAbstractTableModel *> mModels;
// not implemented
Data (const Data&);
Data& operator= (const Data&);
public:
Data();
~Data();
const IdCollection<ESM::Global>& getGlobals() const;
IdCollection<ESM::Global>& getGlobals();
QAbstractTableModel *getTableModel (const UniversalId& id);
///< If no table model is available for \æ id, an exception is thrown.
void merge();
///< Merge modified into base.
};
}
#endif

@ -0,0 +1,6 @@
#include "idcollection.hpp"
CSMWorld::IdCollectionBase::IdCollectionBase() {}
CSMWorld::IdCollectionBase::~IdCollectionBase() {}

@ -0,0 +1,325 @@
#ifndef CSM_WOLRD_IDCOLLECTION_H
#define CSM_WOLRD_IDCOLLECTION_H
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <cctype>
#include <stdexcept>
#include <functional>
#include <QVariant>
#include "columnbase.hpp"
namespace CSMWorld
{
class IdCollectionBase
{
// not implemented
IdCollectionBase (const IdCollectionBase&);
IdCollectionBase& operator= (const IdCollectionBase&);
public:
IdCollectionBase();
virtual ~IdCollectionBase();
virtual int getSize() const = 0;
virtual std::string getId (int index) const = 0;
virtual int getIndex (const std::string& id) const = 0;
virtual int getColumns() const = 0;
virtual const ColumnBase& getColumn (int column) const = 0;
virtual QVariant getData (int index, int column) const = 0;
virtual void setData (int index, int column, const QVariant& data) = 0;
virtual void merge() = 0;
///< Merge modified into base.
virtual void purge() = 0;
///< Remove records that are flagged as erased.
virtual void removeRows (int index, int count) = 0;
virtual void appendBlankRecord (const std::string& id) = 0;
virtual int searchId (const std::string& id) const = 0;
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)
virtual void replace (int index, const RecordBase& record) = 0;
///< If the record type does not match, an exception is thrown.
///
/// \attention \a record must not change the ID.
virtual void appendRecord (const RecordBase& record) = 0;
///< If the record type does not match, an exception is thrown.
virtual std::string getId (const RecordBase& record) const = 0;
///< Return ID for \a record.
///
/// \attention Throw san exception, if the type of \a record does not match.
virtual const RecordBase& getRecord (const std::string& id) const = 0;
};
///< \brief Collection of ID-based records
template<typename ESXRecordT>
class IdCollection : public IdCollectionBase
{
std::vector<Record<ESXRecordT> > mRecords;
std::map<std::string, int> mIndex;
std::vector<Column<ESXRecordT> *> mColumns;
// not implemented
IdCollection (const IdCollection&);
IdCollection& operator= (const IdCollection&);
public:
IdCollection();
virtual ~IdCollection();
void add (const ESXRecordT& record);
///< Add a new record (modified)
virtual int getSize() const;
virtual std::string getId (int index) const;
virtual int getIndex (const std::string& id) const;
virtual int getColumns() const;
virtual QVariant getData (int index, int column) const;
virtual void setData (int index, int column, const QVariant& data);
virtual const ColumnBase& getColumn (int column) const;
virtual void merge();
///< Merge modified into base.
virtual void purge();
///< Remove records that are flagged as erased.
virtual void removeRows (int index, int count) ;
virtual void appendBlankRecord (const std::string& id);
virtual int searchId (const std::string& id) const;
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)
virtual void replace (int index, const RecordBase& record);
///< If the record type does not match, an exception is thrown.
///
/// \attention \a record must not change the ID.
virtual void appendRecord (const RecordBase& record);
///< If the record type does not match, an exception is thrown.
virtual std::string getId (const RecordBase& record) const;
///< Return ID for \a record.
///
/// \attention Throw san exception, if the type of \a record does not match.
virtual const RecordBase& getRecord (const std::string& id) const;
void addColumn (Column<ESXRecordT> *column);
};
template<typename ESXRecordT>
IdCollection<ESXRecordT>::IdCollection()
{}
template<typename ESXRecordT>
IdCollection<ESXRecordT>::~IdCollection()
{
for (typename std::vector<Column<ESXRecordT> *>::iterator iter (mColumns.begin()); iter!=mColumns.end(); ++iter)
delete *iter;
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::add (const ESXRecordT& record)
{
std::string id;
std::transform (record.mId.begin(), record.mId.end(), std::back_inserter (id),
(int(*)(int)) std::tolower);
std::map<std::string, int>::iterator iter = mIndex.find (id);
if (iter==mIndex.end())
{
Record<ESXRecordT> record2;
record2.mState = Record<ESXRecordT>::State_ModifiedOnly;
record2.mModified = record;
mRecords.push_back (record2);
mIndex.insert (std::make_pair (id, mRecords.size()-1));
}
else
{
mRecords[iter->second].setModified (record);
}
}
template<typename ESXRecordT>
int IdCollection<ESXRecordT>::getSize() const
{
return mRecords.size();
}
template<typename ESXRecordT>
std::string IdCollection<ESXRecordT>::getId (int index) const
{
return mRecords.at (index).get().mId;
}
template<typename ESXRecordT>
int IdCollection<ESXRecordT>::getIndex (const std::string& id) const
{
int index = searchId (id);
if (index==-1)
throw std::runtime_error ("invalid ID: " + id);
return index;
}
template<typename ESXRecordT>
int IdCollection<ESXRecordT>::getColumns() const
{
return mColumns.size();
}
template<typename ESXRecordT>
QVariant IdCollection<ESXRecordT>::getData (int index, int column) const
{
return mColumns.at (column)->get (mRecords.at (index));
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::setData (int index, int column, const QVariant& data)
{
return mColumns.at (column)->set (mRecords.at (index), data);
}
template<typename ESXRecordT>
const ColumnBase& IdCollection<ESXRecordT>::getColumn (int column) const
{
return *mColumns.at (column);
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::addColumn (Column<ESXRecordT> *column)
{
mColumns.push_back (column);
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::merge()
{
for (typename std::vector<Record<ESXRecordT> >::iterator iter (mRecords.begin()); iter!=mRecords.end(); ++iter)
iter->merge();
purge();
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::purge()
{
mRecords.erase (std::remove_if (mRecords.begin(), mRecords.end(),
std::mem_fun_ref (&Record<ESXRecordT>::isErased) // I want lambda :(
), mRecords.end());
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::removeRows (int index, int count)
{
mRecords.erase (mRecords.begin()+index, mRecords.begin()+index+count);
typename std::map<std::string, int>::iterator iter = mIndex.begin();
while (iter!=mIndex.end())
{
if (iter->second>=index)
{
if (iter->second>=index+count)
{
iter->second -= count;
}
else
{
mIndex.erase (iter++);
}
}
++iter;
}
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::appendBlankRecord (const std::string& id)
{
ESXRecordT record;
record.mId = id;
record.blank();
add (record);
}
template<typename ESXRecordT>
int IdCollection<ESXRecordT>::searchId (const std::string& id) const
{
std::string id2;
std::transform (id.begin(), id.end(), std::back_inserter (id2),
(int(*)(int)) std::tolower);
std::map<std::string, int>::const_iterator iter = mIndex.find (id2);
if (iter==mIndex.end())
return -1;
return iter->second;
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::replace (int index, const RecordBase& record)
{
mRecords.at (index) = dynamic_cast<const Record<ESXRecordT>&> (record);
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::appendRecord (const RecordBase& record)
{
mRecords.push_back (dynamic_cast<const Record<ESXRecordT>&> (record));
mIndex.insert (std::make_pair (getId (record), mRecords.size()-1));
}
template<typename ESXRecordT>
std::string IdCollection<ESXRecordT>::getId (const RecordBase& record) const
{
const Record<ESXRecordT>& record2 = dynamic_cast<const Record<ESXRecordT>&> (record);
return (record2.isModified() ? record2.mModified : record2.mBase).mId;
}
template<typename ESXRecordT>
const RecordBase& IdCollection<ESXRecordT>::getRecord (const std::string& id) const
{
int index = getIndex (id);
return mRecords.at (index);
}
}
#endif

@ -0,0 +1,137 @@
#include "idtable.hpp"
#include "idcollection.hpp"
CSMWorld::IdTable::IdTable (IdCollectionBase *idCollection) : mIdCollection (idCollection)
{
}
CSMWorld::IdTable::~IdTable()
{
}
int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
return mIdCollection->getSize();
}
int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
return mIdCollection->getColumns();
}
QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const
{
if (role!=Qt::DisplayRole && role!=Qt::EditRole)
return QVariant();
if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable())
return QVariant();
return mIdCollection->getData (index.row(), index.column());
}
QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation, int role) const
{
if (orientation==Qt::Vertical)
return QVariant();
if (role==Qt::DisplayRole)
return tr (mIdCollection->getColumn (section).mTitle.c_str());
if (role==ColumnBase::Role_Flags)
return mIdCollection->getColumn (section).mFlags;
return QVariant();
}
bool CSMWorld::IdTable::setData ( const QModelIndex &index, const QVariant &value, int role)
{
if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole)
{
mIdCollection->setData (index.row(), index.column(), value);
emit dataChanged (CSMWorld::IdTable::index (index.row(), 0),
CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1));
return true;
}
return false;
}
Qt::ItemFlags CSMWorld::IdTable::flags (const QModelIndex & index) const
{
Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
if (mIdCollection->getColumn (index.column()).isUserEditable())
flags |= Qt::ItemIsEditable;
return flags;
}
bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& parent)
{
if (parent.isValid())
return false;
beginRemoveRows (parent, row, row+count-1);
mIdCollection->removeRows (row, count);
endRemoveRows();
return true;
}
void CSMWorld::IdTable::addRecord (const std::string& id)
{
int index = mIdCollection->getSize();
beginInsertRows (QModelIndex(), index, index);
mIdCollection->appendBlankRecord (id);
endInsertRows();
}
QModelIndex CSMWorld::IdTable::getModelIndex (const std::string& id, int column) const
{
return index (mIdCollection->getIndex (id), column);
}
void CSMWorld::IdTable::setRecord (const RecordBase& record)
{
int index = mIdCollection->searchId (mIdCollection->getId (record));
if (index==-1)
{
int index = mIdCollection->getSize();
beginInsertRows (QModelIndex(), index, index);
mIdCollection->appendRecord (record);
endInsertRows();
}
else
{
mIdCollection->replace (index, record);
emit dataChanged (CSMWorld::IdTable::index (index, 0),
CSMWorld::IdTable::index (index, mIdCollection->getColumns()-1));
}
}
const CSMWorld::RecordBase& CSMWorld::IdTable::getRecord (const std::string& id) const
{
return mIdCollection->getRecord (id);
}

@ -0,0 +1,53 @@
#ifndef CSM_WOLRD_IDTABLE_H
#define CSM_WOLRD_IDTABLE_H
#include <QAbstractTableModel>
namespace CSMWorld
{
class IdCollectionBase;
class RecordBase;
class IdTable : public QAbstractTableModel
{
Q_OBJECT
IdCollectionBase *mIdCollection;
// not implemented
IdTable (const IdTable&);
IdTable& operator= (const IdTable&);
public:
IdTable (IdCollectionBase *idCollection);
///< The ownership of \a idCollection is not transferred.
virtual ~IdTable();
virtual int rowCount (const QModelIndex & parent = QModelIndex()) const;
virtual int columnCount (const QModelIndex & parent = QModelIndex()) const;
virtual QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const;
virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
virtual bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags (const QModelIndex & index) const;
virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex());
void addRecord (const std::string& id);
QModelIndex getModelIndex (const std::string& id, int column) const;
void setRecord (const RecordBase& record);
///< Add record or overwrite existing recrod.
const RecordBase& getRecord (const std::string& id) const;
};
}
#endif

@ -0,0 +1,18 @@
#include "idtableproxymodel.hpp"
#include "idtable.hpp"
CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent)
: QSortFilterProxyModel (parent)
{}
void CSMWorld::IdTableProxyModel::addRecord (const std::string& id)
{
dynamic_cast<IdTable&> (*sourceModel()).addRecord (id);
}
QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, int column) const
{
return mapFromSource (dynamic_cast<IdTable&> (*sourceModel()).getModelIndex (id, column));
}

@ -0,0 +1,24 @@
#ifndef CSM_WOLRD_IDTABLEPROXYMODEL_H
#define CSM_WOLRD_IDTABLEPROXYMODEL_H
#include <QSortFilterProxyModel>
#include <string>
namespace CSMWorld
{
class IdTableProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
IdTableProxyModel (QObject *parent = 0);
virtual void addRecord (const std::string& id);
virtual QModelIndex getModelIndex (const std::string& id, int column) const;
};
}
#endif

@ -0,0 +1,21 @@
#include "record.hpp"
CSMWorld::RecordBase::~RecordBase() {}
bool CSMWorld::RecordBase::RecordBase::isDeleted() const
{
return mState==State_Deleted || mState==State_Erased;
}
bool CSMWorld::RecordBase::RecordBase::isErased() const
{
return mState==State_Erased;
}
bool CSMWorld::RecordBase::RecordBase::isModified() const
{
return mState==State_Modified || mState==State_ModifiedOnly;
}

@ -0,0 +1,104 @@
#ifndef CSM_WOLRD_RECORD_H
#define CSM_WOLRD_RECORD_H
#include <stdexcept>
namespace CSMWorld
{
struct RecordBase
{
enum State
{
State_BaseOnly = 0, // defined in base only
State_Modified = 1, // exists in base, but has been modified
State_ModifiedOnly = 2, // newly created in modified
State_Deleted = 3, // exists in base, but has been deleted
State_Erased = 4 // does not exist at all (we mostly treat that the same way as deleted)
};
State mState;
virtual ~RecordBase();
virtual RecordBase *clone() const = 0;
bool isDeleted() const;
bool isErased() const;
bool isModified() const;
};
template <typename ESXRecordT>
struct Record : public RecordBase
{
ESXRecordT mBase;
ESXRecordT mModified;
virtual RecordBase *clone() const;
const ESXRecordT& get() const;
///< Throws an exception, if the record is deleted.
const ESXRecordT& getBase() const;
///< Throws an exception, if the record is deleted. Returns modified, if there is no base.
void setModified (const ESXRecordT& modified);
///< Throws an exception, if the record is deleted.
void merge();
///< Merge modified into base.
};
template <typename ESXRecordT>
RecordBase *Record<ESXRecordT>::clone() const
{
return new Record<ESXRecordT> (*this);
}
template <typename ESXRecordT>
const ESXRecordT& Record<ESXRecordT>::get() const
{
if (mState==State_Erased)
throw std::logic_error ("attempt to access a deleted record");
return mState==State_BaseOnly ? mBase : mModified;
}
template <typename ESXRecordT>
const ESXRecordT& Record<ESXRecordT>::getBase() const
{
if (mState==State_Erased)
throw std::logic_error ("attempt to access a deleted record");
return mState==State_ModifiedOnly ? mModified : mBase;
}
template <typename ESXRecordT>
void Record<ESXRecordT>::setModified (const ESXRecordT& modified)
{
if (mState==State_Erased)
throw std::logic_error ("attempt to modify a deleted record");
mModified = modified;
if (mState!=State_ModifiedOnly)
mState = mBase==mModified ? State_BaseOnly : State_Modified;
}
template <typename ESXRecordT>
void Record<ESXRecordT>::merge()
{
if (isModified())
{
mBase = mModified;
mState = State_BaseOnly;
}
else if (mState==State_Deleted)
{
mState = State_Erased;
}
}
}
#endif

@ -0,0 +1,237 @@
#include "universalid.hpp"
#include <ostream>
#include <stdexcept>
#include <sstream>
namespace
{
struct TypeData
{
CSMWorld::UniversalId::Class mClass;
CSMWorld::UniversalId::Type mType;
const char *mName;
};
static const TypeData sNoArg[] =
{
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, "empty" },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables" },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
};
static const TypeData sIdArg[] =
{
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable" },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
};
static const TypeData sIndexArg[] =
{
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results" },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
};
}
CSMWorld::UniversalId::UniversalId (const std::string& universalId)
{
std::string::size_type index = universalId.find (':');
if (index==std::string::npos)
{
std::string type = universalId.substr (0, index);
if (index==std::string::npos)
{
for (int i=0; sNoArg[i].mName; ++i)
if (type==sNoArg[i].mName)
{
mArgumentType = ArgumentType_None;
mType = sNoArg[i].mType;
mClass = sNoArg[i].mClass;
return;
}
}
else
{
for (int i=0; sIdArg[i].mName; ++i)
if (type==sIdArg[i].mName)
{
mArgumentType = ArgumentType_Id;
mType = sIdArg[i].mType;
mClass = sIdArg[i].mClass;
mId = universalId.substr (0, index);
return;
}
for (int i=0; sIndexArg[i].mName; ++i)
if (type==sIndexArg[i].mName)
{
mArgumentType = ArgumentType_Index;
mType = sIndexArg[i].mType;
mClass = sIndexArg[i].mClass;
std::istringstream stream (universalId.substr (0, index));
if (stream >> mIndex)
return;
break;
}
}
}
throw std::runtime_error ("invalid UniversalId: " + universalId);
}
CSMWorld::UniversalId::UniversalId (Type type) : mArgumentType (ArgumentType_None), mType (type), mIndex (0)
{
for (int i=0; sNoArg[i].mName; ++i)
if (type==sNoArg[i].mType)
{
mClass = sNoArg[i].mClass;
return;
}
throw std::logic_error ("invalid argument-less UniversalId type");
}
CSMWorld::UniversalId::UniversalId (Type type, const std::string& id)
: mArgumentType (ArgumentType_Id), mType (type), mId (id), mIndex (0)
{
for (int i=0; sIdArg[i].mName; ++i)
if (type==sIdArg[i].mType)
{
mClass = sIdArg[i].mClass;
return;
}
throw std::logic_error ("invalid ID argument UniversalId type");
}
CSMWorld::UniversalId::UniversalId (Type type, int index)
: mArgumentType (ArgumentType_Index), mType (type), mIndex (index)
{
for (int i=0; sIndexArg[i].mName; ++i)
if (type==sIndexArg[i].mType)
{
mClass = sIndexArg[i].mClass;
return;
}
throw std::logic_error ("invalid index argument UniversalId type");
}
CSMWorld::UniversalId::Class CSMWorld::UniversalId::getClass() const
{
return mClass;
}
CSMWorld::UniversalId::ArgumentType CSMWorld::UniversalId::getArgumentType() const
{
return mArgumentType;
}
CSMWorld::UniversalId::Type CSMWorld::UniversalId::getType() const
{
return mType;
}
const std::string& CSMWorld::UniversalId::getId() const
{
if (mArgumentType!=ArgumentType_Id)
throw std::logic_error ("invalid access to ID of non-ID UniversalId");
return mId;
}
int CSMWorld::UniversalId::getIndex() const
{
if (mArgumentType!=ArgumentType_Index)
throw std::logic_error ("invalid access to index of non-index UniversalId");
return mIndex;
}
bool CSMWorld::UniversalId::isEqual (const UniversalId& universalId) const
{
if (mClass!=universalId.mClass || mArgumentType!=universalId.mArgumentType || mType!=universalId.mType)
return false;
switch (mArgumentType)
{
case ArgumentType_Id: return mId==universalId.mId;
case ArgumentType_Index: return mIndex==universalId.mIndex;
default: return true;
}
}
bool CSMWorld::UniversalId::isLess (const UniversalId& universalId) const
{
if (mType<universalId.mType)
return true;
if (mType>universalId.mType)
return false;
switch (mArgumentType)
{
case ArgumentType_Id: return mId<universalId.mId;
case ArgumentType_Index: return mIndex<universalId.mIndex;
default: return false;
}
}
std::string CSMWorld::UniversalId::getTypeName() const
{
const TypeData *typeData = mArgumentType==ArgumentType_None ? sNoArg :
(mArgumentType==ArgumentType_Id ? sIdArg : sIndexArg);
for (int i=0; typeData[i].mName; ++i)
if (typeData[i].mType==mType)
return typeData[i].mName;
throw std::logic_error ("failed to retrieve UniversalId type name");
}
std::string CSMWorld::UniversalId::toString() const
{
std::ostringstream stream;
stream << getTypeName();
switch (mArgumentType)
{
case ArgumentType_None: break;
case ArgumentType_Id: stream << ": " << mId; break;
case ArgumentType_Index: stream << ": " << mIndex; break;
}
return stream.str();
}
bool CSMWorld::operator== (const CSMWorld::UniversalId& left, const CSMWorld::UniversalId& right)
{
return left.isEqual (right);
}
bool CSMWorld::operator!= (const CSMWorld::UniversalId& left, const CSMWorld::UniversalId& right)
{
return !left.isEqual (right);
}
bool CSMWorld::operator< (const UniversalId& left, const UniversalId& right)
{
return left.isLess (right);
}
std::ostream& CSMWorld::operator< (std::ostream& stream, const CSMWorld::UniversalId& universalId)
{
return stream << universalId.toString();
}

@ -0,0 +1,96 @@
#ifndef CSM_WOLRD_UNIVERSALID_H
#define CSM_WOLRD_UNIVERSALID_H
#include <string>
#include <iosfwd>
#include <QMetaType>
namespace CSMWorld
{
class UniversalId
{
public:
enum Class
{
Class_None = 0,
Class_Record,
Class_SubRecord,
Class_RecordList,
Class_Collection, // multiple types of records combined
Class_Transient, // not part of the world data or the project data
Class_NonRecord // record like data that is not part of the world
};
enum ArgumentType
{
ArgumentType_None,
ArgumentType_Id,
ArgumentType_Index
};
enum Type
{
Type_None,
Type_Globals,
Type_Global,
Type_VerificationResults
};
private:
Class mClass;
ArgumentType mArgumentType;
Type mType;
std::string mId;
int mIndex;
public:
UniversalId (const std::string& universalId);
UniversalId (Type type = Type_None);
///< Using a type for a non-argument-less UniversalId will throw an exception.
UniversalId (Type type, const std::string& id);
///< Using a type for a non-ID-argument UniversalId will throw an exception.
UniversalId (Type type, int index);
///< Using a type for a non-index-argument UniversalId will throw an exception.
Class getClass() const;
ArgumentType getArgumentType() const;
Type getType() const;
const std::string& getId() const;
///< Calling this function for a non-ID type will throw an exception.
int getIndex() const;
///< Calling this function for a non-index type will throw an exception.
bool isEqual (const UniversalId& universalId) const;
bool isLess (const UniversalId& universalId) const;
std::string getTypeName() const;
std::string toString() const;
};
bool operator== (const UniversalId& left, const UniversalId& right);
bool operator!= (const UniversalId& left, const UniversalId& right);
bool operator< (const UniversalId& left, const UniversalId& right);
std::ostream& operator< (std::ostream& stream, const UniversalId& universalId);
}
Q_DECLARE_METATYPE (CSMWorld::UniversalId)
#endif

@ -0,0 +1,54 @@
#include "operation.hpp"
#include <sstream>
#include "../../model/doc/document.hpp"
void CSVDoc::Operation::updateLabel (int threads)
{
if (threads==-1 || ((threads==0)!=mStalling))
{
std::string name ("unknown operation");
switch (mType)
{
case CSMDoc::State_Saving: name = "saving"; break;
case CSMDoc::State_Verifying: name = "verifying"; break;
}
std::ostringstream stream;
if ((mStalling = (threads<=0)))
{
stream << name << " (waiting for a free worker thread)";
}
else
{
stream << name << " (%p%)";
}
setFormat (stream.str().c_str());
}
}
CSVDoc::Operation::Operation (int type) : mType (type), mStalling (false)
{
/// \todo Add a cancel button or a pop up menu with a cancel item
updateLabel();
/// \todo assign different progress bar colours to allow the user to distinguish easily between operation types
}
void CSVDoc::Operation::setProgress (int current, int max, int threads)
{
updateLabel (threads);
setRange (0, max);
setValue (current);
}
int CSVDoc::Operation::getType() const
{
return mType;
}

@ -0,0 +1,31 @@
#ifndef CSV_DOC_OPERATION_H
#define CSV_DOC_OPERATION_H
#include <QProgressBar>
namespace CSVDoc
{
class Operation : public QProgressBar
{
Q_OBJECT
int mType;
bool mStalling;
// not implemented
Operation (const Operation&);
Operation& operator= (const Operation&);
void updateLabel (int threads = -1);
public:
Operation (int type);
void setProgress (int current, int max, int threads);
int getType() const;
};
}
#endif

@ -0,0 +1,47 @@
#include "operations.hpp"
#include <QVBoxLayout>
#include "operation.hpp"
CSVDoc::Operations::Operations()
{
/// \todo make widget height fixed (exactly the height required to display all operations)
setFeatures (QDockWidget::NoDockWidgetFeatures);
QWidget *widget = new QWidget;
setWidget (widget);
mLayout = new QVBoxLayout;
widget->setLayout (mLayout);
}
void CSVDoc::Operations::setProgress (int current, int max, int type, int threads)
{
for (std::vector<Operation *>::iterator iter (mOperations.begin()); iter!=mOperations.end(); ++iter)
if ((*iter)->getType()==type)
{
(*iter)->setProgress (current, max, threads);
return;
}
Operation *operation = new Operation (type);
mLayout->addWidget (operation);
mOperations.push_back (operation);
operation->setProgress (current, max, threads);
}
void CSVDoc::Operations::quitOperation (int type)
{
for (std::vector<Operation *>::iterator iter (mOperations.begin()); iter!=mOperations.end(); ++iter)
if ((*iter)->getType()==type)
{
delete *iter;
mOperations.erase (iter);
break;
}
}

@ -0,0 +1,37 @@
#ifndef CSV_DOC_OPERATIONS_H
#define CSV_DOC_OPERATIONS_H
#include <vector>
#include <QDockWidget>
class QVBoxLayout;
namespace CSVDoc
{
class Operation;
class Operations : public QDockWidget
{
Q_OBJECT
QVBoxLayout *mLayout;
std::vector<Operation *> mOperations;
// not implemented
Operations (const Operations&);
Operations& operator= (const Operations&);
public:
Operations();
void setProgress (int current, int max, int type, int threads);
///< Implicitly starts the operation, if it is not running already.
void quitOperation (int type);
///< Calling this function for an operation that is not running is a no-op.
};
}
#endif

@ -0,0 +1,18 @@
#include "subview.hpp"
CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) : mUniversalId (id)
{
/// \todo add a button to the title bar that clones this sub view
setWindowTitle (mUniversalId.toString().c_str());
/// \todo remove (for testing only)
setMinimumWidth (100);
setMinimumHeight (60);
}
CSMWorld::UniversalId CSVDoc::SubView::getUniversalId() const
{
return mUniversalId;
}

@ -0,0 +1,45 @@
#ifndef CSV_DOC_SUBVIEW_H
#define CSV_DOC_SUBVIEW_H
#include "../../model/doc/document.hpp"
#include "../../model/world/universalid.hpp"
#include "subviewfactory.hpp"
#include <QDockWidget>
class QUndoStack;
namespace CSMWorld
{
class Data;
}
namespace CSVDoc
{
class SubView : public QDockWidget
{
Q_OBJECT
CSMWorld::UniversalId mUniversalId;
// not implemented
SubView (const SubView&);
SubView& operator= (SubView&);
public:
SubView (const CSMWorld::UniversalId& id);
CSMWorld::UniversalId getUniversalId() const;
virtual void setEditLock (bool locked) = 0;
signals:
void focusId (const CSMWorld::UniversalId& universalId);
};
}
#endif

@ -0,0 +1,38 @@
#include "subviewfactory.hpp"
#include <cassert>
#include <stdexcept>
CSVDoc::SubViewFactoryBase::SubViewFactoryBase() {}
CSVDoc::SubViewFactoryBase::~SubViewFactoryBase() {}
CSVDoc::SubViewFactoryManager::SubViewFactoryManager() {}
CSVDoc::SubViewFactoryManager::~SubViewFactoryManager()
{
for (std::map<CSMWorld::UniversalId::Type, SubViewFactoryBase *>::iterator iter (mSubViewFactories.begin());
iter!=mSubViewFactories.end(); ++iter)
delete iter->second;
}
void CSVDoc::SubViewFactoryManager::add (const CSMWorld::UniversalId::Type& id, SubViewFactoryBase *factory)
{
assert (mSubViewFactories.find (id)==mSubViewFactories.end());
mSubViewFactories.insert (std::make_pair (id, factory));
}
CSVDoc::SubView *CSVDoc::SubViewFactoryManager::makeSubView (const CSMWorld::UniversalId& id,
CSMDoc::Document& document)
{
std::map<CSMWorld::UniversalId::Type, SubViewFactoryBase *>::iterator iter = mSubViewFactories.find (id.getType());
if (iter==mSubViewFactories.end())
throw std::runtime_error ("Failed to create a sub view for: " + id.toString());
return iter->second->makeSubView (id, document);
}

@ -0,0 +1,55 @@
#ifndef CSV_DOC_SUBVIEWFACTORY_H
#define CSV_DOC_SUBVIEWFACTORY_H
#include <map>
#include "../../model/world/universalid.hpp"
namespace CSMDoc
{
class Document;
}
namespace CSVDoc
{
class SubView;
class SubViewFactoryBase
{
// not implemented
SubViewFactoryBase (const SubViewFactoryBase&);
SubViewFactoryBase& operator= (const SubViewFactoryBase&);
public:
SubViewFactoryBase();
virtual ~SubViewFactoryBase();
virtual SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) = 0;
///< The ownership of the returned sub view is not transferred.
};
class SubViewFactoryManager
{
std::map<CSMWorld::UniversalId::Type, SubViewFactoryBase *> mSubViewFactories;
// not implemented
SubViewFactoryManager (const SubViewFactoryManager&);
SubViewFactoryManager& operator= (const SubViewFactoryManager&);
public:
SubViewFactoryManager();
~SubViewFactoryManager();
void add (const CSMWorld::UniversalId::Type& id, SubViewFactoryBase *factory);
///< The ownership of \a factory is transferred to this.
SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
///< The ownership of the returned sub view is not transferred.
};
}
#endif

@ -0,0 +1,50 @@
#ifndef CSV_DOC_SUBVIEWFACTORYIMP_H
#define CSV_DOC_SUBVIEWFACTORYIMP_H
#include "../../model/doc/document.hpp"
#include "subviewfactory.hpp"
namespace CSVDoc
{
template<class SubViewT>
class SubViewFactory : public SubViewFactoryBase
{
public:
virtual CSVDoc::SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
};
template<class SubViewT>
CSVDoc::SubView *SubViewFactory<SubViewT>::makeSubView (const CSMWorld::UniversalId& id,
CSMDoc::Document& document)
{
return new SubViewT (id, document);
}
template<class SubViewT>
class SubViewFactoryWithCreateFlag : public SubViewFactoryBase
{
bool mCreateAndDelete;
public:
SubViewFactoryWithCreateFlag (bool createAndDelete);
virtual CSVDoc::SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
};
template<class SubViewT>
SubViewFactoryWithCreateFlag<SubViewT>::SubViewFactoryWithCreateFlag (bool createAndDelete)
: mCreateAndDelete (createAndDelete)
{}
template<class SubViewT>
CSVDoc::SubView *SubViewFactoryWithCreateFlag<SubViewT>::makeSubView (const CSMWorld::UniversalId& id,
CSMDoc::Document& document)
{
return new SubViewT (id, document, mCreateAndDelete);
}
}
#endif

@ -0,0 +1,216 @@
#include "view.hpp"
#include <sstream>
#include <stdexcept>
#include <QCloseEvent>
#include <QMenuBar>
#include <QMdiArea>
#include "../../model/doc/document.hpp"
#include "../world/subviews.hpp"
#include "../tools/subviews.hpp"
#include "viewmanager.hpp"
#include "operations.hpp"
#include "subview.hpp"
void CSVDoc::View::closeEvent (QCloseEvent *event)
{
if (!mViewManager.closeRequest (this))
event->ignore();
}
void CSVDoc::View::setupFileMenu()
{
QMenu *file = menuBar()->addMenu (tr ("&File"));
QAction *new_ = new QAction (tr ("New"), this);
connect (new_, SIGNAL (triggered()), this, SIGNAL (newDocumentRequest()));
file->addAction (new_);
mSave = new QAction (tr ("&Save"), this);
connect (mSave, SIGNAL (triggered()), this, SLOT (save()));
file->addAction (mSave);
}
void CSVDoc::View::setupEditMenu()
{
QMenu *edit = menuBar()->addMenu (tr ("&Edit"));
mUndo = mDocument->getUndoStack().createUndoAction (this, tr("&Undo"));
mUndo->setShortcuts (QKeySequence::Undo);
edit->addAction (mUndo);
mRedo= mDocument->getUndoStack().createRedoAction (this, tr("&Redo"));
mRedo->setShortcuts (QKeySequence::Redo);
edit->addAction (mRedo);
}
void CSVDoc::View::setupViewMenu()
{
QMenu *view = menuBar()->addMenu (tr ("&View"));
QAction *newWindow = new QAction (tr ("&New View"), this);
connect (newWindow, SIGNAL (triggered()), this, SLOT (newView()));
view->addAction (newWindow);
}
void CSVDoc::View::setupWorldMenu()
{
QMenu *world = menuBar()->addMenu (tr ("&World"));
QAction *globals = new QAction (tr ("Globals"), this);
connect (globals, SIGNAL (triggered()), this, SLOT (addGlobalsSubView()));
world->addAction (globals);
mVerify = new QAction (tr ("&Verify"), this);
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
world->addAction (mVerify);
}
void CSVDoc::View::setupUi()
{
setupFileMenu();
setupEditMenu();
setupViewMenu();
setupWorldMenu();
}
void CSVDoc::View::updateTitle()
{
std::ostringstream stream;
stream << mDocument->getName();
if (mDocument->getState() & CSMDoc::State_Modified)
stream << " *";
if (mViewTotal>1)
stream << " [" << (mViewIndex+1) << "/" << mViewTotal << "]";
setWindowTitle (stream.str().c_str());
}
void CSVDoc::View::updateActions()
{
bool editing = !(mDocument->getState() & CSMDoc::State_Locked);
for (std::vector<QAction *>::iterator iter (mEditingActions.begin()); iter!=mEditingActions.end(); ++iter)
(*iter)->setEnabled (editing);
mUndo->setEnabled (editing & mDocument->getUndoStack().canUndo());
mRedo->setEnabled (editing & mDocument->getUndoStack().canRedo());
mSave->setEnabled (!(mDocument->getState() & CSMDoc::State_Saving));
mVerify->setEnabled (!(mDocument->getState() & CSMDoc::State_Verifying));
}
CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews)
: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), mViewTotal (totalViews)
{
setDockOptions (QMainWindow::AllowNestedDocks);
resize (300, 300); /// \todo get default size from settings and set reasonable minimal size
mOperations = new Operations;
addDockWidget (Qt::BottomDockWidgetArea, mOperations);
updateTitle();
setupUi();
CSVWorld::addSubViewFactories (mSubViewFactory);
CSVTools::addSubViewFactories (mSubViewFactory);
}
CSVDoc::View::~View()
{
}
const CSMDoc::Document *CSVDoc::View::getDocument() const
{
return mDocument;
}
CSMDoc::Document *CSVDoc::View::getDocument()
{
return mDocument;
}
void CSVDoc::View::setIndex (int viewIndex, int totalViews)
{
mViewIndex = viewIndex;
mViewTotal = totalViews;
updateTitle();
}
void CSVDoc::View::updateDocumentState()
{
updateTitle();
updateActions();
static const int operations[] =
{
CSMDoc::State_Saving, CSMDoc::State_Verifying,
-1 // end marker
};
int state = mDocument->getState() ;
for (int i=0; operations[i]!=-1; ++i)
if (!(state & operations[i]))
mOperations->quitOperation (operations[i]);
QList<CSVDoc::SubView *> subViews = findChildren<CSVDoc::SubView *>();
for (QList<CSVDoc::SubView *>::iterator iter (subViews.begin()); iter!=subViews.end(); ++iter)
(*iter)->setEditLock (state & CSMDoc::State_Locked);
}
void CSVDoc::View::updateProgress (int current, int max, int type, int threads)
{
mOperations->setProgress (current, max, type, threads);
}
void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id)
{
/// \todo add an user setting for limiting the number of sub views per top level view. Automatically open a new top level view if this
/// number is exceeded
/// \todo if the sub view limit setting is one, the sub view title bar should be hidden and the text in the main title bar adjusted
/// accordingly
/// \todo add an user setting to reuse sub views (on a per document basis or on a per top level view basis)
SubView *view = mSubViewFactory.makeSubView (id, *mDocument);
addDockWidget (Qt::TopDockWidgetArea, view);
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&)), this,
SLOT (addSubView (const CSMWorld::UniversalId&)));
view->show();
}
void CSVDoc::View::newView()
{
mViewManager.addView (mDocument);
}
void CSVDoc::View::save()
{
mDocument->save();
}
void CSVDoc::View::verify()
{
addSubView (mDocument->verify());
}
void CSVDoc::View::addGlobalsSubView()
{
addSubView (CSMWorld::UniversalId::Type_Globals);
}

@ -0,0 +1,103 @@
#ifndef CSV_DOC_VIEW_H
#define CSV_DOC_VIEW_H
#include <vector>
#include <map>
#include <QMainWindow>
#include "subviewfactory.hpp"
class QAction;
namespace CSMDoc
{
class Document;
}
namespace CSMWorld
{
class UniversalId;
}
namespace CSVDoc
{
class ViewManager;
class Operations;
class View : public QMainWindow
{
Q_OBJECT
ViewManager& mViewManager;
CSMDoc::Document *mDocument;
int mViewIndex;
int mViewTotal;
QAction *mUndo;
QAction *mRedo;
QAction *mSave;
QAction *mVerify;
std::vector<QAction *> mEditingActions;
Operations *mOperations;
SubViewFactoryManager mSubViewFactory;
// not implemented
View (const View&);
View& operator= (const View&);
private:
void closeEvent (QCloseEvent *event);
void setupFileMenu();
void setupEditMenu();
void setupViewMenu();
void setupWorldMenu();
void setupUi();
void updateTitle();
void updateActions();
public:
View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews);
///< The ownership of \a document is not transferred to *this.
virtual ~View();
const CSMDoc::Document *getDocument() const;
CSMDoc::Document *getDocument();
void setIndex (int viewIndex, int totalViews);
void updateDocumentState();
void updateProgress (int current, int max, int type, int threads);
signals:
void newDocumentRequest();
public slots:
void addSubView (const CSMWorld::UniversalId& id);
private slots:
void newView();
void save();
void verify();
void addGlobalsSubView();
};
}
#endif

@ -0,0 +1,112 @@
#include "viewmanager.hpp"
#include <map>
#include "../../model/doc/documentmanager.hpp"
#include "../../model/doc/document.hpp"
#include "view.hpp"
void CSVDoc::ViewManager::updateIndices()
{
std::map<CSMDoc::Document *, std::pair<int, int> > documents;
for (std::vector<View *>::const_iterator iter (mViews.begin()); iter!=mViews.end(); ++iter)
{
std::map<CSMDoc::Document *, std::pair<int, int> >::iterator document = documents.find ((*iter)->getDocument());
if (document==documents.end())
document =
documents.insert (
std::make_pair ((*iter)->getDocument(), std::make_pair (0, countViews ((*iter)->getDocument())))).
first;
(*iter)->setIndex (document->second.first++, document->second.second);
}
}
CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
: mDocumentManager (documentManager)
{
}
CSVDoc::ViewManager::~ViewManager()
{
for (std::vector<View *>::iterator iter (mViews.begin()); iter!=mViews.end(); ++iter)
delete *iter;
}
CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document)
{
if (countViews (document)==0)
{
// new document
connect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)),
this, SLOT (documentStateChanged (int, CSMDoc::Document *)));
connect (document, SIGNAL (progress (int, int, int, int, CSMDoc::Document *)),
this, SLOT (progress (int, int, int, int, CSMDoc::Document *)));
}
View *view = new View (*this, document, countViews (document)+1);
mViews.push_back (view);
view->show();
connect (view, SIGNAL (newDocumentRequest ()), this, SIGNAL (newDocumentRequest()));
updateIndices();
return view;
}
int CSVDoc::ViewManager::countViews (const CSMDoc::Document *document) const
{
int count = 0;
for (std::vector<View *>::const_iterator iter (mViews.begin()); iter!=mViews.end(); ++iter)
if ((*iter)->getDocument()==document)
++count;
return count;
}
bool CSVDoc::ViewManager::closeRequest (View *view)
{
std::vector<View *>::iterator iter = std::find (mViews.begin(), mViews.end(), view);
if (iter!=mViews.end())
{
bool last = countViews (view->getDocument())<=1;
/// \todo check if save is in progress -> warn user about possible data loss
/// \todo check if document has not been saved -> return false and start close dialogue
mViews.erase (iter);
view->deleteLater();
if (last)
mDocumentManager.removeDocument (view->getDocument());
else
updateIndices();
}
return true;
}
void CSVDoc::ViewManager::documentStateChanged (int state, CSMDoc::Document *document)
{
for (std::vector<View *>::const_iterator iter (mViews.begin()); iter!=mViews.end(); ++iter)
if ((*iter)->getDocument()==document)
(*iter)->updateDocumentState();
}
void CSVDoc::ViewManager::progress (int current, int max, int type, int threads, CSMDoc::Document *document)
{
for (std::vector<View *>::const_iterator iter (mViews.begin()); iter!=mViews.end(); ++iter)
if ((*iter)->getDocument()==document)
(*iter)->updateProgress (current, max, type, threads);
}

@ -0,0 +1,58 @@
#ifndef CSV_DOC_VIEWMANAGER_H
#define CSV_DOC_VIEWMANAGER_H
#include <vector>
#include <QObject>
namespace CSMDoc
{
class Document;
class DocumentManager;
}
namespace CSVDoc
{
class View;
class ViewManager : public QObject
{
Q_OBJECT
CSMDoc::DocumentManager& mDocumentManager;
std::vector<View *> mViews;
// not implemented
ViewManager (const ViewManager&);
ViewManager& operator= (const ViewManager&);
void updateIndices();
public:
ViewManager (CSMDoc::DocumentManager& documentManager);
virtual ~ViewManager();
View *addView (CSMDoc::Document *document);
///< The ownership of the returned view is not transferred.
int countViews (const CSMDoc::Document *document) const;
///< Return number of views for \a document.
bool closeRequest (View *view);
signals:
void newDocumentRequest();
private slots:
void documentStateChanged (int state, CSMDoc::Document *document);
void progress (int current, int max, int type, int threads, CSMDoc::Document *document);
};
}
#endif

@ -0,0 +1,32 @@
#include "reportsubview.hpp"
#include <QTableView>
#include <QHeaderView>
#include "../../model/tools/reportmodel.hpp"
CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
: CSVDoc::SubView (id), mModel (document.getReport (id))
{
setWidget (mTable = new QTableView (this));
mTable->setModel (mModel);
mTable->horizontalHeader()->setResizeMode (QHeaderView::Interactive);
mTable->verticalHeader()->hide();
mTable->setSortingEnabled (true);
mTable->setSelectionBehavior (QAbstractItemView::SelectRows);
mTable->setSelectionMode (QAbstractItemView::ExtendedSelection);
connect (mTable, SIGNAL (doubleClicked (const QModelIndex&)), this, SLOT (show (const QModelIndex&)));
}
void CSVTools::ReportSubView::setEditLock (bool locked)
{
// ignored. We don't change document state anyway.
}
void CSVTools::ReportSubView::show (const QModelIndex& index)
{
focusId (mModel->getUniversalId (index.row()));
}

@ -0,0 +1,42 @@
#ifndef CSV_TOOLS_REPORTSUBVIEW_H
#define CSV_TOOLS_REPORTSUBVIEW_H
#include "../doc/subview.hpp"
class QTableView;
class QModelIndex;
namespace CSMDoc
{
class Document;
}
namespace CSMTools
{
class ReportModel;
}
namespace CSVTools
{
class Table;
class ReportSubView : public CSVDoc::SubView
{
Q_OBJECT
CSMTools::ReportModel *mModel;
QTableView *mTable;
public:
ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
virtual void setEditLock (bool locked);
private slots:
void show (const QModelIndex& index);
};
}
#endif

@ -0,0 +1,12 @@
#include "subviews.hpp"
#include "../doc/subviewfactoryimp.hpp"
#include "reportsubview.hpp"
void CSVTools::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
{
manager.add (CSMWorld::UniversalId::Type_VerificationResults,
new CSVDoc::SubViewFactory<ReportSubView>);
}

@ -0,0 +1,14 @@
#ifndef CSV_TOOLS_SUBVIEWS_H
#define CSV_TOOLS_SUBVIEWS_H
namespace CSVDoc
{
class SubViewFactoryManager;
}
namespace CSVTools
{
void addSubViewFactories (CSVDoc::SubViewFactoryManager& manager);
}
#endif

@ -0,0 +1,14 @@
#include "dialoguesubview.hpp"
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
bool createAndDelete)
: SubView (id)
{
}
void CSVWorld::DialogueSubView::setEditLock (bool locked)
{
}

@ -0,0 +1,24 @@
#ifndef CSV_WORLD_DIALOGUESUBVIEW_H
#define CSV_WORLD_DIALOGUESUBVIEW_H
#include "../doc/subview.hpp"
namespace CSMDoc
{
class Document;
}
namespace CSVWorld
{
class DialogueSubView : public CSVDoc::SubView
{
public:
DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete);
virtual void setEditLock (bool locked);
};
}
#endif

@ -0,0 +1,16 @@
#include "subviews.hpp"
#include "../doc/subviewfactoryimp.hpp"
#include "tablesubview.hpp"
#include "dialoguesubview.hpp"
void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
{
manager.add (CSMWorld::UniversalId::Type_Globals,
new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (true));
manager.add (CSMWorld::UniversalId::Type_Global,
new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true));
}

@ -0,0 +1,14 @@
#ifndef CSV_WORLD_SUBVIEWS_H
#define CSV_WORLD_SUBVIEWS_H
namespace CSVDoc
{
class SubViewFactoryManager;
}
namespace CSVWorld
{
void addSubViewFactories (CSVDoc::SubViewFactoryManager& manager);
}
#endif

@ -0,0 +1,199 @@
#include "table.hpp"
#include <QHeaderView>
#include <QAction>
#include <QMenu>
#include <QContextMenuEvent>
#include "../../model/world/data.hpp"
#include "../../model/world/commands.hpp"
#include "../../model/world/idtableproxymodel.hpp"
#include "../../model/world/idtable.hpp"
#include "../../model/world/record.hpp"
#include "util.hpp"
void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
{
QModelIndexList selectedRows = selectionModel()->selectedRows();
QMenu menu (this);
/// \todo add menu items for select all and clear selection
if (!mEditLock)
{
if (mCreateAction)
menu.addAction (mCreateAction);
if (listRevertableSelectedIds().size()>0)
menu.addAction (mRevertAction);
if (listDeletableSelectedIds().size()>0)
menu.addAction (mDeleteAction);
}
menu.exec (event->globalPos());
}
std::vector<std::string> CSVWorld::Table::listRevertableSelectedIds() const
{
QModelIndexList selectedRows = selectionModel()->selectedRows();
std::vector<std::string> revertableIds;
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end(); ++iter)
{
std::string id = mProxyModel->data (*iter).toString().toStdString();
CSMWorld::RecordBase::State state =
static_cast<CSMWorld::RecordBase::State> (mModel->data (mModel->getModelIndex (id, 1)).toInt());
if (state!=CSMWorld::RecordBase::State_BaseOnly)
revertableIds.push_back (id);
}
return revertableIds;
}
std::vector<std::string> CSVWorld::Table::listDeletableSelectedIds() const
{
QModelIndexList selectedRows = selectionModel()->selectedRows();
std::vector<std::string> deletableIds;
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end(); ++iter)
{
std::string id = mProxyModel->data (*iter).toString().toStdString();
CSMWorld::RecordBase::State state =
static_cast<CSMWorld::RecordBase::State> (mModel->data (mModel->getModelIndex (id, 1)).toInt());
if (state!=CSMWorld::RecordBase::State_Deleted)
deletableIds.push_back (id);
}
return deletableIds;
}
CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack,
bool createAndDelete)
: mUndoStack (undoStack), mCreateAction (0), mEditLock (false)
{
mModel = &dynamic_cast<CSMWorld::IdTable&> (*data.getTableModel (id));
mProxyModel = new CSMWorld::IdTableProxyModel (this);
mProxyModel->setSourceModel (mModel);
setModel (mProxyModel);
horizontalHeader()->setResizeMode (QHeaderView::Interactive);
verticalHeader()->hide();
setSortingEnabled (true);
setSelectionBehavior (QAbstractItemView::SelectRows);
setSelectionMode (QAbstractItemView::ExtendedSelection);
int columns = mModel->columnCount();
for (int i=0; i<columns; ++i)
{
int flags = mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt();
if (flags & CSMWorld::ColumnBase::Flag_Table)
{
CommandDelegate *delegate = new CommandDelegate (undoStack, this);
mDelegates.push_back (delegate);
setItemDelegateForColumn (i, delegate);
}
else
hideColumn (i);
}
/// \todo make initial layout fill the whole width of the table
if (createAndDelete)
{
mCreateAction = new QAction (tr ("Add Record"), this);
connect (mCreateAction, SIGNAL (triggered()), this, SLOT (createRecord()));
addAction (mCreateAction);
}
mRevertAction = new QAction (tr ("Revert Record"), this);
connect (mRevertAction, SIGNAL (triggered()), this, SLOT (revertRecord()));
addAction (mRevertAction);
mDeleteAction = new QAction (tr ("Delete Record"), this);
connect (mDeleteAction, SIGNAL (triggered()), this, SLOT (deleteRecord()));
addAction (mDeleteAction);
}
void CSVWorld::Table::setEditLock (bool locked)
{
for (std::vector<CommandDelegate *>::iterator iter (mDelegates.begin()); iter!=mDelegates.end(); ++iter)
(*iter)->setEditLock (locked);
mEditLock = locked;
}
CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const
{
return CSMWorld::UniversalId (
static_cast<CSMWorld::UniversalId::Type> (mProxyModel->data (mProxyModel->index (row, 2)).toInt()),
mProxyModel->data (mProxyModel->index (row, 0)).toString().toStdString());
}
#include <sstream> /// \todo remove
void CSVWorld::Table::createRecord()
{
if (!mEditLock)
{
/// \todo ask the user for an ID instead.
static int index = 0;
std::ostringstream stream;
stream << "id" << index++;
mUndoStack.push (new CSMWorld::CreateCommand (*mProxyModel, stream.str()));
}
}
void CSVWorld::Table::revertRecord()
{
if (!mEditLock)
{
std::vector<std::string> revertableIds = listRevertableSelectedIds();
if (revertableIds.size()>0)
{
if (revertableIds.size()>1)
mUndoStack.beginMacro (tr ("Revert multiple records"));
for (std::vector<std::string>::const_iterator iter (revertableIds.begin()); iter!=revertableIds.end(); ++iter)
mUndoStack.push (new CSMWorld::RevertCommand (*mModel, *iter));
if (revertableIds.size()>1)
mUndoStack.endMacro();
}
}
}
void CSVWorld::Table::deleteRecord()
{
if (!mEditLock)
{
std::vector<std::string> deletableIds = listDeletableSelectedIds();
if (deletableIds.size()>0)
{
if (deletableIds.size()>1)
mUndoStack.beginMacro (tr ("Delete multiple records"));
for (std::vector<std::string>::const_iterator iter (deletableIds.begin()); iter!=deletableIds.end(); ++iter)
mUndoStack.push (new CSMWorld::DeleteCommand (*mModel, *iter));
if (deletableIds.size()>1)
mUndoStack.endMacro();
}
}
}

@ -0,0 +1,65 @@
#ifndef CSV_WORLD_TABLE_H
#define CSV_WORLD_TABLE_H
#include <vector>
#include <string>
#include <QTableView>
class QUndoStack;
class QAction;
namespace CSMWorld
{
class Data;
class UniversalId;
class IdTableProxyModel;
class IdTable;
}
namespace CSVWorld
{
class CommandDelegate;
///< Table widget
class Table : public QTableView
{
Q_OBJECT
std::vector<CommandDelegate *> mDelegates;
QUndoStack& mUndoStack;
QAction *mCreateAction;
QAction *mRevertAction;
QAction *mDeleteAction;
CSMWorld::IdTableProxyModel *mProxyModel;
CSMWorld::IdTable *mModel;
bool mEditLock;
private:
void contextMenuEvent (QContextMenuEvent *event);
std::vector<std::string> listRevertableSelectedIds() const;
std::vector<std::string> listDeletableSelectedIds() const;
public:
Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack, bool createAndDelete);
///< \param createAndDelete Allow creation and deletion of records.
void setEditLock (bool locked);
CSMWorld::UniversalId getUniversalId (int row) const;
private slots:
void createRecord();
void revertRecord();
void deleteRecord();
};
}
#endif

@ -0,0 +1,25 @@
#include "tablesubview.hpp"
#include "../../model/doc/document.hpp"
#include "table.hpp"
CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
bool createAndDelete)
: SubView (id)
{
setWidget (mTable = new Table (id, document.getData(), document.getUndoStack(), createAndDelete));
connect (mTable, SIGNAL (doubleClicked (const QModelIndex&)), this, SLOT (rowActivated (const QModelIndex&)));
}
void CSVWorld::TableSubView::setEditLock (bool locked)
{
mTable->setEditLock (locked);
}
void CSVWorld::TableSubView::rowActivated (const QModelIndex& index)
{
focusId (mTable->getUniversalId (index.row()));
}

@ -0,0 +1,35 @@
#ifndef CSV_WORLD_TABLESUBVIEW_H
#define CSV_WORLD_TABLESUBVIEW_H
#include "../doc/subview.hpp"
class QModelIndex;
namespace CSMDoc
{
class Document;
}
namespace CSVWorld
{
class Table;
class TableSubView : public CSVDoc::SubView
{
Q_OBJECT
Table *mTable;
public:
TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete);
virtual void setEditLock (bool locked);
private slots:
void rowActivated (const QModelIndex& index);
};
}
#endif

@ -0,0 +1,57 @@
#include "util.hpp"
#include <QUndoStack>
#include "../../model/world/commands.hpp"
CSVWorld::NastyTableModelHack::NastyTableModelHack (QAbstractItemModel& model)
: mModel (model)
{}
int CSVWorld::NastyTableModelHack::rowCount (const QModelIndex & parent) const
{
return mModel.rowCount (parent);
}
int CSVWorld::NastyTableModelHack::columnCount (const QModelIndex & parent) const
{
return mModel.columnCount (parent);
}
QVariant CSVWorld::NastyTableModelHack::data (const QModelIndex & index, int role) const
{
return mModel.data (index, role);
}
bool CSVWorld::NastyTableModelHack::setData ( const QModelIndex &index, const QVariant &value, int role)
{
mData = value;
return true;
}
QVariant CSVWorld::NastyTableModelHack::getData() const
{
return mData;
}
CSVWorld::CommandDelegate::CommandDelegate (QUndoStack& undoStack, QObject *parent)
: QStyledItemDelegate (parent), mUndoStack (undoStack), mEditLock (false)
{}
void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemModel *model,
const QModelIndex& index) const
{
if (!mEditLock)
{
NastyTableModelHack hack (*model);
QStyledItemDelegate::setModelData (editor, &hack, index);
mUndoStack.push (new CSMWorld::ModifyCommand (*model, index, hack.getData()));
}
///< \todo provide some kind of feedback to the user, indicating that editing is currently not possible.
}
void CSVWorld::CommandDelegate::setEditLock (bool locked)
{
mEditLock = locked;
}

@ -0,0 +1,50 @@
#ifndef CSV_WORLD_UTIL_H
#define CSV_WORLD_UTIL_H
#include <QAbstractTableModel>
#include <QStyledItemDelegate>
class QUndoStack;
namespace CSVWorld
{
///< \brief Getting the data out of an editor widget
///
/// Really, Qt? Really?
class NastyTableModelHack : public QAbstractTableModel
{
QAbstractItemModel& mModel;
QVariant mData;
public:
NastyTableModelHack (QAbstractItemModel& model);
int rowCount (const QModelIndex & parent = QModelIndex()) const;
int columnCount (const QModelIndex & parent = QModelIndex()) const;
QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const;
bool setData (const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
QVariant getData() const;
};
///< \brief Use commands instead of manipulating the model directly
class CommandDelegate : public QStyledItemDelegate
{
QUndoStack& mUndoStack;
bool mEditLock;
public:
CommandDelegate (QUndoStack& undoStack, QObject *parent);
void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const;
void setEditLock (bool locked);
};
}
#endif

@ -34,7 +34,7 @@ add_openmw_dir (mwgui
)
add_openmw_dir (mwdialogue
dialoguemanagerimp journalimp journalentry quest topic
dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper
)
add_openmw_dir (mwscript
@ -53,6 +53,7 @@ add_openmw_dir (mwworld
containerstore actiontalk actiontake manualref player cellfunctors failedaction
cells localscripts customdata weather inventorystore ptr actionopen actionread
actionequip timestamp actionalchemy cellstore actionapply actioneat
esmstore store recordcmp
)
add_openmw_dir (mwclass
@ -62,7 +63,7 @@ add_openmw_dir (mwclass
add_openmw_dir (mwmechanics
mechanicsmanagerimp stat creaturestats magiceffects movement actors drawstate spells
activespells npcstats aipackage aisequence alchemy
activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow aiescort aiactivate
)
add_openmw_dir (mwbase

@ -8,6 +8,7 @@
#include <components/bsa/bsa_archive.hpp>
#include <components/files/configurationmanager.hpp>
#include <components/translation/translation.hpp>
#include <components/nifoverrides/nifoverrides.hpp>
#include <components/nifbullet/bullet_nif_loader.hpp>
@ -20,6 +21,7 @@
#include "mwscript/scriptmanagerimp.hpp"
#include "mwscript/extensions.hpp"
#include "mwscript/interpretercontext.hpp"
#include "mwsound/soundmanagerimp.hpp"
@ -101,7 +103,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
MWBase::Environment::get().getWorld()->doPhysics (movement, mEnvironment.getFrameDuration());
// update world
MWBase::Environment::get().getWorld()->update (evt.timeSinceLastFrame);
MWBase::Environment::get().getWorld()->update (evt.timeSinceLastFrame, MWBase::Environment::get().getWindowManager()->isGuiMode());
// update GUI
Ogre::RenderWindow* window = mOgre->getWindow();
@ -333,12 +335,15 @@ void OMW::Engine::go()
mEnvironment.setWorld (new MWWorld::World (*mOgre, mFileCollections, mMaster,
mResDir, mCfgMgr.getCachePath(), mNewGame, mEncoding, mFallbackMap));
//Load translation data
mTranslationDataStorage.loadTranslationData(mFileCollections, mMaster);
// Create window manager - this manages all the MW-specific GUI windows
MWScript::registerExtensions (mExtensions);
mEnvironment.setWindowManager (new MWGui::WindowManager(
mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
mCfgMgr.getCachePath ().string(), mScriptConsoleMode));
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage));
// Create sound system
mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound));
@ -355,7 +360,7 @@ void OMW::Engine::go()
// Create dialog system
mEnvironment.setJournal (new MWDialogue::Journal);
mEnvironment.setDialogueManager (new MWDialogue::DialogueManager (mExtensions));
mEnvironment.setDialogueManager (new MWDialogue::DialogueManager (mExtensions, mVerboseScripts));
// Sets up the input system
mEnvironment.setInputManager (new MWInput::InputManager (*mOgre,
@ -486,9 +491,10 @@ void OMW::Engine::showFPS(int level)
mFpsLevel = level;
}
void OMW::Engine::setEncoding(const std::string& encoding)
void OMW::Engine::setEncoding(const ToUTF8::FromType& encoding)
{
mEncoding = encoding;
mTranslationDataStorage.setEncoding (encoding);
}
void OMW::Engine::setFallbackValues(std::map<std::string,std::string> fallbackMap)

@ -5,6 +5,7 @@
#include <components/compiler/extensions.hpp>
#include <components/files/collections.hpp>
#include <components/translation/translation.hpp>
#include "mwbase/environment.hpp"
@ -59,7 +60,7 @@ namespace OMW
class Engine : private Ogre::FrameListener
{
MWBase::Environment mEnvironment;
std::string mEncoding;
ToUTF8::FromType mEncoding;
Files::PathContainer mDataDirs;
boost::filesystem::path mResDir;
OEngine::Render::OgreRenderer *mOgre;
@ -79,9 +80,9 @@ namespace OMW
Compiler::Extensions mExtensions;
Compiler::Context *mScriptContext;
Files::Collections mFileCollections;
bool mFSStrict;
Translation::Storage mTranslationDataStorage;
// not implemented
Engine (const Engine&);
@ -154,7 +155,7 @@ namespace OMW
void setCompileAll (bool all);
/// Font encoding
void setEncoding(const std::string& encoding);
void setEncoding(const ToUTF8::FromType& encoding);
void setAnimationVerbose(bool animverbose);

@ -131,9 +131,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
->default_value(false), "enable console-only script functionality")
("script-run", bpo::value<std::string>()->default_value(""),
"select a file that is executed in the console on startup\n\n"
"Note: The file contains a list of script lines, but not a complete scripts. "
"That means no begin/end and no variable declarations.")
"select a file containing a list of console commands that is executed on startup")
("new-game", bpo::value<bool>()->implicit_value(true)
->default_value(false), "activate char gen/new game mechanics")
@ -183,21 +181,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
// Font encoding settings
std::string encoding(variables["encoding"].as<std::string>());
if (encoding == "win1250")
{
std::cout << "Using Central and Eastern European font encoding." << std::endl;
engine.setEncoding(encoding);
}
else if (encoding == "win1251")
{
std::cout << "Using Cyrillic font encoding." << std::endl;
engine.setEncoding(encoding);
}
else
{
std::cout << "Using default (English) font encoding." << std::endl;
engine.setEncoding("win1252");
}
std::cout << ToUTF8::encodingUsingMessage(encoding) << std::endl;
engine.setEncoding(ToUTF8::calculateEncoding(encoding));
// directory settings
engine.enableFSStrict(variables["fs-strict"].as<bool>());

@ -33,13 +33,17 @@ namespace MWBase
virtual void goodbye() = 0;
///get the faction of the actor you are talking with
virtual std::string getFaction() const = 0;
virtual MWWorld::Ptr getActor() const = 0;
///< Return the actor the player is currently talking to.
//calbacks for the GUI
virtual void keywordSelected (const std::string& keyword) = 0;
virtual void goodbyeSelected() = 0;
virtual void questionAnswered (const std::string& answer) = 0;
virtual void persuade (int type) = 0;
virtual int getTemporaryDispositionChange () const = 0;
virtual void applyTemporaryDispositionChange (int delta) = 0;
};
}

@ -62,7 +62,7 @@ namespace MWBase
virtual void setPlayerName (const std::string& name) = 0;
///< Set player name.
virtual void setPlayerRace (const std::string& id, bool male) = 0;
virtual void setPlayerRace (const std::string& id, bool male, const std::string &head, const std::string &hair) = 0;
///< Set player race.
virtual void setPlayerBirthsign (const std::string& id) = 0;
@ -76,9 +76,28 @@ namespace MWBase
virtual void restoreDynamicStats() = 0;
///< If the player is sleeping, this should be called every hour.
virtual int getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) = 0;
///< This is used by every service to determine the price of objects given the trading skills of the player and NPC.
virtual int getDerivedDisposition(const MWWorld::Ptr& ptr) = 0;
///< Calculate the diposition of an NPC toward the player.
virtual int countDeaths (const std::string& id) const = 0;
///< Return the number of deaths for actors with the given ID.
enum PersuasionType
{
PT_Admire,
PT_Intimidate,
PT_Taunt,
PT_Bribe10,
PT_Bribe100,
PT_Bribe1000
};
virtual void getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type,
float currentTemporaryDispositionDelta, bool& success, float& tempChange, float& permChange) = 0;
///< Perform a persuasion action on NPC
};
}

@ -29,11 +29,7 @@ namespace ESM
struct Class;
struct Potion;
struct Spell;
}
namespace ESMS
{
struct ESMStore;
struct NPC;
}
namespace MWRender
@ -48,6 +44,7 @@ namespace MWWorld
class LocalScripts;
class Ptr;
class TimeStamp;
class ESMStore;
}
namespace MWBase
@ -68,7 +65,8 @@ namespace MWBase
Render_CollisionDebug,
Render_Wireframe,
Render_Pathgrid,
Render_Compositors
Render_Compositors,
Render_BoundingBoxes
};
struct DoorMarker
@ -104,7 +102,7 @@ namespace MWBase
virtual MWWorld::Player& getPlayer() = 0;
virtual const ESMS::ESMStore& getStore() const = 0;
virtual const MWWorld::ESMStore& getStore() const = 0;
virtual ESM::ESMReader& getEsmReader() = 0;
@ -135,6 +133,10 @@ namespace MWBase
virtual char getGlobalVariableType (const std::string& name) const = 0;
///< Return ' ', if there is no global variable with this name.
virtual std::vector<std::string> getGlobals () const = 0;
virtual std::string getCurrentCellName() const = 0;
virtual MWWorld::Ptr getPtr (const std::string& name, bool activeOnly) = 0;
///< Return a pointer to a liveCellRef with the given name.
@ -234,24 +236,28 @@ namespace MWBase
///< Toggle a render mode.
///< \return Resulting mode
virtual std::pair<std::string, const ESM::Potion *> createRecord (const ESM::Potion& record)
virtual const ESM::Potion *createRecord (const ESM::Potion& record)
= 0;
///< Create a new recrod (of type potion) in the ESM store.
/// \return ID, pointer to created record
/// \return pointer to created record
virtual std::pair<std::string, const ESM::Spell *> createRecord (const ESM::Spell& record)
virtual const ESM::Spell *createRecord (const ESM::Spell& record)
= 0;
///< Create a new recrod (of type spell) in the ESM store.
/// \return ID, pointer to created record
/// \return pointer to created record
virtual std::pair<std::string, const ESM::Class *> createRecord (const ESM::Class& record)
virtual const ESM::Class *createRecord (const ESM::Class& record)
= 0;
///< Create a new recrod (of type class) in the ESM store.
/// \return ID, pointer to created record
/// \return pointer to created record
virtual const ESM::Cell *createRecord (const ESM::Cell& record) = 0;
///< Create a new recrod (of type cell) in the ESM store.
/// \return ID, pointer to created record
/// \return pointer to created record
virtual const ESM::NPC *createRecord(const ESM::NPC &record) = 0;
///< Create a new recrod (of type npc) in the ESM store.
/// \return pointer to created record
virtual void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName,
int mode, int number = 1) = 0;
@ -265,7 +271,7 @@ namespace MWBase
///< Skip the animation for the given MW-reference for one frame. Calls to this function for
/// references that are currently not in the rendered scene should be ignored.
virtual void update (float duration) = 0;
virtual void update (float duration, bool paused) = 0;
virtual bool placeObject(const MWWorld::Ptr& object, float cursorX, float cursorY) = 0;
///< place an object into the gameworld at the specified cursor position

@ -30,18 +30,17 @@ namespace MWClass
void Activator::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Activator::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -53,7 +52,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>();
return ref->base->mName;
return ref->mBase->mName;
}
std::string Activator::getScript (const MWWorld::Ptr& ptr) const
@ -61,7 +60,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>();
return ref->base->mScript;
return ref->mBase->mScript;
}
void Activator::registerSelf()
@ -76,7 +75,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Activator::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -85,22 +84,22 @@ namespace MWClass
ptr.get<ESM::Activator>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
std::string text;
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
info.text = text;
return info;
}
MWWorld::Ptr
Activator::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>();
return MWWorld::Ptr(&cell.activators.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mActivators.insert(*ref), &cell);
}
}

@ -33,18 +33,17 @@ namespace MWClass
void Apparatus::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Apparatus::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -56,7 +55,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Apparatus::activate (const MWWorld::Ptr& ptr,
@ -75,7 +74,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>();
return ref->base->mScript;
return ref->mBase->mScript;
}
int Apparatus::getValue (const MWWorld::Ptr& ptr) const
@ -83,7 +82,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Apparatus::registerSelf()
@ -108,7 +107,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Apparatus::hasToolTip (const MWWorld::Ptr& ptr) const
@ -116,7 +115,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Apparatus::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -125,17 +124,17 @@ namespace MWClass
ptr.get<ESM::Apparatus>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -154,6 +153,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>();
return MWWorld::Ptr(&cell.appas.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mAppas.insert(*ref), &cell);
}
}

@ -36,18 +36,17 @@ namespace MWClass
void Armor::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Armor::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -59,7 +58,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Armor::activate (const MWWorld::Ptr& ptr,
@ -82,7 +81,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return ref->base->mData.mHealth;
return ref->mBase->mData.mHealth;
}
std::string Armor::getScript (const MWWorld::Ptr& ptr) const
@ -90,7 +89,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return ref->base->mScript;
return ref->mBase->mScript;
}
std::pair<std::vector<int>, bool> Armor::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -118,7 +117,7 @@ namespace MWClass
};
for (int i=0; i<size; ++i)
if (sMapping[i][0]==ref->base->mData.mType)
if (sMapping[i][0]==ref->mBase->mData.mType)
{
slots.push_back (int (sMapping[i][1]));
break;
@ -134,7 +133,7 @@ namespace MWClass
std::string typeGmst;
switch (ref->base->mData.mType)
switch (ref->mBase->mData.mType)
{
case ESM::Armor::Helmet: typeGmst = "iHelmWeight"; break;
case ESM::Armor::Cuirass: typeGmst = "iCuirassWeight"; break;
@ -152,14 +151,17 @@ namespace MWClass
if (typeGmst.empty())
return -1;
float iWeight = MWBase::Environment::get().getWorld()->getStore().gameSettings.find (typeGmst)->getInt();
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
float iWeight = gmst.find (typeGmst)->getInt();
if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fLightMaxMod")->getFloat()>=
ref->base->mData.mWeight)
if (iWeight * gmst.find ("fLightMaxMod")->getFloat()>=
ref->mBase->mData.mWeight)
return ESM::Skill::LightArmor;
if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMedMaxMod")->getFloat()>=
ref->base->mData.mWeight)
if (iWeight * gmst.find ("fMedMaxMod")->getFloat()>=
ref->mBase->mData.mWeight)
return ESM::Skill::MediumArmor;
return ESM::Skill::HeavyArmor;
@ -170,7 +172,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Armor::registerSelf()
@ -207,7 +209,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Armor::hasToolTip (const MWWorld::Ptr& ptr) const
@ -215,7 +217,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Armor::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -224,8 +226,8 @@ namespace MWClass
ptr.get<ESM::Armor>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
@ -239,20 +241,20 @@ namespace MWClass
else
typeText = "#{sHeavy}";
text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->base->mData.mArmor);
text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->mBase->mData.mArmor);
/// \todo store the current armor health somewhere
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->base->mData.mHealth);
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight) + " (" + typeText + ")";
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight) + " (" + typeText + ")";
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.enchant = ref->base->mEnchant;
info.enchant = ref->mBase->mEnchant;
info.text = text;
@ -264,7 +266,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return ref->base->mEnchant;
return ref->mBase->mEnchant;
}
boost::shared_ptr<MWWorld::Action> Armor::use (const MWWorld::Ptr& ptr) const
@ -282,6 +284,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return MWWorld::Ptr(&cell.armors.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mArmors.insert(*ref), &cell);
}
}

@ -32,18 +32,17 @@ namespace MWClass
void Book::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Book::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -55,7 +54,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Book::activate (const MWWorld::Ptr& ptr,
@ -70,7 +69,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return ref->base->mScript;
return ref->mBase->mScript;
}
int Book::getValue (const MWWorld::Ptr& ptr) const
@ -78,7 +77,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Book::registerSelf()
@ -103,7 +102,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Book::hasToolTip (const MWWorld::Ptr& ptr) const
@ -111,7 +110,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Book::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -120,20 +119,20 @@ namespace MWClass
ptr.get<ESM::Book>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.enchant = ref->base->mEnchant;
info.enchant = ref->mBase->mEnchant;
info.text = text;
@ -145,7 +144,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return ref->base->mEnchant;
return ref->mBase->mEnchant;
}
boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const
@ -159,6 +158,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return MWWorld::Ptr(&cell.books.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mBooks.insert(*ref), &cell);
}
}

@ -34,18 +34,17 @@ namespace MWClass
void Clothing::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Clothing::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -57,7 +56,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Clothing::activate (const MWWorld::Ptr& ptr,
@ -75,7 +74,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return ref->base->mScript;
return ref->mBase->mScript;
}
std::pair<std::vector<int>, bool> Clothing::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -85,7 +84,7 @@ namespace MWClass
std::vector<int> slots;
if (ref->base->mData.mType==ESM::Clothing::Ring)
if (ref->mBase->mData.mType==ESM::Clothing::Ring)
{
slots.push_back (int (MWWorld::InventoryStore::Slot_LeftRing));
slots.push_back (int (MWWorld::InventoryStore::Slot_RightRing));
@ -108,7 +107,7 @@ namespace MWClass
};
for (int i=0; i<size; ++i)
if (sMapping[i][0]==ref->base->mData.mType)
if (sMapping[i][0]==ref->mBase->mData.mType)
{
slots.push_back (int (sMapping[i][1]));
break;
@ -123,7 +122,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
if (ref->base->mData.mType==ESM::Clothing::Shoes)
if (ref->mBase->mData.mType==ESM::Clothing::Shoes)
return ESM::Skill::Unarmored;
return -1;
@ -134,7 +133,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Clothing::registerSelf()
@ -149,7 +148,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
if (ref->base->mData.mType == 8)
if (ref->mBase->mData.mType == 8)
{
return std::string("Item Ring Up");
}
@ -161,7 +160,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
if (ref->base->mData.mType == 8)
if (ref->mBase->mData.mType == 8)
{
return std::string("Item Ring Down");
}
@ -173,7 +172,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Clothing::hasToolTip (const MWWorld::Ptr& ptr) const
@ -181,7 +180,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Clothing::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -190,20 +189,20 @@ namespace MWClass
ptr.get<ESM::Clothing>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.enchant = ref->base->mEnchant;
info.enchant = ref->mBase->mEnchant;
info.text = text;
@ -215,7 +214,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return ref->base->mEnchant;
return ref->mBase->mEnchant;
}
boost::shared_ptr<MWWorld::Action> Clothing::use (const MWWorld::Ptr& ptr) const
@ -233,6 +232,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return MWWorld::Ptr(&cell.clothes.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mClothes.insert(*ref), &cell);
}
}

@ -65,18 +65,17 @@ namespace MWClass
void Container::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Container::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -149,7 +148,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>();
return ref->base->mName;
return ref->mBase->mName;
}
MWWorld::ContainerStore& Container::getContainerStore (const MWWorld::Ptr& ptr)
@ -165,7 +164,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>();
return ref->base->mScript;
return ref->mBase->mScript;
}
void Container::registerSelf()
@ -180,7 +179,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Container::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -189,17 +188,17 @@ namespace MWClass
ptr.get<ESM::Container>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName;
info.caption = ref->mBase->mName;
std::string text;
if (ref->ref.mLockLevel > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->ref.mLockLevel);
if (ref->ref.mTrap != "")
if (ref->mRef.mLockLevel > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel);
if (ref->mRef.mTrap != "")
text += "\n#{sTrapped}";
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -212,7 +211,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>();
return ref->base->mWeight;
return ref->mBase->mWeight;
}
float Container::getEncumbrance (const MWWorld::Ptr& ptr) const
@ -239,6 +238,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>();
return MWWorld::Ptr(&cell.containers.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mContainers.insert(*ref), &cell);
}
}

@ -48,28 +48,28 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
// creature stats
data->mCreatureStats.getAttribute(0).set (ref->base->mData.mStrength);
data->mCreatureStats.getAttribute(1).set (ref->base->mData.mIntelligence);
data->mCreatureStats.getAttribute(2).set (ref->base->mData.mWillpower);
data->mCreatureStats.getAttribute(3).set (ref->base->mData.mAgility);
data->mCreatureStats.getAttribute(4).set (ref->base->mData.mSpeed);
data->mCreatureStats.getAttribute(5).set (ref->base->mData.mEndurance);
data->mCreatureStats.getAttribute(6).set (ref->base->mData.mPersonality);
data->mCreatureStats.getAttribute(7).set (ref->base->mData.mLuck);
data->mCreatureStats.setHealth (ref->base->mData.mHealth);
data->mCreatureStats.setMagicka (ref->base->mData.mMana);
data->mCreatureStats.setFatigue (ref->base->mData.mFatigue);
data->mCreatureStats.setLevel(ref->base->mData.mLevel);
data->mCreatureStats.setHello(ref->base->mAiData.mHello);
data->mCreatureStats.setFight(ref->base->mAiData.mFight);
data->mCreatureStats.setFlee(ref->base->mAiData.mFlee);
data->mCreatureStats.setAlarm(ref->base->mAiData.mAlarm);
data->mCreatureStats.getAttribute(0).set (ref->mBase->mData.mStrength);
data->mCreatureStats.getAttribute(1).set (ref->mBase->mData.mIntelligence);
data->mCreatureStats.getAttribute(2).set (ref->mBase->mData.mWillpower);
data->mCreatureStats.getAttribute(3).set (ref->mBase->mData.mAgility);
data->mCreatureStats.getAttribute(4).set (ref->mBase->mData.mSpeed);
data->mCreatureStats.getAttribute(5).set (ref->mBase->mData.mEndurance);
data->mCreatureStats.getAttribute(6).set (ref->mBase->mData.mPersonality);
data->mCreatureStats.getAttribute(7).set (ref->mBase->mData.mLuck);
data->mCreatureStats.setHealth (ref->mBase->mData.mHealth);
data->mCreatureStats.setMagicka (ref->mBase->mData.mMana);
data->mCreatureStats.setFatigue (ref->mBase->mData.mFatigue);
data->mCreatureStats.setLevel(ref->mBase->mData.mLevel);
data->mCreatureStats.setAiSetting (0, ref->mBase->mAiData.mHello);
data->mCreatureStats.setAiSetting (1, ref->mBase->mAiData.mFight);
data->mCreatureStats.setAiSetting (2, ref->mBase->mAiData.mFlee);
data->mCreatureStats.setAiSetting (3, ref->mBase->mAiData.mAlarm);
// spells
for (std::vector<std::string>::const_iterator iter (ref->base->mSpells.mList.begin());
iter!=ref->base->mSpells.mList.end(); ++iter)
for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin());
iter!=ref->mBase->mSpells.mList.end(); ++iter)
data->mCreatureStats.getSpells().add (*iter);
// store
@ -82,7 +82,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
return ref->base->mId;
return ref->mBase->mId;
}
void Creature::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -94,9 +94,8 @@ namespace MWClass
void Creature::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()){
physics.insertActorPhysics(ptr, model);
}
if(!model.empty())
physics.addActor(ptr);
MWBase::Environment::get().getMechanicsManager()->addActor (ptr);
}
@ -104,9 +103,9 @@ namespace MWClass
{
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
assert (ref->base != NULL);
assert (ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -118,7 +117,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
return ref->base->mName;
return ref->mBase->mName;
}
MWMechanics::CreatureStats& Creature::getCreatureStats (const MWWorld::Ptr& ptr) const
@ -150,7 +149,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
return ref->base->mScript;
return ref->mBase->mScript;
}
bool Creature::isEssential (const MWWorld::Ptr& ptr) const
@ -158,7 +157,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
return ref->base->mFlags & ESM::Creature::Essential;
return ref->mBase->mFlags & ESM::Creature::Essential;
}
void Creature::registerSelf()
@ -181,11 +180,11 @@ namespace MWClass
ptr.get<ESM::Creature>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName;
info.caption = ref->mBase->mName;
std::string text;
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
info.text = text;
return info;
@ -219,6 +218,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
return MWWorld::Ptr(&cell.creatures.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mCreatures.insert(*ref), &cell);
}
}

@ -36,18 +36,17 @@ namespace MWClass
void Door::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Door::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -59,10 +58,10 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
if (ref->ref.mTeleport && !ref->ref.mDestCell.empty()) // TODO doors that lead to exteriors
return ref->ref.mDestCell;
if (ref->mRef.mTeleport && !ref->mRef.mDestCell.empty()) // TODO doors that lead to exteriors
return ref->mRef.mDestCell;
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Door::activate (const MWWorld::Ptr& ptr,
@ -71,8 +70,8 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
const std::string &openSound = ref->base->mOpenSound;
//const std::string &closeSound = ref->base->closeSound;
const std::string &openSound = ref->mBase->mOpenSound;
//const std::string &closeSound = ref->mBase->closeSound;
const std::string lockedSound = "LockedDoor";
const std::string trapActivationSound = "Disarm Trap Fail";
@ -119,13 +118,13 @@ namespace MWClass
return action;
}
if (ref->ref.mTeleport)
if (ref->mRef.mTeleport)
{
// teleport door
/// \todo remove this if clause once ActionTeleport can also support other actors
if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()==actor)
{
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport (ref->ref.mDestCell, ref->ref.mDoorDest));
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport (ref->mRef.mDestCell, ref->mRef.mDoorDest));
action->setSound(openSound);
@ -177,7 +176,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
return ref->base->mScript;
return ref->mBase->mScript;
}
void Door::registerSelf()
@ -192,7 +191,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Door::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -201,57 +200,66 @@ namespace MWClass
ptr.get<ESM::Door>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName;
info.caption = ref->mBase->mName;
std::string text;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
if (ref->ref.mTeleport)
if (ref->mRef.mTeleport)
{
std::string dest;
if (ref->ref.mDestCell != "")
{
// door leads to an interior, use interior name as tooltip
dest = ref->ref.mDestCell;
}
else
{
// door leads to exterior, use cell name (if any), otherwise translated region name
int x,y;
MWBase::Environment::get().getWorld()->positionToIndex (ref->ref.mDoorDest.pos[0], ref->ref.mDoorDest.pos[1], x, y);
const ESM::Cell* cell = store.cells.findExt(x,y);
if (cell->mName != "")
dest = cell->mName;
else
{
const ESM::Region* region = store.regions.search(cell->mRegion);
dest = region->mName;
}
}
text += "\n#{sTo}";
text += "\n"+dest;
text += "\n" + getDestination(*ref);
}
if (ref->ref.mLockLevel > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->ref.mLockLevel);
if (ref->ref.mTrap != "")
if (ref->mRef.mLockLevel > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel);
if (ref->mRef.mTrap != "")
text += "\n#{sTrapped}";
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
info.text = text;
return info;
}
std::string Door::getDestination (const MWWorld::LiveCellRef<ESM::Door>& door)
{
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
std::string dest;
if (door.mRef.mDestCell != "")
{
// door leads to an interior, use interior name as tooltip
dest = door.mRef.mDestCell;
}
else
{
// door leads to exterior, use cell name (if any), otherwise translated region name
int x,y;
MWBase::Environment::get().getWorld()->positionToIndex (door.mRef.mDoorDest.pos[0], door.mRef.mDoorDest.pos[1], x, y);
const ESM::Cell* cell = store.get<ESM::Cell>().find(x,y);
if (cell->mName != "")
dest = cell->mName;
else
{
const ESM::Region* region =
store.get<ESM::Region>().find(cell->mRegion);
//name as is, not a token
return region->mName;
}
}
return "#{sCell=" + dest + "}";
}
MWWorld::Ptr
Door::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
return MWWorld::Ptr(&cell.doors.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mDoors.insert(*ref), &cell);
}
}

@ -31,6 +31,9 @@ namespace MWClass
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
static std::string getDestination (const MWWorld::LiveCellRef<ESM::Door>& door);
///< @return destination cell name or token
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const;
///< Lock object

@ -25,7 +25,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return ref->base->mId;
return ref->mBase->mId;
}
void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -41,18 +41,17 @@ namespace MWClass
void Ingredient::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Ingredient::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -64,7 +63,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Ingredient::activate (const MWWorld::Ptr& ptr,
@ -82,7 +81,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return ref->base->mScript;
return ref->mBase->mScript;
}
int Ingredient::getValue (const MWWorld::Ptr& ptr) const
@ -90,7 +89,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
@ -125,7 +124,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Ingredient::hasToolTip (const MWWorld::Ptr& ptr) const
@ -133,7 +132,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Ingredient::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -142,28 +141,28 @@ namespace MWClass
ptr.get<ESM::Ingredient>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
MWGui::Widgets::SpellEffectList list;
for (int i=0; i<4; ++i)
{
if (ref->base->mData.mEffectID[i] < 0)
if (ref->mBase->mData.mEffectID[i] < 0)
continue;
MWGui::Widgets::SpellEffectParams params;
params.mEffectID = ref->base->mData.mEffectID[i];
params.mAttribute = ref->base->mData.mAttributes[i];
params.mSkill = ref->base->mData.mSkills[i];
params.mEffectID = ref->mBase->mData.mEffectID[i];
params.mAttribute = ref->mBase->mData.mAttributes[i];
params.mSkill = ref->mBase->mData.mSkills[i];
list.push_back(params);
}
info.effects = list;
@ -179,6 +178,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return MWWorld::Ptr(&cell.ingreds.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mIngreds.insert(*ref), &cell);
}
}

@ -28,9 +28,9 @@ namespace MWClass
{
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
assert (ref->base != NULL);
assert (ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
@ -38,11 +38,11 @@ namespace MWClass
if (!model.empty())
objects.insertMesh(ptr, "meshes\\" + model);
const int color = ref->base->mData.mColor;
const int color = ref->mBase->mData.mColor;
const float r = ((color >> 0) & 0xFF) / 255.0f;
const float g = ((color >> 8) & 0xFF) / 255.0f;
const float b = ((color >> 16) & 0xFF) / 255.0f;
const float radius = float (ref->base->mData.mRadius);
const float radius = float (ref->mBase->mData.mRadius);
objects.insertLight (ptr, r, g, b, radius);
}
@ -50,25 +50,24 @@ namespace MWClass
{
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
assert (ref->base != NULL);
assert (ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if(!model.empty()) {
physics.insertObjectPhysics(ptr, "meshes\\" + model);
}
if (!ref->base->mSound.empty()) {
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->base->mSound, 1.0, 1.0, MWBase::SoundManager::Play_Loop);
}
if(!model.empty())
physics.addObject(ptr);
if (!ref->mBase->mSound.empty())
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0, MWBase::SoundManager::Play_Loop);
}
std::string Light::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
assert (ref->base != NULL);
assert (ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -80,10 +79,10 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
if (ref->base->mModel.empty())
if (ref->mBase->mModel.empty())
return "";
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Light::activate (const MWWorld::Ptr& ptr,
@ -92,7 +91,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
if (!(ref->base->mData.mFlags & ESM::Light::Carry))
if (!(ref->mBase->mData.mFlags & ESM::Light::Carry))
return boost::shared_ptr<MWWorld::Action> (new MWWorld::FailedAction);
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTake (ptr));
@ -107,7 +106,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
return ref->base->mScript;
return ref->mBase->mScript;
}
std::pair<std::vector<int>, bool> Light::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -117,7 +116,7 @@ namespace MWClass
std::vector<int> slots;
if (ref->base->mData.mFlags & ESM::Light::Carry)
if (ref->mBase->mData.mFlags & ESM::Light::Carry)
slots.push_back (int (MWWorld::InventoryStore::Slot_CarriedLeft));
return std::make_pair (slots, false);
@ -128,7 +127,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Light::registerSelf()
@ -154,7 +153,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Light::hasToolTip (const MWWorld::Ptr& ptr) const
@ -162,7 +161,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Light::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -171,17 +170,17 @@ namespace MWClass
ptr.get<ESM::Light>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -204,6 +203,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
return MWWorld::Ptr(&cell.lights.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mLights.insert(*ref), &cell);
}
}

@ -34,18 +34,17 @@ namespace MWClass
void Lockpick::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Lockpick::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -57,7 +56,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Lockpick::activate (const MWWorld::Ptr& ptr,
@ -75,7 +74,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
return ref->base->mScript;
return ref->mBase->mScript;
}
std::pair<std::vector<int>, bool> Lockpick::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -92,7 +91,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Lockpick::registerSelf()
@ -117,7 +116,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Lockpick::hasToolTip (const MWWorld::Ptr& ptr) const
@ -125,7 +124,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Lockpick::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -134,21 +133,21 @@ namespace MWClass
ptr.get<ESM::Tool>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
/// \todo store remaining uses somewhere
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->base->mData.mUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -171,6 +170,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
return MWWorld::Ptr(&cell.lockpicks.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mLockpicks.insert(*ref), &cell);
}
}

@ -37,18 +37,17 @@ namespace MWClass
void Miscellaneous::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Miscellaneous::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -60,7 +59,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Miscellaneous::activate (const MWWorld::Ptr& ptr,
@ -78,7 +77,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
return ref->base->mScript;
return ref->mBase->mScript;
}
int Miscellaneous::getValue (const MWWorld::Ptr& ptr) const
@ -86,7 +85,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Miscellaneous::registerSelf()
@ -101,7 +100,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
if (ref->base->mName == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString())
if (ref->mBase->mName == MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGold")->getString())
{
return std::string("Item Gold Up");
}
@ -113,7 +112,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
if (ref->base->mName == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString())
if (ref->mBase->mName == MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGold")->getString())
{
return std::string("Item Gold Down");
}
@ -125,7 +124,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Miscellaneous::hasToolTip (const MWWorld::Ptr& ptr) const
@ -133,7 +132,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Miscellaneous::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -143,13 +142,13 @@ namespace MWClass
MWGui::ToolTipInfo info;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
int count = ptr.getRefData().getCount();
bool isGold = (ref->base->mName == store.gameSettings.find("sGold")->getString());
bool isGold = (ref->mBase->mName == store.get<ESM::GameSetting>().find("sGold")->getString());
if (isGold && count == 1)
count = ref->base->mData.mValue;
count = ref->mBase->mData.mValue;
std::string countString;
if (!isGold)
@ -157,12 +156,12 @@ namespace MWClass
else // gold displays its count also if it's 1.
countString = " (" + boost::lexical_cast<std::string>(count) + ")";
info.caption = ref->base->mName + countString;
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + countString;
info.icon = ref->mBase->mIcon;
if (ref->ref.mSoul != "")
if (ref->mRef.mSoul != "")
{
const ESM::Creature *creature = store.creatures.search(ref->ref.mSoul);
const ESM::Creature *creature = store.get<ESM::Creature>().find(ref->mRef.mSoul);
info.caption += " (" + creature->mName + ")";
}
@ -170,13 +169,13 @@ namespace MWClass
if (!isGold)
{
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
}
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -189,10 +188,10 @@ namespace MWClass
{
MWWorld::Ptr newPtr;
const ESMS::ESMStore &store =
const MWWorld::ESMStore &store =
MWBase::Environment::get().getWorld()->getStore();
if (MWWorld::Class::get(ptr).getName(ptr) == store.gameSettings.find("sGold")->getString()) {
if (MWWorld::Class::get(ptr).getName(ptr) == store.get<ESM::GameSetting>().find("sGold")->getString()) {
int goldAmount = ptr.getRefData().getCount();
std::string base = "Gold_001";
@ -210,11 +209,11 @@ namespace MWClass
MWWorld::ManualRef newRef(store, base);
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
newRef.getPtr().get<ESM::Miscellaneous>();
newPtr = MWWorld::Ptr(&cell.miscItems.insert(*ref), &cell);
newPtr = MWWorld::Ptr(&cell.mMiscItems.insert(*ref), &cell);
} else {
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
newPtr = MWWorld::Ptr(&cell.miscItems.insert(*ref), &cell);
newPtr = MWWorld::Ptr(&cell.mMiscItems.insert(*ref), &cell);
}
return newPtr;
}

@ -62,39 +62,41 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
// NPC stats
if (!ref->base->mFaction.empty())
if (!ref->mBase->mFaction.empty())
{
std::string faction = ref->base->mFaction;
std::string faction = ref->mBase->mFaction;
boost::algorithm::to_lower(faction);
if(ref->base->mNpdt52.mGold != -10)
if(ref->mBase->mNpdt52.mGold != -10)
{
data->mNpcStats.getFactionRanks()[faction] = (int)ref->base->mNpdt52.mRank;
data->mNpcStats.getFactionRanks()[faction] = (int)ref->mBase->mNpdt52.mRank;
}
else
{
data->mNpcStats.getFactionRanks()[faction] = (int)ref->base->mNpdt12.mRank;
data->mNpcStats.getFactionRanks()[faction] = (int)ref->mBase->mNpdt12.mRank;
}
}
// creature stats
if(ref->base->mNpdt52.mGold != -10)
if(ref->mBase->mNpdt52.mGold != -10)
{
for (int i=0; i<27; ++i)
data->mNpcStats.getSkill (i).setBase (ref->base->mNpdt52.mSkills[i]);
data->mCreatureStats.getAttribute(0).set (ref->base->mNpdt52.mStrength);
data->mCreatureStats.getAttribute(1).set (ref->base->mNpdt52.mIntelligence);
data->mCreatureStats.getAttribute(2).set (ref->base->mNpdt52.mWillpower);
data->mCreatureStats.getAttribute(3).set (ref->base->mNpdt52.mAgility);
data->mCreatureStats.getAttribute(4).set (ref->base->mNpdt52.mSpeed);
data->mCreatureStats.getAttribute(5).set (ref->base->mNpdt52.mEndurance);
data->mCreatureStats.getAttribute(6).set (ref->base->mNpdt52.mPersonality);
data->mCreatureStats.getAttribute(7).set (ref->base->mNpdt52.mLuck);
data->mCreatureStats.setHealth (ref->base->mNpdt52.mHealth);
data->mCreatureStats.setMagicka (ref->base->mNpdt52.mMana);
data->mCreatureStats.setFatigue (ref->base->mNpdt52.mFatigue);
data->mCreatureStats.setLevel(ref->base->mNpdt52.mLevel);
data->mNpcStats.getSkill (i).setBase (ref->mBase->mNpdt52.mSkills[i]);
data->mCreatureStats.getAttribute(0).set (ref->mBase->mNpdt52.mStrength);
data->mCreatureStats.getAttribute(1).set (ref->mBase->mNpdt52.mIntelligence);
data->mCreatureStats.getAttribute(2).set (ref->mBase->mNpdt52.mWillpower);
data->mCreatureStats.getAttribute(3).set (ref->mBase->mNpdt52.mAgility);
data->mCreatureStats.getAttribute(4).set (ref->mBase->mNpdt52.mSpeed);
data->mCreatureStats.getAttribute(5).set (ref->mBase->mNpdt52.mEndurance);
data->mCreatureStats.getAttribute(6).set (ref->mBase->mNpdt52.mPersonality);
data->mCreatureStats.getAttribute(7).set (ref->mBase->mNpdt52.mLuck);
data->mCreatureStats.setHealth (ref->mBase->mNpdt52.mHealth);
data->mCreatureStats.setMagicka (ref->mBase->mNpdt52.mMana);
data->mCreatureStats.setFatigue (ref->mBase->mNpdt52.mFatigue);
data->mCreatureStats.setLevel(ref->mBase->mNpdt52.mLevel);
data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt52.mDisposition);
data->mNpcStats.setReputation(ref->mBase->mNpdt52.mReputation);
}
else
{
@ -108,14 +110,14 @@ namespace MWClass
data->mCreatureStats.setLevel (1);
}
data->mCreatureStats.setHello(ref->base->mAiData.mHello);
data->mCreatureStats.setFight(ref->base->mAiData.mFight);
data->mCreatureStats.setFlee(ref->base->mAiData.mFlee);
data->mCreatureStats.setAlarm(ref->base->mAiData.mAlarm);
data->mCreatureStats.setAiSetting (0, ref->mBase->mAiData.mHello);
data->mCreatureStats.setAiSetting (1, ref->mBase->mAiData.mFight);
data->mCreatureStats.setAiSetting (2, ref->mBase->mAiData.mFlee);
data->mCreatureStats.setAiSetting (3, ref->mBase->mAiData.mAlarm);
// spells
for (std::vector<std::string>::const_iterator iter (ref->base->mSpells.mList.begin());
iter!=ref->base->mSpells.mList.end(); ++iter)
for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin());
iter!=ref->mBase->mSpells.mList.end(); ++iter)
data->mCreatureStats.getSpells().add (*iter);
// store
@ -128,7 +130,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>();
return ref->base->mId;
return ref->mBase->mId;
}
void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -138,7 +140,7 @@ namespace MWClass
void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
physics.insertActorPhysics(ptr, getModel(ptr));
physics.addActor(ptr);
MWBase::Environment::get().getMechanicsManager()->addActor(ptr);
}
@ -146,9 +148,9 @@ namespace MWClass
{
MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
std::string headID = ref->base->mHead;
std::string headID = ref->mBase->mHead;
int end = headID.find_last_of("head_") - 4;
std::string bodyRaceID = headID.substr(0, end);
@ -170,7 +172,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>();
return ref->base->mName;
return ref->mBase->mName;
}
MWMechanics::CreatureStats& Npc::getCreatureStats (const MWWorld::Ptr& ptr) const
@ -217,7 +219,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>();
return ref->base->mScript;
return ref->mBase->mScript;
}
void Npc::setForceStance (const MWWorld::Ptr& ptr, Stance stance, bool force) const
@ -325,7 +327,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>();
return ref->base->mFlags & ESM::NPC::Essential;
return ref->mBase->mFlags & ESM::NPC::Essential;
}
void Npc::registerSelf()
@ -347,11 +349,11 @@ namespace MWClass
ptr.get<ESM::NPC>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName;
info.caption = ref->mBase->mName;
std::string text;
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
info.text = text;
return info;
@ -395,8 +397,10 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
const ESM::Class *class_ = MWBase::Environment::get().getWorld()->getStore().classes.find (
ref->base->mClass);
const ESM::Class *class_ =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find (
ref->mBase->mClass
);
stats.useSkill (skill, *class_, usageType);
}
@ -413,6 +417,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>();
return MWWorld::Ptr(&cell.npcs.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mNpcs.insert(*ref), &cell);
}
}

@ -34,18 +34,17 @@ namespace MWClass
void Potion::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Potion::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -57,7 +56,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Potion::activate (const MWWorld::Ptr& ptr,
@ -76,7 +75,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>();
return ref->base->mScript;
return ref->mBase->mScript;
}
int Potion::getValue (const MWWorld::Ptr& ptr) const
@ -84,7 +83,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Potion::registerSelf()
@ -109,7 +108,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Potion::hasToolTip (const MWWorld::Ptr& ptr) const
@ -117,7 +116,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Potion::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -126,20 +125,20 @@ namespace MWClass
ptr.get<ESM::Potion>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->base->mEffects);
info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects);
info.isPotion = true;
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -157,7 +156,7 @@ namespace MWClass
MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
boost::shared_ptr<MWWorld::Action> action (
new MWWorld::ActionApply (actor, ref->base->mId));
new MWWorld::ActionApply (actor, ref->mBase->mId));
action->setSound ("Drink");
@ -170,6 +169,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>();
return MWWorld::Ptr(&cell.potions.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mPotions.insert(*ref), &cell);
}
}

@ -34,18 +34,17 @@ namespace MWClass
void Probe::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Probe::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -57,7 +56,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Probe::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor) const
@ -74,7 +73,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
return ref->base->mScript;
return ref->mBase->mScript;
}
std::pair<std::vector<int>, bool> Probe::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -91,7 +90,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Probe::registerSelf()
@ -116,7 +115,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Probe::hasToolTip (const MWWorld::Ptr& ptr) const
@ -124,7 +123,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Probe::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -133,21 +132,21 @@ namespace MWClass
ptr.get<ESM::Probe>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
/// \todo store remaining uses somewhere
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->base->mData.mUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -170,6 +169,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
return MWWorld::Ptr(&cell.probes.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mProbes.insert(*ref), &cell);
}
}

@ -32,18 +32,17 @@ namespace MWClass
void Repair::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Repair::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -55,7 +54,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Repair::activate (const MWWorld::Ptr& ptr,
@ -73,7 +72,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
return ref->base->mScript;
return ref->mBase->mScript;
}
int Repair::getValue (const MWWorld::Ptr& ptr) const
@ -81,7 +80,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Repair::registerSelf()
@ -106,7 +105,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Repair::hasToolTip (const MWWorld::Ptr& ptr) const
@ -114,7 +113,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Repair::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -123,21 +122,21 @@ namespace MWClass
ptr.get<ESM::Repair>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
/// \todo store remaining uses somewhere
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->base->mData.mUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -151,6 +150,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
return MWWorld::Ptr(&cell.repairs.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mRepairs.insert(*ref), &cell);
}
}

@ -24,18 +24,17 @@ namespace MWClass
void Static::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Static::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Static> *ref =
ptr.get<ESM::Static>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -60,6 +59,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Static> *ref =
ptr.get<ESM::Static>();
return MWWorld::Ptr(&cell.statics.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mStatics.insert(*ref), &cell);
}
}

@ -34,18 +34,17 @@ namespace MWClass
void Weapon::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Weapon::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -57,7 +56,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Weapon::activate (const MWWorld::Ptr& ptr,
@ -80,7 +79,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return ref->base->mData.mHealth;
return ref->mBase->mData.mHealth;
}
std::string Weapon::getScript (const MWWorld::Ptr& ptr) const
@ -88,7 +87,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return ref->base->mScript;
return ref->mBase->mScript;
}
std::pair<std::vector<int>, bool> Weapon::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -99,12 +98,12 @@ namespace MWClass
std::vector<int> slots;
bool stack = false;
if (ref->base->mData.mType==ESM::Weapon::Arrow || ref->base->mData.mType==ESM::Weapon::Bolt)
if (ref->mBase->mData.mType==ESM::Weapon::Arrow || ref->mBase->mData.mType==ESM::Weapon::Bolt)
{
slots.push_back (int (MWWorld::InventoryStore::Slot_Ammunition));
stack = true;
}
else if (ref->base->mData.mType==ESM::Weapon::MarksmanThrown)
else if (ref->mBase->mData.mType==ESM::Weapon::MarksmanThrown)
{
slots.push_back (int (MWWorld::InventoryStore::Slot_CarriedRight));
stack = true;
@ -139,7 +138,7 @@ namespace MWClass
};
for (int i=0; i<size; ++i)
if (sMapping[i][0]==ref->base->mData.mType)
if (sMapping[i][0]==ref->mBase->mData.mType)
return sMapping[i][1];
return -1;
@ -150,7 +149,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Weapon::registerSelf()
@ -165,7 +164,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
int type = ref->base->mData.mType;
int type = ref->mBase->mData.mType;
// Ammo
if (type == 12 || type == 13)
{
@ -211,7 +210,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
int type = ref->base->mData.mType;
int type = ref->mBase->mData.mType;
// Ammo
if (type == 12 || type == 13)
{
@ -257,7 +256,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Weapon::hasToolTip (const MWWorld::Ptr& ptr) const
@ -265,7 +264,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Weapon::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -274,15 +273,15 @@ namespace MWClass
ptr.get<ESM::Weapon>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
std::string text;
// weapon type & damage. arrows / bolts don't have his info.
if (ref->base->mData.mType < 12)
if (ref->mBase->mData.mType < 12)
{
text += "\n#{sType} ";
@ -300,49 +299,49 @@ namespace MWClass
mapping[ESM::Weapon::MarksmanCrossbow] = std::make_pair("sSkillMarksman", "");
mapping[ESM::Weapon::MarksmanThrown] = std::make_pair("sSkillMarksman", "");
std::string type = mapping[ref->base->mData.mType].first;
std::string oneOrTwoHanded = mapping[ref->base->mData.mType].second;
std::string type = mapping[ref->mBase->mData.mType].first;
std::string oneOrTwoHanded = mapping[ref->mBase->mData.mType].second;
text += store.gameSettings.find(type)->getString() +
((oneOrTwoHanded != "") ? ", " + store.gameSettings.find(oneOrTwoHanded)->getString() : "");
text += store.get<ESM::GameSetting>().find(type)->getString() +
((oneOrTwoHanded != "") ? ", " + store.get<ESM::GameSetting>().find(oneOrTwoHanded)->getString() : "");
// weapon damage
if (ref->base->mData.mType >= 9)
if (ref->mBase->mData.mType >= 9)
{
// marksman
text += "\n#{sAttack}: "
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mChop[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mChop[1]));
+ MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[1]));
}
else
{
// Chop
text += "\n#{sChop}: "
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mChop[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mChop[1]));
+ MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[1]));
// Slash
text += "\n#{sSlash}: "
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mSlash[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mSlash[1]));
+ MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mSlash[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mSlash[1]));
// Thrust
text += "\n#{sThrust}: "
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mThrust[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mThrust[1]));
+ MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mThrust[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mThrust[1]));
}
}
/// \todo store the current weapon health somewhere
if (ref->base->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->base->mData.mHealth);
if (ref->mBase->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
info.enchant = ref->base->mEnchant;
info.enchant = ref->mBase->mEnchant;
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -355,7 +354,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return ref->base->mEnchant;
return ref->mBase->mEnchant;
}
boost::shared_ptr<MWWorld::Action> Weapon::use (const MWWorld::Ptr& ptr) const
@ -373,6 +372,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return MWWorld::Ptr(&cell.weapons.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mWeapons.insert(*ref), &cell);
}
}

@ -6,42 +6,44 @@
#include <iterator>
#include <components/esm/loaddial.hpp>
#include <components/esm/loadinfo.hpp>
#include <components/esm_store/store.hpp>
#include <components/compiler/exception.hpp>
#include <components/compiler/errorhandler.hpp>
#include <components/compiler/scanner.hpp>
#include <components/compiler/locals.hpp>
#include <components/compiler/output.hpp>
#include <components/compiler/scriptparser.hpp>
#include <components/interpreter/interpreter.hpp>
#include <components/interpreter/defines.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/scriptmanager.hpp"
#include "../mwbase/journal.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/refdata.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/player.hpp"
#include "../mwgui/dialogue.hpp"
#include <iostream>
#include <components/compiler/exception.hpp>
#include <components/compiler/errorhandler.hpp>
#include <components/compiler/scanner.hpp>
#include <components/compiler/locals.hpp>
#include <components/compiler/output.hpp>
#include <components/compiler/scriptparser.hpp>
#include <components/interpreter/interpreter.hpp>
#include "../mwscript/compilercontext.hpp"
#include "../mwscript/interpretercontext.hpp"
#include "../mwscript/extensions.hpp"
#include "../mwclass/npc.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "filter.hpp"
namespace
{
<<<<<<< HEAD
template<typename T1, typename T2>
bool selectCompare (char comp, T1 value1, T2 value2)
{
@ -122,6 +124,8 @@ namespace
return false;
}
=======
>>>>>>> 92623921add0d6e16a34973dcf6f2ee1f52dbbe7
//helper function
std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos)
{
@ -131,6 +135,7 @@ namespace
namespace MWDialogue
{
<<<<<<< HEAD
bool DialogueManager::functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice)
@ -558,18 +563,31 @@ namespace MWDialogue
}
DialogueManager::DialogueManager (const Compiler::Extensions& extensions) :
=======
DialogueManager::DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose) :
>>>>>>> 92623921add0d6e16a34973dcf6f2ee1f52dbbe7
mCompilerContext (MWScript::CompilerContext::Type_Dialgoue),
mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream)
, mTemporaryDispositionChange(0.f)
, mPermanentDispositionChange(0.f), mScriptVerbose (scriptVerbose)
{
mChoice = -1;
mIsInChoice = false;
mCompilerContext.setExtensions (&extensions);
mDialogueMap.clear();
mActorKnownTopics.clear();
ESMS::RecListCaseT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list;
for(ESMS::RecListCaseT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
const MWWorld::Store<ESM::Dialogue> &dialogs =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
MWWorld::Store<ESM::Dialogue>::iterator it = dialogs.begin();
for (; it != dialogs.end(); ++it)
{
<<<<<<< HEAD
mDialogueMap[Misc::toLower(it->first)] = it->second;
=======
mDialogueMap[toLower(it->mId)] = *it;
>>>>>>> 92623921add0d6e16a34973dcf6f2ee1f52dbbe7
}
}
@ -578,7 +596,7 @@ namespace MWDialogue
mKnownTopics[Misc::toLower(topic)] = true;
}
void DialogueManager::parseText (std::string text)
void DialogueManager::parseText (const std::string& text)
{
std::list<std::string>::iterator it;
for(it = mActorKnownTopics.begin();it != mActorKnownTopics.end();++it)
@ -586,14 +604,7 @@ namespace MWDialogue
size_t pos = find_str_ci(text,*it,0);
if(pos !=std::string::npos)
{
if(pos==0)
{
mKnownTopics[*it] = true;
}
else if(text.substr(pos -1,1) == " ")
{
mKnownTopics[*it] = true;
}
mKnownTopics[*it] = true;
}
}
updateTopics();
@ -606,6 +617,10 @@ namespace MWDialogue
mActor = actor;
MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (actor).getCreatureStats (actor);
mTalkedTo = creatureStats.hasTalkedToPlayer();
creatureStats.talkedToPlayer();
mActorKnownTopics.clear();
//initialise the GUI
@ -617,34 +632,30 @@ namespace MWDialogue
updateTopics();
//greeting
bool greetingFound = false;
//ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list;
ESMS::RecListCaseT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list;
for(ESMS::RecListCaseT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
const MWWorld::Store<ESM::Dialogue> &dialogs =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
Filter filter (actor, mChoice, mTalkedTo);
for (MWWorld::Store<ESM::Dialogue>::iterator it = dialogs.begin(); it != dialogs.end(); ++it)
{
ESM::Dialogue ndialogue = it->second;
if(ndialogue.mType == ESM::Dialogue::Greeting)
if(it->mType == ESM::Dialogue::Greeting)
{
if (greetingFound) break;
for (std::vector<ESM::DialInfo>::const_iterator iter (it->second.mInfo.begin());
iter!=it->second.mInfo.end(); ++iter)
if (const ESM::DialInfo *info = filter.search (*it))
{
if (isMatching (actor, *iter) && functionFilter(mActor,*iter,true))
if (!info->mSound.empty())
{
if (!iter->mSound.empty())
{
// TODO play sound
}
std::string text = iter->mResponse;
parseText(text);
win->addText(iter->mResponse);
executeScript(iter->mResultScript);
greetingFound = true;
mLastTopic = it->first;
mLastDialogue = *iter;
break;
// TODO play sound
}
parseText (info->mResponse);
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
win->addText (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
executeScript (info->mResultScript);
mLastTopic = it->mId;
mLastDialogue = *info;
break;
}
}
}
@ -652,6 +663,8 @@ namespace MWDialogue
bool DialogueManager::compile (const std::string& cmd,std::vector<Interpreter::Type_Code>& code)
{
bool success = true;
try
{
mErrorHandler.reset();
@ -673,26 +686,36 @@ namespace MWDialogue
Compiler::ScriptParser parser(mErrorHandler,mCompilerContext, locals, false);
scanner.scan (parser);
if(mErrorHandler.isGood())
{
parser.getCode(code);
return true;
}
return false;
if (!mErrorHandler.isGood())
success = false;
if (success)
parser.getCode (code);
}
catch (const Compiler::SourceException& /* error */)
{
// error has already been reported via error handler
success = false;
}
catch (const std::exception& error)
{
printError (std::string ("An exception has been thrown: ") + error.what());
std::cerr << std::string ("Dialogue error: An exception has been thrown: ") + error.what() << std::endl;
success = false;
}
return false;
if (!success && mScriptVerbose)
{
std::cerr
<< "compiling failed (dialogue script)" << std::endl
<< cmd
<< std::endl << std::endl;
}
return success;
}
void DialogueManager::executeScript(std::string script)
void DialogueManager::executeScript (const std::string& script)
{
std::vector<Interpreter::Type_Code> code;
if(compile(script,code))
@ -706,29 +729,74 @@ namespace MWDialogue
}
catch (const std::exception& error)
{
printError (std::string ("An exception has been thrown: ") + error.what());
std::cerr << std::string ("Dialogue error: An exception has been thrown: ") + error.what();
}
}
}
void DialogueManager::executeTopic (const std::string& topic)
{
Filter filter (mActor, mChoice, mTalkedTo);
const MWWorld::Store<ESM::Dialogue> &dialogues =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
const ESM::Dialogue& dialogue = *dialogues.find (topic);
if (const ESM::DialInfo *info = filter.search (dialogue))
{
parseText (info->mResponse);
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
if (dialogue.mType==ESM::Dialogue::Persuasion)
{
std::string modifiedTopic = "s" + topic;
modifiedTopic.erase (std::remove (modifiedTopic.begin(), modifiedTopic.end(), ' '), modifiedTopic.end());
const MWWorld::Store<ESM::GameSetting>& gmsts =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
win->addTitle (gmsts.find (modifiedTopic)->getString());
}
else
win->addTitle (topic);
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
win->addText (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
executeScript (info->mResultScript);
mLastTopic = topic;
mLastDialogue = *info;
}
}
void DialogueManager::updateTopics()
{
std::list<std::string> keywordList;
int choice = mChoice;
mChoice = -1;
mActorKnownTopics.clear();
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
ESMS::RecListCaseT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list;
for(ESMS::RecListCaseT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
const MWWorld::Store<ESM::Dialogue> &dialogs =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
Filter filter (mActor, mChoice, mTalkedTo);
for (MWWorld::Store<ESM::Dialogue>::iterator iter = dialogs.begin(); iter != dialogs.end(); ++iter)
{
ESM::Dialogue ndialogue = it->second;
if(ndialogue.mType == ESM::Dialogue::Topic)
if (iter->mType == ESM::Dialogue::Topic)
{
for (std::vector<ESM::DialInfo>::const_iterator iter (it->second.mInfo.begin());
iter!=it->second.mInfo.end(); ++iter)
if (filter.search (*iter))
{
if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true))
mActorKnownTopics.push_back (toLower (iter->mId));
//does the player know the topic?
if (mKnownTopics.find (toLower (iter->mId)) != mKnownTopics.end())
{
<<<<<<< HEAD
mActorKnownTopics.push_back(Misc::toLower(it->first));
//does the player know the topic?
if(mKnownTopics.find(Misc::toLower(it->first)) != mKnownTopics.end())
@ -736,6 +804,9 @@ namespace MWDialogue
keywordList.push_back(it->first);
break;
}
=======
keywordList.push_back (iter->mId);
>>>>>>> 92623921add0d6e16a34973dcf6f2ee1f52dbbe7
}
}
}
@ -746,14 +817,14 @@ namespace MWDialogue
if (mActor.getTypeName() == typeid(ESM::NPC).name())
{
MWWorld::LiveCellRef<ESM::NPC>* ref = mActor.get<ESM::NPC>();
if (ref->base->mHasAI)
services = ref->base->mAiData.mServices;
if (ref->mBase->mHasAI)
services = ref->mBase->mAiData.mServices;
}
else if (mActor.getTypeName() == typeid(ESM::Creature).name())
{
MWWorld::LiveCellRef<ESM::Creature>* ref = mActor.get<ESM::Creature>();
if (ref->base->mHasAI)
services = ref->base->mAiData.mServices;
if (ref->mBase->mHasAI)
services = ref->mBase->mAiData.mServices;
}
int windowServices = 0;
@ -771,7 +842,7 @@ namespace MWDialogue
|| services & ESM::NPC::Misc)
windowServices |= MWGui::DialogueWindow::Service_Trade;
if( !mActor.get<ESM::NPC>()->base->mTransport.empty())
if(mActor.getTypeName() == typeid(ESM::NPC).name() && !mActor.get<ESM::NPC>()->mBase->mTransport.empty())
windowServices |= MWGui::DialogueWindow::Service_Travel;
if (services & ESM::NPC::Spells)
@ -786,6 +857,8 @@ namespace MWDialogue
if (services & ESM::NPC::Enchanting)
windowServices |= MWGui::DialogueWindow::Service_Enchant;
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->setServices (windowServices);
// sort again, because the previous sort was case-sensitive
@ -802,29 +875,9 @@ namespace MWDialogue
if(mDialogueMap.find(keyword) != mDialogueMap.end())
{
ESM::Dialogue ndialogue = mDialogueMap[keyword];
if(ndialogue.mType == ESM::Dialogue::Topic)
if (mDialogueMap[keyword].mType == ESM::Dialogue::Topic)
{
for (std::vector<ESM::DialInfo>::const_iterator iter = ndialogue.mInfo.begin();
iter!=ndialogue.mInfo.end(); ++iter)
{
if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true))
{
std::string text = iter->mResponse;
std::string script = iter->mResultScript;
parseText(text);
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->addTitle(keyword);
win->addText(iter->mResponse);
executeScript(script);
mLastTopic = keyword;
mLastDialogue = *iter;
break;
}
}
executeTopic (keyword);
}
}
}
@ -835,45 +888,51 @@ namespace MWDialogue
void DialogueManager::goodbyeSelected()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Dialogue);
// Apply disposition change to NPC's base disposition
if (mActor.getTypeName() == typeid(ESM::NPC).name())
{
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(mActor).getNpcStats(mActor);
npcStats.setBaseDisposition(npcStats.getBaseDisposition() + mPermanentDispositionChange);
}
mPermanentDispositionChange = 0;
mTemporaryDispositionChange = 0;
}
void DialogueManager::questionAnswered (const std::string& answer)
{
if(mChoiceMap.find(answer) != mChoiceMap.end())
if (mChoiceMap.find(answer) != mChoiceMap.end())
{
mChoice = mChoiceMap[answer];
std::vector<ESM::DialInfo>::const_iterator iter;
if(mDialogueMap.find(mLastTopic) != mDialogueMap.end())
if (mDialogueMap.find(mLastTopic) != mDialogueMap.end())
{
ESM::Dialogue ndialogue = mDialogueMap[mLastTopic];
if(ndialogue.mType == ESM::Dialogue::Topic)
if (mDialogueMap[mLastTopic].mType == ESM::Dialogue::Topic)
{
for (std::vector<ESM::DialInfo>::const_iterator iter = ndialogue.mInfo.begin();
iter!=ndialogue.mInfo.end(); ++iter)
Filter filter (mActor, mChoice, mTalkedTo);
if (const ESM::DialInfo *info = filter.search (mDialogueMap[mLastTopic]))
{
if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true))
{
mChoiceMap.clear();
mChoice = -1;
mIsInChoice = false;
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
std::string text = iter->mResponse;
parseText(text);
win->addText(text);
executeScript(iter->mResultScript);
mLastTopic = mLastTopic;
mLastDialogue = *iter;
break;
}
mChoiceMap.clear();
mChoice = -1;
mIsInChoice = false;
std::string text = info->mResponse;
parseText (text);
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addText (Interpreter::fixDefinesDialog(text, interpreterContext));
executeScript (info->mResultScript);
mLastTopic = mLastTopic;
mLastDialogue = *info;
}
}
}
updateTopics();
}
}
void DialogueManager::printError (std::string error)
void DialogueManager::printError (const std::string& error)
{
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->addText(error);
@ -887,22 +946,9 @@ namespace MWDialogue
mIsInChoice = true;
}
std::string DialogueManager::getFaction() const
MWWorld::Ptr DialogueManager::getActor() const
{
if (mActor.getTypeName() != typeid(ESM::NPC).name())
return "";
std::string factionID("");
MWMechanics::NpcStats stats = MWWorld::Class::get(mActor).getNpcStats(mActor);
if(stats.getFactionRanks().empty())
{
std::cout << "No faction for this actor!";
}
else
{
factionID = stats.getFactionRanks().begin()->first;
}
return factionID;
return mActor;
}
void DialogueManager::goodbye()
@ -911,4 +957,49 @@ namespace MWDialogue
win->goodbye();
}
void DialogueManager::persuade(int type)
{
bool success;
float temp, perm;
MWBase::Environment::get().getMechanicsManager()->getPersuasionDispositionChange(
mActor, MWBase::MechanicsManager::PersuasionType(type), mTemporaryDispositionChange,
success, temp, perm);
mTemporaryDispositionChange += temp;
mPermanentDispositionChange += perm;
// change temp disposition so that final disposition is between 0...100
int curDisp = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor);
if (curDisp + mTemporaryDispositionChange < 0)
mTemporaryDispositionChange = -curDisp;
else if (curDisp + mTemporaryDispositionChange > 100)
mTemporaryDispositionChange = 100 - curDisp;
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWWorld::Class::get(player).skillUsageSucceeded(player, ESM::Skill::Speechcraft, success ? 0 : 1);
std::string text;
if (type == MWBase::MechanicsManager::PT_Admire)
text = "Admire";
else if (type == MWBase::MechanicsManager::PT_Taunt)
text = "Taunt";
else if (type == MWBase::MechanicsManager::PT_Intimidate)
text = "Intimidate";
else{
text = "Bribe";
}
executeTopic (text + (success ? " Success" : " Fail"));
}
int DialogueManager::getTemporaryDispositionChange() const
{
return mTemporaryDispositionChange;
}
void DialogueManager::applyTemporaryDispositionChange(int delta)
{
mTemporaryDispositionChange += delta;
}
}

@ -3,55 +3,54 @@
#include "../mwbase/dialoguemanager.hpp"
#include <components/esm/loadinfo.hpp>
#include <map>
#include <list>
#include <components/compiler/streamerrorhandler.hpp>
#include "../mwscript/compilercontext.hpp"
#include "../mwscript/interpretercontext.hpp"
#include <components/compiler/output.hpp>
#include "../mwworld/ptr.hpp"
#include <map>
#include "../mwscript/compilercontext.hpp"
namespace MWDialogue
{
class DialogueManager : public MWBase::DialogueManager
{
bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo::SelectStruct& select) const;
bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const;
bool functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice);
void parseText(std::string text);
void updateTopics();
std::map<std::string,ESM::Dialogue> mDialogueMap;
std::map<std::string,bool> mKnownTopics;// Those are the topics the player knows.
std::map<std::string, ESM::Dialogue> mDialogueMap;
std::map<std::string, bool> mKnownTopics;// Those are the topics the player knows.
std::list<std::string> mActorKnownTopics;
MWScript::CompilerContext mCompilerContext;
std::ostream mErrorStream;
Compiler::StreamErrorHandler mErrorHandler;
bool compile (const std::string& cmd,std::vector<Interpreter::Type_Code>& code);
void executeScript(std::string script);
MWWorld::Ptr mActor;
void printError(std::string error);
bool mTalkedTo;
int mChoice;
std::map<std::string,int> mChoiceMap;
std::map<std::string, int> mChoiceMap;
std::string mLastTopic;
ESM::DialInfo mLastDialogue;
bool mIsInChoice;
float mTemporaryDispositionChange;
float mPermanentDispositionChange;
bool mScriptVerbose;
void parseText (const std::string& text);
void updateTopics();
bool compile (const std::string& cmd,std::vector<Interpreter::Type_Code>& code);
void executeScript (const std::string& script);
void printError (const std::string& error);
void executeTopic (const std::string& topic);
public:
DialogueManager (const Compiler::Extensions& extensions);
DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose);
virtual void startDialogue (const MWWorld::Ptr& actor);
@ -61,14 +60,17 @@ namespace MWDialogue
virtual void goodbye();
///get the faction of the actor you are talking with
virtual std::string getFaction() const;
virtual MWWorld::Ptr getActor() const;
///< Return the actor the player is currently talking to.
//calbacks for the GUI
virtual void keywordSelected (const std::string& keyword);
virtual void goodbyeSelected();
virtual void questionAnswered (const std::string& answer);
virtual void persuade (int type);
virtual int getTemporaryDispositionChange () const;
virtual void applyTemporaryDispositionChange (int delta);
};
}

@ -0,0 +1,570 @@
#include "filter.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/journal.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/magiceffects.hpp"
#include "selectwrapper.hpp"
namespace
{
std::string toLower (const std::string& name)
{
std::string lowerCase;
std::transform (name.begin(), name.end(), std::back_inserter (lowerCase),
(int(*)(int)) std::tolower);
return lowerCase;
}
}
bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
{
// actor id
if (!info.mActor.empty())
if (toLower (info.mActor)!=MWWorld::Class::get (mActor).getId (mActor))
return false;
bool isCreature = (mActor.getTypeName() != typeid (ESM::NPC).name());
// NPC race
if (!info.mRace.empty())
{
if (isCreature)
return false;
MWWorld::LiveCellRef<ESM::NPC> *cellRef = mActor.get<ESM::NPC>();
if (toLower (info.mRace)!=toLower (cellRef->mBase->mRace))
return false;
}
// NPC class
if (!info.mClass.empty())
{
if (isCreature)
return false;
MWWorld::LiveCellRef<ESM::NPC> *cellRef = mActor.get<ESM::NPC>();
if (toLower (info.mClass)!=toLower (cellRef->mBase->mClass))
return false;
}
// NPC faction
if (!info.mNpcFaction.empty())
{
if (isCreature)
return false;
MWMechanics::NpcStats& stats = MWWorld::Class::get (mActor).getNpcStats (mActor);
std::map<std::string, int>::iterator iter = stats.getFactionRanks().find (toLower (info.mNpcFaction));
if (iter==stats.getFactionRanks().end())
return false;
// check rank
if (iter->second < info.mData.mRank)
return false;
}
// Gender
if (!isCreature)
{
MWWorld::LiveCellRef<ESM::NPC>* npc = mActor.get<ESM::NPC>();
if (info.mData.mGender==(npc->mBase->mFlags & npc->mBase->Female ? 0 : 1))
return false;
}
return true;
}
bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const
{
const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
// check player faction
if (!info.mPcFaction.empty())
{
MWMechanics::NpcStats& stats = MWWorld::Class::get (player).getNpcStats (player);
std::map<std::string,int>::iterator iter = stats.getFactionRanks().find (toLower (info.mPcFaction));
if(iter==stats.getFactionRanks().end())
return false;
// check rank
if (iter->second < info.mData.mPCrank)
return false;
}
// check cell
if (!info.mCell.empty())
if (toLower (player.getCell()->mCell->mName) != toLower (info.mCell))
return false;
return true;
}
bool MWDialogue::Filter::testSelectStructs (const ESM::DialInfo& info) const
{
for (std::vector<ESM::DialInfo::SelectStruct>::const_iterator iter (info.mSelects.begin());
iter != info.mSelects.end(); ++iter)
if (!testSelectStruct (*iter))
return false;
return true;
}
bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const
{
if (select.isNpcOnly() && mActor.getTypeName()!=typeid (ESM::NPC).name())
return select.isInverted();
switch (select.getType())
{
case SelectWrapper::Type_None: return true;
case SelectWrapper::Type_Integer: return select.selectCompare (getSelectStructInteger (select));
case SelectWrapper::Type_Numeric: return testSelectStructNumeric (select);
case SelectWrapper::Type_Boolean: return select.selectCompare (getSelectStructBoolean (select));
}
return true;
}
bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) const
{
switch (select.getFunction())
{
case SelectWrapper::Function_Global:
// internally all globals are float :(
return select.selectCompare (
MWBase::Environment::get().getWorld()->getGlobalVariable (select.getName()).mFloat);
case SelectWrapper::Function_Local:
{
std::string scriptName = MWWorld::Class::get (mActor).getScript (mActor);
if (scriptName.empty())
return false; // no script
const ESM::Script *script =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Script>().find (scriptName);
std::string name = select.getName();
int i = 0;
for (; i<static_cast<int> (script->mVarNames.size()); ++i)
if (script->mVarNames[i]==name)
break;
if (i>=static_cast<int> (script->mVarNames.size()))
return false; // script does not have a variable of this name
const MWScript::Locals& locals = mActor.getRefData().getLocals();
if (i<script->mData.mNumShorts)
return select.selectCompare (static_cast<int> (locals.mShorts[i]));
i -= script->mData.mNumShorts;
if (i<script->mData.mNumLongs)
return select.selectCompare (locals.mLongs[i]);
i -= script->mData.mNumShorts;
return select.selectCompare (locals.mFloats.at (i));
}
case SelectWrapper::Function_PcHealthPercent:
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
float ratio = MWWorld::Class::get (player).getCreatureStats (player).getHealth().getCurrent() /
MWWorld::Class::get (player).getCreatureStats (player).getHealth().getModified();
return select.selectCompare (ratio);
}
case SelectWrapper::Function_PcDynamicStat:
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
float value = MWWorld::Class::get (player).getCreatureStats (player).
getDynamic (select.getArgument()).getCurrent();
return select.selectCompare (value);
}
case SelectWrapper::Function_HealthPercent:
{
float ratio = MWWorld::Class::get (mActor).getCreatureStats (mActor).getHealth().getCurrent() /
MWWorld::Class::get (mActor).getCreatureStats (mActor).getHealth().getModified();
return select.selectCompare (ratio);
}
default:
throw std::runtime_error ("unknown numeric select function");
}
}
int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) const
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
switch (select.getFunction())
{
case SelectWrapper::Function_Journal:
return MWBase::Environment::get().getJournal()->getJournalIndex (select.getName());
case SelectWrapper::Function_Item:
{
MWWorld::ContainerStore& store = MWWorld::Class::get (player).getContainerStore (player);
int sum = 0;
std::string name = select.getName();
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
if (toLower(iter->getCellRef().mRefID) == name)
sum += iter->getRefData().getCount();
return sum;
}
case SelectWrapper::Function_Dead:
return MWBase::Environment::get().getMechanicsManager()->countDeaths (select.getName());
case SelectWrapper::Function_Choice:
return mChoice;
case SelectWrapper::Function_AiSetting:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAiSetting (select.getArgument());
case SelectWrapper::Function_PcAttribute:
return MWWorld::Class::get (player).getCreatureStats (player).
getAttribute (select.getArgument()).getModified();
case SelectWrapper::Function_PcSkill:
return static_cast<int> (MWWorld::Class::get (player).
getNpcStats (player).getSkill (select.getArgument()).getModified());
case SelectWrapper::Function_FriendlyHit:
{
int hits = MWWorld::Class::get (mActor).getCreatureStats (mActor).getFriendlyHits();
return hits>4 ? 4 : hits;
}
case SelectWrapper::Function_PcLevel:
return MWWorld::Class::get (player).getCreatureStats (player).getLevel();
case SelectWrapper::Function_PcGender:
return player.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female ? 0 : 1;
case SelectWrapper::Function_PcClothingModifier:
{
MWWorld::InventoryStore& store = MWWorld::Class::get (player).getInventoryStore (player);
int value = 0;
for (int i=0; i<=15; ++i) // everything except thigns held in hands and amunition
{
MWWorld::ContainerStoreIterator slot = store.getSlot (i);
if (slot!=store.end())
value += MWWorld::Class::get (*slot).getValue (*slot);
}
return value;
}
case SelectWrapper::Function_PcCrimeLevel:
return MWWorld::Class::get (player).getNpcStats (player).getBounty();
case SelectWrapper::Function_RankRequirement:
{
if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty())
return 0;
std::string faction =
MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first;
int rank = getFactionRank (player, faction);
if (rank>=9)
return 0; // max rank
int result = 0;
if (hasFactionRankSkillRequirements (player, faction, rank+1))
result += 1;
if (hasFactionRankReputationRequirements (player, faction, rank+1))
result += 2;
return result;
}
case SelectWrapper::Function_Level:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getLevel();
case SelectWrapper::Function_PCReputation:
return MWWorld::Class::get (player).getNpcStats (player).getReputation();
case SelectWrapper::Function_Weather:
return MWBase::Environment::get().getWorld()->getCurrentWeather();
case SelectWrapper::Function_Reputation:
return MWWorld::Class::get (mActor).getNpcStats (mActor).getReputation();
case SelectWrapper::Function_FactionRankDiff:
{
if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty())
return 0;
std::pair<std::string, int> faction =
*MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin();
int rank = getFactionRank (player, faction.first);
return rank-faction.second;
}
case SelectWrapper::Function_WerewolfKills:
return MWWorld::Class::get (player).getNpcStats (player).getWerewolfKills();
case SelectWrapper::Function_RankLow:
case SelectWrapper::Function_RankHigh:
{
bool low = select.getFunction()==SelectWrapper::Function_RankLow;
if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty())
return 0;
std::string factionId =
MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first;
int value = 0;
const ESM::Faction& faction =
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId);
MWMechanics::NpcStats& playerStats = MWWorld::Class::get (player).getNpcStats (player);
for (std::vector<ESM::Faction::Reaction>::const_iterator iter (faction.mReactions.begin());
iter!=faction.mReactions.end(); ++iter)
if (playerStats.getFactionRanks().find (iter->mFaction)!=playerStats.getFactionRanks().end())
if (low ? iter->mReaction<value : iter->mReaction>value)
value = iter->mReaction;
return value;
}
default:
throw std::runtime_error ("unknown integer select function");
}
}
bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) const
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
switch (select.getFunction())
{
case SelectWrapper::Function_False:
return false;
case SelectWrapper::Function_Id:
return select.getName()==toLower (MWWorld::Class::get (mActor).getId (mActor));
case SelectWrapper::Function_Faction:
return toLower (mActor.get<ESM::NPC>()->mBase->mFaction)==select.getName();
case SelectWrapper::Function_Class:
return toLower (mActor.get<ESM::NPC>()->mBase->mClass)==select.getName();
case SelectWrapper::Function_Race:
return toLower (mActor.get<ESM::NPC>()->mBase->mRace)==select.getName();
case SelectWrapper::Function_Cell:
return toLower (mActor.getCell()->mCell->mName)==select.getName();
case SelectWrapper::Function_SameGender:
return (player.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female)==
(mActor.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female);
case SelectWrapper::Function_SameRace:
return toLower (mActor.get<ESM::NPC>()->mBase->mRace)!=
toLower (player.get<ESM::NPC>()->mBase->mRace);
case SelectWrapper::Function_SameFaction:
return MWWorld::Class::get (mActor).getNpcStats (mActor).isSameFaction (
MWWorld::Class::get (player).getNpcStats (player));
case SelectWrapper::Function_PcCommonDisease:
return MWWorld::Class::get (player).getCreatureStats (player).hasCommonDisease();
case SelectWrapper::Function_PcBlightDisease:
return MWWorld::Class::get (player).getCreatureStats (player).hasBlightDisease();
case SelectWrapper::Function_PcCorprus:
return MWWorld::Class::get (player).getCreatureStats (player).
getMagicEffects().get (132).mMagnitude!=0;
case SelectWrapper::Function_PcExpelled:
{
if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty())
return false;
std::string faction =
MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first;
std::set<std::string>& expelled = MWWorld::Class::get (player).getNpcStats (player).getExpelled();
return expelled.find (faction)!=expelled.end();
}
case SelectWrapper::Function_PcVampire:
return MWWorld::Class::get (player).getNpcStats (player).isVampire();
case SelectWrapper::Function_TalkedToPc:
return mTalkedToPlayer;
case SelectWrapper::Function_Alarmed:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).isAlarmed();
case SelectWrapper::Function_Detected:
return MWWorld::Class::get (mActor).hasDetected (mActor, player);
case SelectWrapper::Function_Attacked:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAttacked();
case SelectWrapper::Function_ShouldAttack:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).isHostile();
case SelectWrapper::Function_CreatureTargetted:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getCreatureTargetted();
case SelectWrapper::Function_PCWerewolf:
return MWWorld::Class::get (player).getNpcStats (player).isWerewolf();
default:
throw std::runtime_error ("unknown boolean select function");
}
}
int MWDialogue::Filter::getFactionRank (const MWWorld::Ptr& actor, const std::string& factionId) const
{
MWMechanics::NpcStats& stats = MWWorld::Class::get (actor).getNpcStats (actor);
std::map<std::string, int>::const_iterator iter = stats.getFactionRanks().find (factionId);
if (iter==stats.getFactionRanks().end())
return -1;
return iter->second;
}
bool MWDialogue::Filter::hasFactionRankSkillRequirements (const MWWorld::Ptr& actor,
const std::string& factionId, int rank) const
{
if (rank<0 || rank>=10)
throw std::runtime_error ("rank index out of range");
if (!MWWorld::Class::get (actor).getNpcStats (actor).hasSkillsForRank (factionId, rank))
return false;
const ESM::Faction& faction =
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId);
MWMechanics::CreatureStats& stats = MWWorld::Class::get (actor).getCreatureStats (actor);
return stats.getAttribute (faction.mData.mAttribute1).getBase()>=faction.mData.mRankData[rank].mAttribute1 &&
stats.getAttribute (faction.mData.mAttribute2).getBase()>=faction.mData.mRankData[rank].mAttribute2;
}
bool MWDialogue::Filter::hasFactionRankReputationRequirements (const MWWorld::Ptr& actor,
const std::string& factionId, int rank) const
{
if (rank<0 || rank>=10)
throw std::runtime_error ("rank index out of range");
MWMechanics::NpcStats& stats = MWWorld::Class::get (actor).getNpcStats (actor);
const ESM::Faction& faction =
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId);
return stats.getFactionReputation (factionId)>=faction.mData.mRankData[rank].mFactReaction;
}
MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer)
: mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer)
{}
bool MWDialogue::Filter::operator() (const ESM::DialInfo& info) const
{
return testActor (info) && testPlayer (info) && testSelectStructs (info);
}
const ESM::DialInfo *MWDialogue::Filter::search (const ESM::Dialogue& dialogue) const
{
for (std::vector<ESM::DialInfo>::const_iterator iter = dialogue.mInfo.begin();
iter!=dialogue.mInfo.end(); ++iter)
if ((*this) (*iter))
return &*iter;
return 0;
}

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

Loading…
Cancel
Save