forked from mirror/openmw-tes3mp
Merge branch 'master' of https://github.com/zinnschlag/openmw into savedgame
Conflicts: apps/openmw/mwgui/referenceinterface.cpp apps/openmw/mwmechanics/actors.cpp apps/openmw/mwmechanics/mechanicsmanagerimp.cpp apps/openmw/mwmechanics/mechanicsmanagerimp.hpp apps/openmw/mwscript/cellextensions.cpp apps/openmw/mwworld/cells.cpp apps/openmw/mwworld/cells.hpp apps/openmw/mwworld/cellstore.cpp apps/openmw/mwworld/store.cpp apps/openmw/mwworld/worldimp.cpp
This commit is contained in:
commit
03cf383be7
215 changed files with 4791 additions and 3007 deletions
|
@ -93,8 +93,6 @@ set(OENGINE_GUI
|
|||
)
|
||||
|
||||
set(OENGINE_BULLET
|
||||
${LIBDIR}/openengine/bullet/btKinematicCharacterController.cpp
|
||||
${LIBDIR}/openengine/bullet/btKinematicCharacterController.h
|
||||
${LIBDIR}/openengine/bullet/BtOgre.cpp
|
||||
${LIBDIR}/openengine/bullet/BtOgreExtras.h
|
||||
${LIBDIR}/openengine/bullet/BtOgreGP.h
|
||||
|
@ -183,10 +181,11 @@ if (WIN32)
|
|||
set(Boost_USE_STATIC_LIBS ON)
|
||||
set(PLATFORM_INCLUDE_DIR "platform")
|
||||
add_definitions(-DBOOST_ALL_NO_LIB)
|
||||
|
||||
# Suppress WinMain(), provided by SDL
|
||||
add_definitions(-DSDL_MAIN_HANDLED)
|
||||
else (WIN32)
|
||||
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 "")
|
||||
|
@ -238,7 +237,6 @@ include_directories("."
|
|||
${MYGUI_INCLUDE_DIRS}
|
||||
${MYGUI_PLATFORM_INCLUDE_DIRS}
|
||||
${OPENAL_INCLUDE_DIR}
|
||||
${UUID_INCLUDE_DIR}
|
||||
${LIBDIR}
|
||||
)
|
||||
|
||||
|
@ -408,46 +406,6 @@ IF(NOT WIN32 AND NOT APPLE)
|
|||
# Install resources
|
||||
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT "Resources")
|
||||
INSTALL(DIRECTORY DESTINATION "${DATADIR}/data" COMPONENT "Resources")
|
||||
|
||||
IF (DPKG_PROGRAM)
|
||||
## Debian Specific
|
||||
IF(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
|
||||
EXEC_PROGRAM("git" ${CMAKE_CURRENT_SOURCE_DIR} ARGS "describe" OUTPUT_VARIABLE GIT_VERSION )
|
||||
STRING(REGEX REPLACE "openmw-" "" VERSION_STRING "${GIT_VERSION}")
|
||||
EXEC_PROGRAM("git" ARGS "config --get user.name" OUTPUT_VARIABLE GIT_NAME )
|
||||
EXEC_PROGRAM("git" ARGS "config --get user.email" OUTPUT_VARIABLE GIT_EMAIL)
|
||||
SET(PACKAGE_MAINTAINER "${GIT_NAME} <${GIT_EMAIL}>")
|
||||
ELSE()
|
||||
SET(VERSION_STRING "${OPENMW_VERSION}")
|
||||
SET(PACKAGE_MAINTAINER "unknown")
|
||||
ENDIF()
|
||||
|
||||
SET(CPACK_GENERATOR "DEB")
|
||||
SET(CPACK_PACKAGE_NAME "openmw")
|
||||
SET(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://openmw.org")
|
||||
SET(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "${PACKAGE_MAINTAINER}")
|
||||
SET(CPACK_DEBIAN_PACKAGE_DESCRIPTION "A reimplementation of The Elder Scrolls III: Morrowind
|
||||
OpenMW is a reimplementation of the Bethesda Game Studios game The Elder Scrolls III: Morrowind.
|
||||
Data files from the original game is required to run it.")
|
||||
SET(CPACK_DEBIAN_PACKAGE_NAME "openmw")
|
||||
SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}")
|
||||
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW opencs;OpenCS bsatool;Bsatool esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter")
|
||||
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), 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")
|
||||
|
||||
STRING(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_PACKAGE_NAME_LOWERCASE)
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND ${DPKG_PROGRAM} --print-architecture
|
||||
OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME_LOWERCASE}_${CPACK_DEBIAN_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}")
|
||||
|
||||
|
||||
INCLUDE(CPack)
|
||||
ENDIF(DPKG_PROGRAM)
|
||||
ENDIF(NOT WIN32 AND NOT APPLE)
|
||||
|
||||
if(WIN32)
|
||||
|
|
|
@ -680,7 +680,7 @@ std::string creatureFlags(int flags)
|
|||
if (flags & ESM::Creature::Walks) properties += "Walks ";
|
||||
if (flags & ESM::Creature::Swims) properties += "Swims ";
|
||||
if (flags & ESM::Creature::Flies) properties += "Flies ";
|
||||
if (flags & ESM::Creature::Biped) properties += "Biped ";
|
||||
if (flags & ESM::Creature::Bipedal) properties += "Bipedal ";
|
||||
if (flags & ESM::Creature::Respawn) properties += "Respawn ";
|
||||
if (flags & ESM::Creature::Weapon) properties += "Weapon ";
|
||||
if (flags & ESM::Creature::Skeleton) properties += "Skeleton ";
|
||||
|
@ -691,7 +691,7 @@ std::string creatureFlags(int flags)
|
|||
ESM::Creature::Walks|
|
||||
ESM::Creature::Swims|
|
||||
ESM::Creature::Flies|
|
||||
ESM::Creature::Biped|
|
||||
ESM::Creature::Bipedal|
|
||||
ESM::Creature::Respawn|
|
||||
ESM::Creature::Weapon|
|
||||
ESM::Creature::Skeleton|
|
||||
|
@ -717,16 +717,26 @@ std::string landFlags(int flags)
|
|||
return properties;
|
||||
}
|
||||
|
||||
std::string leveledListFlags(int flags)
|
||||
std::string itemListFlags(int flags)
|
||||
{
|
||||
std::string properties = "";
|
||||
if (flags == 0) properties += "[None] ";
|
||||
if (flags & ESM::LeveledListBase::AllLevels) properties += "AllLevels ";
|
||||
// This flag apparently not present on creature lists...
|
||||
if (flags & ESM::LeveledListBase::Each) properties += "Each ";
|
||||
if (flags & ESM::ItemLevList::AllLevels) properties += "AllLevels ";
|
||||
if (flags & ESM::ItemLevList::Each) properties += "Each ";
|
||||
int unused = (0xFFFFFFFF ^
|
||||
(ESM::LeveledListBase::AllLevels|
|
||||
ESM::LeveledListBase::Each));
|
||||
(ESM::ItemLevList::AllLevels|
|
||||
ESM::ItemLevList::Each));
|
||||
if (flags & unused) properties += "Invalid ";
|
||||
properties += str(boost::format("(0x%08X)") % flags);
|
||||
return properties;
|
||||
}
|
||||
|
||||
std::string creatureListFlags(int flags)
|
||||
{
|
||||
std::string properties = "";
|
||||
if (flags == 0) properties += "[None] ";
|
||||
if (flags & ESM::CreatureLevList::AllLevels) properties += "AllLevels ";
|
||||
int unused = (0xFFFFFFFF ^ ESM::CreatureLevList::AllLevels);
|
||||
if (flags & unused) properties += "Invalid ";
|
||||
properties += str(boost::format("(0x%08X)") % flags);
|
||||
return properties;
|
||||
|
@ -764,34 +774,19 @@ std::string magicEffectFlags(int flags)
|
|||
{
|
||||
std::string properties = "";
|
||||
if (flags == 0) properties += "[None] ";
|
||||
// Enchanting & SpellMaking occur on the same list of effects.
|
||||
// "EXTRA SPELL" appears in the construction set under both the
|
||||
// spell making and enchanting tabs as an allowed effect. Since
|
||||
// most of the effects without this flags are defective in various
|
||||
// ways, it's still very unclear what these flag bits are.
|
||||
if (flags & ESM::MagicEffect::SpellMaking) properties += "SpellMaking ";
|
||||
if (flags & ESM::MagicEffect::Enchanting) properties += "Enchanting ";
|
||||
if (flags & 0x00000040) properties += "RangeNoSelf ";
|
||||
if (flags & 0x00000080) properties += "RangeTouch ";
|
||||
if (flags & 0x00000100) properties += "RangeTarget ";
|
||||
if (flags & 0x00001000) properties += "Unknown2 ";
|
||||
if (flags & 0x00000001) properties += "AffectSkill ";
|
||||
if (flags & 0x00000002) properties += "AffectAttribute ";
|
||||
if (flags & ESM::MagicEffect::TargetAttribute) properties += "TargetAttribute ";
|
||||
if (flags & ESM::MagicEffect::TargetSkill) properties += "TargetSkill ";
|
||||
if (flags & ESM::MagicEffect::NoDuration) properties += "NoDuration ";
|
||||
if (flags & 0x00000008) properties += "NoMagnitude ";
|
||||
if (flags & 0x00000010) properties += "Negative ";
|
||||
if (flags & 0x00000020) properties += "Unknown1 ";
|
||||
// ESM componet says 0x800 is negative, but none of the magic
|
||||
// effects have this flags set.
|
||||
if (flags & ESM::MagicEffect::Negative) properties += "Unused ";
|
||||
// Since only Chameleon has this flag it could be anything
|
||||
// that uniquely distinguishes Chameleon.
|
||||
if (flags & 0x00002000) properties += "Chameleon ";
|
||||
if (flags & 0x00004000) properties += "Bound ";
|
||||
if (flags & 0x00008000) properties += "Summon ";
|
||||
// Calm, Demoralize, Frenzy, Lock, Open, Rally, Soultrap, Turn Unded
|
||||
if (flags & 0x00010000) properties += "Unknown3 ";
|
||||
if (flags & 0x00020000) properties += "Absorb ";
|
||||
if (flags & ESM::MagicEffect::NoMagnitude) properties += "NoMagnitude ";
|
||||
if (flags & ESM::MagicEffect::Harmful) properties += "Harmful ";
|
||||
if (flags & ESM::MagicEffect::ContinuousVfx) properties += "ContinuousVFX ";
|
||||
if (flags & ESM::MagicEffect::CastSelf) properties += "CastSelf ";
|
||||
if (flags & ESM::MagicEffect::CastTouch) properties += "CastTouch ";
|
||||
if (flags & ESM::MagicEffect::CastTarget) properties += "CastTarget ";
|
||||
if (flags & ESM::MagicEffect::UncappedDamage) properties += "UncappedDamage ";
|
||||
if (flags & ESM::MagicEffect::NonRecastable) properties += "NonRecastable ";
|
||||
if (flags & ESM::MagicEffect::Unreflectable) properties += "Unreflectable ";
|
||||
if (flags & ESM::MagicEffect::CasterLinked) properties += "CasterLinked ";
|
||||
if (flags & 0xFFFC0000) properties += "Invalid ";
|
||||
properties += str(boost::format("(0x%08X)") % flags);
|
||||
return properties;
|
||||
|
|
|
@ -50,7 +50,8 @@ std::string cellFlags(int flags);
|
|||
std::string containerFlags(int flags);
|
||||
std::string creatureFlags(int flags);
|
||||
std::string landFlags(int flags);
|
||||
std::string leveledListFlags(int flags);
|
||||
std::string creatureListFlags(int flags);
|
||||
std::string itemListFlags(int flags);
|
||||
std::string lightFlags(int flags);
|
||||
std::string magicEffectFlags(int flags);
|
||||
std::string npcFlags(int flags);
|
||||
|
|
|
@ -13,8 +13,8 @@ void printAIPackage(ESM::AIPackage p)
|
|||
std::cout << " Distance: " << p.mWander.mDistance << std::endl;
|
||||
std::cout << " Duration: " << p.mWander.mDuration << std::endl;
|
||||
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;
|
||||
if (p.mWander.mShouldRepeat != 1)
|
||||
std::cout << " Should repeat: " << (bool)p.mWander.mShouldRepeat << std::endl;
|
||||
|
||||
std::cout << " Idle: ";
|
||||
for (int i = 0; i != 8; i++)
|
||||
|
@ -834,7 +834,7 @@ template<>
|
|||
void Record<ESM::CreatureLevList>::print()
|
||||
{
|
||||
std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl;
|
||||
std::cout << " Flags: " << leveledListFlags(mData.mFlags) << std::endl;
|
||||
std::cout << " Flags: " << creatureListFlags(mData.mFlags) << std::endl;
|
||||
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++)
|
||||
|
@ -846,11 +846,11 @@ template<>
|
|||
void Record<ESM::ItemLevList>::print()
|
||||
{
|
||||
std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl;
|
||||
std::cout << " Flags: " << leveledListFlags(mData.mFlags) << std::endl;
|
||||
std::cout << " Flags: " << itemListFlags(mData.mFlags) << std::endl;
|
||||
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 << " Inventory: Count: " << iit->mLevel
|
||||
std::cout << " Inventory: Level: " << iit->mLevel
|
||||
<< " Item: " << iit->mId << std::endl;
|
||||
}
|
||||
|
||||
|
@ -958,7 +958,7 @@ void Record<ESM::MagicEffect>::print()
|
|||
std::cout << " RGB Color: " << "("
|
||||
<< mData.mData.mRed << ","
|
||||
<< mData.mData.mGreen << ","
|
||||
<< mData.mData.mGreen << ")" << std::endl;
|
||||
<< mData.mData.mBlue << ")" << std::endl;
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
int main(int argc, char *argv[])
|
||||
{
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
|
||||
SDL_SetMainReady();
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||
{
|
||||
qDebug() << "SDL_Init failed: " << QString::fromStdString(SDL_GetError());
|
||||
|
|
|
@ -235,7 +235,7 @@ namespace
|
|||
{
|
||||
for ( bfs::recursive_directory_iterator end, dir(in); dir != end; ++dir )
|
||||
{
|
||||
if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename)
|
||||
if(Misc::StringUtils::ciEqual(dir->path().filename().string(), filename))
|
||||
return dir->path();
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ namespace
|
|||
{
|
||||
for ( bfs::directory_iterator end, dir(in); dir != end; ++dir )
|
||||
{
|
||||
if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename)
|
||||
if(Misc::StringUtils::ciEqual(dir->path().filename().string(), filename))
|
||||
return dir->path();
|
||||
}
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ namespace
|
|||
{
|
||||
for(bfs::directory_iterator end, dir(in); dir != end; ++dir)
|
||||
{
|
||||
if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename)
|
||||
if(Misc::StringUtils::ciEqual(dir->path().filename().string(), filename))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -623,6 +623,17 @@ MwIniImporter::MwIniImporter()
|
|||
"Moons:Masser Fade Out Finish",
|
||||
"Moons:Script Color",
|
||||
|
||||
// blood
|
||||
"Blood:Model 0",
|
||||
"Blood:Model 1",
|
||||
"Blood:Model 2",
|
||||
"Blood:Texture 0",
|
||||
"Blood:Texture 1",
|
||||
"Blood:Texture 2",
|
||||
"Blood:Texture Name 0",
|
||||
"Blood:Texture Name 1",
|
||||
"Blood:Texture Name 2",
|
||||
|
||||
0
|
||||
};
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ opencs_units (model/tools
|
|||
|
||||
opencs_units_noqt (model/tools
|
||||
mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
|
||||
birthsigncheck spellcheck
|
||||
birthsigncheck spellcheck referenceablecheck
|
||||
)
|
||||
|
||||
|
||||
|
|
1095
apps/opencs/model/tools/referenceablecheck.cpp
Normal file
1095
apps/opencs/model/tools/referenceablecheck.cpp
Normal file
File diff suppressed because it is too large
Load diff
78
apps/opencs/model/tools/referenceablecheck.hpp
Normal file
78
apps/opencs/model/tools/referenceablecheck.hpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
#ifndef REFERENCEABLECHECKSTAGE_H
|
||||
#define REFERENCEABLECHECKSTAGE_H
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
#include "../doc/stage.hpp"
|
||||
#include "../world/data.hpp"
|
||||
#include "../world/refiddata.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
class ReferenceableCheckStage : public CSMDoc::Stage
|
||||
{
|
||||
public:
|
||||
ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable,
|
||||
const CSMWorld::IdCollection<ESM::Race>& races,
|
||||
const CSMWorld::IdCollection<ESM::Class>& classes,
|
||||
const CSMWorld::IdCollection<ESM::Faction>& factions);
|
||||
|
||||
virtual void perform(int stage, std::vector< std::string >& messages);
|
||||
virtual int setup();
|
||||
|
||||
private:
|
||||
//CONCRETE CHECKS
|
||||
void bookCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, std::vector< std::string >& messages);
|
||||
void activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, std::vector< std::string >& messages);
|
||||
void potionCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Potion>& records, std::vector<std::string>& messages);
|
||||
void apparatusCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Apparatus>& records, std::vector<std::string>& messages);
|
||||
void armorCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Armor>& records, std::vector<std::string>& messages);
|
||||
void clothingCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Clothing>& records, std::vector<std::string>& messages);
|
||||
void containerCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Container>& records, std::vector<std::string>& messages);
|
||||
void creatureCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Creature>& records, std::vector<std::string>& messages);
|
||||
void doorCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Door>& records, std::vector<std::string>& messages);
|
||||
void ingredientCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Ingredient>& records, std::vector<std::string>& messages);
|
||||
void creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::CreatureLevList>& records, std::vector<std::string>& messages);
|
||||
void itemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::ItemLevList>& records, std::vector<std::string>& messages);
|
||||
void lightCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Light>& records, std::vector<std::string>& messages);
|
||||
void lockpickCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Lockpick>& records, std::vector<std::string>& messages);
|
||||
void miscCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Miscellaneous>& records, std::vector<std::string>& messages);
|
||||
void npcCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::NPC>& records, std::vector<std::string>& messages);
|
||||
void weaponCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Weapon>& records, std::vector<std::string>& messages);
|
||||
void probeCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Probe>& records, std::vector<std::string>& messages);
|
||||
void repairCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Repair>& records, std::vector<std::string>& messages);
|
||||
void staticCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Static>& records, std::vector<std::string>& messages);
|
||||
|
||||
//FINAL CHECK
|
||||
void finalCheck(std::vector<std::string>& messages);
|
||||
|
||||
//TEMPLATE CHECKS
|
||||
template<typename ITEM> void inventoryItemCheck(const ITEM& someItem,
|
||||
std::vector<std::string>& messages,
|
||||
const std::string& someID,
|
||||
bool enchantable); //for all enchantable items.
|
||||
|
||||
template<typename ITEM> void inventoryItemCheck(const ITEM& someItem,
|
||||
std::vector<std::string>& messages,
|
||||
const std::string& someID); //for non-enchantable items.
|
||||
|
||||
template<typename TOOL> void toolCheck(const TOOL& someTool,
|
||||
std::vector<std::string>& messages,
|
||||
const std::string& someID,
|
||||
bool canbebroken); //for tools with uses.
|
||||
|
||||
template<typename TOOL> void toolCheck(const TOOL& someTool,
|
||||
std::vector<std::string>& messages,
|
||||
const std::string& someID); //for tools without uses.
|
||||
|
||||
template<typename LIST> void listCheck(const LIST& someList,
|
||||
std::vector< std::string >& messages,
|
||||
const std::string& someID);
|
||||
|
||||
const CSMWorld::RefIdData& mReferencables;
|
||||
const CSMWorld::IdCollection<ESM::Race>& mRaces;
|
||||
const CSMWorld::IdCollection<ESM::Class>& mClasses;
|
||||
const CSMWorld::IdCollection<ESM::Faction>& mFactions;
|
||||
bool mPlayerPresent;
|
||||
};
|
||||
}
|
||||
#endif // REFERENCEABLECHECKSTAGE_H
|
|
@ -68,4 +68,4 @@ void CSMTools::ReportModel::add (const std::string& row)
|
|||
const CSMWorld::UniversalId& CSMTools::ReportModel::getUniversalId (int row) const
|
||||
{
|
||||
return mRows.at (row).first;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "regioncheck.hpp"
|
||||
#include "birthsigncheck.hpp"
|
||||
#include "spellcheck.hpp"
|
||||
#include "referenceablecheck.hpp"
|
||||
|
||||
CSMDoc::Operation *CSMTools::Tools::get (int type)
|
||||
{
|
||||
|
@ -74,6 +75,8 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier()
|
|||
mVerifier->appendStage (new BirthsignCheckStage (mData.getBirthsigns()));
|
||||
|
||||
mVerifier->appendStage (new SpellCheckStage (mData.getSpells()));
|
||||
|
||||
mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions()));
|
||||
}
|
||||
|
||||
return mVerifier;
|
||||
|
@ -138,4 +141,5 @@ void CSMTools::Tools::verifierMessage (const QString& message, int type)
|
|||
|
||||
if (iter!=mActiveReports.end())
|
||||
mReports[iter->second]->add (message.toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ int CSMWorld::Columns::getId (const std::string& name)
|
|||
std::string name2 = Misc::StringUtils::lowerCase (name);
|
||||
|
||||
for (int i=0; sNames[i].mName; ++i)
|
||||
if (name2==Misc::StringUtils::lowerCase (sNames[i].mName))
|
||||
if (Misc::StringUtils::ciEqual(sNames[i].mName, name2))
|
||||
return sNames[i].mId;
|
||||
|
||||
return -1;
|
||||
|
|
|
@ -67,7 +67,7 @@ int CSMWorld::InfoCollection::getIndex (const std::string& id, const std::string
|
|||
std::pair<RecordConstIterator, RecordConstIterator> range = getTopicRange (topic);
|
||||
|
||||
for (; range.first!=range.second; ++range.first)
|
||||
if (Misc::StringUtils::lowerCase (range.first->get().mId)==fullId)
|
||||
if (Misc::StringUtils::ciEqual(range.first->get().mId, fullId))
|
||||
return std::distance (getRecords().begin(), range.first);
|
||||
|
||||
return -1;
|
||||
|
@ -177,8 +177,8 @@ CSMWorld::InfoCollection::Range CSMWorld::InfoCollection::getTopicRange (const s
|
|||
RecordConstIterator end = begin;
|
||||
|
||||
for (; end!=getRecords().end(); ++end)
|
||||
if (Misc::StringUtils::lowerCase (end->get().mTopicId)!=topic2)
|
||||
if (!Misc::StringUtils::ciEqual(end->get().mTopicId, topic2))
|
||||
break;
|
||||
|
||||
return Range (begin, end);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -181,7 +181,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
unsigned int mFlag;
|
||||
} sCreatureFlagTable[] =
|
||||
{
|
||||
{ Columns::ColumnId_Biped, ESM::Creature::Biped },
|
||||
{ Columns::ColumnId_Biped, ESM::Creature::Bipedal },
|
||||
{ Columns::ColumnId_HasWeapon, ESM::Creature::Weapon },
|
||||
{ Columns::ColumnId_NoMovement, ESM::Creature::None },
|
||||
{ Columns::ColumnId_Swims, ESM::Creature::Swims },
|
||||
|
@ -549,3 +549,9 @@ void CSMWorld::RefIdCollection::save (int index, ESM::ESMWriter& writer) const
|
|||
{
|
||||
mData.save (index, writer);
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdData& CSMWorld::RefIdCollection::getDataSet() const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
|
|
|
@ -107,7 +107,10 @@ namespace CSMWorld
|
|||
/// \return Success?
|
||||
|
||||
void save (int index, ESM::ESMWriter& writer) const;
|
||||
|
||||
const RefIdData& getDataSet() const; //I can't figure out a better name for this one :(
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -230,4 +230,104 @@ void CSMWorld::RefIdData::save (int index, ESM::ESMWriter& writer) const
|
|||
throw std::logic_error ("invalid local index type");
|
||||
|
||||
iter->second->save (localIndex.first, writer);
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Book >& CSMWorld::RefIdData::getBooks() const
|
||||
{
|
||||
return mBooks;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Activator >& CSMWorld::RefIdData::getActivators() const
|
||||
{
|
||||
return mActivators;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Potion >& CSMWorld::RefIdData::getPotions() const
|
||||
{
|
||||
return mPotions;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Apparatus >& CSMWorld::RefIdData::getApparati() const
|
||||
{
|
||||
return mApparati;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Armor >& CSMWorld::RefIdData::getArmors() const
|
||||
{
|
||||
return mArmors;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Clothing >& CSMWorld::RefIdData::getClothing() const
|
||||
{
|
||||
return mClothing;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Container >& CSMWorld::RefIdData::getContainers() const
|
||||
{
|
||||
return mContainers;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Creature >& CSMWorld::RefIdData::getCreatures() const
|
||||
{
|
||||
return mCreatures;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Door >& CSMWorld::RefIdData::getDoors() const
|
||||
{
|
||||
return mDoors;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Ingredient >& CSMWorld::RefIdData::getIngredients() const
|
||||
{
|
||||
return mIngredients;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& CSMWorld::RefIdData::getCreatureLevelledLists() const
|
||||
{
|
||||
return mCreatureLevelledLists;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& CSMWorld::RefIdData::getItemLevelledList() const
|
||||
{
|
||||
return mItemLevelledLists;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Light >& CSMWorld::RefIdData::getLights() const
|
||||
{
|
||||
return mLights;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Lockpick >& CSMWorld::RefIdData::getLocpicks() const
|
||||
{
|
||||
return mLockpicks;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Miscellaneous >& CSMWorld::RefIdData::getMiscellaneous() const
|
||||
{
|
||||
return mMiscellaneous;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::NPC >& CSMWorld::RefIdData::getNPCs() const
|
||||
{
|
||||
return mNpcs;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Weapon >& CSMWorld::RefIdData::getWeapons() const
|
||||
{
|
||||
return mWeapons;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Probe >& CSMWorld::RefIdData::getProbes() const
|
||||
{
|
||||
return mProbes;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Repair >& CSMWorld::RefIdData::getRepairs() const
|
||||
{
|
||||
return mRepairs;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdDataContainer< ESM::Static >& CSMWorld::RefIdData::getStatics() const
|
||||
{
|
||||
return mStatics;
|
||||
}
|
|
@ -214,7 +214,33 @@ namespace CSMWorld
|
|||
/// \param listDeleted include deleted record in the list
|
||||
|
||||
void save (int index, ESM::ESMWriter& writer) const;
|
||||
|
||||
//RECORD CONTAINERS ACCESS METHODS
|
||||
const RefIdDataContainer<ESM::Book>& getBooks() const;
|
||||
const RefIdDataContainer<ESM::Activator>& getActivators() const;
|
||||
const RefIdDataContainer<ESM::Potion>& getPotions() const;
|
||||
const RefIdDataContainer<ESM::Apparatus>& getApparati() const;
|
||||
const RefIdDataContainer<ESM::Armor>& getArmors() const;
|
||||
const RefIdDataContainer<ESM::Clothing>& getClothing() const;
|
||||
const RefIdDataContainer<ESM::Container>& getContainers() const;
|
||||
const RefIdDataContainer<ESM::Creature>& getCreatures() const;
|
||||
const RefIdDataContainer<ESM::Door>& getDoors() const;
|
||||
const RefIdDataContainer<ESM::Ingredient>& getIngredients() const;
|
||||
const RefIdDataContainer<ESM::CreatureLevList>& getCreatureLevelledLists() const;
|
||||
const RefIdDataContainer<ESM::ItemLevList>& getItemLevelledList() const;
|
||||
const RefIdDataContainer<ESM::Light>& getLights() const;
|
||||
const RefIdDataContainer<ESM::Lockpick>& getLocpicks() const;
|
||||
const RefIdDataContainer<ESM::Miscellaneous>& getMiscellaneous() const;
|
||||
const RefIdDataContainer<ESM::NPC>& getNPCs() const;
|
||||
const RefIdDataContainer<ESM::Weapon >& getWeapons() const;
|
||||
const RefIdDataContainer<ESM::Probe >& getProbes() const;
|
||||
const RefIdDataContainer<ESM::Repair>& getRepairs() const;
|
||||
const RefIdDataContainer<ESM::Static>& getStatics() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
|
|||
add_openmw_dir (mwrender
|
||||
renderingmanager debugging sky camera animation npcanimation creatureanimation activatoranimation
|
||||
actors objects renderinginterface localmap occlusionquery water shadows
|
||||
characterpreview externalrendering globalmap videoplayer ripplesimulation refraction
|
||||
terrainstorage renderconst
|
||||
characterpreview globalmap videoplayer ripplesimulation refraction
|
||||
terrainstorage renderconst effectmanager
|
||||
)
|
||||
|
||||
add_openmw_dir (mwinput
|
||||
|
@ -74,7 +74,7 @@ add_openmw_dir (mwmechanics
|
|||
mechanicsmanagerimp stat character creaturestats magiceffects movement actors objects
|
||||
drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow
|
||||
aiescort aiactivate aicombat repair enchanting pathfinding security spellsuccess spellcasting
|
||||
disease
|
||||
disease pickpocket levelledlist
|
||||
)
|
||||
|
||||
add_openmw_dir (mwstate
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <sys/wait.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ucontext.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
@ -42,78 +43,78 @@ static char altstack[SIGSTKSZ];
|
|||
|
||||
|
||||
static struct {
|
||||
int signum;
|
||||
pid_t pid;
|
||||
int has_siginfo;
|
||||
siginfo_t siginfo;
|
||||
char buf[1024];
|
||||
int signum;
|
||||
pid_t pid;
|
||||
int has_siginfo;
|
||||
siginfo_t siginfo;
|
||||
char buf[1024];
|
||||
} crash_info;
|
||||
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
int signum;
|
||||
const char *name;
|
||||
int signum;
|
||||
} signals[] = {
|
||||
{ "Segmentation fault", SIGSEGV },
|
||||
{ "Illegal instruction", SIGILL },
|
||||
{ "FPU exception", SIGFPE },
|
||||
{ "System BUS error", SIGBUS },
|
||||
{ NULL, 0 }
|
||||
{ "Segmentation fault", SIGSEGV },
|
||||
{ "Illegal instruction", SIGILL },
|
||||
{ "FPU exception", SIGFPE },
|
||||
{ "System BUS error", SIGBUS },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static const struct {
|
||||
int code;
|
||||
const char *name;
|
||||
int code;
|
||||
const char *name;
|
||||
} sigill_codes[] = {
|
||||
#ifndef __FreeBSD__
|
||||
{ ILL_ILLOPC, "Illegal opcode" },
|
||||
{ ILL_ILLOPN, "Illegal operand" },
|
||||
{ ILL_ILLADR, "Illegal addressing mode" },
|
||||
{ ILL_ILLTRP, "Illegal trap" },
|
||||
{ ILL_PRVOPC, "Privileged opcode" },
|
||||
{ ILL_PRVREG, "Privileged register" },
|
||||
{ ILL_COPROC, "Coprocessor error" },
|
||||
{ ILL_BADSTK, "Internal stack error" },
|
||||
#endif
|
||||
{ 0, NULL }
|
||||
#ifndef __FreeBSD__
|
||||
{ ILL_ILLOPC, "Illegal opcode" },
|
||||
{ ILL_ILLOPN, "Illegal operand" },
|
||||
{ ILL_ILLADR, "Illegal addressing mode" },
|
||||
{ ILL_ILLTRP, "Illegal trap" },
|
||||
{ ILL_PRVOPC, "Privileged opcode" },
|
||||
{ ILL_PRVREG, "Privileged register" },
|
||||
{ ILL_COPROC, "Coprocessor error" },
|
||||
{ ILL_BADSTK, "Internal stack error" },
|
||||
#endif
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static const struct {
|
||||
int code;
|
||||
const char *name;
|
||||
int code;
|
||||
const char *name;
|
||||
} sigfpe_codes[] = {
|
||||
{ FPE_INTDIV, "Integer divide by zero" },
|
||||
{ FPE_INTOVF, "Integer overflow" },
|
||||
{ FPE_FLTDIV, "Floating point divide by zero" },
|
||||
{ FPE_FLTOVF, "Floating point overflow" },
|
||||
{ FPE_FLTUND, "Floating point underflow" },
|
||||
{ FPE_FLTRES, "Floating point inexact result" },
|
||||
{ FPE_FLTINV, "Floating point invalid operation" },
|
||||
{ FPE_FLTSUB, "Subscript out of range" },
|
||||
{ 0, NULL }
|
||||
{ FPE_INTDIV, "Integer divide by zero" },
|
||||
{ FPE_INTOVF, "Integer overflow" },
|
||||
{ FPE_FLTDIV, "Floating point divide by zero" },
|
||||
{ FPE_FLTOVF, "Floating point overflow" },
|
||||
{ FPE_FLTUND, "Floating point underflow" },
|
||||
{ FPE_FLTRES, "Floating point inexact result" },
|
||||
{ FPE_FLTINV, "Floating point invalid operation" },
|
||||
{ FPE_FLTSUB, "Subscript out of range" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static const struct {
|
||||
int code;
|
||||
const char *name;
|
||||
int code;
|
||||
const char *name;
|
||||
} sigsegv_codes[] = {
|
||||
#ifndef __FreeBSD__
|
||||
{ SEGV_MAPERR, "Address not mapped to object" },
|
||||
{ SEGV_ACCERR, "Invalid permissions for mapped object" },
|
||||
#endif
|
||||
{ 0, NULL }
|
||||
#ifndef __FreeBSD__
|
||||
{ SEGV_MAPERR, "Address not mapped to object" },
|
||||
{ SEGV_ACCERR, "Invalid permissions for mapped object" },
|
||||
#endif
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static const struct {
|
||||
int code;
|
||||
const char *name;
|
||||
int code;
|
||||
const char *name;
|
||||
} sigbus_codes[] = {
|
||||
#ifndef __FreeBSD__
|
||||
{ BUS_ADRALN, "Invalid address alignment" },
|
||||
{ BUS_ADRERR, "Non-existent physical address" },
|
||||
{ BUS_OBJERR, "Object specific hardware error" },
|
||||
#endif
|
||||
{ 0, NULL }
|
||||
#ifndef __FreeBSD__
|
||||
{ BUS_ADRALN, "Invalid address alignment" },
|
||||
{ BUS_ADRERR, "Non-existent physical address" },
|
||||
{ BUS_OBJERR, "Object specific hardware error" },
|
||||
#endif
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static int (*cc_user_info)(char*, char*);
|
||||
|
@ -121,314 +122,318 @@ static int (*cc_user_info)(char*, char*);
|
|||
|
||||
static void gdb_info(pid_t pid)
|
||||
{
|
||||
char respfile[64];
|
||||
char cmd_buf[128];
|
||||
FILE *f;
|
||||
int fd;
|
||||
char respfile[64];
|
||||
char cmd_buf[128];
|
||||
FILE *f;
|
||||
int fd;
|
||||
|
||||
/* Create a temp file to put gdb commands into */
|
||||
strcpy(respfile, "gdb-respfile-XXXXXX");
|
||||
if((fd=mkstemp(respfile)) >= 0 && (f=fdopen(fd, "w")) != NULL)
|
||||
{
|
||||
fprintf(f, "attach %d\n"
|
||||
"shell echo \"\"\n"
|
||||
"shell echo \"* Loaded Libraries\"\n"
|
||||
"info sharedlibrary\n"
|
||||
"shell echo \"\"\n"
|
||||
"shell echo \"* Threads\"\n"
|
||||
"info threads\n"
|
||||
"shell echo \"\"\n"
|
||||
"shell echo \"* FPU Status\"\n"
|
||||
"info float\n"
|
||||
"shell echo \"\"\n"
|
||||
"shell echo \"* Registers\"\n"
|
||||
"info registers\n"
|
||||
"shell echo \"\"\n"
|
||||
"shell echo \"* Backtrace\"\n"
|
||||
"thread apply all backtrace full\n"
|
||||
"detach\n"
|
||||
"quit\n", pid);
|
||||
fclose(f);
|
||||
/* Create a temp file to put gdb commands into */
|
||||
strcpy(respfile, "gdb-respfile-XXXXXX");
|
||||
if((fd=mkstemp(respfile)) >= 0 && (f=fdopen(fd, "w")) != NULL)
|
||||
{
|
||||
fprintf(f, "attach %d\n"
|
||||
"shell echo \"\"\n"
|
||||
"shell echo \"* Loaded Libraries\"\n"
|
||||
"info sharedlibrary\n"
|
||||
"shell echo \"\"\n"
|
||||
"shell echo \"* Threads\"\n"
|
||||
"info threads\n"
|
||||
"shell echo \"\"\n"
|
||||
"shell echo \"* FPU Status\"\n"
|
||||
"info float\n"
|
||||
"shell echo \"\"\n"
|
||||
"shell echo \"* Registers\"\n"
|
||||
"info registers\n"
|
||||
"shell echo \"\"\n"
|
||||
"shell echo \"* Backtrace\"\n"
|
||||
"thread apply all backtrace full\n"
|
||||
"detach\n"
|
||||
"quit\n", pid);
|
||||
fclose(f);
|
||||
|
||||
/* Run gdb and print process info. */
|
||||
snprintf(cmd_buf, sizeof(cmd_buf), "gdb --quiet --batch --command=%s", respfile);
|
||||
printf("Executing: %s\n", cmd_buf);
|
||||
fflush(stdout);
|
||||
/* Run gdb and print process info. */
|
||||
snprintf(cmd_buf, sizeof(cmd_buf), "gdb --quiet --batch --command=%s", respfile);
|
||||
printf("Executing: %s\n", cmd_buf);
|
||||
fflush(stdout);
|
||||
|
||||
system(cmd_buf);
|
||||
/* Clean up */
|
||||
remove(respfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error creating temp file */
|
||||
if(fd >= 0)
|
||||
{
|
||||
close(fd);
|
||||
remove(respfile);
|
||||
}
|
||||
printf("!!! Could not create gdb command file\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
system(cmd_buf);
|
||||
/* Clean up */
|
||||
remove(respfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error creating temp file */
|
||||
if(fd >= 0)
|
||||
{
|
||||
close(fd);
|
||||
remove(respfile);
|
||||
}
|
||||
printf("!!! Could not create gdb command file\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static void sys_info(void)
|
||||
{
|
||||
#ifdef __unix__
|
||||
system("echo \"System: `uname -a`\"");
|
||||
putchar('\n');
|
||||
fflush(stdout);
|
||||
struct utsname info;
|
||||
if(uname(&info))
|
||||
printf("!!! Failed to get system information\n");
|
||||
else
|
||||
printf("System: %s %s %s %s %s\n",
|
||||
info.sysname, info.nodename, info.release, info.version, info.machine);
|
||||
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static size_t safe_write(int fd, const void *buf, size_t len)
|
||||
{
|
||||
size_t ret = 0;
|
||||
while(ret < len)
|
||||
{
|
||||
ssize_t rem;
|
||||
if((rem=write(fd, (const char*)buf+ret, len-ret)) == -1)
|
||||
{
|
||||
if(errno == EINTR)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
ret += rem;
|
||||
}
|
||||
return ret;
|
||||
size_t ret = 0;
|
||||
while(ret < len)
|
||||
{
|
||||
ssize_t rem;
|
||||
if((rem=write(fd, (const char*)buf+ret, len-ret)) == -1)
|
||||
{
|
||||
if(errno == EINTR)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
ret += rem;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void crash_catcher(int signum, siginfo_t *siginfo, void *context)
|
||||
{
|
||||
//ucontext_t *ucontext = (ucontext_t*)context;
|
||||
pid_t dbg_pid;
|
||||
int fd[2];
|
||||
pid_t dbg_pid;
|
||||
int fd[2];
|
||||
|
||||
/* Make sure the effective uid is the real uid */
|
||||
if(getuid() != geteuid())
|
||||
{
|
||||
raise(signum);
|
||||
return;
|
||||
}
|
||||
/* Make sure the effective uid is the real uid */
|
||||
if(getuid() != geteuid())
|
||||
{
|
||||
raise(signum);
|
||||
return;
|
||||
}
|
||||
|
||||
safe_write(STDERR_FILENO, fatal_err, sizeof(fatal_err)-1);
|
||||
if(pipe(fd) == -1)
|
||||
{
|
||||
safe_write(STDERR_FILENO, pipe_err, sizeof(pipe_err)-1);
|
||||
raise(signum);
|
||||
return;
|
||||
}
|
||||
safe_write(STDERR_FILENO, fatal_err, sizeof(fatal_err)-1);
|
||||
if(pipe(fd) == -1)
|
||||
{
|
||||
safe_write(STDERR_FILENO, pipe_err, sizeof(pipe_err)-1);
|
||||
raise(signum);
|
||||
return;
|
||||
}
|
||||
|
||||
crash_info.signum = signum;
|
||||
crash_info.pid = getpid();
|
||||
crash_info.has_siginfo = !!siginfo;
|
||||
if(siginfo)
|
||||
crash_info.siginfo = *siginfo;
|
||||
if(cc_user_info)
|
||||
cc_user_info(crash_info.buf, crash_info.buf+sizeof(crash_info.buf));
|
||||
crash_info.signum = signum;
|
||||
crash_info.pid = getpid();
|
||||
crash_info.has_siginfo = !!siginfo;
|
||||
if(siginfo)
|
||||
crash_info.siginfo = *siginfo;
|
||||
if(cc_user_info)
|
||||
cc_user_info(crash_info.buf, crash_info.buf+sizeof(crash_info.buf));
|
||||
|
||||
/* Fork off to start a crash handler */
|
||||
switch((dbg_pid=fork()))
|
||||
{
|
||||
/* Error */
|
||||
case -1:
|
||||
safe_write(STDERR_FILENO, fork_err, sizeof(fork_err)-1);
|
||||
raise(signum);
|
||||
return;
|
||||
/* Fork off to start a crash handler */
|
||||
switch((dbg_pid=fork()))
|
||||
{
|
||||
/* Error */
|
||||
case -1:
|
||||
safe_write(STDERR_FILENO, fork_err, sizeof(fork_err)-1);
|
||||
raise(signum);
|
||||
return;
|
||||
|
||||
case 0:
|
||||
dup2(fd[0], STDIN_FILENO);
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
case 0:
|
||||
dup2(fd[0], STDIN_FILENO);
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
|
||||
execl(argv0, argv0, crash_switch, NULL);
|
||||
execl(argv0, argv0, crash_switch, NULL);
|
||||
|
||||
safe_write(STDERR_FILENO, exec_err, sizeof(exec_err)-1);
|
||||
_exit(1);
|
||||
safe_write(STDERR_FILENO, exec_err, sizeof(exec_err)-1);
|
||||
_exit(1);
|
||||
|
||||
default:
|
||||
default:
|
||||
#ifdef __linux__
|
||||
prctl(PR_SET_PTRACER, dbg_pid, 0, 0, 0);
|
||||
prctl(PR_SET_PTRACER, dbg_pid, 0, 0, 0);
|
||||
#endif
|
||||
safe_write(fd[1], &crash_info, sizeof(crash_info));
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
safe_write(fd[1], &crash_info, sizeof(crash_info));
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
|
||||
/* Wait; we'll be killed when gdb is done */
|
||||
do {
|
||||
int status;
|
||||
if(waitpid(dbg_pid, &status, 0) == dbg_pid &&
|
||||
(WIFEXITED(status) || WIFSIGNALED(status)))
|
||||
{
|
||||
/* The debug process died before it could kill us */
|
||||
raise(signum);
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
}
|
||||
/* Wait; we'll be killed when gdb is done */
|
||||
do {
|
||||
int status;
|
||||
if(waitpid(dbg_pid, &status, 0) == dbg_pid &&
|
||||
(WIFEXITED(status) || WIFSIGNALED(status)))
|
||||
{
|
||||
/* The debug process died before it could kill us */
|
||||
raise(signum);
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void crash_handler(const char *logfile)
|
||||
{
|
||||
const char *sigdesc = "";
|
||||
const char *sigdesc = "";
|
||||
int i;
|
||||
|
||||
if(fread(&crash_info, sizeof(crash_info), 1, stdin) != 1)
|
||||
{
|
||||
fprintf(stderr, "!!! Failed to retrieve info from crashed process\n");
|
||||
exit(1);
|
||||
}
|
||||
if(fread(&crash_info, sizeof(crash_info), 1, stdin) != 1)
|
||||
{
|
||||
fprintf(stderr, "!!! Failed to retrieve info from crashed process\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Get the signal description */
|
||||
for(i = 0;signals[i].name;++i)
|
||||
{
|
||||
if(signals[i].signum == crash_info.signum)
|
||||
{
|
||||
sigdesc = signals[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Get the signal description */
|
||||
for(i = 0;signals[i].name;++i)
|
||||
{
|
||||
if(signals[i].signum == crash_info.signum)
|
||||
{
|
||||
sigdesc = signals[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(crash_info.has_siginfo)
|
||||
{
|
||||
switch(crash_info.signum)
|
||||
{
|
||||
case SIGSEGV:
|
||||
for(i = 0;sigsegv_codes[i].name;++i)
|
||||
{
|
||||
if(sigsegv_codes[i].code == crash_info.siginfo.si_code)
|
||||
{
|
||||
sigdesc = sigsegv_codes[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
if(crash_info.has_siginfo)
|
||||
{
|
||||
switch(crash_info.signum)
|
||||
{
|
||||
case SIGSEGV:
|
||||
for(i = 0;sigsegv_codes[i].name;++i)
|
||||
{
|
||||
if(sigsegv_codes[i].code == crash_info.siginfo.si_code)
|
||||
{
|
||||
sigdesc = sigsegv_codes[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SIGFPE:
|
||||
for(i = 0;sigfpe_codes[i].name;++i)
|
||||
{
|
||||
if(sigfpe_codes[i].code == crash_info.siginfo.si_code)
|
||||
{
|
||||
sigdesc = sigfpe_codes[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SIGFPE:
|
||||
for(i = 0;sigfpe_codes[i].name;++i)
|
||||
{
|
||||
if(sigfpe_codes[i].code == crash_info.siginfo.si_code)
|
||||
{
|
||||
sigdesc = sigfpe_codes[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SIGILL:
|
||||
for(i = 0;sigill_codes[i].name;++i)
|
||||
{
|
||||
if(sigill_codes[i].code == crash_info.siginfo.si_code)
|
||||
{
|
||||
sigdesc = sigill_codes[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SIGILL:
|
||||
for(i = 0;sigill_codes[i].name;++i)
|
||||
{
|
||||
if(sigill_codes[i].code == crash_info.siginfo.si_code)
|
||||
{
|
||||
sigdesc = sigill_codes[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SIGBUS:
|
||||
for(i = 0;sigbus_codes[i].name;++i)
|
||||
{
|
||||
if(sigbus_codes[i].code == crash_info.siginfo.si_code)
|
||||
{
|
||||
sigdesc = sigbus_codes[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "%s (signal %i)\n", sigdesc, crash_info.signum);
|
||||
if(crash_info.has_siginfo)
|
||||
fprintf(stderr, "Address: %p\n", crash_info.siginfo.si_addr);
|
||||
fputc('\n', stderr);
|
||||
case SIGBUS:
|
||||
for(i = 0;sigbus_codes[i].name;++i)
|
||||
{
|
||||
if(sigbus_codes[i].code == crash_info.siginfo.si_code)
|
||||
{
|
||||
sigdesc = sigbus_codes[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "%s (signal %i)\n", sigdesc, crash_info.signum);
|
||||
if(crash_info.has_siginfo)
|
||||
fprintf(stderr, "Address: %p\n", crash_info.siginfo.si_addr);
|
||||
fputc('\n', stderr);
|
||||
|
||||
if(logfile)
|
||||
{
|
||||
/* Create crash log file and redirect shell output to it */
|
||||
if(freopen(logfile, "wa", stdout) != stdout)
|
||||
{
|
||||
fprintf(stderr, "!!! Could not create %s following signal\n", logfile);
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr, "Generating %s and killing process %d, please wait... ", logfile, crash_info.pid);
|
||||
if(logfile)
|
||||
{
|
||||
/* Create crash log file and redirect shell output to it */
|
||||
if(freopen(logfile, "wa", stdout) != stdout)
|
||||
{
|
||||
fprintf(stderr, "!!! Could not create %s following signal\n", logfile);
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr, "Generating %s and killing process %d, please wait... ", logfile, crash_info.pid);
|
||||
|
||||
printf("*** Fatal Error ***\n"
|
||||
"%s (signal %i)\n", sigdesc, crash_info.signum);
|
||||
if(crash_info.has_siginfo)
|
||||
printf("Address: %p\n", crash_info.siginfo.si_addr);
|
||||
fputc('\n', stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
printf("*** Fatal Error ***\n"
|
||||
"%s (signal %i)\n", sigdesc, crash_info.signum);
|
||||
if(crash_info.has_siginfo)
|
||||
printf("Address: %p\n", crash_info.siginfo.si_addr);
|
||||
fputc('\n', stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
sys_info();
|
||||
sys_info();
|
||||
|
||||
crash_info.buf[sizeof(crash_info.buf)-1] = '\0';
|
||||
printf("%s\n", crash_info.buf);
|
||||
fflush(stdout);
|
||||
crash_info.buf[sizeof(crash_info.buf)-1] = '\0';
|
||||
printf("%s\n", crash_info.buf);
|
||||
fflush(stdout);
|
||||
|
||||
if(crash_info.pid > 0)
|
||||
{
|
||||
gdb_info(crash_info.pid);
|
||||
kill(crash_info.pid, SIGKILL);
|
||||
}
|
||||
if(crash_info.pid > 0)
|
||||
{
|
||||
gdb_info(crash_info.pid);
|
||||
kill(crash_info.pid, SIGKILL);
|
||||
}
|
||||
|
||||
if(logfile)
|
||||
{
|
||||
if(logfile)
|
||||
{
|
||||
char cwd[MAXPATHLEN];
|
||||
getcwd(cwd, MAXPATHLEN);
|
||||
|
||||
std::string message = "OpenMW has encountered a fatal error.\nCrash log saved to '" + std::string(cwd) + "/" + std::string(logfile) + "'.\n Please report this to https://bugs.openmw.org !";
|
||||
SDL_ShowSimpleMessageBox(0, "Fatal Error", message.c_str(), NULL);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int cc_install_handlers(int argc, char **argv, int num_signals, int *signals, const char *logfile, int (*user_info)(char*, char*))
|
||||
{
|
||||
struct sigaction sa;
|
||||
stack_t altss;
|
||||
int retval;
|
||||
struct sigaction sa;
|
||||
stack_t altss;
|
||||
int retval;
|
||||
|
||||
if(argc == 2 && strcmp(argv[1], crash_switch) == 0)
|
||||
crash_handler(logfile);
|
||||
if(argc == 2 && strcmp(argv[1], crash_switch) == 0)
|
||||
crash_handler(logfile);
|
||||
|
||||
cc_user_info = user_info;
|
||||
cc_user_info = user_info;
|
||||
|
||||
if(argv[0][0] == '/')
|
||||
snprintf(argv0, sizeof(argv0), "%s", argv[0]);
|
||||
else
|
||||
{
|
||||
getcwd(argv0, sizeof(argv0));
|
||||
retval = strlen(argv0);
|
||||
snprintf(argv0+retval, sizeof(argv0)-retval, "/%s", argv[0]);
|
||||
}
|
||||
if(argv[0][0] == '/')
|
||||
snprintf(argv0, sizeof(argv0), "%s", argv[0]);
|
||||
else
|
||||
{
|
||||
getcwd(argv0, sizeof(argv0));
|
||||
retval = strlen(argv0);
|
||||
snprintf(argv0+retval, sizeof(argv0)-retval, "/%s", argv[0]);
|
||||
}
|
||||
|
||||
/* Set an alternate signal stack so SIGSEGVs caused by stack overflows
|
||||
* still run */
|
||||
altss.ss_sp = altstack;
|
||||
altss.ss_flags = 0;
|
||||
altss.ss_size = sizeof(altstack);
|
||||
sigaltstack(&altss, NULL);
|
||||
/* Set an alternate signal stack so SIGSEGVs caused by stack overflows
|
||||
* still run */
|
||||
altss.ss_sp = altstack;
|
||||
altss.ss_flags = 0;
|
||||
altss.ss_size = sizeof(altstack);
|
||||
sigaltstack(&altss, NULL);
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_sigaction = crash_catcher;
|
||||
sa.sa_flags = SA_RESETHAND | SA_NODEFER | SA_SIGINFO | SA_ONSTACK;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_sigaction = crash_catcher;
|
||||
sa.sa_flags = SA_RESETHAND | SA_NODEFER | SA_SIGINFO | SA_ONSTACK;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
|
||||
retval = 0;
|
||||
while(num_signals--)
|
||||
{
|
||||
retval = 0;
|
||||
while(num_signals--)
|
||||
{
|
||||
if((*signals != SIGSEGV && *signals != SIGILL && *signals != SIGFPE && *signals != SIGABRT &&
|
||||
*signals != SIGBUS) || sigaction(*signals, &sa, NULL) == -1)
|
||||
{
|
||||
*signals = 0;
|
||||
retval = -1;
|
||||
}
|
||||
++signals;
|
||||
}
|
||||
return retval;
|
||||
*signals != SIGBUS) || sigaction(*signals, &sa, NULL) == -1)
|
||||
{
|
||||
*signals = 0;
|
||||
retval = -1;
|
||||
}
|
||||
++signals;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -172,6 +172,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
|||
//kindly ask SDL not to trash our OGL context
|
||||
//might this be related to http://bugzilla.libsdl.org/show_bug.cgi?id=748 ?
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
|
||||
SDL_SetMainReady();
|
||||
if(SDL_Init(flags) != 0)
|
||||
{
|
||||
throw std::runtime_error("Could not initialize SDL! " + std::string(SDL_GetError()));
|
||||
|
@ -534,13 +535,13 @@ void OMW::Engine::activate()
|
|||
MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr);
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> action =
|
||||
MWWorld::Class::get (ptr).activate (ptr, MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
MWWorld::Class::get (ptr).activate (ptr, MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||
|
||||
interpreterContext.activate (ptr, action);
|
||||
|
||||
std::string script = MWWorld::Class::get (ptr).getScript (ptr);
|
||||
|
||||
MWBase::Environment::get().getWorld()->breakInvisibility(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
MWBase::Environment::get().getWorld()->breakInvisibility(MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||
|
||||
if (!script.empty())
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <boost/iostreams/stream_buffer.hpp>
|
||||
|
||||
// For OutputDebugString
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
// makes __argc and __argv available on windows
|
||||
#include <cstdlib>
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace MWBase
|
|||
|
||||
virtual void persuade (int type) = 0;
|
||||
virtual int getTemporaryDispositionChange () const = 0;
|
||||
virtual void applyTemporaryDispositionChange (int delta) = 0;
|
||||
virtual void applyDispositionChange (int delta) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -76,8 +76,12 @@ namespace MWBase
|
|||
virtual void setPlayerClass (const ESM::Class& class_) = 0;
|
||||
///< Set player class to custom class.
|
||||
|
||||
virtual void restoreDynamicStats() = 0;
|
||||
///< If the player is sleeping, this should be called every hour.
|
||||
virtual void rest(bool sleep) = 0;
|
||||
///< If the player is sleeping or waiting, this should be called every hour.
|
||||
/// @param sleep is the player sleeping or waiting?
|
||||
|
||||
virtual int getHoursToRest() const = 0;
|
||||
///< Calculate how many hours the player needs to rest in order to be fully healed
|
||||
|
||||
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.
|
||||
|
@ -88,6 +92,36 @@ namespace MWBase
|
|||
virtual int countDeaths (const std::string& id) const = 0;
|
||||
///< Return the number of deaths for actors with the given ID.
|
||||
|
||||
/// Check if \a observer is potentially aware of \a ptr. Does not do a line of sight check!
|
||||
virtual bool awarenessCheck (const MWWorld::Ptr& ptr, const MWWorld::Ptr& observer) = 0;
|
||||
|
||||
enum OffenseType
|
||||
{
|
||||
OT_Theft, // Taking items owned by an NPC or a faction you are not a member of
|
||||
OT_Assault, // Attacking a peaceful NPC
|
||||
OT_Murder, // Murdering a peaceful NPC
|
||||
OT_Trespassing, // Staying in a cell you are not allowed in (where is this defined?)
|
||||
OT_SleepingInOwnedBed, // Sleeping in a bed owned by an NPC or a faction you are not a member of
|
||||
OT_Pickpocket // Entering pickpocket mode, leaving it, and being detected. Any items stolen are a separate crime (Theft)
|
||||
};
|
||||
/**
|
||||
* @brief Commit a crime. If any actors witness the crime and report it,
|
||||
* reportCrime will be called automatically.
|
||||
* @param arg Depends on \a type, e.g. for Theft, the value of the item that was stolen.
|
||||
* @return was the crime reported?
|
||||
*/
|
||||
virtual bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim,
|
||||
OffenseType type, int arg=0) = 0;
|
||||
virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim,
|
||||
OffenseType type, int arg=0) = 0;
|
||||
/// Utility to check if taking this item is illegal and calling commitCrime if so
|
||||
virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count) = 0;
|
||||
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so
|
||||
virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) = 0;
|
||||
/// Attempt sleeping in a bed. If this is illegal, call commitCrime.
|
||||
/// @return was it illegal, and someone saw you doing it?
|
||||
virtual bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed) = 0;
|
||||
|
||||
enum PersuasionType
|
||||
{
|
||||
PT_Admire,
|
||||
|
|
|
@ -227,9 +227,6 @@ namespace MWBase
|
|||
virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons = std::vector<std::string>(), bool showInDialogueModeOnly = false) = 0;
|
||||
virtual void staticMessageBox(const std::string& message) = 0;
|
||||
virtual void removeStaticMessageBox() = 0;
|
||||
|
||||
virtual void enterPressed () = 0;
|
||||
virtual void activateKeyPressed () = 0;
|
||||
virtual int readPressedButton() = 0;
|
||||
///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox)
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ namespace ESM
|
|||
|
||||
namespace MWRender
|
||||
{
|
||||
class ExternalRendering;
|
||||
class Animation;
|
||||
}
|
||||
|
||||
|
@ -127,6 +126,7 @@ namespace MWBase
|
|||
virtual const MWWorld::Fallback *getFallback () const = 0;
|
||||
|
||||
virtual MWWorld::Player& getPlayer() = 0;
|
||||
virtual MWWorld::Ptr getPlayerPtr() = 0;
|
||||
|
||||
virtual const MWWorld::ESMStore& getStore() const = 0;
|
||||
|
||||
|
@ -181,6 +181,10 @@ namespace MWBase
|
|||
///< Return a pointer to a liveCellRef with the given name.
|
||||
/// \param activeOnly do non search inactive cells.
|
||||
|
||||
virtual MWWorld::Ptr searchPtr (const std::string& name, bool activeOnly) = 0;
|
||||
///< Return a pointer to a liveCellRef with the given name.
|
||||
/// \param activeOnly do non search inactive cells.
|
||||
|
||||
virtual MWWorld::Ptr getPtrViaHandle (const std::string& handle) = 0;
|
||||
///< Return a pointer to a liveCellRef with the given Ogre handle.
|
||||
|
||||
|
@ -396,8 +400,6 @@ namespace MWBase
|
|||
|
||||
virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0;
|
||||
|
||||
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0;
|
||||
|
||||
virtual int canRest() = 0;
|
||||
///< check if the player is allowed to rest \n
|
||||
/// 0 - yes \n
|
||||
|
@ -466,11 +468,10 @@ namespace MWBase
|
|||
|
||||
virtual bool findInteriorPositionInWorldSpace(MWWorld::CellStore* cell, Ogre::Vector3& result) = 0;
|
||||
|
||||
/// Teleports \a ptr to the reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
||||
/// closest to \a worldPos.
|
||||
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
||||
/// @note id must be lower case
|
||||
virtual void teleportToClosestMarker (const MWWorld::Ptr& ptr,
|
||||
const std::string& id, Ogre::Vector3 worldPos) = 0;
|
||||
const std::string& id) = 0;
|
||||
|
||||
enum DetectionType
|
||||
{
|
||||
|
@ -483,6 +484,21 @@ namespace MWBase
|
|||
/// @note This also works for references in containers.
|
||||
virtual void listDetectedReferences (const MWWorld::Ptr& ptr, std::vector<MWWorld::Ptr>& out,
|
||||
DetectionType type) = 0;
|
||||
|
||||
/// Update the value of some globals according to the world state, which may be used by dialogue entries.
|
||||
/// This should be called when initiating a dialogue.
|
||||
virtual void updateDialogueGlobals() = 0;
|
||||
|
||||
/// Moves all stolen items from \a ptr to the closest evidence chest.
|
||||
virtual void confiscateStolenItems(const MWWorld::Ptr& ptr) = 0;
|
||||
|
||||
virtual void goToJail () = 0;
|
||||
|
||||
/// Spawn a random creature from a levelled list next to the player
|
||||
virtual void spawnRandomCreature(const std::string& creatureList) = 0;
|
||||
|
||||
/// Spawn a blood effect for \a ptr at \a worldPosition
|
||||
virtual void spawnBloodEffect (const MWWorld::Ptr& ptr, const Ogre::Vector3& worldPosition) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -96,7 +96,11 @@ namespace MWClass
|
|||
|
||||
std::string text;
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||
{
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||
}
|
||||
info.text = text;
|
||||
|
||||
return info;
|
||||
|
|
|
@ -128,6 +128,7 @@ namespace MWClass
|
|||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||
}
|
||||
info.text = text;
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "../mwworld/physicssystem.hpp"
|
||||
#include "../mwworld/nullaction.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
#include "../mwrender/renderinginterface.hpp"
|
||||
|
@ -252,6 +251,7 @@ namespace MWClass
|
|||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||
}
|
||||
|
||||
|
|
|
@ -140,6 +140,7 @@ namespace MWClass
|
|||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/physicssystem.hpp"
|
||||
#include "../mwworld/nullaction.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
|
@ -195,6 +194,7 @@ namespace MWClass
|
|||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "../mwworld/actionopen.hpp"
|
||||
#include "../mwworld/actiontrap.hpp"
|
||||
#include "../mwworld/physicssystem.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
@ -53,7 +52,7 @@ namespace MWClass
|
|||
ptr.get<ESM::Container>();
|
||||
|
||||
data->mContainerStore.fill(
|
||||
ref->mBase->mInventory, ptr.getCellRef().mOwner, MWBase::Environment::get().getWorld()->getStore());
|
||||
ref->mBase->mInventory, ptr.getCellRef().mOwner, ptr.getCellRef().mFaction, MWBase::Environment::get().getWorld()->getStore());
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
|
@ -108,7 +107,7 @@ namespace MWClass
|
|||
const std::string lockedSound = "LockedChest";
|
||||
const std::string trapActivationSound = "Disarm Trap Fail";
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(player).getInventoryStore(player);
|
||||
|
||||
bool needKey = ptr.getCellRef().mLockLevel>0;
|
||||
|
@ -216,6 +215,7 @@ namespace MWClass
|
|||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,17 @@ namespace MWClass
|
|||
|
||||
fMinWalkSpeedCreature = gmst.find("fMinWalkSpeedCreature");
|
||||
fMaxWalkSpeedCreature = gmst.find("fMaxWalkSpeedCreature");
|
||||
fEncumberedMoveEffect = gmst.find("fEncumberedMoveEffect");
|
||||
fSneakSpeedMultiplier = gmst.find("fSneakSpeedMultiplier");
|
||||
fAthleticsRunBonus = gmst.find("fAthleticsRunBonus");
|
||||
fBaseRunMultiplier = gmst.find("fBaseRunMultiplier");
|
||||
fMinFlySpeed = gmst.find("fMinFlySpeed");
|
||||
fMaxFlySpeed = gmst.find("fMaxFlySpeed");
|
||||
fSwimRunBase = gmst.find("fSwimRunBase");
|
||||
fSwimRunAthleticsMult = gmst.find("fSwimRunAthleticsMult");
|
||||
fKnockDownMult = gmst.find("fKnockDownMult");
|
||||
iKnockDownOddsMult = gmst.find("iKnockDownOddsMult");
|
||||
iKnockDownOddsBase = gmst.find("iKnockDownOddsBase");
|
||||
|
||||
inited = true;
|
||||
}
|
||||
|
@ -95,10 +106,12 @@ namespace MWClass
|
|||
data->mCreatureStats.getSpells().add (*iter);
|
||||
|
||||
// inventory
|
||||
data->mContainerStore.fill(ref->mBase->mInventory, getId(ptr),
|
||||
data->mContainerStore.fill(ref->mBase->mInventory, getId(ptr), "",
|
||||
MWBase::Environment::get().getWorld()->getStore());
|
||||
|
||||
data->mContainerStore.add("gold_001", ref->mBase->mData.mGold, ptr);
|
||||
// TODO: this is not quite correct, in vanilla the merchant's gold pool is not available in his inventory.
|
||||
// (except for gold you gave him)
|
||||
data->mContainerStore.add(MWWorld::ContainerStore::sGoldId, ref->mBase->mData.mGold, ptr);
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
|
@ -163,6 +176,62 @@ namespace MWClass
|
|||
|
||||
void Creature::hit(const MWWorld::Ptr& ptr, int type) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Creature> *ref =
|
||||
ptr.get<ESM::Creature>();
|
||||
|
||||
// TODO: where is the distance defined?
|
||||
std::pair<MWWorld::Ptr, Ogre::Vector3> result = MWBase::Environment::get().getWorld()->getHitContact(ptr, 100);
|
||||
if (result.first.isEmpty())
|
||||
return; // Didn't hit anything
|
||||
|
||||
MWWorld::Ptr victim = result.first;
|
||||
|
||||
if (!victim.getClass().isActor())
|
||||
return; // Can't hit non-actors
|
||||
|
||||
Ogre::Vector3 hitPosition = result.second;
|
||||
|
||||
MWMechanics::CreatureStats &stats = getCreatureStats(ptr);
|
||||
MWMechanics::CreatureStats &otherstats = victim.getClass().getCreatureStats(victim);
|
||||
const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects();
|
||||
float hitchance = ref->mBase->mData.mCombat +
|
||||
(stats.getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) +
|
||||
(stats.getAttribute(ESM::Attribute::Luck).getModified() / 10.0f);
|
||||
hitchance *= stats.getFatigueTerm();
|
||||
hitchance += mageffects.get(ESM::MagicEffect::FortifyAttack).mMagnitude -
|
||||
mageffects.get(ESM::MagicEffect::Blind).mMagnitude;
|
||||
hitchance -= otherstats.getEvasion();
|
||||
|
||||
if((::rand()/(RAND_MAX+1.0)) > hitchance/100.0f)
|
||||
{
|
||||
victim.getClass().onHit(victim, 0.0f, false, MWWorld::Ptr(), ptr, false);
|
||||
return;
|
||||
}
|
||||
|
||||
int min,max;
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
min = ref->mBase->mData.mAttack[0];
|
||||
max = ref->mBase->mData.mAttack[1];
|
||||
break;
|
||||
case 1:
|
||||
min = ref->mBase->mData.mAttack[2];
|
||||
max = ref->mBase->mData.mAttack[3];
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
min = ref->mBase->mData.mAttack[4];
|
||||
max = ref->mBase->mData.mAttack[5];
|
||||
break;
|
||||
}
|
||||
|
||||
float damage = min + (max - min) * ::rand()/(RAND_MAX+1.0);
|
||||
|
||||
// TODO: do not do this if the attack is blocked
|
||||
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition);
|
||||
|
||||
victim.getClass().onHit(victim, damage, true, MWWorld::Ptr(), ptr, true);
|
||||
}
|
||||
|
||||
void Creature::onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, bool successful) const
|
||||
|
@ -189,6 +258,19 @@ namespace MWClass
|
|||
ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1);
|
||||
}
|
||||
|
||||
// Check for knockdown
|
||||
float agilityTerm = getCreatureStats(ptr).getAttribute(ESM::Attribute::Agility).getModified() * fKnockDownMult->getFloat();
|
||||
float knockdownTerm = getCreatureStats(ptr).getAttribute(ESM::Attribute::Agility).getModified()
|
||||
* iKnockDownOddsMult->getInt() * 0.01 + iKnockDownOddsBase->getInt();
|
||||
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
|
||||
if (ishealth && agilityTerm <= damage && knockdownTerm <= roll)
|
||||
{
|
||||
getCreatureStats(ptr).setKnockedDown(true);
|
||||
|
||||
}
|
||||
else
|
||||
getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur?
|
||||
|
||||
if(ishealth)
|
||||
{
|
||||
if(damage > 0.0f)
|
||||
|
@ -284,10 +366,51 @@ namespace MWClass
|
|||
float Creature::getSpeed(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
|
||||
|
||||
float walkSpeed = fMinWalkSpeedCreature->getFloat() + 0.01 * stats.getAttribute(ESM::Attribute::Speed).getModified()
|
||||
* (fMaxWalkSpeedCreature->getFloat() - fMinWalkSpeedCreature->getFloat());
|
||||
/// \todo what about the rest?
|
||||
return walkSpeed;
|
||||
|
||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects();
|
||||
|
||||
const float normalizedEncumbrance = getEncumbrance(ptr) / getCapacity(ptr);
|
||||
|
||||
bool running = ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run);
|
||||
|
||||
float runSpeed = walkSpeed*(0.01f * getSkill(ptr, ESM::Skill::Athletics) *
|
||||
fAthleticsRunBonus->getFloat() + fBaseRunMultiplier->getFloat());
|
||||
|
||||
float moveSpeed;
|
||||
if(normalizedEncumbrance >= 1.0f)
|
||||
moveSpeed = 0.0f;
|
||||
else if(mageffects.get(ESM::MagicEffect::Levitate).mMagnitude > 0 &&
|
||||
world->isLevitationEnabled())
|
||||
{
|
||||
float flySpeed = 0.01f*(stats.getAttribute(ESM::Attribute::Speed).getModified() +
|
||||
mageffects.get(ESM::MagicEffect::Levitate).mMagnitude);
|
||||
flySpeed = fMinFlySpeed->getFloat() + flySpeed*(fMaxFlySpeed->getFloat() - fMinFlySpeed->getFloat());
|
||||
flySpeed *= 1.0f - fEncumberedMoveEffect->getFloat() * normalizedEncumbrance;
|
||||
flySpeed = std::max(0.0f, flySpeed);
|
||||
moveSpeed = flySpeed;
|
||||
}
|
||||
else if(world->isSwimming(ptr))
|
||||
{
|
||||
float swimSpeed = walkSpeed;
|
||||
if(running)
|
||||
swimSpeed = runSpeed;
|
||||
swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).mMagnitude;
|
||||
swimSpeed *= fSwimRunBase->getFloat() + 0.01f*getSkill(ptr, ESM::Skill::Athletics) *
|
||||
fSwimRunAthleticsMult->getFloat();
|
||||
moveSpeed = swimSpeed;
|
||||
}
|
||||
else if(running)
|
||||
moveSpeed = runSpeed;
|
||||
else
|
||||
moveSpeed = walkSpeed;
|
||||
if(getMovementSettings(ptr).mPosition[0] != 0 && getMovementSettings(ptr).mPosition[1] == 0)
|
||||
moveSpeed *= 0.75f;
|
||||
|
||||
return moveSpeed;
|
||||
}
|
||||
|
||||
MWMechanics::Movement& Creature::getMovementSettings (const MWWorld::Ptr& ptr) const
|
||||
|
@ -459,6 +582,49 @@ namespace MWClass
|
|||
throw std::runtime_error(std::string("Unexpected soundgen type: ")+name);
|
||||
}
|
||||
|
||||
int Creature::getSkill(const MWWorld::Ptr &ptr, int skill) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Creature> *ref =
|
||||
ptr.get<ESM::Creature>();
|
||||
|
||||
const ESM::Skill* skillRecord = MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find(skill);
|
||||
|
||||
switch (skillRecord->mData.mSpecialization)
|
||||
{
|
||||
case ESM::Class::Combat:
|
||||
return ref->mBase->mData.mCombat;
|
||||
case ESM::Class::Magic:
|
||||
return ref->mBase->mData.mMagic;
|
||||
case ESM::Class::Stealth:
|
||||
return ref->mBase->mData.mStealth;
|
||||
default:
|
||||
throw std::runtime_error("invalid specialisation");
|
||||
}
|
||||
}
|
||||
|
||||
int Creature::getBloodTexture(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
|
||||
|
||||
if (ref->mBase->mFlags & ESM::Creature::Skeleton)
|
||||
return 1;
|
||||
if (ref->mBase->mFlags & ESM::Creature::Metal)
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const ESM::GameSetting* Creature::fMinWalkSpeedCreature;
|
||||
const ESM::GameSetting* Creature::fMaxWalkSpeedCreature;
|
||||
const ESM::GameSetting *Creature::fEncumberedMoveEffect;
|
||||
const ESM::GameSetting *Creature::fSneakSpeedMultiplier;
|
||||
const ESM::GameSetting *Creature::fAthleticsRunBonus;
|
||||
const ESM::GameSetting *Creature::fBaseRunMultiplier;
|
||||
const ESM::GameSetting *Creature::fMinFlySpeed;
|
||||
const ESM::GameSetting *Creature::fMaxFlySpeed;
|
||||
const ESM::GameSetting *Creature::fSwimRunBase;
|
||||
const ESM::GameSetting *Creature::fSwimRunAthleticsMult;
|
||||
const ESM::GameSetting *Creature::fKnockDownMult;
|
||||
const ESM::GameSetting *Creature::iKnockDownOddsMult;
|
||||
const ESM::GameSetting *Creature::iKnockDownOddsBase;
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,18 @@ namespace MWClass
|
|||
|
||||
static const ESM::GameSetting *fMinWalkSpeedCreature;
|
||||
static const ESM::GameSetting *fMaxWalkSpeedCreature;
|
||||
static const ESM::GameSetting *fEncumberedMoveEffect;
|
||||
static const ESM::GameSetting *fSneakSpeedMultiplier;
|
||||
static const ESM::GameSetting *fAthleticsRunBonus;
|
||||
static const ESM::GameSetting *fBaseRunMultiplier;
|
||||
static const ESM::GameSetting *fMinFlySpeed;
|
||||
static const ESM::GameSetting *fMaxFlySpeed;
|
||||
static const ESM::GameSetting *fSwimRunBase;
|
||||
static const ESM::GameSetting *fSwimRunAthleticsMult;
|
||||
static const ESM::GameSetting *fKnockDownMult;
|
||||
static const ESM::GameSetting *iKnockDownOddsMult;
|
||||
static const ESM::GameSetting *iKnockDownOddsBase;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
@ -101,6 +113,11 @@ namespace MWClass
|
|||
}
|
||||
|
||||
virtual bool isFlying (const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual int getSkill(const MWWorld::Ptr &ptr, int skill) const;
|
||||
|
||||
/// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini)
|
||||
virtual int getBloodTexture (const MWWorld::Ptr& ptr) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/soundmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/nullaction.hpp"
|
||||
#include "../mwworld/failedaction.hpp"
|
||||
|
@ -97,7 +96,7 @@ namespace MWClass
|
|||
|
||||
if (needKey && hasKey)
|
||||
{
|
||||
if(actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer())
|
||||
if(actor == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||
MWBase::Environment::get().getWindowManager()->messageBox(keyName + " #{sKeyUsed}");
|
||||
ptr.getCellRef().mLockLevel = 0;
|
||||
// using a key disarms the trap
|
||||
|
@ -118,7 +117,7 @@ namespace MWClass
|
|||
{
|
||||
// teleport door
|
||||
/// \todo remove this if clause once ActionTeleport can also support other actors
|
||||
if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()==actor)
|
||||
if (MWBase::Environment::get().getWorld()->getPlayerPtr()==actor)
|
||||
{
|
||||
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport (ref->mRef.mDestCell, ref->mRef.mDoorDest));
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/physicssystem.hpp"
|
||||
#include "../mwworld/actioneat.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/nullaction.hpp"
|
||||
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
@ -149,10 +148,11 @@ namespace MWClass
|
|||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||
}
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||
int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase();
|
||||
|
||||
|
|
|
@ -187,6 +187,7 @@ namespace MWClass
|
|||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||
}
|
||||
|
||||
|
|
|
@ -145,6 +145,7 @@ namespace MWClass
|
|||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||
}
|
||||
|
||||
|
|
|
@ -93,7 +93,9 @@ namespace MWClass
|
|||
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
||||
ptr.get<ESM::Miscellaneous>();
|
||||
|
||||
int value = (ptr.getCellRef().mGoldValue == 1) ? ref->mBase->mData.mValue : ptr.getCellRef().mGoldValue;
|
||||
int value = ref->mBase->mData.mValue;
|
||||
if (ptr.getCellRef().mGoldValue > 1 && ptr.getRefData().getCount() == 1)
|
||||
value = ptr.getCellRef().mGoldValue;
|
||||
|
||||
if (ptr.getCellRef().mSoul != "")
|
||||
{
|
||||
|
@ -184,6 +186,7 @@ namespace MWClass
|
|||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <OgreSceneNode.h>
|
||||
|
||||
#include <components/esm/loadmgef.hpp>
|
||||
|
@ -242,6 +240,9 @@ namespace MWClass
|
|||
fJumpAcroMultiplier = gmst.find("fJumpAcroMultiplier");
|
||||
fJumpRunMultiplier = gmst.find("fJumpRunMultiplier");
|
||||
fWereWolfRunMult = gmst.find("fWereWolfRunMult");
|
||||
fKnockDownMult = gmst.find("fKnockDownMult");
|
||||
iKnockDownOddsMult = gmst.find("iKnockDownOddsMult");
|
||||
iKnockDownOddsBase = gmst.find("iKnockDownOddsBase");
|
||||
|
||||
inited = true;
|
||||
}
|
||||
|
@ -307,6 +308,17 @@ namespace MWClass
|
|||
autoCalculateSkills(ref->mBase, data->mNpcStats);
|
||||
}
|
||||
|
||||
if (data->mNpcStats.getFactionRanks().size())
|
||||
{
|
||||
static const int iAutoRepFacMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||
.find("iAutoRepFacMod")->getInt();
|
||||
static const int iAutoRepLevMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||
.find("iAutoRepLevMod")->getInt();
|
||||
int rank = data->mNpcStats.getFactionRanks().begin()->second;
|
||||
|
||||
data->mNpcStats.setReputation(iAutoRepFacMod * (rank+1) + iAutoRepLevMod * (data->mNpcStats.getLevel()-1));
|
||||
}
|
||||
|
||||
data->mNpcStats.getAiSequence().fill(ref->mBase->mAiPackage);
|
||||
|
||||
data->mNpcStats.setAiSetting (MWMechanics::CreatureStats::AI_Hello, ref->mBase->mAiData.mHello);
|
||||
|
@ -320,13 +332,15 @@ namespace MWClass
|
|||
data->mNpcStats.getSpells().add (*iter);
|
||||
|
||||
// inventory
|
||||
data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr),
|
||||
data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr), "",
|
||||
MWBase::Environment::get().getWorld()->getStore());
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
|
||||
getContainerStore(ptr).add("gold_001", gold, ptr);
|
||||
// TODO: this is not quite correct, in vanilla the merchant's gold pool is not available in his inventory.
|
||||
// (except for gold you gave him)
|
||||
getContainerStore(ptr).add(MWWorld::ContainerStore::sGoldId, gold, ptr);
|
||||
|
||||
getInventoryStore(ptr).autoEquip(ptr);
|
||||
}
|
||||
|
@ -423,11 +437,27 @@ namespace MWClass
|
|||
if(!weapon.isEmpty() && weapon.getTypeName() != typeid(ESM::Weapon).name())
|
||||
weapon = MWWorld::Ptr();
|
||||
|
||||
// Reduce fatigue
|
||||
// somewhat of a guess, but using the weapon weight makes sense
|
||||
const float fFatigueAttackBase = gmst.find("fFatigueAttackBase")->getFloat();
|
||||
const float fFatigueAttackMult = gmst.find("fFatigueAttackMult")->getFloat();
|
||||
const float fWeaponFatigueMult = gmst.find("fWeaponFatigueMult")->getFloat();
|
||||
MWMechanics::DynamicStat<float> fatigue = getCreatureStats(ptr).getFatigue();
|
||||
const float normalizedEncumbrance = getEncumbrance(ptr) / getCapacity(ptr);
|
||||
float fatigueLoss = fFatigueAttackBase + normalizedEncumbrance * fFatigueAttackMult;
|
||||
if (!weapon.isEmpty())
|
||||
fatigueLoss += weapon.getClass().getWeight(weapon) * getNpcStats(ptr).getAttackStrength() * fWeaponFatigueMult;
|
||||
fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss);
|
||||
getCreatureStats(ptr).setFatigue(fatigue);
|
||||
|
||||
|
||||
float dist = 100.0f * (!weapon.isEmpty() ?
|
||||
weapon.get<ESM::Weapon>()->mBase->mData.mReach :
|
||||
gmst.find("fHandToHandReach")->getFloat());
|
||||
// TODO: Use second to work out the hit angle and where to spawn the blood effect
|
||||
MWWorld::Ptr victim = world->getHitContact(ptr, dist).first;
|
||||
// TODO: Use second to work out the hit angle
|
||||
std::pair<MWWorld::Ptr, Ogre::Vector3> result = world->getHitContact(ptr, dist);
|
||||
MWWorld::Ptr victim = result.first;
|
||||
Ogre::Vector3 hitPosition = result.second;
|
||||
if(victim.isEmpty()) // Didn't hit anything
|
||||
return;
|
||||
|
||||
|
@ -484,12 +514,6 @@ namespace MWClass
|
|||
weapon.getCellRef().mCharge = weapmaxhealth;
|
||||
damage *= float(weapon.getCellRef().mCharge) / weapmaxhealth;
|
||||
}
|
||||
if(!othercls.hasDetected(victim, ptr))
|
||||
{
|
||||
damage *= gmst.find("fCombatCriticalStrikeMult")->getFloat();
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}");
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
if (!MWBase::Environment::get().getWorld()->getGodModeState())
|
||||
weapon.getCellRef().mCharge -= std::min(std::max(1,
|
||||
|
@ -511,12 +535,6 @@ namespace MWClass
|
|||
float maxstrike = gmst.find("fMaxHandToHandMult")->getFloat();
|
||||
damage = stats.getSkill(weapskill).getModified();
|
||||
damage *= minstrike + ((maxstrike-minstrike)*stats.getAttackStrength());
|
||||
if(!othercls.hasDetected(victim, ptr))
|
||||
{
|
||||
damage *= gmst.find("fCombatCriticalStrikeMult")->getFloat();
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}");
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
healthdmg = (otherstats.getFatigue().getCurrent() < 1.0f)
|
||||
|| (otherstats.getMagicEffects().get(ESM::MagicEffect::Paralyze).mMagnitude > 0);
|
||||
|
@ -543,6 +561,16 @@ namespace MWClass
|
|||
if(ptr.getRefData().getHandle() == "player")
|
||||
skillUsageSucceeded(ptr, weapskill, 0);
|
||||
|
||||
bool detected = MWBase::Environment::get().getMechanicsManager()->awarenessCheck(ptr, victim);
|
||||
if(!detected)
|
||||
{
|
||||
damage *= gmst.find("fCombatCriticalStrikeMult")->getFloat();
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}");
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f);
|
||||
}
|
||||
if (othercls.getCreatureStats(victim).getKnockedDown())
|
||||
damage *= gmst.find("fCombatKODamageMult")->getFloat();
|
||||
|
||||
// Apply "On hit" enchanted weapons
|
||||
std::string enchantmentName = !weapon.isEmpty() ? weapon.getClass().getEnchantment(weapon) : "";
|
||||
if (!enchantmentName.empty())
|
||||
|
@ -576,6 +604,10 @@ namespace MWClass
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: do not do this if the attack is blocked
|
||||
if (healthdmg)
|
||||
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition);
|
||||
|
||||
othercls.onHit(victim, damage, healthdmg, weapon, ptr, true);
|
||||
}
|
||||
|
||||
|
@ -585,6 +617,10 @@ namespace MWClass
|
|||
|
||||
// NOTE: 'object' and/or 'attacker' may be empty.
|
||||
|
||||
// Attacking peaceful NPCs is a crime
|
||||
if (!attacker.isEmpty() && ptr.getClass().isNpc() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30)
|
||||
MWBase::Environment::get().getMechanicsManager()->commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault);
|
||||
|
||||
if(!successful)
|
||||
{
|
||||
// TODO: Handle HitAttemptOnMe script function
|
||||
|
@ -599,7 +635,7 @@ namespace MWClass
|
|||
|
||||
if(!attacker.isEmpty() && attacker.getRefData().getHandle() == "player")
|
||||
{
|
||||
const std::string &script = ptr.get<ESM::NPC>()->mBase->mScript;
|
||||
const std::string &script = ptr.getClass().getScript(ptr);
|
||||
/* Set the OnPCHitMe script variable. The script is responsible for clearing it. */
|
||||
if(!script.empty())
|
||||
ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1);
|
||||
|
@ -613,7 +649,27 @@ namespace MWClass
|
|||
// 'ptr' is losing health. Play a 'hit' voiced dialog entry if not already saying
|
||||
// something, alert the character controller, scripts, etc.
|
||||
|
||||
MWBase::Environment::get().getDialogueManager()->say(ptr, "thief");
|
||||
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||
int chance = store.get<ESM::GameSetting>().find("iVoiceHitOdds")->getInt();
|
||||
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
|
||||
if (roll < chance)
|
||||
{
|
||||
MWBase::Environment::get().getDialogueManager()->say(ptr, "hit");
|
||||
}
|
||||
getCreatureStats(ptr).setAttacked(true);
|
||||
|
||||
// Check for knockdown
|
||||
float agilityTerm = getCreatureStats(ptr).getAttribute(ESM::Attribute::Agility).getModified() * fKnockDownMult->getFloat();
|
||||
float knockdownTerm = getCreatureStats(ptr).getAttribute(ESM::Attribute::Agility).getModified()
|
||||
* iKnockDownOddsMult->getInt() * 0.01 + iKnockDownOddsBase->getInt();
|
||||
roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
|
||||
if (ishealth && agilityTerm <= damage && knockdownTerm <= roll)
|
||||
{
|
||||
getCreatureStats(ptr).setKnockedDown(true);
|
||||
|
||||
}
|
||||
else
|
||||
getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur?
|
||||
|
||||
if(object.isEmpty())
|
||||
{
|
||||
|
@ -725,10 +781,10 @@ namespace MWClass
|
|||
}
|
||||
if(getCreatureStats(ptr).isDead())
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr, true));
|
||||
if(get(actor).getStance(actor, MWWorld::Class::Sneak))
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr)); // stealing
|
||||
if(get(ptr).getCreatureStats(ptr).isHostile())
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::FailedAction("#{sActorInCombat}"));
|
||||
if(getCreatureStats(actor).getStance(MWMechanics::CreatureStats::Stance_Sneak))
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr)); // stealing
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionTalk(ptr));
|
||||
}
|
||||
|
||||
|
@ -756,80 +812,6 @@ namespace MWClass
|
|||
return ref->mBase->mScript;
|
||||
}
|
||||
|
||||
void Npc::setForceStance (const MWWorld::Ptr& ptr, Stance stance, bool force) const
|
||||
{
|
||||
MWMechanics::NpcStats& stats = getNpcStats (ptr);
|
||||
|
||||
switch (stance)
|
||||
{
|
||||
case Run:
|
||||
|
||||
stats.setMovementFlag (MWMechanics::NpcStats::Flag_ForceRun, force);
|
||||
break;
|
||||
|
||||
case Sneak:
|
||||
|
||||
stats.setMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak, force);
|
||||
break;
|
||||
|
||||
case Combat:
|
||||
|
||||
throw std::runtime_error ("combat stance not enforcable for NPCs");
|
||||
}
|
||||
}
|
||||
|
||||
void Npc::setStance (const MWWorld::Ptr& ptr, Stance stance, bool set) const
|
||||
{
|
||||
MWMechanics::NpcStats& stats = getNpcStats (ptr);
|
||||
|
||||
switch (stance)
|
||||
{
|
||||
case Run:
|
||||
|
||||
stats.setMovementFlag (MWMechanics::NpcStats::Flag_Run, set);
|
||||
break;
|
||||
|
||||
case Sneak:
|
||||
|
||||
stats.setMovementFlag (MWMechanics::NpcStats::Flag_Sneak, set);
|
||||
break;
|
||||
|
||||
case Combat:
|
||||
|
||||
// Combat stance ignored for now; need to be determined based on draw state instead of
|
||||
// being maunally set.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Npc::getStance (const MWWorld::Ptr& ptr, Stance stance, bool ignoreForce) const
|
||||
{
|
||||
MWMechanics::NpcStats& stats = getNpcStats (ptr);
|
||||
|
||||
switch (stance)
|
||||
{
|
||||
case Run:
|
||||
|
||||
if (!ignoreForce && stats.getMovementFlag (MWMechanics::NpcStats::Flag_ForceRun))
|
||||
return true;
|
||||
|
||||
return stats.getMovementFlag (MWMechanics::NpcStats::Flag_Run);
|
||||
|
||||
case Sneak:
|
||||
|
||||
if (!ignoreForce && stats.getMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak))
|
||||
return true;
|
||||
|
||||
return stats.getMovementFlag (MWMechanics::NpcStats::Flag_Sneak);
|
||||
|
||||
case Combat:
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
float Npc::getSpeed(const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
|
@ -838,11 +820,14 @@ namespace MWClass
|
|||
|
||||
const float normalizedEncumbrance = Npc::getEncumbrance(ptr) / Npc::getCapacity(ptr);
|
||||
|
||||
bool sneaking = ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Sneak);
|
||||
bool running = ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run);
|
||||
|
||||
float walkSpeed = fMinWalkSpeed->getFloat() + 0.01f*npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified()*
|
||||
(fMaxWalkSpeed->getFloat() - fMinWalkSpeed->getFloat());
|
||||
walkSpeed *= 1.0f - fEncumberedMoveEffect->getFloat()*normalizedEncumbrance;
|
||||
walkSpeed = std::max(0.0f, walkSpeed);
|
||||
if(Npc::getStance(ptr, Sneak, false))
|
||||
if(sneaking)
|
||||
walkSpeed *= fSneakSpeedMultiplier->getFloat();
|
||||
|
||||
float runSpeed = walkSpeed*(0.01f * npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified() *
|
||||
|
@ -866,14 +851,14 @@ namespace MWClass
|
|||
else if(world->isSwimming(ptr))
|
||||
{
|
||||
float swimSpeed = walkSpeed;
|
||||
if(Npc::getStance(ptr, Run, false))
|
||||
if(running)
|
||||
swimSpeed = runSpeed;
|
||||
swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).mMagnitude;
|
||||
swimSpeed *= fSwimRunBase->getFloat() + 0.01f*npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified()*
|
||||
fSwimRunAthleticsMult->getFloat();
|
||||
moveSpeed = swimSpeed;
|
||||
}
|
||||
else if(Npc::getStance(ptr, Run, false) && !Npc::getStance(ptr, Sneak, false))
|
||||
else if(running && !sneaking)
|
||||
moveSpeed = runSpeed;
|
||||
else
|
||||
moveSpeed = walkSpeed;
|
||||
|
@ -905,7 +890,7 @@ namespace MWClass
|
|||
x += mageffects.get(ESM::MagicEffect::Jump).mMagnitude * 64;
|
||||
x *= encumbranceTerm;
|
||||
|
||||
if(Npc::getStance(ptr, Run, false))
|
||||
if(ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run))
|
||||
x *= fJumpRunMultiplier->getFloat();
|
||||
x *= npcdata->mNpcStats.getFatigueTerm();
|
||||
x -= -627.2f;/*gravity constant*/
|
||||
|
@ -1017,7 +1002,8 @@ namespace MWClass
|
|||
float Npc::getCapacity (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
|
||||
return stats.getAttribute(0).getModified()*5;
|
||||
static const float fEncumbranceStrMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fEncumbranceStrMult")->getFloat();
|
||||
return stats.getAttribute(0).getModified()*fEncumbranceStrMult;
|
||||
}
|
||||
|
||||
float Npc::getEncumbrance (const MWWorld::Ptr& ptr) const
|
||||
|
@ -1231,6 +1217,22 @@ namespace MWClass
|
|||
return MWWorld::Ptr(&cell.mNpcs.insert(*ref), &cell);
|
||||
}
|
||||
|
||||
int Npc::getSkill(const MWWorld::Ptr& ptr, int skill) const
|
||||
{
|
||||
return ptr.getClass().getNpcStats(ptr).getSkill(skill).getModified();
|
||||
}
|
||||
|
||||
int Npc::getBloodTexture(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
||||
|
||||
if (ref->mBase->mFlags & ESM::NPC::Skeleton)
|
||||
return 1;
|
||||
if (ref->mBase->mFlags & ESM::NPC::Metal)
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const ESM::GameSetting *Npc::fMinWalkSpeed;
|
||||
const ESM::GameSetting *Npc::fMaxWalkSpeed;
|
||||
const ESM::GameSetting *Npc::fEncumberedMoveEffect;
|
||||
|
@ -1247,4 +1249,7 @@ namespace MWClass
|
|||
const ESM::GameSetting *Npc::fJumpAcroMultiplier;
|
||||
const ESM::GameSetting *Npc::fJumpRunMultiplier;
|
||||
const ESM::GameSetting *Npc::fWereWolfRunMult;
|
||||
const ESM::GameSetting *Npc::fKnockDownMult;
|
||||
const ESM::GameSetting *Npc::iKnockDownOddsMult;
|
||||
const ESM::GameSetting *Npc::iKnockDownOddsBase;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,9 @@ namespace MWClass
|
|||
static const ESM::GameSetting *fJumpAcroMultiplier;
|
||||
static const ESM::GameSetting *fJumpRunMultiplier;
|
||||
static const ESM::GameSetting *fWereWolfRunMult;
|
||||
static const ESM::GameSetting *fKnockDownMult;
|
||||
static const ESM::GameSetting *iKnockDownOddsMult;
|
||||
static const ESM::GameSetting *iKnockDownOddsBase;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -81,16 +84,6 @@ namespace MWClass
|
|||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of the script attached to ptr
|
||||
|
||||
virtual void setForceStance (const MWWorld::Ptr& ptr, Stance stance, bool force) const;
|
||||
///< Force or unforce a stance.
|
||||
|
||||
virtual void setStance (const MWWorld::Ptr& ptr, Stance stance, bool set) const;
|
||||
///< Set or unset a stance.
|
||||
|
||||
virtual bool getStance (const MWWorld::Ptr& ptr, Stance stance, bool ignoreForce = false)
|
||||
const;
|
||||
///< Check if a stance is active or not.
|
||||
|
||||
virtual float getSpeed (const MWWorld::Ptr& ptr) const;
|
||||
///< Return movement speed.
|
||||
|
||||
|
@ -147,6 +140,11 @@ namespace MWClass
|
|||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual int getSkill(const MWWorld::Ptr& ptr, int skill) const;
|
||||
|
||||
/// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini)
|
||||
virtual int getBloodTexture (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual bool isActor() const {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/physicssystem.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/nullaction.hpp"
|
||||
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
@ -133,7 +132,7 @@ namespace MWClass
|
|||
info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects);
|
||||
|
||||
// hide effects the player doesnt know about
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||
int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase();
|
||||
int i=0;
|
||||
|
@ -153,6 +152,7 @@ namespace MWClass
|
|||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ namespace MWClass
|
|||
MWWorld::LiveCellRef<ESM::Potion> *ref =
|
||||
ptr.get<ESM::Potion>();
|
||||
|
||||
MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
|
||||
// remove used potion (assume it is present in inventory)
|
||||
ptr.getContainerStore()->remove(ptr, 1, actor);
|
||||
|
|
|
@ -144,6 +144,7 @@ namespace MWClass
|
|||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||
}
|
||||
|
||||
|
|
|
@ -148,6 +148,7 @@ namespace MWClass
|
|||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||
}
|
||||
|
||||
|
|
|
@ -355,6 +355,7 @@ namespace MWClass
|
|||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "../mwgui/dialogue.hpp"
|
||||
|
||||
|
@ -126,6 +125,8 @@ namespace MWDialogue
|
|||
void DialogueManager::startDialogue (const MWWorld::Ptr& actor)
|
||||
{
|
||||
mLastTopic = "";
|
||||
mPermanentDispositionChange = 0;
|
||||
mTemporaryDispositionChange = 0;
|
||||
|
||||
mChoice = -1;
|
||||
mIsInChoice = false;
|
||||
|
@ -142,6 +143,7 @@ namespace MWDialogue
|
|||
|
||||
//setup the list of topics known by the actor. Topics who are also on the knownTopics list will be added to the GUI
|
||||
updateTopics();
|
||||
updateGlobals();
|
||||
|
||||
//greeting
|
||||
const MWWorld::Store<ESM::Dialogue> &dialogs =
|
||||
|
@ -297,6 +299,11 @@ namespace MWDialogue
|
|||
}
|
||||
}
|
||||
|
||||
void DialogueManager::updateGlobals()
|
||||
{
|
||||
MWBase::Environment::get().getWorld()->updateDialogueGlobals();
|
||||
}
|
||||
|
||||
void DialogueManager::updateTopics()
|
||||
{
|
||||
std::list<std::string> keywordList;
|
||||
|
@ -491,7 +498,7 @@ namespace MWDialogue
|
|||
else if (curDisp + mTemporaryDispositionChange > 100)
|
||||
mTemporaryDispositionChange = 100 - curDisp;
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWWorld::Class::get(player).skillUsageSucceeded(player, ESM::Skill::Speechcraft, success ? 0 : 1);
|
||||
|
||||
std::string text;
|
||||
|
@ -514,9 +521,19 @@ namespace MWDialogue
|
|||
return mTemporaryDispositionChange;
|
||||
}
|
||||
|
||||
void DialogueManager::applyTemporaryDispositionChange(int delta)
|
||||
void DialogueManager::applyDispositionChange(int delta)
|
||||
{
|
||||
int oldTemp = mTemporaryDispositionChange;
|
||||
mTemporaryDispositionChange += delta;
|
||||
// don't allow increasing beyond 100 or decreasing below 0
|
||||
int curDisp = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor);
|
||||
if (curDisp + mTemporaryDispositionChange < 0)
|
||||
mTemporaryDispositionChange = -curDisp;
|
||||
else if (curDisp + mTemporaryDispositionChange > 100)
|
||||
mTemporaryDispositionChange = 100 - curDisp;
|
||||
|
||||
int diff = mTemporaryDispositionChange - oldTemp;
|
||||
mPermanentDispositionChange += diff;
|
||||
}
|
||||
|
||||
bool DialogueManager::checkServiceRefused()
|
||||
|
|
|
@ -40,6 +40,7 @@ namespace MWDialogue
|
|||
void parseText (const std::string& text);
|
||||
|
||||
void updateTopics();
|
||||
void updateGlobals();
|
||||
|
||||
bool compile (const std::string& cmd,std::vector<Interpreter::Type_Code>& code);
|
||||
void executeScript (const std::string& script);
|
||||
|
@ -76,7 +77,7 @@ namespace MWDialogue
|
|||
|
||||
virtual void persuade (int type);
|
||||
virtual int getTemporaryDispositionChange () const;
|
||||
virtual void applyTemporaryDispositionChange (int delta);
|
||||
virtual void applyDispositionChange (int delta);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "../mwbase/dialoguemanager.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
|
||||
|
@ -25,7 +24,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
|
|||
// actor id
|
||||
if (!info.mActor.empty())
|
||||
{
|
||||
if ( Misc::StringUtils::lowerCase (info.mActor)!=MWWorld::Class::get (mActor).getId (mActor))
|
||||
if ( !Misc::StringUtils::ciEqual(info.mActor, MWWorld::Class::get (mActor).getId (mActor)))
|
||||
return false;
|
||||
}
|
||||
else if (isCreature)
|
||||
|
@ -42,7 +41,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
|
|||
|
||||
MWWorld::LiveCellRef<ESM::NPC> *cellRef = mActor.get<ESM::NPC>();
|
||||
|
||||
if (Misc::StringUtils::lowerCase (info.mRace)!= Misc::StringUtils::lowerCase (cellRef->mBase->mRace))
|
||||
if (!Misc::StringUtils::ciEqual(info.mRace, cellRef->mBase->mRace))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -54,7 +53,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
|
|||
|
||||
MWWorld::LiveCellRef<ESM::NPC> *cellRef = mActor.get<ESM::NPC>();
|
||||
|
||||
if ( Misc::StringUtils::lowerCase (info.mClass)!= Misc::StringUtils::lowerCase (cellRef->mBase->mClass))
|
||||
if ( !Misc::StringUtils::ciEqual(info.mClass, cellRef->mBase->mClass))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -93,7 +92,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
|
|||
|
||||
bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const
|
||||
{
|
||||
const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
|
||||
// check player faction
|
||||
if (!info.mPcFaction.empty())
|
||||
|
@ -111,7 +110,7 @@ bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const
|
|||
|
||||
// check cell
|
||||
if (!info.mCell.empty())
|
||||
if (Misc::StringUtils::lowerCase (player.getCell()->mCell->mName) != Misc::StringUtils::lowerCase (info.mCell))
|
||||
if (!Misc::StringUtils::ciEqual(player.getCell()->mCell->mName, info.mCell))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -189,7 +188,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
|
|||
int i = 0;
|
||||
|
||||
for (; i<static_cast<int> (script->mVarNames.size()); ++i)
|
||||
if (Misc::StringUtils::lowerCase(script->mVarNames[i]) == name)
|
||||
if (Misc::StringUtils::ciEqual(script->mVarNames[i], name))
|
||||
break;
|
||||
|
||||
if (i>=static_cast<int> (script->mVarNames.size()))
|
||||
|
@ -212,7 +211,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
|
|||
|
||||
case SelectWrapper::Function_PcHealthPercent:
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
|
||||
float ratio = MWWorld::Class::get (player).getCreatureStats (player).getHealth().getCurrent() /
|
||||
MWWorld::Class::get (player).getCreatureStats (player).getHealth().getModified();
|
||||
|
@ -222,7 +221,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
|
|||
|
||||
case SelectWrapper::Function_PcDynamicStat:
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
|
||||
float value = MWWorld::Class::get (player).getCreatureStats (player).
|
||||
getDynamic (select.getArgument()).getCurrent();
|
||||
|
@ -246,7 +245,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
|
|||
|
||||
int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) const
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
|
||||
switch (select.getFunction())
|
||||
{
|
||||
|
@ -263,7 +262,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
|
|||
std::string name = select.getName();
|
||||
|
||||
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
|
||||
if (Misc::StringUtils::lowerCase(iter->getCellRef().mRefID) == name)
|
||||
if (Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, name))
|
||||
sum += iter->getRefData().getCount();
|
||||
|
||||
return sum;
|
||||
|
@ -420,7 +419,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
|
|||
|
||||
bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) const
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
|
||||
switch (select.getFunction())
|
||||
{
|
||||
|
@ -430,23 +429,23 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
|
|||
|
||||
case SelectWrapper::Function_NotId:
|
||||
|
||||
return select.getName()!=Misc::StringUtils::lowerCase (MWWorld::Class::get (mActor).getId (mActor));
|
||||
return !Misc::StringUtils::ciEqual(MWWorld::Class::get (mActor).getId (mActor), select.getName());
|
||||
|
||||
case SelectWrapper::Function_NotFaction:
|
||||
|
||||
return Misc::StringUtils::lowerCase (mActor.get<ESM::NPC>()->mBase->mFaction)!=select.getName();
|
||||
return !Misc::StringUtils::ciEqual(mActor.get<ESM::NPC>()->mBase->mFaction, select.getName());
|
||||
|
||||
case SelectWrapper::Function_NotClass:
|
||||
|
||||
return Misc::StringUtils::lowerCase (mActor.get<ESM::NPC>()->mBase->mClass)!=select.getName();
|
||||
return !Misc::StringUtils::ciEqual(mActor.get<ESM::NPC>()->mBase->mClass, select.getName());
|
||||
|
||||
case SelectWrapper::Function_NotRace:
|
||||
|
||||
return Misc::StringUtils::lowerCase (mActor.get<ESM::NPC>()->mBase->mRace)!=select.getName();
|
||||
return !Misc::StringUtils::ciEqual(mActor.get<ESM::NPC>()->mBase->mRace, select.getName());
|
||||
|
||||
case SelectWrapper::Function_NotCell:
|
||||
|
||||
return Misc::StringUtils::lowerCase (mActor.getCell()->mCell->mName)!=select.getName();
|
||||
return !Misc::StringUtils::ciEqual(mActor.getCell()->mCell->mName, select.getName());
|
||||
|
||||
case SelectWrapper::Function_NotLocal:
|
||||
{
|
||||
|
@ -463,7 +462,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
|
|||
|
||||
int i = 0;
|
||||
for (; i < static_cast<int> (script->mVarNames.size()); ++i)
|
||||
if (Misc::StringUtils::lowerCase(script->mVarNames[i]) == name)
|
||||
if (Misc::StringUtils::ciEqual(script->mVarNames[i], name))
|
||||
break;
|
||||
|
||||
if (i >= static_cast<int> (script->mVarNames.size()))
|
||||
|
@ -479,8 +478,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
|
|||
|
||||
case SelectWrapper::Function_SameRace:
|
||||
|
||||
return Misc::StringUtils::lowerCase (mActor.get<ESM::NPC>()->mBase->mRace)!=
|
||||
Misc::StringUtils::lowerCase (player.get<ESM::NPC>()->mBase->mRace);
|
||||
return !Misc::StringUtils::ciEqual(mActor.get<ESM::NPC>()->mBase->mRace, player.get<ESM::NPC>()->mBase->mRace);
|
||||
|
||||
case SelectWrapper::Function_SameFaction:
|
||||
|
||||
|
@ -508,9 +506,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
|
|||
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();
|
||||
return player.getClass().getNpcStats(player).getExpelled(faction);
|
||||
}
|
||||
|
||||
case SelectWrapper::Function_PcVampire:
|
||||
|
@ -528,7 +524,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
|
|||
|
||||
case SelectWrapper::Function_Detected:
|
||||
|
||||
return MWWorld::Class::get (mActor).hasDetected (mActor, player);
|
||||
return MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, mActor);
|
||||
|
||||
case SelectWrapper::Function_Attacked:
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "../mwbase/soundmanager.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "inventoryitemmodel.hpp"
|
||||
|
@ -143,9 +142,9 @@ namespace MWGui
|
|||
|
||||
void AlchemyWindow::open()
|
||||
{
|
||||
mAlchemy.setAlchemist (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
mAlchemy.setAlchemist (MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||
|
||||
InventoryItemModel* model = new InventoryItemModel(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
InventoryItemModel* model = new InventoryItemModel(MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||
mSortModel = new SortFilterItemModel(model);
|
||||
mSortModel->setFilter(SortFilterItemModel::Filter_OnlyIngredients);
|
||||
mItemView->setModel (mSortModel);
|
||||
|
@ -154,7 +153,7 @@ namespace MWGui
|
|||
|
||||
int index = 0;
|
||||
|
||||
mAlchemy.setAlchemist (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
mAlchemy.setAlchemist (MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||
|
||||
for (MWMechanics::Alchemy::TToolsIterator iter (mAlchemy.beginTools());
|
||||
iter!=mAlchemy.endTools() && index<static_cast<int> (mApparatus.size()); ++iter, ++index)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "birth.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
@ -77,7 +76,7 @@ namespace MWGui
|
|||
size_t count = mBirthList->getItemCount();
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (boost::iequals(*mBirthList->getItemDataAt<std::string>(i), birthId))
|
||||
if (Misc::StringUtils::ciEqual(*mBirthList->getItemDataAt<std::string>(i), birthId))
|
||||
{
|
||||
mBirthList->setIndexSelected(i);
|
||||
MyGUI::Button* okButton;
|
||||
|
@ -112,7 +111,7 @@ namespace MWGui
|
|||
getWidget(okButton, "OKButton");
|
||||
|
||||
const std::string *birthId = mBirthList->getItemDataAt<std::string>(_index);
|
||||
if (boost::iequals(mCurrentBirthId, *birthId))
|
||||
if (Misc::StringUtils::ciEqual(mCurrentBirthId, *birthId))
|
||||
return;
|
||||
|
||||
mCurrentBirthId = *birthId;
|
||||
|
@ -148,7 +147,7 @@ namespace MWGui
|
|||
mBirthList->setIndexSelected(index);
|
||||
mCurrentBirthId = it2->first;
|
||||
}
|
||||
else if (boost::iequals(it2->first, mCurrentBirthId))
|
||||
else if (Misc::StringUtils::ciEqual(it2->first, mCurrentBirthId))
|
||||
{
|
||||
mBirthList->setIndexSelected(index);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "formatting.hpp"
|
||||
|
||||
|
@ -138,7 +137,7 @@ namespace MWGui
|
|||
MWBase::Environment::get().getSoundManager()->playSound("Item Book Up", 1.0, 1.0);
|
||||
|
||||
MWWorld::ActionTake take(mBook);
|
||||
take.execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
take.execute (MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Book);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/fallback.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -47,7 +46,7 @@ namespace
|
|||
|
||||
void updatePlayerHealth()
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
|
||||
creatureStats.updateHealth();
|
||||
|
@ -220,8 +219,8 @@ namespace MWGui
|
|||
mReviewDialog->setBirthSign(mPlayerBirthSignId);
|
||||
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWMechanics::CreatureStats stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
const MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
|
||||
mReviewDialog->setHealth ( stats.getHealth() );
|
||||
mReviewDialog->setMagicka( stats.getMagicka() );
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "class.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
@ -29,11 +27,12 @@ namespace MWGui
|
|||
|
||||
MyGUI::Button* backButton;
|
||||
getWidget(backButton, "BackButton");
|
||||
backButton->setCaptionWithReplacing("#{sMessageQuestionAnswer3}");
|
||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onBackClicked);
|
||||
|
||||
MyGUI::Button* okButton;
|
||||
getWidget(okButton, "OKButton");
|
||||
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
|
||||
okButton->setCaptionWithReplacing("#{sMessageQuestionAnswer2}");
|
||||
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onOkClicked);
|
||||
}
|
||||
|
||||
|
@ -127,7 +126,7 @@ namespace MWGui
|
|||
size_t count = mClassList->getItemCount();
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (boost::iequals(*mClassList->getItemDataAt<std::string>(i), classId))
|
||||
if (Misc::StringUtils::ciEqual(*mClassList->getItemDataAt<std::string>(i), classId))
|
||||
{
|
||||
mClassList->setIndexSelected(i);
|
||||
MyGUI::Button* okButton;
|
||||
|
@ -162,7 +161,7 @@ namespace MWGui
|
|||
getWidget(okButton, "OKButton");
|
||||
|
||||
const std::string *classId = mClassList->getItemDataAt<std::string>(_index);
|
||||
if (boost::iequals(mCurrentClassId, *classId))
|
||||
if (Misc::StringUtils::ciEqual(mCurrentClassId, *classId))
|
||||
return;
|
||||
|
||||
mCurrentClassId = *classId;
|
||||
|
@ -192,7 +191,7 @@ namespace MWGui
|
|||
mCurrentClassId = id;
|
||||
mClassList->setIndexSelected(index);
|
||||
}
|
||||
else if (boost::iequals(id, mCurrentClassId))
|
||||
else if (Misc::StringUtils::ciEqual(id, mCurrentClassId))
|
||||
{
|
||||
mClassList->setIndexSelected(index);
|
||||
}
|
||||
|
|
|
@ -6,9 +6,13 @@
|
|||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/soundmanager.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/dialoguemanager.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
#include "../mwmechanics/pickpocket.hpp"
|
||||
|
||||
#include "countdialog.hpp"
|
||||
#include "tradewindow.hpp"
|
||||
|
@ -123,6 +127,7 @@ namespace MWGui
|
|||
, mSelectedItem(-1)
|
||||
, mModel(NULL)
|
||||
, mSortModel(NULL)
|
||||
, mPickpocketDetected(false)
|
||||
{
|
||||
getWidget(mDisposeCorpseButton, "DisposeCorpseButton");
|
||||
getWidget(mTakeButton, "TakeButton");
|
||||
|
@ -134,6 +139,7 @@ namespace MWGui
|
|||
|
||||
mDisposeCorpseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onDisposeCorpseButtonClicked);
|
||||
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onCloseButtonClicked);
|
||||
mCloseButton->eventKeyButtonPressed += MyGUI::newDelegate(this, &ContainerWindow::onKeyPressed);
|
||||
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onTakeAllButtonClicked);
|
||||
|
||||
setCoord(200,0,600,300);
|
||||
|
@ -171,6 +177,9 @@ namespace MWGui
|
|||
|
||||
void ContainerWindow::dragItem(MyGUI::Widget* sender, int count)
|
||||
{
|
||||
if (!onTakeItem(mModel->getItem(mSelectedItem), count))
|
||||
return;
|
||||
|
||||
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count);
|
||||
}
|
||||
|
||||
|
@ -208,12 +217,13 @@ namespace MWGui
|
|||
|
||||
void ContainerWindow::open(const MWWorld::Ptr& container, bool loot)
|
||||
{
|
||||
mPickpocketDetected = false;
|
||||
mPtr = container;
|
||||
|
||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name() && !loot)
|
||||
{
|
||||
// we are stealing stuff
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
mModel = new PickpocketItemModel(player, new InventoryItemModel(container));
|
||||
}
|
||||
else
|
||||
|
@ -225,11 +235,46 @@ namespace MWGui
|
|||
|
||||
mItemView->setModel (mSortModel);
|
||||
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(mCloseButton);
|
||||
|
||||
// Careful here. setTitle may cause size updates, causing itemview redraw, so make sure to do it last
|
||||
// or we end up using a possibly invalid model.
|
||||
setTitle(MWWorld::Class::get(container).getName(container));
|
||||
}
|
||||
|
||||
void ContainerWindow::onKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char)
|
||||
{
|
||||
if (_key == MyGUI::KeyCode::Space)
|
||||
onCloseButtonClicked(mCloseButton);
|
||||
if (_key == MyGUI::KeyCode::Return || _key == MyGUI::KeyCode::NumpadEnter)
|
||||
onTakeAllButtonClicked(mTakeButton);
|
||||
}
|
||||
|
||||
void ContainerWindow::close()
|
||||
{
|
||||
WindowBase::close();
|
||||
|
||||
if (dynamic_cast<PickpocketItemModel*>(mModel)
|
||||
// Make sure we were actually closed, rather than just temporarily hidden (e.g. console or main menu opened)
|
||||
&& !MWBase::Environment::get().getWindowManager()->containsMode(GM_Container)
|
||||
// If it was already detected while taking an item, no need to check now
|
||||
&& !mPickpocketDetected
|
||||
)
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWMechanics::Pickpocket pickpocket(player, mPtr);
|
||||
if (pickpocket.finish())
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->reportCrime(
|
||||
player, mPtr, MWBase::MechanicsManager::OT_Pickpocket);
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
|
||||
MWBase::Environment::get().getDialogueManager()->say(mPtr, "Thief");
|
||||
mPickpocketDetected = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
||||
|
@ -255,8 +300,13 @@ namespace MWGui
|
|||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
}
|
||||
|
||||
playerModel->copyItem(mModel->getItem(i), mModel->getItem(i).mCount);
|
||||
mModel->removeItem(mModel->getItem(i), mModel->getItem(i).mCount);
|
||||
const ItemStack& item = mModel->getItem(i);
|
||||
|
||||
if (!onTakeItem(item, item.mCount))
|
||||
break;
|
||||
|
||||
playerModel->copyItem(item, item.mCount);
|
||||
mModel->removeItem(item, item.mCount);
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
||||
|
@ -283,4 +333,30 @@ namespace MWGui
|
|||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
||||
}
|
||||
|
||||
bool ContainerWindow::onTakeItem(const ItemStack &item, int count)
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
if (dynamic_cast<PickpocketItemModel*>(mModel))
|
||||
{
|
||||
MWMechanics::Pickpocket pickpocket(player, mPtr);
|
||||
if (pickpocket.pick(item.mBase, count))
|
||||
{
|
||||
int value = item.mBase.getClass().getValue(item.mBase) * count;
|
||||
MWBase::Environment::get().getMechanicsManager()->reportCrime(
|
||||
player, MWWorld::Ptr(), MWBase::MechanicsManager::OT_Theft, value);
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
|
||||
MWBase::Environment::get().getDialogueManager()->say(mPtr, "Thief");
|
||||
mPickpocketDetected = true;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
player.getClass().skillUsageSucceeded(player, ESM::Skill::Sneak, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item.mBase, count);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,10 +52,13 @@ namespace MWGui
|
|||
ContainerWindow(DragAndDrop* dragAndDrop);
|
||||
|
||||
void open(const MWWorld::Ptr& container, bool loot=false);
|
||||
virtual void close();
|
||||
|
||||
private:
|
||||
DragAndDrop* mDragAndDrop;
|
||||
|
||||
bool mPickpocketDetected;
|
||||
|
||||
MWGui::ItemView* mItemView;
|
||||
SortFilterItemModel* mSortModel;
|
||||
ItemModel* mModel;
|
||||
|
@ -72,6 +75,10 @@ namespace MWGui
|
|||
void onCloseButtonClicked(MyGUI::Widget* _sender);
|
||||
void onTakeAllButtonClicked(MyGUI::Widget* _sender);
|
||||
void onDisposeCorpseButtonClicked(MyGUI::Widget* sender);
|
||||
void onKeyPressed(MyGUI::Widget* _sender, MyGUI::KeyCode _key, MyGUI::Char _char);
|
||||
|
||||
/// @return is taking the item allowed?
|
||||
bool onTakeItem(const ItemStack& item, int count);
|
||||
|
||||
virtual void onReferenceUnavailable();
|
||||
};
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
#include "../mwdialogue/dialoguemanagerimp.hpp"
|
||||
|
@ -21,7 +20,6 @@
|
|||
#include "list.hpp"
|
||||
#include "tradewindow.hpp"
|
||||
#include "spellbuyingwindow.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
#include "travelwindow.hpp"
|
||||
#include "bookpage.hpp"
|
||||
|
||||
|
@ -69,24 +67,24 @@ namespace MWGui
|
|||
|
||||
void PersuasionDialog::onPersuade(MyGUI::Widget *sender)
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWBase::MechanicsManager::PersuasionType type;
|
||||
if (sender == mAdmireButton) type = MWBase::MechanicsManager::PT_Admire;
|
||||
else if (sender == mIntimidateButton) type = MWBase::MechanicsManager::PT_Intimidate;
|
||||
else if (sender == mTauntButton) type = MWBase::MechanicsManager::PT_Taunt;
|
||||
else if (sender == mBribe10Button)
|
||||
{
|
||||
player.getClass().getContainerStore(player).remove("gold_001", 10, player);
|
||||
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, 10, player);
|
||||
type = MWBase::MechanicsManager::PT_Bribe10;
|
||||
}
|
||||
else if (sender == mBribe100Button)
|
||||
{
|
||||
player.getClass().getContainerStore(player).remove("gold_001", 100, player);
|
||||
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, 100, player);
|
||||
type = MWBase::MechanicsManager::PT_Bribe100;
|
||||
}
|
||||
else /*if (sender == mBribe1000Button)*/
|
||||
{
|
||||
player.getClass().getContainerStore(player).remove("gold_001", 1000, player);
|
||||
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, 1000, player);
|
||||
type = MWBase::MechanicsManager::PT_Bribe1000;
|
||||
}
|
||||
|
||||
|
@ -100,7 +98,8 @@ namespace MWGui
|
|||
WindowModal::open();
|
||||
center();
|
||||
|
||||
int playerGold = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
|
||||
|
||||
mBribe10Button->setEnabled (playerGold >= 10);
|
||||
mBribe100Button->setEnabled (playerGold >= 100);
|
||||
|
@ -546,7 +545,7 @@ namespace MWGui
|
|||
for (size_t i=0; i<mTopicsList->getItemCount(); ++i)
|
||||
{
|
||||
std::string item = mTopicsList->getItemNameAt(i);
|
||||
if (Misc::StringUtils::lowerCase(item) == title)
|
||||
if (Misc::StringUtils::ciEqual(item, title))
|
||||
{
|
||||
realTitle = item;
|
||||
break;
|
||||
|
|
|
@ -5,13 +5,11 @@
|
|||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/soundmanager.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
#include "itemselection.hpp"
|
||||
#include "container.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
#include "sortfilteritemmodel.hpp"
|
||||
|
||||
|
@ -106,7 +104,7 @@ namespace MWGui
|
|||
|
||||
void EnchantingDialog::startSelfEnchanting(MWWorld::Ptr soulgem)
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
|
||||
mEnchanting.setSelfEnchanting(true);
|
||||
mEnchanting.setEnchanter(player);
|
||||
|
@ -149,7 +147,7 @@ namespace MWGui
|
|||
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onItemSelected);
|
||||
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onItemCancel);
|
||||
mItemSelectionDialog->setVisible(true);
|
||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyEnchantable);
|
||||
}
|
||||
|
||||
|
@ -236,7 +234,7 @@ namespace MWGui
|
|||
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onSoulSelected);
|
||||
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onSoulCancel);
|
||||
mItemSelectionDialog->setVisible(true);
|
||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyChargedSoulstones);
|
||||
|
||||
//MWBase::Environment::get().getWindowManager()->messageBox("#{sInventorySelectNoSoul}");
|
||||
|
@ -259,7 +257,7 @@ namespace MWGui
|
|||
{
|
||||
if (mEffects.size() <= 0)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage30}");
|
||||
MWBase::Environment::get().getWindowManager()->messageBox ("#{sEnchantmentMenu11}");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -290,7 +288,9 @@ namespace MWGui
|
|||
mEnchanting.setNewItemName(mName->getCaption());
|
||||
mEnchanting.setEffect(mEffectList);
|
||||
|
||||
if (mEnchanting.getEnchantPrice() > MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold())
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
|
||||
if (mEnchanting.getEnchantPrice() > playerGold)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage18}");
|
||||
return;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "../mwbase/soundmanager.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
|
@ -242,7 +241,7 @@ namespace MWGui
|
|||
if (world->canPlaceObject(mouseX, mouseY))
|
||||
world->placeObject(object, mouseX, mouseY, mDragAndDrop->mDraggedCount);
|
||||
else
|
||||
world->dropObjectOnGround(world->getPlayer().getPlayer(), object, mDragAndDrop->mDraggedCount);
|
||||
world->dropObjectOnGround(world->getPlayerPtr(), object, mDragAndDrop->mDraggedCount);
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->changePointer("arrow");
|
||||
|
||||
|
@ -268,7 +267,8 @@ namespace MWGui
|
|||
else if ((mode == GM_Container) || (mode == GM_Inventory))
|
||||
{
|
||||
// pick up object
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->pickUpObject(object);
|
||||
if (!object.isEmpty())
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->pickUpObject(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ namespace MWGui
|
|||
|
||||
void HUD::onWeaponClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
if (MWWorld::Class::get(player).getNpcStats(player).isWerewolf())
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sWerewolfRefusal}");
|
||||
|
@ -332,7 +332,7 @@ namespace MWGui
|
|||
|
||||
void HUD::onMagicClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
if (MWWorld::Class::get(player).getNpcStats(player).isWerewolf())
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sWerewolfRefusal}");
|
||||
|
@ -517,7 +517,7 @@ namespace MWGui
|
|||
mWeapStatus->setProgressPosition(0);
|
||||
|
||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
MWWorld::Ptr player = world->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = world->getPlayerPtr();
|
||||
if (MWWorld::Class::get(player).getNpcStats(player).isWerewolf())
|
||||
mWeapImage->setImageTexture("icons\\k\\tx_werewolf_hand.dds");
|
||||
else
|
||||
|
|
|
@ -8,11 +8,13 @@
|
|||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/soundmanager.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/action.hpp"
|
||||
#include "../mwscript/interpretercontext.hpp"
|
||||
#include "../mwbase/scriptmanager.hpp"
|
||||
|
||||
#include "bookwindow.hpp"
|
||||
#include "scrollwindow.hpp"
|
||||
|
@ -33,7 +35,7 @@ namespace MWGui
|
|||
, mTrading(false)
|
||||
, mLastXSize(0)
|
||||
, mLastYSize(0)
|
||||
, mPreview(MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ())
|
||||
, mPreview(MWBase::Environment::get().getWorld ()->getPlayerPtr())
|
||||
, mPreviewDirty(true)
|
||||
, mDragAndDrop(dragAndDrop)
|
||||
, mSelectedItem(-1)
|
||||
|
@ -84,7 +86,7 @@ namespace MWGui
|
|||
|
||||
void InventoryWindow::updatePlayer()
|
||||
{
|
||||
mPtr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ();
|
||||
mPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||
mTradeModel = new TradeItemModel(new InventoryItemModel(mPtr), MWWorld::Ptr());
|
||||
mSortModel = new SortFilterItemModel(mTradeModel);
|
||||
mItemView->setModel(mSortModel);
|
||||
|
@ -276,7 +278,7 @@ namespace MWGui
|
|||
|
||||
void InventoryWindow::open()
|
||||
{
|
||||
mPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
mPtr = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
|
||||
updateEncumbranceBar();
|
||||
|
||||
|
@ -351,6 +353,48 @@ namespace MWGui
|
|||
MWBase::Environment::get().getWindowManager()->setWeaponVisibility(!mPinned);
|
||||
}
|
||||
|
||||
void InventoryWindow::useItem(const MWWorld::Ptr &ptr)
|
||||
{
|
||||
const std::string& script = ptr.getClass().getScript(ptr);
|
||||
|
||||
// If the item has a script, set its OnPcEquip to 1
|
||||
if (!script.empty()
|
||||
// Another morrowind oddity: when an item has skipped equipping and pcskipequip is reset to 0 afterwards,
|
||||
// the next time it is equipped will work normally, but will not set onpcequip
|
||||
&& (ptr != mSkippedToEquip || ptr.getRefData().getLocals().getIntVar(script, "pcskipequip") == 1))
|
||||
ptr.getRefData().getLocals().setVarByInt(script, "onpcequip", 1);
|
||||
|
||||
// Give the script a chance to run once before we do anything else
|
||||
// this is important when setting pcskipequip as a reaction to onpcequip being set (bk_treasuryreport does this)
|
||||
if (!script.empty())
|
||||
{
|
||||
MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr);
|
||||
MWBase::Environment::get().getScriptManager()->run (script, interpreterContext);
|
||||
}
|
||||
|
||||
if (script.empty() || ptr.getRefData().getLocals().getIntVar(script, "pcskipequip") == 0)
|
||||
{
|
||||
boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(ptr).use(ptr);
|
||||
|
||||
action->execute (MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||
|
||||
// this is necessary for books/scrolls: if they are already in the player's inventory,
|
||||
// the "Take" button should not be visible.
|
||||
// NOTE: the take button is "reset" when the window opens, so we can safely do the following
|
||||
// without screwing up future book windows
|
||||
MWBase::Environment::get().getWindowManager()->getBookWindow()->setTakeButtonShow(false);
|
||||
MWBase::Environment::get().getWindowManager()->getScrollWindow()->setTakeButtonShow(false);
|
||||
|
||||
mSkippedToEquip = MWWorld::Ptr();
|
||||
}
|
||||
else
|
||||
mSkippedToEquip = ptr;
|
||||
|
||||
mItemView->update();
|
||||
|
||||
notifyContentChanged();
|
||||
}
|
||||
|
||||
void InventoryWindow::onAvatarClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
|
@ -369,21 +413,7 @@ namespace MWGui
|
|||
mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount);
|
||||
ptr = *it;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(ptr).use(ptr);
|
||||
|
||||
action->execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
|
||||
// this is necessary for books/scrolls: if they are already in the player's inventory,
|
||||
// the "Take" button should not be visible.
|
||||
// NOTE: the take button is "reset" when the window opens, so we can safely do the following
|
||||
// without screwing up future book windows
|
||||
MWBase::Environment::get().getWindowManager()->getBookWindow()->setTakeButtonShow(false);
|
||||
MWBase::Environment::get().getWindowManager()->getScrollWindow()->setTakeButtonShow(false);
|
||||
|
||||
mItemView->update();
|
||||
|
||||
notifyContentChanged();
|
||||
useItem(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -432,7 +462,7 @@ namespace MWGui
|
|||
|
||||
void InventoryWindow::updateEncumbranceBar()
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
|
||||
float capacity = MWWorld::Class::get(player).getCapacity(player);
|
||||
float encumbrance = MWWorld::Class::get(player).getEncumbrance(player);
|
||||
|
@ -447,19 +477,6 @@ namespace MWGui
|
|||
updateEncumbranceBar();
|
||||
}
|
||||
|
||||
int InventoryWindow::getPlayerGold()
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
it != invStore.end(); ++it)
|
||||
{
|
||||
if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, "gold_001"))
|
||||
return it->getRefData().getCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InventoryWindow::setTrading(bool trading)
|
||||
{
|
||||
mTrading = trading;
|
||||
|
@ -512,12 +529,10 @@ namespace MWGui
|
|||
return;
|
||||
|
||||
int count = object.getRefData().getCount();
|
||||
if (object.getCellRef().mGoldValue > 1)
|
||||
count = object.getCellRef().mGoldValue;
|
||||
|
||||
// add to player inventory
|
||||
// can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWWorld::Ptr newObject = *player.getClass().getContainerStore (player).add (object, object.getRefData().getCount(), player);
|
||||
// remove from world
|
||||
MWBase::Environment::get().getWorld()->deleteObject (object);
|
||||
|
@ -533,6 +548,8 @@ namespace MWGui
|
|||
if (i == mTradeModel->getItemCount())
|
||||
throw std::runtime_error("Added item not found");
|
||||
mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count);
|
||||
|
||||
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, newObject, count);
|
||||
}
|
||||
|
||||
MyGUI::IntCoord InventoryWindow::getAvatarScreenCoord ()
|
||||
|
|
|
@ -31,8 +31,6 @@ namespace MWGui
|
|||
|
||||
void pickUpObject (MWWorld::Ptr object);
|
||||
|
||||
int getPlayerGold();
|
||||
|
||||
MyGUI::IntCoord getAvatarScreenCoord();
|
||||
|
||||
MWWorld::Ptr getAvatarSelectedItem(int x, int y);
|
||||
|
@ -48,6 +46,8 @@ namespace MWGui
|
|||
|
||||
void updatePlayer();
|
||||
|
||||
void useItem(const MWWorld::Ptr& ptr);
|
||||
|
||||
void setGuiMode(GuiMode mode);
|
||||
|
||||
private:
|
||||
|
@ -76,6 +76,8 @@ namespace MWGui
|
|||
MyGUI::Button* mFilterMagic;
|
||||
MyGUI::Button* mFilterMisc;
|
||||
|
||||
MWWorld::Ptr mSkippedToEquip;
|
||||
|
||||
GuiMode mGuiMode;
|
||||
|
||||
int mLastXSize;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/fallback.hpp"
|
||||
|
||||
|
@ -59,7 +58,7 @@ namespace MWGui
|
|||
|
||||
void LevelupDialog::setAttributeValues()
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||
MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player);
|
||||
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||
|
||||
|
@ -115,7 +114,7 @@ namespace MWGui
|
|||
void LevelupDialog::open()
|
||||
{
|
||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
MWWorld::Ptr player = world->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = world->getPlayerPtr();
|
||||
MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player);
|
||||
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||
|
||||
|
@ -155,7 +154,7 @@ namespace MWGui
|
|||
|
||||
void LevelupDialog::onOkButtonClicked (MyGUI::Widget* sender)
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||
MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player);
|
||||
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||
|
||||
|
|
|
@ -294,7 +294,7 @@ namespace MWGui
|
|||
std::vector<MWWorld::Ptr> markers;
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
world->listDetectedReferences(
|
||||
world->getPlayer().getPlayer(),
|
||||
world->getPlayerPtr(),
|
||||
markers, MWBase::World::DetectionType(type));
|
||||
if (markers.empty())
|
||||
return;
|
||||
|
@ -515,8 +515,8 @@ namespace MWGui
|
|||
// For interiors, position is set by WindowManager via setGlobalMapPlayerPosition
|
||||
if (MWBase::Environment::get().getWorld ()->isCellExterior ())
|
||||
{
|
||||
Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedPosition ();
|
||||
Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedOrientation ();
|
||||
Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayerPtr().getRefData ().getBaseNode ()->_getDerivedPosition ();
|
||||
Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayerPtr().getRefData ().getBaseNode ()->_getDerivedOrientation ();
|
||||
Ogre::Vector2 dir (orient.yAxis ().x, orient.yAxis().y);
|
||||
|
||||
float worldX, worldY;
|
||||
|
|
|
@ -8,12 +8,9 @@
|
|||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/soundmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
|
@ -36,7 +33,9 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
|
|||
|
||||
int currentY = 0;
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
|
||||
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
|
||||
int categories = MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Armor;
|
||||
for (MWWorld::ContainerStoreIterator iter (store.begin(categories));
|
||||
|
@ -69,8 +68,7 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
|
|||
|
||||
|
||||
MyGUI::Button* button =
|
||||
mList->createWidget<MyGUI::Button>(
|
||||
(price>MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton",
|
||||
mList->createWidget<MyGUI::Button>("SandTextButton",
|
||||
0,
|
||||
currentY,
|
||||
0,
|
||||
|
@ -80,7 +78,7 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
|
|||
|
||||
currentY += 18;
|
||||
|
||||
button->setEnabled(price<=MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold());
|
||||
button->setEnabled(price<=playerGold);
|
||||
button->setUserString("Price", boost::lexical_cast<std::string>(price));
|
||||
button->setUserData(*iter);
|
||||
button->setCaptionWithReplacing(name);
|
||||
|
@ -93,7 +91,7 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
|
|||
mList->setCanvasSize (MyGUI::IntSize(mList->getWidth(), std::max(mList->getHeight(), currentY)));
|
||||
|
||||
mGoldLabel->setCaptionWithReplacing("#{sGold}: "
|
||||
+ boost::lexical_cast<std::string>(MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()));
|
||||
+ boost::lexical_cast<std::string>(playerGold));
|
||||
}
|
||||
|
||||
void MerchantRepair::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||
|
@ -119,8 +117,8 @@ void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender)
|
|||
|
||||
int price = boost::lexical_cast<int>(sender->getUserString("Price"));
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
player.getClass().getContainerStore(player).remove("gold_001", price, player);
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player);
|
||||
|
||||
startRepair(mActor);
|
||||
}
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
namespace MWGui
|
||||
{
|
||||
|
||||
MessageBoxManager::MessageBoxManager ()
|
||||
MessageBoxManager::MessageBoxManager (float timePerChar)
|
||||
{
|
||||
mMessageBoxSpeed = 0.1;
|
||||
mInterMessageBoxe = NULL;
|
||||
mStaticMessageBox = NULL;
|
||||
mLastButtonPressed = -1;
|
||||
mMessageBoxSpeed = timePerChar;
|
||||
}
|
||||
|
||||
MessageBoxManager::~MessageBoxManager ()
|
||||
|
@ -62,7 +62,8 @@ namespace MWGui
|
|||
{
|
||||
MessageBox *box = new MessageBox(*this, message);
|
||||
box->mCurrentTime = 0;
|
||||
box->mMaxTime = message.length()*mMessageBoxSpeed;
|
||||
std::string realMessage = MyGUI::LanguageManager::getInstance().replaceTags(message);
|
||||
box->mMaxTime = realMessage.length()*mMessageBoxSpeed;
|
||||
|
||||
if(stat)
|
||||
mStaticMessageBox = box;
|
||||
|
@ -126,12 +127,6 @@ namespace MWGui
|
|||
mMessageBoxSpeed = speed;
|
||||
}
|
||||
|
||||
void MessageBoxManager::okayPressed ()
|
||||
{
|
||||
if(mInterMessageBoxe != NULL)
|
||||
mInterMessageBoxe->okayPressed();
|
||||
}
|
||||
|
||||
int MessageBoxManager::readPressedButton ()
|
||||
{
|
||||
int pressed = mLastButtonPressed;
|
||||
|
@ -332,23 +327,25 @@ namespace MWGui
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void InteractiveMessageBox::okayPressed()
|
||||
{
|
||||
|
||||
// Set key focus to "Ok" button
|
||||
std::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}"));
|
||||
std::vector<MyGUI::Button*>::const_iterator button;
|
||||
for(button = mButtons.begin(); button != mButtons.end(); ++button)
|
||||
{
|
||||
if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok)
|
||||
if(Misc::StringUtils::ciEqual((*button)->getCaption(), ok))
|
||||
{
|
||||
buttonActivated(*button);
|
||||
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(*button);
|
||||
(*button)->eventKeyButtonPressed += MyGUI::newDelegate(this, &InteractiveMessageBox::onKeyPressed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InteractiveMessageBox::onKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char)
|
||||
{
|
||||
if (_key == MyGUI::KeyCode::Return || _key == MyGUI::KeyCode::NumpadEnter || _key == MyGUI::KeyCode::Space)
|
||||
buttonActivated(_sender);
|
||||
}
|
||||
|
||||
void InteractiveMessageBox::mousePressed (MyGUI::Widget* pressed)
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace MWGui
|
|||
class MessageBoxManager
|
||||
{
|
||||
public:
|
||||
MessageBoxManager ();
|
||||
MessageBoxManager (float timePerChar);
|
||||
~MessageBoxManager ();
|
||||
void onFrame (float frameDuration);
|
||||
void createMessageBox (const std::string& message, bool stat = false);
|
||||
|
@ -33,7 +33,6 @@ namespace MWGui
|
|||
bool removeMessageBox (MessageBox *msgbox);
|
||||
void setMessageBoxSpeed (int speed);
|
||||
|
||||
void okayPressed();
|
||||
int readPressedButton ();
|
||||
|
||||
typedef MyGUI::delegates::CMultiDelegate1<int> EventHandle_Int;
|
||||
|
@ -74,7 +73,6 @@ namespace MWGui
|
|||
{
|
||||
public:
|
||||
InteractiveMessageBox (MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons);
|
||||
void okayPressed ();
|
||||
void mousePressed (MyGUI::Widget* _widget);
|
||||
int readPressedButton ();
|
||||
|
||||
|
@ -82,6 +80,7 @@ namespace MWGui
|
|||
|
||||
private:
|
||||
void buttonActivated (MyGUI::Widget* _widget);
|
||||
void onKeyPressed(MyGUI::Widget* _sender, MyGUI::KeyCode _key, MyGUI::Char _char);
|
||||
|
||||
MessageBoxManager& mMessageBoxManager;
|
||||
MyGUI::EditBox* mMessageWidget;
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace MWGui
|
|||
PickpocketItemModel::PickpocketItemModel(const MWWorld::Ptr& thief, ItemModel *sourceModel)
|
||||
{
|
||||
mSourceModel = sourceModel;
|
||||
int chance = MWWorld::Class::get(thief).getNpcStats(thief).getSkill(ESM::Skill::Sneak).getModified();
|
||||
int chance = thief.getClass().getSkill(thief, ESM::Skill::Sneak);
|
||||
|
||||
mSourceModel->update();
|
||||
for (size_t i = 0; i<mSourceModel->getItemCount(); ++i)
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/actionequip.hpp"
|
||||
#include "../mwmechanics/spellcasting.hpp"
|
||||
|
@ -126,7 +125,7 @@ namespace MWGui
|
|||
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &QuickKeysMenu::onAssignItemCancel);
|
||||
}
|
||||
mItemSelectionDialog->setVisible(true);
|
||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||
|
||||
mAssignDialog->setVisible (false);
|
||||
}
|
||||
|
@ -267,7 +266,7 @@ namespace MWGui
|
|||
|
||||
QuickKeyType type = *button->getUserData<QuickKeyType>();
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
|
||||
|
||||
if (type == Type_Item || type == Type_MagicItem)
|
||||
|
@ -302,6 +301,12 @@ namespace MWGui
|
|||
if (type == Type_Magic)
|
||||
{
|
||||
std::string spellId = button->getChildAt(0)->getUserString("Spell");
|
||||
|
||||
// Make sure the player still has this spell
|
||||
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
|
||||
MWMechanics::Spells& spells = stats.getSpells();
|
||||
if (!spells.hasSpell(spellId))
|
||||
return;
|
||||
store.setSelectedEnchantItem(store.end());
|
||||
MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player)));
|
||||
}
|
||||
|
@ -309,19 +314,7 @@ namespace MWGui
|
|||
{
|
||||
MWWorld::Ptr item = *button->getChildAt (0)->getUserData<MWWorld::Ptr>();
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(item).use(item);
|
||||
|
||||
action->execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
|
||||
// this is necessary for books/scrolls: if they are already in the player's inventory,
|
||||
// the "Take" button should not be visible.
|
||||
// NOTE: the take button is "reset" when the window opens, so we can safely do the following
|
||||
// without screwing up future book windows
|
||||
MWBase::Environment::get().getWindowManager()->getBookWindow()->setTakeButtonShow(false);
|
||||
MWBase::Environment::get().getWindowManager()->getScrollWindow()->setTakeButtonShow(false);
|
||||
|
||||
// since we changed equipping status, update the inventory window
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView();
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->useItem(item);
|
||||
}
|
||||
else if (type == Type_MagicItem)
|
||||
{
|
||||
|
@ -344,7 +337,7 @@ namespace MWGui
|
|||
// Note: can't use Class::use here because enchanted scrolls for example would then open the scroll window instead of equipping
|
||||
|
||||
MWWorld::ActionEquip action(item);
|
||||
action.execute (MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ());
|
||||
action.execute (MWBase::Environment::get().getWorld ()->getPlayerPtr());
|
||||
}
|
||||
|
||||
store.setSelectedEnchantItem(it);
|
||||
|
@ -430,7 +423,7 @@ namespace MWGui
|
|||
|
||||
const int spellHeight = 18;
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
|
||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
MWMechanics::Spells& spells = stats.getSpells();
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "race.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
|
@ -140,7 +139,7 @@ namespace MWGui
|
|||
size_t count = mRaceList->getItemCount();
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (boost::iequals(*mRaceList->getItemDataAt<std::string>(i), raceId))
|
||||
if (Misc::StringUtils::ciEqual(*mRaceList->getItemDataAt<std::string>(i), raceId))
|
||||
{
|
||||
mRaceList->setIndexSelected(i);
|
||||
MyGUI::Button* okButton;
|
||||
|
@ -230,7 +229,7 @@ namespace MWGui
|
|||
MyGUI::Button* okButton;
|
||||
getWidget(okButton, "OKButton");
|
||||
const std::string *raceId = mRaceList->getItemDataAt<std::string>(_index);
|
||||
if (boost::iequals(mCurrentRaceId, *raceId))
|
||||
if (Misc::StringUtils::ciEqual(mCurrentRaceId, *raceId))
|
||||
return;
|
||||
|
||||
mCurrentRaceId = *raceId;
|
||||
|
@ -320,7 +319,7 @@ namespace MWGui
|
|||
continue;
|
||||
|
||||
mRaceList->addItem(it->mName, it->mId);
|
||||
if (boost::iequals(it->mId, mCurrentRaceId))
|
||||
if (Misc::StringUtils::ciEqual(it->mId, mCurrentRaceId))
|
||||
mRaceList->setIndexSelected(index);
|
||||
++index;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
|
@ -85,7 +84,7 @@ void Recharge::updateView()
|
|||
|
||||
int currentY = 0;
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
|
||||
for (MWWorld::ContainerStoreIterator iter (store.begin());
|
||||
iter!=store.end(); ++iter)
|
||||
|
@ -141,7 +140,7 @@ void Recharge::onItemClicked(MyGUI::Widget *sender)
|
|||
|
||||
MWWorld::Ptr item = *sender->getUserData<MWWorld::Ptr>();
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
|
||||
MWMechanics::NpcStats& npcStats = player.getClass().getNpcStats(player);
|
||||
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
ReferenceInterface::ReferenceInterface()
|
||||
|
@ -18,7 +16,7 @@ namespace MWGui
|
|||
|
||||
void ReferenceInterface::checkReferenceAvailable()
|
||||
{
|
||||
MWWorld::CellStore* playerCell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell();
|
||||
MWWorld::CellStore* playerCell = MWBase::Environment::get().getWorld()->getPlayerPtr().getCell();
|
||||
|
||||
// check if player has changed cell, or count of the reference has become 0
|
||||
if ((playerCell != mCurrentPlayerCell && mCurrentPlayerCell != NULL)
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
|
@ -88,7 +87,7 @@ void Repair::updateRepairView()
|
|||
|
||||
int currentY = 0;
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
|
||||
int categories = MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Armor;
|
||||
for (MWWorld::ContainerStoreIterator iter (store.begin(categories));
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "formatting.hpp"
|
||||
|
||||
|
@ -90,7 +89,7 @@ namespace MWGui
|
|||
MWBase::Environment::get().getSoundManager()->playSound("Item Book Up", 1.0, 1.0);
|
||||
|
||||
MWWorld::ActionTake take(mScroll);
|
||||
take.execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
take.execute (MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll);
|
||||
}
|
||||
|
|
|
@ -8,14 +8,11 @@
|
|||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
const int SpellBuyingWindow::sLineHeight = 18;
|
||||
|
@ -43,15 +40,19 @@ namespace MWGui
|
|||
int price = spell->mData.mCost*store.get<ESM::GameSetting>().find("fSpellValueMult")->getFloat();
|
||||
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true);
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
|
||||
|
||||
MyGUI::Button* toAdd =
|
||||
mSpellsView->createWidget<MyGUI::Button>(
|
||||
(price>MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton",
|
||||
"SandTextButton",
|
||||
0,
|
||||
mCurrentY,
|
||||
200,
|
||||
sLineHeight,
|
||||
MyGUI::Align::Default
|
||||
);
|
||||
toAdd->setEnabled(price<=playerGold);
|
||||
|
||||
mCurrentY += sLineHeight;
|
||||
|
||||
|
@ -103,7 +104,7 @@ namespace MWGui
|
|||
|
||||
bool SpellBuyingWindow::playerHasSpell(const std::string &id)
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWMechanics::Spells& playerSpells = MWWorld::Class::get (player).getCreatureStats (player).getSpells();
|
||||
for (MWMechanics::Spells::TIterator it = playerSpells.begin(); it != playerSpells.end(); ++it)
|
||||
{
|
||||
|
@ -117,17 +118,14 @@ namespace MWGui
|
|||
{
|
||||
int price = *_sender->getUserData<int>();
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()>=price)
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
MWMechanics::Spells& spells = stats.getSpells();
|
||||
spells.add (mSpellsWidgetMap.find(_sender)->second);
|
||||
player.getClass().getContainerStore(player).remove("gold_001", price, player);
|
||||
startSpellBuying(mPtr);
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
MWMechanics::Spells& spells = stats.getSpells();
|
||||
spells.add (mSpellsWidgetMap.find(_sender)->second);
|
||||
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player);
|
||||
startSpellBuying(mPtr);
|
||||
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0);
|
||||
}
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0);
|
||||
}
|
||||
|
||||
void SpellBuyingWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
|
||||
|
@ -137,7 +135,10 @@ namespace MWGui
|
|||
|
||||
void SpellBuyingWindow::updateLabels()
|
||||
{
|
||||
mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()));
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
|
||||
|
||||
mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(playerGold));
|
||||
mPlayerGold->setCoord(8,
|
||||
mPlayerGold->getTop(),
|
||||
mPlayerGold->getTextSize().width,
|
||||
|
|
|
@ -7,14 +7,12 @@
|
|||
#include "../mwbase/soundmanager.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
#include "../mwmechanics/spellcasting.hpp"
|
||||
|
||||
#include "tooltips.hpp"
|
||||
#include "class.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -334,7 +332,10 @@ namespace MWGui
|
|||
return;
|
||||
}
|
||||
|
||||
if (boost::lexical_cast<int>(mPriceLabel->getCaption()) > MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold())
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
|
||||
|
||||
if (boost::lexical_cast<int>(mPriceLabel->getCaption()) > playerGold)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage18}");
|
||||
return;
|
||||
|
@ -342,9 +343,7 @@ namespace MWGui
|
|||
|
||||
mSpell.mName = mNameEdit->getCaption();
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
|
||||
player.getClass().getContainerStore(player).remove("gold_001", boost::lexical_cast<int>(mPriceLabel->getCaption()), player);
|
||||
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, boost::lexical_cast<int>(mPriceLabel->getCaption()), player);
|
||||
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0);
|
||||
|
||||
|
@ -414,7 +413,7 @@ namespace MWGui
|
|||
|
||||
mPriceLabel->setCaption(boost::lexical_cast<std::string>(int(price)));
|
||||
|
||||
float chance = MWMechanics::getSpellSuccessChance(&mSpell, MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
float chance = MWMechanics::getSpellSuccessChance(&mSpell, MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||
mSuccessChance->setCaption(boost::lexical_cast<std::string>(int(chance)));
|
||||
}
|
||||
|
||||
|
@ -441,7 +440,7 @@ namespace MWGui
|
|||
{
|
||||
// get the list of magic effects that are known to the player
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
MWMechanics::Spells& spells = stats.getSpells();
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
|
||||
|
@ -40,7 +39,7 @@ namespace MWGui
|
|||
{
|
||||
// TODO: Tracking add/remove/expire would be better than force updating every frame
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
const MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/actionequip.hpp"
|
||||
|
||||
|
@ -81,7 +80,7 @@ namespace MWGui
|
|||
|
||||
// retrieve all player spells, divide them into Powers and Spells and sort them
|
||||
std::vector<std::string> spellList;
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
|
||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
MWMechanics::Spells& spells = stats.getSpells();
|
||||
|
@ -298,7 +297,7 @@ namespace MWGui
|
|||
|
||||
void SpellWindow::onEnchantedItemSelected(MyGUI::Widget* _sender)
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
|
||||
MWWorld::Ptr item = *_sender->getUserData<MWWorld::Ptr>();
|
||||
|
||||
|
@ -320,7 +319,7 @@ namespace MWGui
|
|||
// Note: can't use Class::use here because enchanted scrolls for example would then open the scroll window instead of equipping
|
||||
|
||||
MWWorld::ActionEquip action(item);
|
||||
action.execute (MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ());
|
||||
action.execute (MWBase::Environment::get().getWorld ()->getPlayerPtr());
|
||||
|
||||
// since we changed equipping status, update the inventory window
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView();
|
||||
|
@ -335,7 +334,7 @@ namespace MWGui
|
|||
void SpellWindow::onSpellSelected(MyGUI::Widget* _sender)
|
||||
{
|
||||
std::string spellId = _sender->getUserString("Spell");
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
|
||||
|
||||
if (MyGUI::InputManager::getInstance().isShiftPressed())
|
||||
|
@ -389,7 +388,7 @@ namespace MWGui
|
|||
|
||||
void SpellWindow::onDeleteSpellAccept()
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
MWMechanics::Spells& spells = stats.getSpells();
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
||||
|
@ -185,8 +185,8 @@ namespace MWGui
|
|||
MyGUI::TextBox* widget = mSkillWidgetMap[(int)parSkill];
|
||||
if (widget)
|
||||
{
|
||||
float modified = value.getModified(), base = value.getBase();
|
||||
std::string text = boost::lexical_cast<std::string>(std::floor(modified));
|
||||
int modified = value.getModified(), base = value.getBase();
|
||||
std::string text = boost::lexical_cast<std::string>(modified);
|
||||
std::string state = "normal";
|
||||
if (modified > base)
|
||||
state = "increased";
|
||||
|
@ -224,7 +224,7 @@ namespace MWGui
|
|||
if (!mMainWidget->getVisible())
|
||||
return;
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
const MWMechanics::NpcStats &PCstats = MWWorld::Class::get(player).getNpcStats(player);
|
||||
|
||||
// level progress
|
||||
|
@ -424,7 +424,7 @@ namespace MWGui
|
|||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
const MWWorld::ESMStore &store = world->getStore();
|
||||
const ESM::NPC *player =
|
||||
world->getPlayer().getPlayer().get<ESM::NPC>()->mBase;
|
||||
world->getPlayerPtr().get<ESM::NPC>()->mBase;
|
||||
|
||||
// race tooltip
|
||||
const ESM::Race* playerRace = store.get<ESM::Race>().find(player->mRace);
|
||||
|
@ -452,7 +452,7 @@ namespace MWGui
|
|||
if (!mSkillWidgets.empty())
|
||||
addSeparator(coord1, coord2);
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
const MWMechanics::NpcStats &PCstats = MWWorld::Class::get(player).getNpcStats(player);
|
||||
const std::set<std::string> &expelled = PCstats.getExpelled();
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ namespace MWGui
|
|||
if(!mMerchant.isEmpty())
|
||||
{
|
||||
MWWorld::Ptr base = item.mBase;
|
||||
if(Misc::StringUtils::ciEqual(base.getCellRef().mRefID, "gold_001"))
|
||||
if(Misc::StringUtils::ciEqual(base.getCellRef().mRefID, MWWorld::ContainerStore::sGoldId))
|
||||
continue;
|
||||
if(!MWWorld::Class::get(base).canSell(base, services))
|
||||
continue;
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "inventorywindow.hpp"
|
||||
#include "itemview.hpp"
|
||||
#include "sortfilteritemmodel.hpp"
|
||||
|
@ -212,11 +210,11 @@ namespace MWGui
|
|||
|
||||
if (amount > 0)
|
||||
{
|
||||
store.add("gold_001", amount, actor);
|
||||
store.add(MWWorld::ContainerStore::sGoldId, amount, actor);
|
||||
}
|
||||
else
|
||||
{
|
||||
store.remove("gold_001", - amount, actor);
|
||||
store.remove(MWWorld::ContainerStore::sGoldId, - amount, actor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -253,8 +251,11 @@ namespace MWGui
|
|||
return;
|
||||
}
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
|
||||
|
||||
// check if the player can afford this
|
||||
if (mCurrentBalance < 0 && MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold() < std::abs(mCurrentBalance))
|
||||
if (mCurrentBalance < 0 && playerGold < std::abs(mCurrentBalance))
|
||||
{
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
|
@ -271,8 +272,6 @@ namespace MWGui
|
|||
return;
|
||||
}
|
||||
|
||||
MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
|
||||
if(mCurrentBalance > mCurrentMerchantOffer)
|
||||
{
|
||||
//if npc is a creature: reject (no haggle)
|
||||
|
@ -294,13 +293,13 @@ namespace MWGui
|
|||
float clampedDisposition = std::max<int>(0,std::min<int>(int(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)
|
||||
+ MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()),100));
|
||||
|
||||
const MWMechanics::NpcStats &sellerStats = MWWorld::Class::get(mPtr).getNpcStats(mPtr);
|
||||
const MWMechanics::NpcStats &playerStats = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr);
|
||||
const MWMechanics::NpcStats &sellerStats = mPtr.getClass().getNpcStats(mPtr);
|
||||
const MWMechanics::NpcStats &playerStats = player.getClass().getNpcStats(player);
|
||||
|
||||
float a1 = std::min(playerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100);
|
||||
float a1 = std::min(player.getClass().getSkill(player, ESM::Skill::Mercantile), 100);
|
||||
float b1 = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
|
||||
float c1 = std::min(0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
|
||||
float d1 = std::min(sellerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100);
|
||||
float d1 = std::min(mPtr.getClass().getSkill(mPtr, ESM::Skill::Mercantile), 100);
|
||||
float e1 = std::min(0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
|
||||
float f1 = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
|
||||
|
||||
|
@ -319,16 +318,18 @@ namespace MWGui
|
|||
messageBox("#{sNotifyMessage9}");
|
||||
|
||||
int iBarterFailDisposition = gmst.find("iBarterFailDisposition")->getInt();
|
||||
MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterFailDisposition);
|
||||
if (mPtr.getClass().isNpc())
|
||||
MWBase::Environment::get().getDialogueManager()->applyDispositionChange(iBarterFailDisposition);
|
||||
return;
|
||||
}
|
||||
|
||||
//skill use!
|
||||
MWWorld::Class::get(playerPtr).skillUsageSucceeded(playerPtr, ESM::Skill::Mercantile, 0);
|
||||
player.getClass().skillUsageSucceeded(player, ESM::Skill::Mercantile, 0);
|
||||
}
|
||||
|
||||
int iBarterSuccessDisposition = gmst.find("iBarterSuccessDisposition")->getInt();
|
||||
MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterSuccessDisposition);
|
||||
if (mPtr.getClass().isNpc())
|
||||
MWBase::Environment::get().getDialogueManager()->applyDispositionChange(iBarterSuccessDisposition);
|
||||
|
||||
// make the item transfer
|
||||
mTradeModel->transferItems();
|
||||
|
@ -337,7 +338,7 @@ namespace MWGui
|
|||
// transfer the gold
|
||||
if (mCurrentBalance != 0)
|
||||
{
|
||||
addOrRemoveGold(mCurrentBalance, playerPtr);
|
||||
addOrRemoveGold(mCurrentBalance, player);
|
||||
addOrRemoveGold(-mCurrentBalance, mPtr);
|
||||
}
|
||||
|
||||
|
@ -398,7 +399,10 @@ namespace MWGui
|
|||
|
||||
void TradeWindow::updateLabels()
|
||||
{
|
||||
mPlayerGold->setCaptionWithReplacing("#{sYourGold} " + boost::lexical_cast<std::string>(MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()));
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
|
||||
|
||||
mPlayerGold->setCaptionWithReplacing("#{sYourGold} " + boost::lexical_cast<std::string>(playerGold));
|
||||
|
||||
if (mCurrentBalance > 0)
|
||||
{
|
||||
|
@ -447,7 +451,7 @@ namespace MWGui
|
|||
MWWorld::ContainerStore store = mPtr.getClass().getContainerStore(mPtr);
|
||||
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
||||
{
|
||||
if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, "gold_001"))
|
||||
if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, MWWorld::ContainerStore::sGoldId))
|
||||
merchantGold += it->getRefData().getCount();
|
||||
}
|
||||
return merchantGold;
|
||||
|
|
|
@ -28,8 +28,6 @@ namespace MWGui
|
|||
|
||||
void startTrade(const MWWorld::Ptr& actor);
|
||||
|
||||
void addOrRemoveGold(int gold, const MWWorld::Ptr& actor);
|
||||
|
||||
void onFrame(float frameDuration);
|
||||
|
||||
void borrowItem (int index, size_t count);
|
||||
|
@ -95,6 +93,8 @@ namespace MWGui
|
|||
void onIncreaseButtonTriggered();
|
||||
void onDecreaseButtonTriggered();
|
||||
|
||||
void addOrRemoveGold(int gold, const MWWorld::Ptr& actor);
|
||||
|
||||
void updateLabels();
|
||||
|
||||
virtual void onReferenceUnavailable();
|
||||
|
|
|
@ -9,13 +9,11 @@
|
|||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
||||
#include "inventorywindow.hpp"
|
||||
#include "tooltips.hpp"
|
||||
|
||||
namespace MWGui
|
||||
|
@ -41,7 +39,10 @@ namespace MWGui
|
|||
{
|
||||
mPtr = actor;
|
||||
|
||||
mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()));
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
|
||||
|
||||
mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(playerGold));
|
||||
|
||||
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats (actor);
|
||||
|
||||
|
@ -72,7 +73,6 @@ namespace MWGui
|
|||
MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator ();
|
||||
MyGUI::Gui::getInstance ().destroyWidgets (widgets);
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ();
|
||||
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||
|
||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||
|
@ -83,11 +83,10 @@ namespace MWGui
|
|||
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer
|
||||
(mPtr,pcStats.getSkill (bestSkills[i].first).getBase() * gmst.find("iTrainingMod")->getInt (),true);
|
||||
|
||||
std::string skin = (price > MWBase::Environment::get().getWindowManager()->getInventoryWindow ()->getPlayerGold ()) ? "SandTextGreyedOut" : "SandTextButton";
|
||||
|
||||
MyGUI::Button* button = mTrainingOptions->createWidget<MyGUI::Button>(skin,
|
||||
MyGUI::Button* button = mTrainingOptions->createWidget<MyGUI::Button>("SandTextButton",
|
||||
MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default);
|
||||
|
||||
button->setEnabled(price <= playerGold);
|
||||
button->setUserData(bestSkills[i].first);
|
||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected);
|
||||
|
||||
|
@ -115,7 +114,7 @@ namespace MWGui
|
|||
{
|
||||
int skillId = *sender->getUserData<int>();
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||
|
||||
const MWWorld::ESMStore &store =
|
||||
|
@ -124,9 +123,6 @@ namespace MWGui
|
|||
int price = pcStats.getSkill (skillId).getBase() * store.get<ESM::GameSetting>().find("iTrainingMod")->getInt ();
|
||||
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true);
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()<price)
|
||||
return;
|
||||
|
||||
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(mPtr).getNpcStats (mPtr);
|
||||
if (npcStats.getSkill (skillId).getBase () <= pcStats.getSkill (skillId).getBase ())
|
||||
{
|
||||
|
@ -134,6 +130,14 @@ namespace MWGui
|
|||
return;
|
||||
}
|
||||
|
||||
// You can not train a skill above its governing attribute
|
||||
const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find(skillId);
|
||||
if (pcStats.getSkill(skillId).getBase() >= pcStats.getAttribute(skill->mData.mAttribute).getBase())
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage17}");
|
||||
return;
|
||||
}
|
||||
|
||||
// increase skill
|
||||
MWWorld::LiveCellRef<ESM::NPC> *playerRef = player.get<ESM::NPC>();
|
||||
|
||||
|
@ -142,7 +146,7 @@ namespace MWGui
|
|||
pcStats.increaseSkill (skillId, *class_, true);
|
||||
|
||||
// remove gold
|
||||
player.getClass().getContainerStore(player).remove("gold_001", price, player);
|
||||
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player);
|
||||
|
||||
// go back to game mode
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Training);
|
||||
|
@ -150,6 +154,8 @@ namespace MWGui
|
|||
|
||||
// advance time
|
||||
MWBase::Environment::get().getWorld ()->advanceTime (2);
|
||||
MWBase::Environment::get().getMechanicsManager()->rest(false);
|
||||
MWBase::Environment::get().getMechanicsManager()->rest(false);
|
||||
|
||||
MWBase::Environment::get().getWorld ()->getFader()->fadeOut(0.25);
|
||||
mFadeTimeRemaining = 0.5;
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <OgreVector3.h>
|
||||
|
||||
#include <libs/openengine/ogre/fader.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
@ -9,12 +11,9 @@
|
|||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
const int TravelWindow::sLineHeight = 18;
|
||||
|
@ -51,13 +50,15 @@ namespace MWGui
|
|||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
|
||||
|
||||
if(interior)
|
||||
{
|
||||
price = gmst.find("fMagesGuildTravel")->getFloat();
|
||||
}
|
||||
else
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
ESM::Position PlayerPos = player.getRefData().getPosition();
|
||||
float d = sqrt( pow(pos.pos[0] - PlayerPos.pos[0],2) + pow(pos.pos[1] - PlayerPos.pos[1],2) + pow(pos.pos[2] - PlayerPos.pos[2],2) );
|
||||
price = d/gmst.find("fTravelMult")->getFloat();
|
||||
|
@ -65,7 +66,8 @@ namespace MWGui
|
|||
|
||||
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true);
|
||||
|
||||
MyGUI::Button* toAdd = mDestinationsView->createWidget<MyGUI::Button>((price>MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default);
|
||||
MyGUI::Button* toAdd = mDestinationsView->createWidget<MyGUI::Button>("SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default);
|
||||
toAdd->setEnabled(price<=playerGold);
|
||||
mCurrentY += sLineHeight;
|
||||
if(interior)
|
||||
toAdd->setUserString("interior","y");
|
||||
|
@ -121,13 +123,14 @@ namespace MWGui
|
|||
int price;
|
||||
iss >> price;
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()<price)
|
||||
if (playerGold<price)
|
||||
return;
|
||||
|
||||
|
||||
player.getClass().getContainerStore(player).remove("gold_001", price, player);
|
||||
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player);
|
||||
|
||||
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1);
|
||||
ESM::Position pos = *_sender->getUserData<ESM::Position>();
|
||||
|
@ -145,7 +148,7 @@ namespace MWGui
|
|||
int hours = static_cast<int>(d /MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fTravelTimeMult")->getFloat());
|
||||
for(int i = 0;i < hours;i++)
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager ()->restoreDynamicStats ();
|
||||
MWBase::Environment::get().getMechanicsManager ()->rest (true);
|
||||
}
|
||||
MWBase::Environment::get().getWorld()->advanceTime(hours);
|
||||
|
||||
|
@ -166,7 +169,10 @@ namespace MWGui
|
|||
|
||||
void TravelWindow::updateLabels()
|
||||
{
|
||||
mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()));
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
|
||||
|
||||
mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(playerGold));
|
||||
mPlayerGold->setCoord(8,
|
||||
mPlayerGold->getTop(),
|
||||
mPlayerGold->getTextSize().width,
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
|
@ -49,6 +48,7 @@ namespace MWGui
|
|||
, mRemainingTime(0.05)
|
||||
, mCurHour(0)
|
||||
, mManualHours(1)
|
||||
, mInterruptAt(-1)
|
||||
{
|
||||
getWidget(mDateTimeText, "DateTimeText");
|
||||
getWidget(mRestText, "RestText");
|
||||
|
@ -103,43 +103,7 @@ namespace MWGui
|
|||
|
||||
void WaitDialog::onUntilHealedButtonClicked(MyGUI::Widget* sender)
|
||||
{
|
||||
// we need to sleep for a specific time, and since that isn't calculated yet, we'll do it here
|
||||
// I'm making the assumption here that the # of hours rested is calculated when rest is started
|
||||
// TODO: the rougher logic here (calculating the hourly deltas) should really go into helper funcs elsewhere
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWMechanics::CreatureStats stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
float hourlyHealthDelta = stats.getAttribute(ESM::Attribute::Endurance).getModified() * 0.1;
|
||||
|
||||
bool stunted = (stats.getMagicEffects().get(ESM::MagicEffect::StuntedMagicka).mMagnitude > 0);
|
||||
float fRestMagicMult = store.get<ESM::GameSetting>().find("fRestMagicMult")->getFloat();
|
||||
float hourlyMagickaDelta = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified();
|
||||
|
||||
// this massive duplication is why it has to be put into helper functions instead
|
||||
float fFatigueReturnBase = store.get<ESM::GameSetting>().find("fFatigueReturnBase")->getFloat();
|
||||
float fFatigueReturnMult = store.get<ESM::GameSetting>().find("fFatigueReturnMult")->getFloat();
|
||||
float fEndFatigueMult = store.get<ESM::GameSetting>().find("fEndFatigueMult")->getFloat();
|
||||
float capacity = MWWorld::Class::get(player).getCapacity(player);
|
||||
float encumbrance = MWWorld::Class::get(player).getEncumbrance(player);
|
||||
float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity);
|
||||
if (normalizedEncumbrance > 1)
|
||||
normalizedEncumbrance = 1;
|
||||
float hourlyFatigueDelta = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance);
|
||||
hourlyFatigueDelta *= 3600 * fEndFatigueMult * stats.getAttribute(ESM::Attribute::Endurance).getModified();
|
||||
|
||||
float healthHours = hourlyHealthDelta >= 0.0
|
||||
? (stats.getHealth().getBase() - stats.getHealth().getCurrent()) / hourlyHealthDelta
|
||||
: 1.0f;
|
||||
float magickaHours = stunted ? 0.0 :
|
||||
hourlyMagickaDelta >= 0.0
|
||||
? (stats.getMagicka().getBase() - stats.getMagicka().getCurrent()) / hourlyMagickaDelta
|
||||
: 1.0f;
|
||||
float fatigueHours = hourlyFatigueDelta >= 0.0
|
||||
? (stats.getFatigue().getBase() - stats.getFatigue().getCurrent()) / hourlyFatigueDelta
|
||||
: 1.0f;
|
||||
|
||||
int autoHours = int(std::ceil( std::max(std::max(healthHours, magickaHours), std::max(fatigueHours, 1.0f)) )); // this should use a variadic max if possible
|
||||
int autoHours = MWBase::Environment::get().getMechanicsManager()->getHoursToRest();
|
||||
|
||||
startWaiting(autoHours);
|
||||
}
|
||||
|
@ -151,7 +115,8 @@ namespace MWGui
|
|||
|
||||
void WaitDialog::startWaiting(int hoursToWait)
|
||||
{
|
||||
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0.2);
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
world->getFader ()->fadeOut(0.2);
|
||||
setVisible(false);
|
||||
mProgressBar.setVisible (true);
|
||||
|
||||
|
@ -159,6 +124,30 @@ namespace MWGui
|
|||
mCurHour = 0;
|
||||
mHours = hoursToWait;
|
||||
|
||||
// FIXME: move this somewhere else?
|
||||
mInterruptAt = -1;
|
||||
MWWorld::Ptr player = world->getPlayerPtr();
|
||||
if (mSleeping && player.getCell()->isExterior())
|
||||
{
|
||||
std::string regionstr = player.getCell()->mCell->mRegion;
|
||||
if (!regionstr.empty())
|
||||
{
|
||||
const ESM::Region *region = world->getStore().get<ESM::Region>().find (regionstr);
|
||||
if (!region->mSleepList.empty())
|
||||
{
|
||||
float fSleepRandMod = world->getStore().get<ESM::GameSetting>().find("fSleepRandMod")->getFloat();
|
||||
int x = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * hoursToWait; // [0, hoursRested]
|
||||
float y = fSleepRandMod * hoursToWait;
|
||||
if (x > y)
|
||||
{
|
||||
float fSleepRestMod = world->getStore().get<ESM::GameSetting>().find("fSleepRestMod")->getFloat();
|
||||
mInterruptAt = hoursToWait - int(fSleepRestMod * hoursToWait);
|
||||
mInterruptCreatureList = region->mSleepList;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mRemainingTime = 0.05;
|
||||
mProgressBar.setProgress (0, mHours);
|
||||
}
|
||||
|
@ -176,7 +165,7 @@ namespace MWGui
|
|||
|
||||
void WaitDialog::setCanRest (bool canRest)
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
bool full = (stats.getFatigue().getCurrent() >= stats.getFatigue().getModified())
|
||||
&& (stats.getHealth().getCurrent() >= stats.getHealth().getModified())
|
||||
|
@ -201,6 +190,13 @@ namespace MWGui
|
|||
if (!mWaiting)
|
||||
return;
|
||||
|
||||
if (mCurHour == mInterruptAt)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sSleepInterrupt}");
|
||||
MWBase::Environment::get().getWorld()->spawnRandomCreature(mInterruptCreatureList);
|
||||
stopWaiting();
|
||||
}
|
||||
|
||||
mRemainingTime -= dt;
|
||||
|
||||
while (mRemainingTime < 0)
|
||||
|
@ -212,8 +208,7 @@ namespace MWGui
|
|||
if (mCurHour <= mHours)
|
||||
{
|
||||
MWBase::Environment::get().getWorld ()->advanceTime (1);
|
||||
if (mSleeping)
|
||||
MWBase::Environment::get().getMechanicsManager ()->restoreDynamicStats ();
|
||||
MWBase::Environment::get().getMechanicsManager ()->rest (mSleeping);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,7 +225,7 @@ namespace MWGui
|
|||
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_RestBed);
|
||||
mWaiting = false;
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
const MWMechanics::NpcStats &pcstats = MWWorld::Class::get(player).getNpcStats(player);
|
||||
|
||||
// trigger levelup if possible
|
||||
|
|
|
@ -51,6 +51,9 @@ namespace MWGui
|
|||
int mManualHours; // stores the hours to rest selected via slider
|
||||
float mRemainingTime;
|
||||
|
||||
int mInterruptAt;
|
||||
std::string mInterruptCreatureList;
|
||||
|
||||
WaitDialogProgressBar mProgressBar;
|
||||
|
||||
void onUntilHealedButtonClicked(MyGUI::Widget* sender);
|
||||
|
|
|
@ -208,7 +208,8 @@ namespace MWGui
|
|||
mConsole = new Console(w,h, mConsoleOnlyScripts);
|
||||
trackWindow(mConsole, "console");
|
||||
mJournal = JournalWindow::create(JournalViewModel::create ());
|
||||
mMessageBoxManager = new MessageBoxManager();
|
||||
mMessageBoxManager = new MessageBoxManager(
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fMessageTimePerChar")->getFloat());
|
||||
mInventoryWindow = new InventoryWindow(mDragAndDrop);
|
||||
mTradeWindow = new TradeWindow();
|
||||
trackWindow(mTradeWindow, "barter");
|
||||
|
@ -677,17 +678,6 @@ namespace MWGui
|
|||
mMessageBoxManager->removeStaticMessageBox();
|
||||
}
|
||||
|
||||
void WindowManager::enterPressed ()
|
||||
{
|
||||
mMessageBoxManager->okayPressed();
|
||||
}
|
||||
|
||||
void WindowManager::activateKeyPressed ()
|
||||
{
|
||||
mMessageBoxManager->okayPressed();
|
||||
mCountDialog->cancel();
|
||||
}
|
||||
|
||||
int WindowManager::readPressedButton ()
|
||||
{
|
||||
return mMessageBoxManager->readPressedButton();
|
||||
|
|
|
@ -222,8 +222,6 @@ namespace MWGui
|
|||
virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons = std::vector<std::string>(), bool showInDialogueModeOnly = false);
|
||||
virtual void staticMessageBox(const std::string& message);
|
||||
virtual void removeStaticMessageBox();
|
||||
virtual void enterPressed ();
|
||||
virtual void activateKeyPressed ();
|
||||
virtual int readPressedButton (); ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox)
|
||||
|
||||
virtual void onFrame (float frameDuration);
|
||||
|
|
|
@ -198,14 +198,7 @@ namespace MWInput
|
|||
case A_Activate:
|
||||
resetIdleTime();
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
{
|
||||
if (MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_Container)
|
||||
toggleContainer ();
|
||||
else
|
||||
MWBase::Environment::get().getWindowManager()->activateKeyPressed();
|
||||
}
|
||||
else
|
||||
if (!MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
activate();
|
||||
break;
|
||||
case A_Journal:
|
||||
|
@ -360,7 +353,7 @@ namespace MWInput
|
|||
// if player tried to start moving, but can't (due to being overencumbered), display a notification.
|
||||
if (triedToMove)
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||
mOverencumberedMessageDelay -= dt;
|
||||
if (MWWorld::Class::get(player).getEncumbrance(player) >= MWWorld::Class::get(player).getCapacity(player))
|
||||
{
|
||||
|
@ -516,13 +509,6 @@ namespace MWInput
|
|||
|
||||
mInputBinder->keyPressed (arg);
|
||||
|
||||
if((arg.keysym.sym == SDLK_RETURN || arg.keysym.sym == SDLK_KP_ENTER)
|
||||
&& MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
{
|
||||
// Pressing enter when a messagebox is prompting for "ok" will activate the ok button
|
||||
MWBase::Environment::get().getWindowManager()->enterPressed();
|
||||
}
|
||||
|
||||
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
|
||||
|
||||
if (kc != OIS::KC_UNASSIGNED)
|
||||
|
@ -560,7 +546,7 @@ namespace MWInput
|
|||
if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0)
|
||||
{
|
||||
MyGUI::Button* b = MyGUI::InputManager::getInstance ().getMouseFocusWidget ()->castType<MyGUI::Button>(false);
|
||||
if (b)
|
||||
if (b && b->getEnabled())
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager ()->playSound ("Menu Click", 1.f, 1.f);
|
||||
}
|
||||
|
@ -735,21 +721,6 @@ namespace MWInput
|
|||
// .. but don't touch any other mode, except container.
|
||||
}
|
||||
|
||||
void InputManager::toggleContainer()
|
||||
{
|
||||
if (MyGUI::InputManager::getInstance ().isModalAny())
|
||||
return;
|
||||
|
||||
if(MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
{
|
||||
if (MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_Container)
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
else
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Container);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void InputManager::toggleConsole()
|
||||
{
|
||||
if (MyGUI::InputManager::getInstance ().isModalAny())
|
||||
|
|
|
@ -173,7 +173,6 @@ namespace MWInput
|
|||
void toggleSpell();
|
||||
void toggleWeapon();
|
||||
void toggleInventory();
|
||||
void toggleContainer();
|
||||
void toggleConsole();
|
||||
void screenshot();
|
||||
void toggleJournal();
|
||||
|
|
|
@ -205,4 +205,22 @@ namespace MWMechanics
|
|||
}
|
||||
mSpellsChanged = true;
|
||||
}
|
||||
|
||||
void ActiveSpells::purge(const std::string &actorHandle)
|
||||
{
|
||||
for (TContainer::iterator it = mSpells.begin(); it != mSpells.end(); ++it)
|
||||
{
|
||||
for (std::vector<Effect>::iterator effectIt = it->second.mEffects.begin();
|
||||
effectIt != it->second.mEffects.end();)
|
||||
{
|
||||
const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effectIt->mKey.mId);
|
||||
if (effect->mData.mFlags & ESM::MagicEffect::CasterLinked
|
||||
&& it->second.mCasterHandle == actorHandle)
|
||||
effectIt = it->second.mEffects.erase(effectIt);
|
||||
else
|
||||
effectIt++;
|
||||
}
|
||||
}
|
||||
mSpellsChanged = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,6 +90,9 @@ namespace MWMechanics
|
|||
/// Remove all active effects, if roll succeeds (for each effect)
|
||||
void purgeAll (float chance);
|
||||
|
||||
/// Remove all effects with CASTER_LINKED flag that were cast by \a actorHandle
|
||||
void purge (const std::string& actorHandle);
|
||||
|
||||
bool isSpellActive (std::string id) const;
|
||||
///< case insensitive
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwworld/actionequip.hpp"
|
||||
|
||||
|
@ -80,9 +79,26 @@ bool disintegrateSlot (MWWorld::Ptr ptr, int slot, float disintegrate)
|
|||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void getRestorationPerHourOfSleep (const MWWorld::Ptr& ptr, float& health, float& magicka)
|
||||
{
|
||||
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr);
|
||||
const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
|
||||
bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).mMagnitude > 0;
|
||||
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
|
||||
|
||||
health = 0.1 * endurance;
|
||||
|
||||
magicka = 0;
|
||||
if (!stunted)
|
||||
{
|
||||
float fRestMagicMult = settings.find("fRestMagicMult")->getFloat ();
|
||||
magicka = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -158,50 +174,49 @@ namespace MWMechanics
|
|||
calculateDynamicStats (ptr);
|
||||
calculateCreatureStatModifiers (ptr, duration);
|
||||
|
||||
if(!MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
// AI
|
||||
if(MWBase::Environment::get().getMechanicsManager()->isAIActive())
|
||||
{
|
||||
// AI
|
||||
if(MWBase::Environment::get().getMechanicsManager()->isAIActive())
|
||||
CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
|
||||
//engage combat or not?
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
if(ptr != player && !creatureStats.isHostile())
|
||||
{
|
||||
CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
|
||||
//engage combat or not?
|
||||
if(ptr != MWBase::Environment::get().getWorld()->getPlayer().getPlayer() && !creatureStats.isHostile())
|
||||
ESM::Position playerpos = player.getRefData().getPosition();
|
||||
ESM::Position actorpos = ptr.getRefData().getPosition();
|
||||
float d = sqrt((actorpos.pos[0] - playerpos.pos[0])*(actorpos.pos[0] - playerpos.pos[0])
|
||||
+(actorpos.pos[1] - playerpos.pos[1])*(actorpos.pos[1] - playerpos.pos[1])
|
||||
+(actorpos.pos[2] - playerpos.pos[2])*(actorpos.pos[2] - playerpos.pos[2]));
|
||||
float fight = ptr.getClass().getCreatureStats(ptr).getAiSetting(CreatureStats::AI_Fight).getModified();
|
||||
float disp = 100; //creatures don't have disposition, so set it to 100 by default
|
||||
if(ptr.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
ESM::Position playerpos = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getRefData().getPosition();
|
||||
ESM::Position actorpos = ptr.getRefData().getPosition();
|
||||
float d = sqrt((actorpos.pos[0] - playerpos.pos[0])*(actorpos.pos[0] - playerpos.pos[0])
|
||||
+(actorpos.pos[1] - playerpos.pos[1])*(actorpos.pos[1] - playerpos.pos[1])
|
||||
+(actorpos.pos[2] - playerpos.pos[2])*(actorpos.pos[2] - playerpos.pos[2]));
|
||||
float fight = ptr.getClass().getCreatureStats(ptr).getAiSetting(CreatureStats::AI_Fight).getModified();
|
||||
float disp = 100; //creatures don't have disposition, so set it to 100 by default
|
||||
if(ptr.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
disp = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(ptr);
|
||||
}
|
||||
bool LOS = MWBase::Environment::get().getWorld()->getLOS(ptr,MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
if( ( (fight == 100 )
|
||||
|| (fight >= 95 && d <= 3000)
|
||||
|| (fight >= 90 && d <= 2000)
|
||||
|| (fight >= 80 && d <= 1000)
|
||||
|| (fight >= 80 && disp <= 40)
|
||||
|| (fight >= 70 && disp <= 35 && d <= 1000)
|
||||
|| (fight >= 60 && disp <= 30 && d <= 1000)
|
||||
|| (fight >= 50 && disp == 0)
|
||||
|| (fight >= 40 && disp <= 10 && d <= 500) )
|
||||
&& LOS
|
||||
)
|
||||
{
|
||||
creatureStats.getAiSequence().stack(AiCombat("player"));
|
||||
creatureStats.setHostile(true);
|
||||
}
|
||||
disp = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(ptr);
|
||||
}
|
||||
bool LOS = MWBase::Environment::get().getWorld()->getLOS(ptr,player)
|
||||
&& MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr);
|
||||
if( ( (fight == 100 )
|
||||
|| (fight >= 95 && d <= 3000)
|
||||
|| (fight >= 90 && d <= 2000)
|
||||
|| (fight >= 80 && d <= 1000)
|
||||
|| (fight >= 80 && disp <= 40)
|
||||
|| (fight >= 70 && disp <= 35 && d <= 1000)
|
||||
|| (fight >= 60 && disp <= 30 && d <= 1000)
|
||||
|| (fight >= 50 && disp == 0)
|
||||
|| (fight >= 40 && disp <= 10 && d <= 500) )
|
||||
&& LOS
|
||||
)
|
||||
{
|
||||
creatureStats.getAiSequence().stack(AiCombat("player"));
|
||||
creatureStats.setHostile(true);
|
||||
}
|
||||
|
||||
creatureStats.getAiSequence().execute (ptr,duration);
|
||||
}
|
||||
|
||||
// fatigue restoration
|
||||
calculateRestoration(ptr, duration);
|
||||
creatureStats.getAiSequence().execute (ptr,duration);
|
||||
}
|
||||
|
||||
// fatigue restoration
|
||||
calculateRestoration(ptr, duration, false);
|
||||
}
|
||||
|
||||
void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused)
|
||||
|
@ -259,44 +274,37 @@ namespace MWMechanics
|
|||
creatureStats.setFatigue(fatigue);
|
||||
}
|
||||
|
||||
void Actors::calculateRestoration (const MWWorld::Ptr& ptr, float duration)
|
||||
void Actors::calculateRestoration (const MWWorld::Ptr& ptr, float duration, bool sleep)
|
||||
{
|
||||
if (ptr.getClass().getCreatureStats(ptr).isDead())
|
||||
return;
|
||||
CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
|
||||
|
||||
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr);
|
||||
const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
|
||||
if (sleep)
|
||||
{
|
||||
float health, magicka;
|
||||
getRestorationPerHourOfSleep(ptr, health, magicka);
|
||||
|
||||
DynamicStat<float> stat = stats.getHealth();
|
||||
stat.setCurrent(stat.getCurrent() + health);
|
||||
stats.setHealth(stat);
|
||||
|
||||
stat = stats.getMagicka();
|
||||
stat.setCurrent(stat.getCurrent() + magicka);
|
||||
stats.setMagicka(stat);
|
||||
}
|
||||
|
||||
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
|
||||
|
||||
float capacity = MWWorld::Class::get(ptr).getCapacity(ptr);
|
||||
float encumbrance = MWWorld::Class::get(ptr).getEncumbrance(ptr);
|
||||
float capacity = ptr.getClass().getCapacity(ptr);
|
||||
float encumbrance = ptr.getClass().getEncumbrance(ptr);
|
||||
float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity);
|
||||
if (normalizedEncumbrance > 1)
|
||||
normalizedEncumbrance = 1;
|
||||
|
||||
if (duration == 3600)
|
||||
{
|
||||
// the actor is sleeping, restore health and magicka
|
||||
|
||||
bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).mMagnitude > 0;
|
||||
|
||||
DynamicStat<float> health = stats.getHealth();
|
||||
health.setCurrent (health.getCurrent() + 0.1 * endurance);
|
||||
stats.setHealth (health);
|
||||
|
||||
if (!stunted)
|
||||
{
|
||||
float fRestMagicMult = settings.find("fRestMagicMult")->getFloat ();
|
||||
|
||||
DynamicStat<float> magicka = stats.getMagicka();
|
||||
magicka.setCurrent (magicka.getCurrent()
|
||||
+ fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified());
|
||||
stats.setMagicka (magicka);
|
||||
}
|
||||
}
|
||||
|
||||
// restore fatigue
|
||||
|
||||
float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat ();
|
||||
float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat ();
|
||||
float fEndFatigueMult = settings.find("fEndFatigueMult")->getFloat ();
|
||||
|
@ -307,6 +315,7 @@ namespace MWMechanics
|
|||
DynamicStat<float> fatigue = stats.getFatigue();
|
||||
fatigue.setCurrent (fatigue.getCurrent() + duration * x);
|
||||
stats.setFatigue (fatigue);
|
||||
|
||||
}
|
||||
|
||||
void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr, float duration)
|
||||
|
@ -336,7 +345,7 @@ namespace MWMechanics
|
|||
float currentDiff = creatureStats.getMagicEffects().get(ESM::MagicEffect::RestoreHealth+i).mMagnitude
|
||||
- creatureStats.getMagicEffects().get(ESM::MagicEffect::DamageHealth+i).mMagnitude
|
||||
- creatureStats.getMagicEffects().get(ESM::MagicEffect::AbsorbHealth+i).mMagnitude;
|
||||
stat.setCurrent(stat.getCurrent() + currentDiff * duration);
|
||||
stat.setCurrent(stat.getCurrent() + currentDiff * duration, i == 2);
|
||||
|
||||
creatureStats.setDynamic(i, stat);
|
||||
}
|
||||
|
@ -506,7 +515,7 @@ namespace MWMechanics
|
|||
if (magnitude > 0)
|
||||
{
|
||||
ESM::Position ipos = ptr.getRefData().getPosition();
|
||||
Ogre::Vector3 pos(ipos.pos[0],ipos.pos[1],ipos.pos[2]);
|
||||
Ogre::Vector3 pos(ipos.pos);
|
||||
Ogre::Quaternion rot(Ogre::Radian(-ipos.rot[2]), Ogre::Vector3::UNIT_Z);
|
||||
const float distance = 50;
|
||||
pos = pos + distance*rot.yAxis();
|
||||
|
@ -527,7 +536,7 @@ namespace MWMechanics
|
|||
ref.getPtr().getCellRef().mPos = ipos;
|
||||
|
||||
// TODO: Add AI to follow player and fight for him
|
||||
|
||||
// TODO: VFX_SummonStart, VFX_SummonEnd
|
||||
creatureStats.mSummonedCreatures.insert(std::make_pair(it->first,
|
||||
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),*store,ipos).getRefData().getHandle()));
|
||||
}
|
||||
|
@ -583,10 +592,11 @@ namespace MWMechanics
|
|||
if(timeLeft == 0.0f)
|
||||
{
|
||||
// If drowning, apply 3 points of damage per second
|
||||
ptr.getClass().setActorHealth(ptr, stats.getHealth().getCurrent() - 3.0f*duration);
|
||||
static const float fSuffocationDamage = world->getStore().get<ESM::GameSetting>().find("fSuffocationDamage")->getFloat();
|
||||
ptr.getClass().setActorHealth(ptr, stats.getHealth().getCurrent() - fSuffocationDamage*duration);
|
||||
|
||||
// Play a drowning sound as necessary for the player
|
||||
if(ptr == world->getPlayer().getPlayer())
|
||||
if(ptr == world->getPlayerPtr())
|
||||
{
|
||||
MWBase::SoundManager *sndmgr = MWBase::Environment::get().getSoundManager();
|
||||
if(!sndmgr->getSoundPlaying(MWWorld::Ptr(), "drown"))
|
||||
|
@ -595,7 +605,10 @@ namespace MWMechanics
|
|||
}
|
||||
}
|
||||
else
|
||||
stats.setTimeToStartDrowning(20);
|
||||
{
|
||||
static const float fHoldBreathTime = world->getStore().get<ESM::GameSetting>().find("fHoldBreathTime")->getFloat();
|
||||
stats.setTimeToStartDrowning(fHoldBreathTime);
|
||||
}
|
||||
}
|
||||
|
||||
void Actors::updateEquippedLight (const MWWorld::Ptr& ptr, float duration)
|
||||
|
@ -797,6 +810,14 @@ namespace MWMechanics
|
|||
}
|
||||
}
|
||||
|
||||
// Make sure spell effects with CasterLinked flag are removed
|
||||
// TODO: would be nice not to do this all the time...
|
||||
for(PtrControllerMap::iterator iter2(mActors.begin());iter2 != mActors.end();++iter2)
|
||||
{
|
||||
MWMechanics::ActiveSpells& spells = iter2->first.getClass().getCreatureStats(iter2->first).getActiveSpells();
|
||||
spells.purge(iter->first.getRefData().getHandle());
|
||||
}
|
||||
|
||||
if (iter->second->kill())
|
||||
{
|
||||
++mDeathCount[cls.getId(iter->first)];
|
||||
|
@ -837,10 +858,28 @@ namespace MWMechanics
|
|||
}
|
||||
}
|
||||
}
|
||||
void Actors::restoreDynamicStats()
|
||||
void Actors::restoreDynamicStats(bool sleep)
|
||||
{
|
||||
for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
|
||||
calculateRestoration(iter->first, 3600);
|
||||
calculateRestoration(iter->first, 3600, sleep);
|
||||
}
|
||||
|
||||
int Actors::getHoursToRest(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
float healthPerHour, magickaPerHour;
|
||||
getRestorationPerHourOfSleep(ptr, healthPerHour, magickaPerHour);
|
||||
|
||||
CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
||||
|
||||
float healthHours = healthPerHour >= 0
|
||||
? (stats.getHealth().getModified() - stats.getHealth().getCurrent()) / healthPerHour
|
||||
: 1.0f;
|
||||
float magickaHours = magickaPerHour >= 0
|
||||
? (stats.getMagicka().getModified() - stats.getMagicka().getCurrent()) / magickaPerHour
|
||||
: 1.0f;
|
||||
|
||||
int autoHours = std::ceil(std::max(1.f, std::max(healthHours, magickaHours)));
|
||||
return autoHours;
|
||||
}
|
||||
|
||||
int Actors::countDeaths (const std::string& id) const
|
||||
|
|
|
@ -25,9 +25,6 @@ namespace MWMechanics
|
|||
{
|
||||
class Actors
|
||||
{
|
||||
typedef std::map<MWWorld::Ptr,CharacterController*> PtrControllerMap;
|
||||
PtrControllerMap mActors;
|
||||
|
||||
std::map<std::string, int> mDeathCount;
|
||||
|
||||
void updateNpc(const MWWorld::Ptr &ptr, float duration, bool paused);
|
||||
|
@ -39,7 +36,7 @@ namespace MWMechanics
|
|||
void calculateCreatureStatModifiers (const MWWorld::Ptr& ptr, float duration);
|
||||
void calculateNpcStatModifiers (const MWWorld::Ptr& ptr);
|
||||
|
||||
void calculateRestoration (const MWWorld::Ptr& ptr, float duration);
|
||||
void calculateRestoration (const MWWorld::Ptr& ptr, float duration, bool sleep);
|
||||
|
||||
void updateDrowning (const MWWorld::Ptr& ptr, float duration);
|
||||
|
||||
|
@ -50,6 +47,11 @@ namespace MWMechanics
|
|||
Actors();
|
||||
~Actors();
|
||||
|
||||
typedef std::map<MWWorld::Ptr,CharacterController*> PtrControllerMap;
|
||||
|
||||
PtrControllerMap::const_iterator begin() { return mActors.begin(); }
|
||||
PtrControllerMap::const_iterator end() { return mActors.end(); }
|
||||
|
||||
/// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently
|
||||
/// paused we may want to do it manually (after equipping permanent enchantment)
|
||||
void updateMagicEffects (const MWWorld::Ptr& ptr) { adjustMagicEffects(ptr); }
|
||||
|
@ -77,8 +79,11 @@ namespace MWMechanics
|
|||
///< This function is normally called automatically during the update process, but it can
|
||||
/// also be called explicitly at any time to force an update.
|
||||
|
||||
void restoreDynamicStats();
|
||||
void restoreDynamicStats(bool sleep);
|
||||
///< If the player is sleeping, this should be called every hour.
|
||||
|
||||
int getHoursToRest(const MWWorld::Ptr& ptr) const;
|
||||
///< Calculate how many hours the given actor needs to rest in order to be fully healed
|
||||
|
||||
int countDeaths (const std::string& id) const;
|
||||
///< Return the number of deaths for actors with the given ID.
|
||||
|
@ -88,6 +93,10 @@ namespace MWMechanics
|
|||
void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
|
||||
void skipAnimation(const MWWorld::Ptr& ptr);
|
||||
bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName);
|
||||
|
||||
private:
|
||||
PtrControllerMap mActors;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
#include "aiactivate.hpp"
|
||||
#include <iostream>
|
||||
#include <iostream>
|
||||
|
||||
MWMechanics::AiActivate::AiActivate(const std::string &objectId)
|
||||
: mObjectId(objectId)
|
||||
{
|
||||
}
|
||||
MWMechanics::AiActivate *MWMechanics::AiActivate::clone() const
|
||||
{
|
||||
return new AiActivate(*this);
|
||||
}
|
||||
bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration)
|
||||
{
|
||||
std::cout << "AiActivate completed.\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
int MWMechanics::AiActivate::getTypeId() const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
MWMechanics::AiActivate::AiActivate(const std::string &objectId)
|
||||
: mObjectId(objectId)
|
||||
{
|
||||
}
|
||||
MWMechanics::AiActivate *MWMechanics::AiActivate::clone() const
|
||||
{
|
||||
return new AiActivate(*this);
|
||||
}
|
||||
bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration)
|
||||
{
|
||||
std::cout << "AiActivate completed.\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
int MWMechanics::AiActivate::getTypeId() const
|
||||
{
|
||||
return TypeIdActivate;
|
||||
}
|
||||
|
|
|
@ -3,22 +3,22 @@
|
|||
#include "movement.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/timestamp.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
#include "../mwbase/dialoguemanager.hpp"
|
||||
|
||||
#include "creaturestats.hpp"
|
||||
#include "npcstats.hpp"
|
||||
|
||||
#include "OgreMath.h"
|
||||
#include <OgreMath.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
static float sgn(float a)
|
||||
static float sgn(Ogre::Radian a)
|
||||
{
|
||||
if(a > 0)
|
||||
if(a.valueDegrees() > 0)
|
||||
return 1.0;
|
||||
return -1.0;
|
||||
}
|
||||
|
@ -40,13 +40,13 @@ namespace MWMechanics
|
|||
|
||||
if(MWWorld::Class::get(actor).getCreatureStats(actor).getHealth().getCurrent() <= 0) return true;
|
||||
|
||||
actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true);
|
||||
|
||||
if(actor.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
MWWorld::Class::get(actor).
|
||||
MWWorld::Class::get(actor).setStance(actor, MWWorld::Class::Run,true);
|
||||
MWMechanics::DrawState_ state = MWWorld::Class::get(actor).getNpcStats(actor).getDrawState();
|
||||
MWMechanics::DrawState_ state = actor.getClass().getNpcStats(actor).getDrawState();
|
||||
if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing)
|
||||
MWWorld::Class::get(actor).getNpcStats(actor).setDrawState(MWMechanics::DrawState_Weapon);
|
||||
actor.getClass().getNpcStats(actor).setDrawState(MWMechanics::DrawState_Weapon);
|
||||
//MWWorld::Class::get(actor).getCreatureStats(actor).setAttackingOrSpell(true);
|
||||
}
|
||||
ESM::Position pos = actor.getRefData().getPosition();
|
||||
|
@ -106,7 +106,7 @@ namespace MWMechanics
|
|||
float directionY = dest.mY - start.mY;
|
||||
float directionResult = sqrt(directionX * directionX + directionY * directionY);
|
||||
|
||||
zAngle = Ogre::Radian( acos(directionY / directionResult) * sgn(asin(directionX / directionResult)) ).valueDegrees();
|
||||
zAngle = Ogre::Radian( Ogre::Math::ACos(directionY / directionResult) * sgn(Ogre::Math::ASin(directionX / directionResult)) ).valueDegrees();
|
||||
// TODO: use movement settings instead of rotating directly
|
||||
MWBase::Environment::get().getWorld()->rotateObject(actor, 0, 0, zAngle, false);
|
||||
|
||||
|
@ -119,6 +119,17 @@ namespace MWMechanics
|
|||
}
|
||||
if( mTimer > 1)
|
||||
{
|
||||
if (actor.getClass().isNpc())
|
||||
{
|
||||
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||
int chance = store.get<ESM::GameSetting>().find("iVoiceAttackOdds")->getInt();
|
||||
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
|
||||
if (roll < chance)
|
||||
{
|
||||
MWBase::Environment::get().getDialogueManager()->say(actor, "attack");
|
||||
}
|
||||
}
|
||||
|
||||
MWWorld::Class::get(actor).getCreatureStats(actor).setAttackingOrSpell(true);
|
||||
mTimer = 0;
|
||||
}
|
||||
|
@ -135,7 +146,7 @@ namespace MWMechanics
|
|||
|
||||
int AiCombat::getTypeId() const
|
||||
{
|
||||
return 5;
|
||||
return TypeIdCombat;
|
||||
}
|
||||
|
||||
unsigned int AiCombat::getPriority() const
|
||||
|
@ -143,6 +154,11 @@ namespace MWMechanics
|
|||
return 1;
|
||||
}
|
||||
|
||||
const std::string &AiCombat::getTargetId() const
|
||||
{
|
||||
return mTargetId;
|
||||
}
|
||||
|
||||
AiCombat *MWMechanics::AiCombat::clone() const
|
||||
{
|
||||
return new AiCombat(*this);
|
||||
|
|
|
@ -23,6 +23,8 @@ namespace MWMechanics
|
|||
|
||||
virtual unsigned int getPriority() const;
|
||||
|
||||
const std::string &getTargetId() const;
|
||||
|
||||
private:
|
||||
std::string mTargetId;
|
||||
|
||||
|
@ -33,4 +35,4 @@ namespace MWMechanics
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include "movement.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/timestamp.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
@ -83,7 +82,7 @@ namespace MWMechanics
|
|||
return true;
|
||||
}
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
ESM::Position pos = actor.getRefData().getPosition();
|
||||
bool cellChange = actor.getCell()->mCell->mData.mX != cellX || actor.getCell()->mCell->mData.mY != cellY;
|
||||
const ESM::Pathgrid *pathgrid =
|
||||
|
@ -179,7 +178,7 @@ namespace MWMechanics
|
|||
|
||||
int AiEscort::getTypeId() const
|
||||
{
|
||||
return 2;
|
||||
return TypeIdEscort;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "aifollow.hpp"
|
||||
#include <iostream>
|
||||
#include <iostream>
|
||||
|
||||
MWMechanics::AiFollow::AiFollow(const std::string &actorId,float duration, float x, float y, float z)
|
||||
MWMechanics::AiFollow::AiFollow(const std::string &actorId,float duration, float x, float y, float z)
|
||||
: mDuration(duration), mX(x), mY(y), mZ(z), mActorId(actorId)
|
||||
{
|
||||
}
|
||||
|
@ -10,18 +10,18 @@ MWMechanics::AiFollow::AiFollow(const std::string &actorId,const std::string &ce
|
|||
{
|
||||
}
|
||||
|
||||
MWMechanics::AiFollow *MWMechanics::AiFollow::clone() const
|
||||
{
|
||||
return new AiFollow(*this);
|
||||
}
|
||||
|
||||
bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
|
||||
{
|
||||
std::cout << "AiFollow completed.\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
int MWMechanics::AiFollow::getTypeId() const
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
MWMechanics::AiFollow *MWMechanics::AiFollow::clone() const
|
||||
{
|
||||
return new AiFollow(*this);
|
||||
}
|
||||
|
||||
bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
|
||||
{
|
||||
std::cout << "AiFollow completed.\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
int MWMechanics::AiFollow::getTypeId() const
|
||||
{
|
||||
return TypeIdFollow;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,16 @@ namespace MWMechanics
|
|||
class AiPackage
|
||||
{
|
||||
public:
|
||||
|
||||
enum TypeId {
|
||||
TypeIdNone = -1,
|
||||
TypeIdWander = 0,
|
||||
TypeIdTravel = 1,
|
||||
TypeIdEscort = 2,
|
||||
TypeIdFollow = 3,
|
||||
TypeIdActivate = 4,
|
||||
TypeIdCombat = 5
|
||||
};
|
||||
|
||||
virtual ~AiPackage();
|
||||
|
||||
virtual AiPackage *clone() const = 0;
|
||||
|
@ -21,7 +30,7 @@ namespace MWMechanics
|
|||
///< \return Package completed?
|
||||
|
||||
virtual int getTypeId() const = 0;
|
||||
///< 0: Wanter, 1 Travel, 2 Escort, 3 Follow, 4 Activate
|
||||
///< @see enum TypeId
|
||||
|
||||
virtual unsigned int getPriority() const {return 0;}
|
||||
///< higher number is higher priority (0 beeing the lowest)
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "npcstats.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
void MWMechanics::AiSequence::copy (const AiSequence& sequence)
|
||||
{
|
||||
|
@ -56,6 +55,24 @@ int MWMechanics::AiSequence::getTypeId() const
|
|||
return mPackages.front()->getTypeId();
|
||||
}
|
||||
|
||||
bool MWMechanics::AiSequence::getCombatTarget(std::string &targetActorId) const
|
||||
{
|
||||
if (getTypeId() != AiPackage::TypeIdCombat)
|
||||
return false;
|
||||
const AiCombat *combat = static_cast<const AiCombat *>(mPackages.front());
|
||||
targetActorId = combat->getTargetId();
|
||||
return true;
|
||||
}
|
||||
|
||||
void MWMechanics::AiSequence::stopCombat()
|
||||
{
|
||||
while (getTypeId() == AiPackage::TypeIdCombat)
|
||||
{
|
||||
delete *mPackages.begin();
|
||||
mPackages.erase (mPackages.begin());
|
||||
}
|
||||
}
|
||||
|
||||
bool MWMechanics::AiSequence::isPackageDone() const
|
||||
{
|
||||
return mDone;
|
||||
|
@ -63,12 +80,13 @@ bool MWMechanics::AiSequence::isPackageDone() const
|
|||
|
||||
void MWMechanics::AiSequence::execute (const MWWorld::Ptr& actor,float duration)
|
||||
{
|
||||
if(actor != MWBase::Environment::get().getWorld()->getPlayer().getPlayer())
|
||||
if(actor != MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||
{
|
||||
if (!mPackages.empty())
|
||||
{
|
||||
if (mPackages.front()->execute (actor,duration))
|
||||
{
|
||||
delete *mPackages.begin();
|
||||
mPackages.erase (mPackages.begin());
|
||||
mDone = true;
|
||||
}
|
||||
|
@ -91,7 +109,10 @@ void MWMechanics::AiSequence::stack (const AiPackage& package)
|
|||
for(std::list<AiPackage *>::iterator it = mPackages.begin(); it != mPackages.end(); it++)
|
||||
{
|
||||
if(mPackages.front()->getPriority() <= package.getPriority())
|
||||
{
|
||||
mPackages.insert(it,package.clone());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(mPackages.empty())
|
||||
|
@ -114,7 +135,7 @@ void MWMechanics::AiSequence::fill(const ESM::AIPackageList &list)
|
|||
std::vector<int> idles;
|
||||
for (int i=0; i<8; ++i)
|
||||
idles.push_back(data.mIdle[i]);
|
||||
package = new MWMechanics::AiWander(data.mDistance, data.mDuration, data.mTimeOfDay, idles, data.mUnk);
|
||||
package = new MWMechanics::AiWander(data.mDistance, data.mDuration, data.mTimeOfDay, idles, data.mShouldRepeat);
|
||||
}
|
||||
else if (it->mType == ESM::AI_Escort)
|
||||
{
|
||||
|
|
|
@ -34,7 +34,14 @@ namespace MWMechanics
|
|||
virtual ~AiSequence();
|
||||
|
||||
int getTypeId() const;
|
||||
///< -1: None, 0: Wanter, 1 Travel, 2 Escort, 3 Follow, 4 Activate, 5 Combat
|
||||
///< @see enum AiPackage::TypeId
|
||||
|
||||
bool getCombatTarget (std::string &targetActorId) const;
|
||||
///< Return true and assign target if combat package is currently
|
||||
/// active, return false otherwise
|
||||
|
||||
void stopCombat();
|
||||
///< Removes all combat packages until first non-combat or stack empty.
|
||||
|
||||
bool isPackageDone() const;
|
||||
///< Has a package been completed during the last update?
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue