forked from teamnwah/openmw-tes3coop
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
|
set(OENGINE_BULLET
|
||||||
${LIBDIR}/openengine/bullet/btKinematicCharacterController.cpp
|
|
||||||
${LIBDIR}/openengine/bullet/btKinematicCharacterController.h
|
|
||||||
${LIBDIR}/openengine/bullet/BtOgre.cpp
|
${LIBDIR}/openengine/bullet/BtOgre.cpp
|
||||||
${LIBDIR}/openengine/bullet/BtOgreExtras.h
|
${LIBDIR}/openengine/bullet/BtOgreExtras.h
|
||||||
${LIBDIR}/openengine/bullet/BtOgreGP.h
|
${LIBDIR}/openengine/bullet/BtOgreGP.h
|
||||||
|
@ -183,10 +181,11 @@ if (WIN32)
|
||||||
set(Boost_USE_STATIC_LIBS ON)
|
set(Boost_USE_STATIC_LIBS ON)
|
||||||
set(PLATFORM_INCLUDE_DIR "platform")
|
set(PLATFORM_INCLUDE_DIR "platform")
|
||||||
add_definitions(-DBOOST_ALL_NO_LIB)
|
add_definitions(-DBOOST_ALL_NO_LIB)
|
||||||
|
|
||||||
|
# Suppress WinMain(), provided by SDL
|
||||||
|
add_definitions(-DSDL_MAIN_HANDLED)
|
||||||
else (WIN32)
|
else (WIN32)
|
||||||
set(PLATFORM_INCLUDE_DIR "")
|
set(PLATFORM_INCLUDE_DIR "")
|
||||||
find_path (UUID_INCLUDE_DIR uuid/uuid.h)
|
|
||||||
include_directories(${UUID_INCLUDE_DIR})
|
|
||||||
endif (WIN32)
|
endif (WIN32)
|
||||||
if (MSVC10)
|
if (MSVC10)
|
||||||
set(PLATFORM_INCLUDE_DIR "")
|
set(PLATFORM_INCLUDE_DIR "")
|
||||||
|
@ -238,7 +237,6 @@ include_directories("."
|
||||||
${MYGUI_INCLUDE_DIRS}
|
${MYGUI_INCLUDE_DIRS}
|
||||||
${MYGUI_PLATFORM_INCLUDE_DIRS}
|
${MYGUI_PLATFORM_INCLUDE_DIRS}
|
||||||
${OPENAL_INCLUDE_DIR}
|
${OPENAL_INCLUDE_DIR}
|
||||||
${UUID_INCLUDE_DIR}
|
|
||||||
${LIBDIR}
|
${LIBDIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -408,46 +406,6 @@ IF(NOT WIN32 AND NOT APPLE)
|
||||||
# Install resources
|
# Install resources
|
||||||
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT "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")
|
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)
|
ENDIF(NOT WIN32 AND NOT APPLE)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|
|
@ -680,7 +680,7 @@ std::string creatureFlags(int flags)
|
||||||
if (flags & ESM::Creature::Walks) properties += "Walks ";
|
if (flags & ESM::Creature::Walks) properties += "Walks ";
|
||||||
if (flags & ESM::Creature::Swims) properties += "Swims ";
|
if (flags & ESM::Creature::Swims) properties += "Swims ";
|
||||||
if (flags & ESM::Creature::Flies) properties += "Flies ";
|
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::Respawn) properties += "Respawn ";
|
||||||
if (flags & ESM::Creature::Weapon) properties += "Weapon ";
|
if (flags & ESM::Creature::Weapon) properties += "Weapon ";
|
||||||
if (flags & ESM::Creature::Skeleton) properties += "Skeleton ";
|
if (flags & ESM::Creature::Skeleton) properties += "Skeleton ";
|
||||||
|
@ -691,7 +691,7 @@ std::string creatureFlags(int flags)
|
||||||
ESM::Creature::Walks|
|
ESM::Creature::Walks|
|
||||||
ESM::Creature::Swims|
|
ESM::Creature::Swims|
|
||||||
ESM::Creature::Flies|
|
ESM::Creature::Flies|
|
||||||
ESM::Creature::Biped|
|
ESM::Creature::Bipedal|
|
||||||
ESM::Creature::Respawn|
|
ESM::Creature::Respawn|
|
||||||
ESM::Creature::Weapon|
|
ESM::Creature::Weapon|
|
||||||
ESM::Creature::Skeleton|
|
ESM::Creature::Skeleton|
|
||||||
|
@ -717,16 +717,26 @@ std::string landFlags(int flags)
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string leveledListFlags(int flags)
|
std::string itemListFlags(int flags)
|
||||||
{
|
{
|
||||||
std::string properties = "";
|
std::string properties = "";
|
||||||
if (flags == 0) properties += "[None] ";
|
if (flags == 0) properties += "[None] ";
|
||||||
if (flags & ESM::LeveledListBase::AllLevels) properties += "AllLevels ";
|
if (flags & ESM::ItemLevList::AllLevels) properties += "AllLevels ";
|
||||||
// This flag apparently not present on creature lists...
|
if (flags & ESM::ItemLevList::Each) properties += "Each ";
|
||||||
if (flags & ESM::LeveledListBase::Each) properties += "Each ";
|
|
||||||
int unused = (0xFFFFFFFF ^
|
int unused = (0xFFFFFFFF ^
|
||||||
(ESM::LeveledListBase::AllLevels|
|
(ESM::ItemLevList::AllLevels|
|
||||||
ESM::LeveledListBase::Each));
|
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 ";
|
if (flags & unused) properties += "Invalid ";
|
||||||
properties += str(boost::format("(0x%08X)") % flags);
|
properties += str(boost::format("(0x%08X)") % flags);
|
||||||
return properties;
|
return properties;
|
||||||
|
@ -764,34 +774,19 @@ std::string magicEffectFlags(int flags)
|
||||||
{
|
{
|
||||||
std::string properties = "";
|
std::string properties = "";
|
||||||
if (flags == 0) properties += "[None] ";
|
if (flags == 0) properties += "[None] ";
|
||||||
// Enchanting & SpellMaking occur on the same list of effects.
|
if (flags & ESM::MagicEffect::TargetAttribute) properties += "TargetAttribute ";
|
||||||
// "EXTRA SPELL" appears in the construction set under both the
|
if (flags & ESM::MagicEffect::TargetSkill) properties += "TargetSkill ";
|
||||||
// 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::NoDuration) properties += "NoDuration ";
|
if (flags & ESM::MagicEffect::NoDuration) properties += "NoDuration ";
|
||||||
if (flags & 0x00000008) properties += "NoMagnitude ";
|
if (flags & ESM::MagicEffect::NoMagnitude) properties += "NoMagnitude ";
|
||||||
if (flags & 0x00000010) properties += "Negative ";
|
if (flags & ESM::MagicEffect::Harmful) properties += "Harmful ";
|
||||||
if (flags & 0x00000020) properties += "Unknown1 ";
|
if (flags & ESM::MagicEffect::ContinuousVfx) properties += "ContinuousVFX ";
|
||||||
// ESM componet says 0x800 is negative, but none of the magic
|
if (flags & ESM::MagicEffect::CastSelf) properties += "CastSelf ";
|
||||||
// effects have this flags set.
|
if (flags & ESM::MagicEffect::CastTouch) properties += "CastTouch ";
|
||||||
if (flags & ESM::MagicEffect::Negative) properties += "Unused ";
|
if (flags & ESM::MagicEffect::CastTarget) properties += "CastTarget ";
|
||||||
// Since only Chameleon has this flag it could be anything
|
if (flags & ESM::MagicEffect::UncappedDamage) properties += "UncappedDamage ";
|
||||||
// that uniquely distinguishes Chameleon.
|
if (flags & ESM::MagicEffect::NonRecastable) properties += "NonRecastable ";
|
||||||
if (flags & 0x00002000) properties += "Chameleon ";
|
if (flags & ESM::MagicEffect::Unreflectable) properties += "Unreflectable ";
|
||||||
if (flags & 0x00004000) properties += "Bound ";
|
if (flags & ESM::MagicEffect::CasterLinked) properties += "CasterLinked ";
|
||||||
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 & 0xFFFC0000) properties += "Invalid ";
|
if (flags & 0xFFFC0000) properties += "Invalid ";
|
||||||
properties += str(boost::format("(0x%08X)") % flags);
|
properties += str(boost::format("(0x%08X)") % flags);
|
||||||
return properties;
|
return properties;
|
||||||
|
|
|
@ -50,7 +50,8 @@ std::string cellFlags(int flags);
|
||||||
std::string containerFlags(int flags);
|
std::string containerFlags(int flags);
|
||||||
std::string creatureFlags(int flags);
|
std::string creatureFlags(int flags);
|
||||||
std::string landFlags(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 lightFlags(int flags);
|
||||||
std::string magicEffectFlags(int flags);
|
std::string magicEffectFlags(int flags);
|
||||||
std::string npcFlags(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 << " Distance: " << p.mWander.mDistance << std::endl;
|
||||||
std::cout << " Duration: " << p.mWander.mDuration << std::endl;
|
std::cout << " Duration: " << p.mWander.mDuration << std::endl;
|
||||||
std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl;
|
std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl;
|
||||||
if (p.mWander.mUnk != 1)
|
if (p.mWander.mShouldRepeat != 1)
|
||||||
std::cout << " Unknown: " << (int)p.mWander.mUnk << std::endl;
|
std::cout << " Should repeat: " << (bool)p.mWander.mShouldRepeat << std::endl;
|
||||||
|
|
||||||
std::cout << " Idle: ";
|
std::cout << " Idle: ";
|
||||||
for (int i = 0; i != 8; i++)
|
for (int i = 0; i != 8; i++)
|
||||||
|
@ -834,7 +834,7 @@ template<>
|
||||||
void Record<ESM::CreatureLevList>::print()
|
void Record<ESM::CreatureLevList>::print()
|
||||||
{
|
{
|
||||||
std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl;
|
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::cout << " Number of items: " << mData.mList.size() << std::endl;
|
||||||
std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
|
std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
|
||||||
for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++)
|
for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++)
|
||||||
|
@ -846,11 +846,11 @@ template<>
|
||||||
void Record<ESM::ItemLevList>::print()
|
void Record<ESM::ItemLevList>::print()
|
||||||
{
|
{
|
||||||
std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl;
|
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::cout << " Number of items: " << mData.mList.size() << std::endl;
|
||||||
std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
|
std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
|
||||||
for (iit = mData.mList.begin(); iit != mData.mList.end(); 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;
|
<< " Item: " << iit->mId << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -958,7 +958,7 @@ void Record<ESM::MagicEffect>::print()
|
||||||
std::cout << " RGB Color: " << "("
|
std::cout << " RGB Color: " << "("
|
||||||
<< mData.mData.mRed << ","
|
<< mData.mData.mRed << ","
|
||||||
<< mData.mData.mGreen << ","
|
<< mData.mData.mGreen << ","
|
||||||
<< mData.mData.mGreen << ")" << std::endl;
|
<< mData.mData.mBlue << ")" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
|
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
|
||||||
|
SDL_SetMainReady();
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||||
{
|
{
|
||||||
qDebug() << "SDL_Init failed: " << QString::fromStdString(SDL_GetError());
|
qDebug() << "SDL_Init failed: " << QString::fromStdString(SDL_GetError());
|
||||||
|
|
|
@ -235,7 +235,7 @@ namespace
|
||||||
{
|
{
|
||||||
for ( bfs::recursive_directory_iterator end, dir(in); dir != end; ++dir )
|
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();
|
return dir->path();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,7 +243,7 @@ namespace
|
||||||
{
|
{
|
||||||
for ( bfs::directory_iterator end, dir(in); dir != end; ++dir )
|
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();
|
return dir->path();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,7 +255,7 @@ namespace
|
||||||
{
|
{
|
||||||
for(bfs::directory_iterator end, dir(in); dir != end; ++dir)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -623,6 +623,17 @@ MwIniImporter::MwIniImporter()
|
||||||
"Moons:Masser Fade Out Finish",
|
"Moons:Masser Fade Out Finish",
|
||||||
"Moons:Script Color",
|
"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
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ opencs_units (model/tools
|
||||||
|
|
||||||
opencs_units_noqt (model/tools
|
opencs_units_noqt (model/tools
|
||||||
mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
|
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
|
const CSMWorld::UniversalId& CSMTools::ReportModel::getUniversalId (int row) const
|
||||||
{
|
{
|
||||||
return mRows.at (row).first;
|
return mRows.at (row).first;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "regioncheck.hpp"
|
#include "regioncheck.hpp"
|
||||||
#include "birthsigncheck.hpp"
|
#include "birthsigncheck.hpp"
|
||||||
#include "spellcheck.hpp"
|
#include "spellcheck.hpp"
|
||||||
|
#include "referenceablecheck.hpp"
|
||||||
|
|
||||||
CSMDoc::Operation *CSMTools::Tools::get (int type)
|
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 BirthsignCheckStage (mData.getBirthsigns()));
|
||||||
|
|
||||||
mVerifier->appendStage (new SpellCheckStage (mData.getSpells()));
|
mVerifier->appendStage (new SpellCheckStage (mData.getSpells()));
|
||||||
|
|
||||||
|
mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mVerifier;
|
return mVerifier;
|
||||||
|
@ -138,4 +141,5 @@ void CSMTools::Tools::verifierMessage (const QString& message, int type)
|
||||||
|
|
||||||
if (iter!=mActiveReports.end())
|
if (iter!=mActiveReports.end())
|
||||||
mReports[iter->second]->add (message.toStdString());
|
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);
|
std::string name2 = Misc::StringUtils::lowerCase (name);
|
||||||
|
|
||||||
for (int i=0; sNames[i].mName; ++i)
|
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 sNames[i].mId;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -67,7 +67,7 @@ int CSMWorld::InfoCollection::getIndex (const std::string& id, const std::string
|
||||||
std::pair<RecordConstIterator, RecordConstIterator> range = getTopicRange (topic);
|
std::pair<RecordConstIterator, RecordConstIterator> range = getTopicRange (topic);
|
||||||
|
|
||||||
for (; range.first!=range.second; ++range.first)
|
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 std::distance (getRecords().begin(), range.first);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -177,8 +177,8 @@ CSMWorld::InfoCollection::Range CSMWorld::InfoCollection::getTopicRange (const s
|
||||||
RecordConstIterator end = begin;
|
RecordConstIterator end = begin;
|
||||||
|
|
||||||
for (; end!=getRecords().end(); ++end)
|
for (; end!=getRecords().end(); ++end)
|
||||||
if (Misc::StringUtils::lowerCase (end->get().mTopicId)!=topic2)
|
if (!Misc::StringUtils::ciEqual(end->get().mTopicId, topic2))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
return Range (begin, end);
|
return Range (begin, end);
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,7 +181,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
||||||
unsigned int mFlag;
|
unsigned int mFlag;
|
||||||
} sCreatureFlagTable[] =
|
} sCreatureFlagTable[] =
|
||||||
{
|
{
|
||||||
{ Columns::ColumnId_Biped, ESM::Creature::Biped },
|
{ Columns::ColumnId_Biped, ESM::Creature::Bipedal },
|
||||||
{ Columns::ColumnId_HasWeapon, ESM::Creature::Weapon },
|
{ Columns::ColumnId_HasWeapon, ESM::Creature::Weapon },
|
||||||
{ Columns::ColumnId_NoMovement, ESM::Creature::None },
|
{ Columns::ColumnId_NoMovement, ESM::Creature::None },
|
||||||
{ Columns::ColumnId_Swims, ESM::Creature::Swims },
|
{ Columns::ColumnId_Swims, ESM::Creature::Swims },
|
||||||
|
@ -549,3 +549,9 @@ void CSMWorld::RefIdCollection::save (int index, ESM::ESMWriter& writer) const
|
||||||
{
|
{
|
||||||
mData.save (index, writer);
|
mData.save (index, writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CSMWorld::RefIdData& CSMWorld::RefIdCollection::getDataSet() const
|
||||||
|
{
|
||||||
|
return mData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,10 @@ namespace CSMWorld
|
||||||
/// \return Success?
|
/// \return Success?
|
||||||
|
|
||||||
void save (int index, ESM::ESMWriter& writer) const;
|
void save (int index, ESM::ESMWriter& writer) const;
|
||||||
|
|
||||||
|
const RefIdData& getDataSet() const; //I can't figure out a better name for this one :(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -230,4 +230,104 @@ void CSMWorld::RefIdData::save (int index, ESM::ESMWriter& writer) const
|
||||||
throw std::logic_error ("invalid local index type");
|
throw std::logic_error ("invalid local index type");
|
||||||
|
|
||||||
iter->second->save (localIndex.first, writer);
|
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
|
/// \param listDeleted include deleted record in the list
|
||||||
|
|
||||||
void save (int index, ESM::ESMWriter& writer) const;
|
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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
|
||||||
add_openmw_dir (mwrender
|
add_openmw_dir (mwrender
|
||||||
renderingmanager debugging sky camera animation npcanimation creatureanimation activatoranimation
|
renderingmanager debugging sky camera animation npcanimation creatureanimation activatoranimation
|
||||||
actors objects renderinginterface localmap occlusionquery water shadows
|
actors objects renderinginterface localmap occlusionquery water shadows
|
||||||
characterpreview externalrendering globalmap videoplayer ripplesimulation refraction
|
characterpreview globalmap videoplayer ripplesimulation refraction
|
||||||
terrainstorage renderconst
|
terrainstorage renderconst effectmanager
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwinput
|
add_openmw_dir (mwinput
|
||||||
|
@ -74,7 +74,7 @@ add_openmw_dir (mwmechanics
|
||||||
mechanicsmanagerimp stat character creaturestats magiceffects movement actors objects
|
mechanicsmanagerimp stat character creaturestats magiceffects movement actors objects
|
||||||
drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow
|
drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow
|
||||||
aiescort aiactivate aicombat repair enchanting pathfinding security spellsuccess spellcasting
|
aiescort aiactivate aicombat repair enchanting pathfinding security spellsuccess spellcasting
|
||||||
disease
|
disease pickpocket levelledlist
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwstate
|
add_openmw_dir (mwstate
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/ucontext.h>
|
#include <sys/ucontext.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
@ -42,78 +43,78 @@ static char altstack[SIGSTKSZ];
|
||||||
|
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
int signum;
|
int signum;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int has_siginfo;
|
int has_siginfo;
|
||||||
siginfo_t siginfo;
|
siginfo_t siginfo;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
} crash_info;
|
} crash_info;
|
||||||
|
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
int signum;
|
int signum;
|
||||||
} signals[] = {
|
} signals[] = {
|
||||||
{ "Segmentation fault", SIGSEGV },
|
{ "Segmentation fault", SIGSEGV },
|
||||||
{ "Illegal instruction", SIGILL },
|
{ "Illegal instruction", SIGILL },
|
||||||
{ "FPU exception", SIGFPE },
|
{ "FPU exception", SIGFPE },
|
||||||
{ "System BUS error", SIGBUS },
|
{ "System BUS error", SIGBUS },
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
int code;
|
int code;
|
||||||
const char *name;
|
const char *name;
|
||||||
} sigill_codes[] = {
|
} sigill_codes[] = {
|
||||||
#ifndef __FreeBSD__
|
#ifndef __FreeBSD__
|
||||||
{ ILL_ILLOPC, "Illegal opcode" },
|
{ ILL_ILLOPC, "Illegal opcode" },
|
||||||
{ ILL_ILLOPN, "Illegal operand" },
|
{ ILL_ILLOPN, "Illegal operand" },
|
||||||
{ ILL_ILLADR, "Illegal addressing mode" },
|
{ ILL_ILLADR, "Illegal addressing mode" },
|
||||||
{ ILL_ILLTRP, "Illegal trap" },
|
{ ILL_ILLTRP, "Illegal trap" },
|
||||||
{ ILL_PRVOPC, "Privileged opcode" },
|
{ ILL_PRVOPC, "Privileged opcode" },
|
||||||
{ ILL_PRVREG, "Privileged register" },
|
{ ILL_PRVREG, "Privileged register" },
|
||||||
{ ILL_COPROC, "Coprocessor error" },
|
{ ILL_COPROC, "Coprocessor error" },
|
||||||
{ ILL_BADSTK, "Internal stack error" },
|
{ ILL_BADSTK, "Internal stack error" },
|
||||||
#endif
|
#endif
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
int code;
|
int code;
|
||||||
const char *name;
|
const char *name;
|
||||||
} sigfpe_codes[] = {
|
} sigfpe_codes[] = {
|
||||||
{ FPE_INTDIV, "Integer divide by zero" },
|
{ FPE_INTDIV, "Integer divide by zero" },
|
||||||
{ FPE_INTOVF, "Integer overflow" },
|
{ FPE_INTOVF, "Integer overflow" },
|
||||||
{ FPE_FLTDIV, "Floating point divide by zero" },
|
{ FPE_FLTDIV, "Floating point divide by zero" },
|
||||||
{ FPE_FLTOVF, "Floating point overflow" },
|
{ FPE_FLTOVF, "Floating point overflow" },
|
||||||
{ FPE_FLTUND, "Floating point underflow" },
|
{ FPE_FLTUND, "Floating point underflow" },
|
||||||
{ FPE_FLTRES, "Floating point inexact result" },
|
{ FPE_FLTRES, "Floating point inexact result" },
|
||||||
{ FPE_FLTINV, "Floating point invalid operation" },
|
{ FPE_FLTINV, "Floating point invalid operation" },
|
||||||
{ FPE_FLTSUB, "Subscript out of range" },
|
{ FPE_FLTSUB, "Subscript out of range" },
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
int code;
|
int code;
|
||||||
const char *name;
|
const char *name;
|
||||||
} sigsegv_codes[] = {
|
} sigsegv_codes[] = {
|
||||||
#ifndef __FreeBSD__
|
#ifndef __FreeBSD__
|
||||||
{ SEGV_MAPERR, "Address not mapped to object" },
|
{ SEGV_MAPERR, "Address not mapped to object" },
|
||||||
{ SEGV_ACCERR, "Invalid permissions for mapped object" },
|
{ SEGV_ACCERR, "Invalid permissions for mapped object" },
|
||||||
#endif
|
#endif
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
int code;
|
int code;
|
||||||
const char *name;
|
const char *name;
|
||||||
} sigbus_codes[] = {
|
} sigbus_codes[] = {
|
||||||
#ifndef __FreeBSD__
|
#ifndef __FreeBSD__
|
||||||
{ BUS_ADRALN, "Invalid address alignment" },
|
{ BUS_ADRALN, "Invalid address alignment" },
|
||||||
{ BUS_ADRERR, "Non-existent physical address" },
|
{ BUS_ADRERR, "Non-existent physical address" },
|
||||||
{ BUS_OBJERR, "Object specific hardware error" },
|
{ BUS_OBJERR, "Object specific hardware error" },
|
||||||
#endif
|
#endif
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int (*cc_user_info)(char*, char*);
|
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)
|
static void gdb_info(pid_t pid)
|
||||||
{
|
{
|
||||||
char respfile[64];
|
char respfile[64];
|
||||||
char cmd_buf[128];
|
char cmd_buf[128];
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
/* Create a temp file to put gdb commands into */
|
/* Create a temp file to put gdb commands into */
|
||||||
strcpy(respfile, "gdb-respfile-XXXXXX");
|
strcpy(respfile, "gdb-respfile-XXXXXX");
|
||||||
if((fd=mkstemp(respfile)) >= 0 && (f=fdopen(fd, "w")) != NULL)
|
if((fd=mkstemp(respfile)) >= 0 && (f=fdopen(fd, "w")) != NULL)
|
||||||
{
|
{
|
||||||
fprintf(f, "attach %d\n"
|
fprintf(f, "attach %d\n"
|
||||||
"shell echo \"\"\n"
|
"shell echo \"\"\n"
|
||||||
"shell echo \"* Loaded Libraries\"\n"
|
"shell echo \"* Loaded Libraries\"\n"
|
||||||
"info sharedlibrary\n"
|
"info sharedlibrary\n"
|
||||||
"shell echo \"\"\n"
|
"shell echo \"\"\n"
|
||||||
"shell echo \"* Threads\"\n"
|
"shell echo \"* Threads\"\n"
|
||||||
"info threads\n"
|
"info threads\n"
|
||||||
"shell echo \"\"\n"
|
"shell echo \"\"\n"
|
||||||
"shell echo \"* FPU Status\"\n"
|
"shell echo \"* FPU Status\"\n"
|
||||||
"info float\n"
|
"info float\n"
|
||||||
"shell echo \"\"\n"
|
"shell echo \"\"\n"
|
||||||
"shell echo \"* Registers\"\n"
|
"shell echo \"* Registers\"\n"
|
||||||
"info registers\n"
|
"info registers\n"
|
||||||
"shell echo \"\"\n"
|
"shell echo \"\"\n"
|
||||||
"shell echo \"* Backtrace\"\n"
|
"shell echo \"* Backtrace\"\n"
|
||||||
"thread apply all backtrace full\n"
|
"thread apply all backtrace full\n"
|
||||||
"detach\n"
|
"detach\n"
|
||||||
"quit\n", pid);
|
"quit\n", pid);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
/* Run gdb and print process info. */
|
/* Run gdb and print process info. */
|
||||||
snprintf(cmd_buf, sizeof(cmd_buf), "gdb --quiet --batch --command=%s", respfile);
|
snprintf(cmd_buf, sizeof(cmd_buf), "gdb --quiet --batch --command=%s", respfile);
|
||||||
printf("Executing: %s\n", cmd_buf);
|
printf("Executing: %s\n", cmd_buf);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
system(cmd_buf);
|
system(cmd_buf);
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
remove(respfile);
|
remove(respfile);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Error creating temp file */
|
/* Error creating temp file */
|
||||||
if(fd >= 0)
|
if(fd >= 0)
|
||||||
{
|
{
|
||||||
close(fd);
|
close(fd);
|
||||||
remove(respfile);
|
remove(respfile);
|
||||||
}
|
}
|
||||||
printf("!!! Could not create gdb command file\n");
|
printf("!!! Could not create gdb command file\n");
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sys_info(void)
|
static void sys_info(void)
|
||||||
{
|
{
|
||||||
#ifdef __unix__
|
#ifdef __unix__
|
||||||
system("echo \"System: `uname -a`\"");
|
struct utsname info;
|
||||||
putchar('\n');
|
if(uname(&info))
|
||||||
fflush(stdout);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static size_t safe_write(int fd, const void *buf, size_t len)
|
static size_t safe_write(int fd, const void *buf, size_t len)
|
||||||
{
|
{
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
while(ret < len)
|
while(ret < len)
|
||||||
{
|
{
|
||||||
ssize_t rem;
|
ssize_t rem;
|
||||||
if((rem=write(fd, (const char*)buf+ret, len-ret)) == -1)
|
if((rem=write(fd, (const char*)buf+ret, len-ret)) == -1)
|
||||||
{
|
{
|
||||||
if(errno == EINTR)
|
if(errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ret += rem;
|
ret += rem;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void crash_catcher(int signum, siginfo_t *siginfo, void *context)
|
static void crash_catcher(int signum, siginfo_t *siginfo, void *context)
|
||||||
{
|
{
|
||||||
//ucontext_t *ucontext = (ucontext_t*)context;
|
//ucontext_t *ucontext = (ucontext_t*)context;
|
||||||
pid_t dbg_pid;
|
pid_t dbg_pid;
|
||||||
int fd[2];
|
int fd[2];
|
||||||
|
|
||||||
/* Make sure the effective uid is the real uid */
|
/* Make sure the effective uid is the real uid */
|
||||||
if(getuid() != geteuid())
|
if(getuid() != geteuid())
|
||||||
{
|
{
|
||||||
raise(signum);
|
raise(signum);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_write(STDERR_FILENO, fatal_err, sizeof(fatal_err)-1);
|
safe_write(STDERR_FILENO, fatal_err, sizeof(fatal_err)-1);
|
||||||
if(pipe(fd) == -1)
|
if(pipe(fd) == -1)
|
||||||
{
|
{
|
||||||
safe_write(STDERR_FILENO, pipe_err, sizeof(pipe_err)-1);
|
safe_write(STDERR_FILENO, pipe_err, sizeof(pipe_err)-1);
|
||||||
raise(signum);
|
raise(signum);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
crash_info.signum = signum;
|
crash_info.signum = signum;
|
||||||
crash_info.pid = getpid();
|
crash_info.pid = getpid();
|
||||||
crash_info.has_siginfo = !!siginfo;
|
crash_info.has_siginfo = !!siginfo;
|
||||||
if(siginfo)
|
if(siginfo)
|
||||||
crash_info.siginfo = *siginfo;
|
crash_info.siginfo = *siginfo;
|
||||||
if(cc_user_info)
|
if(cc_user_info)
|
||||||
cc_user_info(crash_info.buf, crash_info.buf+sizeof(crash_info.buf));
|
cc_user_info(crash_info.buf, crash_info.buf+sizeof(crash_info.buf));
|
||||||
|
|
||||||
/* Fork off to start a crash handler */
|
/* Fork off to start a crash handler */
|
||||||
switch((dbg_pid=fork()))
|
switch((dbg_pid=fork()))
|
||||||
{
|
{
|
||||||
/* Error */
|
/* Error */
|
||||||
case -1:
|
case -1:
|
||||||
safe_write(STDERR_FILENO, fork_err, sizeof(fork_err)-1);
|
safe_write(STDERR_FILENO, fork_err, sizeof(fork_err)-1);
|
||||||
raise(signum);
|
raise(signum);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
dup2(fd[0], STDIN_FILENO);
|
dup2(fd[0], STDIN_FILENO);
|
||||||
close(fd[0]);
|
close(fd[0]);
|
||||||
close(fd[1]);
|
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);
|
safe_write(STDERR_FILENO, exec_err, sizeof(exec_err)-1);
|
||||||
_exit(1);
|
_exit(1);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
prctl(PR_SET_PTRACER, dbg_pid, 0, 0, 0);
|
prctl(PR_SET_PTRACER, dbg_pid, 0, 0, 0);
|
||||||
#endif
|
#endif
|
||||||
safe_write(fd[1], &crash_info, sizeof(crash_info));
|
safe_write(fd[1], &crash_info, sizeof(crash_info));
|
||||||
close(fd[0]);
|
close(fd[0]);
|
||||||
close(fd[1]);
|
close(fd[1]);
|
||||||
|
|
||||||
/* Wait; we'll be killed when gdb is done */
|
/* Wait; we'll be killed when gdb is done */
|
||||||
do {
|
do {
|
||||||
int status;
|
int status;
|
||||||
if(waitpid(dbg_pid, &status, 0) == dbg_pid &&
|
if(waitpid(dbg_pid, &status, 0) == dbg_pid &&
|
||||||
(WIFEXITED(status) || WIFSIGNALED(status)))
|
(WIFEXITED(status) || WIFSIGNALED(status)))
|
||||||
{
|
{
|
||||||
/* The debug process died before it could kill us */
|
/* The debug process died before it could kill us */
|
||||||
raise(signum);
|
raise(signum);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while(1);
|
} while(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void crash_handler(const char *logfile)
|
static void crash_handler(const char *logfile)
|
||||||
{
|
{
|
||||||
const char *sigdesc = "";
|
const char *sigdesc = "";
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(fread(&crash_info, sizeof(crash_info), 1, stdin) != 1)
|
if(fread(&crash_info, sizeof(crash_info), 1, stdin) != 1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "!!! Failed to retrieve info from crashed process\n");
|
fprintf(stderr, "!!! Failed to retrieve info from crashed process\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the signal description */
|
/* Get the signal description */
|
||||||
for(i = 0;signals[i].name;++i)
|
for(i = 0;signals[i].name;++i)
|
||||||
{
|
{
|
||||||
if(signals[i].signum == crash_info.signum)
|
if(signals[i].signum == crash_info.signum)
|
||||||
{
|
{
|
||||||
sigdesc = signals[i].name;
|
sigdesc = signals[i].name;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(crash_info.has_siginfo)
|
if(crash_info.has_siginfo)
|
||||||
{
|
{
|
||||||
switch(crash_info.signum)
|
switch(crash_info.signum)
|
||||||
{
|
{
|
||||||
case SIGSEGV:
|
case SIGSEGV:
|
||||||
for(i = 0;sigsegv_codes[i].name;++i)
|
for(i = 0;sigsegv_codes[i].name;++i)
|
||||||
{
|
{
|
||||||
if(sigsegv_codes[i].code == crash_info.siginfo.si_code)
|
if(sigsegv_codes[i].code == crash_info.siginfo.si_code)
|
||||||
{
|
{
|
||||||
sigdesc = sigsegv_codes[i].name;
|
sigdesc = sigsegv_codes[i].name;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIGFPE:
|
case SIGFPE:
|
||||||
for(i = 0;sigfpe_codes[i].name;++i)
|
for(i = 0;sigfpe_codes[i].name;++i)
|
||||||
{
|
{
|
||||||
if(sigfpe_codes[i].code == crash_info.siginfo.si_code)
|
if(sigfpe_codes[i].code == crash_info.siginfo.si_code)
|
||||||
{
|
{
|
||||||
sigdesc = sigfpe_codes[i].name;
|
sigdesc = sigfpe_codes[i].name;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIGILL:
|
case SIGILL:
|
||||||
for(i = 0;sigill_codes[i].name;++i)
|
for(i = 0;sigill_codes[i].name;++i)
|
||||||
{
|
{
|
||||||
if(sigill_codes[i].code == crash_info.siginfo.si_code)
|
if(sigill_codes[i].code == crash_info.siginfo.si_code)
|
||||||
{
|
{
|
||||||
sigdesc = sigill_codes[i].name;
|
sigdesc = sigill_codes[i].name;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIGBUS:
|
case SIGBUS:
|
||||||
for(i = 0;sigbus_codes[i].name;++i)
|
for(i = 0;sigbus_codes[i].name;++i)
|
||||||
{
|
{
|
||||||
if(sigbus_codes[i].code == crash_info.siginfo.si_code)
|
if(sigbus_codes[i].code == crash_info.siginfo.si_code)
|
||||||
{
|
{
|
||||||
sigdesc = sigbus_codes[i].name;
|
sigdesc = sigbus_codes[i].name;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(stderr, "%s (signal %i)\n", sigdesc, crash_info.signum);
|
fprintf(stderr, "%s (signal %i)\n", sigdesc, crash_info.signum);
|
||||||
if(crash_info.has_siginfo)
|
if(crash_info.has_siginfo)
|
||||||
fprintf(stderr, "Address: %p\n", crash_info.siginfo.si_addr);
|
fprintf(stderr, "Address: %p\n", crash_info.siginfo.si_addr);
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
|
|
||||||
if(logfile)
|
if(logfile)
|
||||||
{
|
{
|
||||||
/* Create crash log file and redirect shell output to it */
|
/* Create crash log file and redirect shell output to it */
|
||||||
if(freopen(logfile, "wa", stdout) != stdout)
|
if(freopen(logfile, "wa", stdout) != stdout)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "!!! Could not create %s following signal\n", logfile);
|
fprintf(stderr, "!!! Could not create %s following signal\n", logfile);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "Generating %s and killing process %d, please wait... ", logfile, crash_info.pid);
|
fprintf(stderr, "Generating %s and killing process %d, please wait... ", logfile, crash_info.pid);
|
||||||
|
|
||||||
printf("*** Fatal Error ***\n"
|
printf("*** Fatal Error ***\n"
|
||||||
"%s (signal %i)\n", sigdesc, crash_info.signum);
|
"%s (signal %i)\n", sigdesc, crash_info.signum);
|
||||||
if(crash_info.has_siginfo)
|
if(crash_info.has_siginfo)
|
||||||
printf("Address: %p\n", crash_info.siginfo.si_addr);
|
printf("Address: %p\n", crash_info.siginfo.si_addr);
|
||||||
fputc('\n', stdout);
|
fputc('\n', stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
sys_info();
|
sys_info();
|
||||||
|
|
||||||
crash_info.buf[sizeof(crash_info.buf)-1] = '\0';
|
crash_info.buf[sizeof(crash_info.buf)-1] = '\0';
|
||||||
printf("%s\n", crash_info.buf);
|
printf("%s\n", crash_info.buf);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
if(crash_info.pid > 0)
|
if(crash_info.pid > 0)
|
||||||
{
|
{
|
||||||
gdb_info(crash_info.pid);
|
gdb_info(crash_info.pid);
|
||||||
kill(crash_info.pid, SIGKILL);
|
kill(crash_info.pid, SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(logfile)
|
if(logfile)
|
||||||
{
|
{
|
||||||
char cwd[MAXPATHLEN];
|
char cwd[MAXPATHLEN];
|
||||||
getcwd(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 !";
|
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);
|
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*))
|
int cc_install_handlers(int argc, char **argv, int num_signals, int *signals, const char *logfile, int (*user_info)(char*, char*))
|
||||||
{
|
{
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
stack_t altss;
|
stack_t altss;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
if(argc == 2 && strcmp(argv[1], crash_switch) == 0)
|
if(argc == 2 && strcmp(argv[1], crash_switch) == 0)
|
||||||
crash_handler(logfile);
|
crash_handler(logfile);
|
||||||
|
|
||||||
cc_user_info = user_info;
|
cc_user_info = user_info;
|
||||||
|
|
||||||
if(argv[0][0] == '/')
|
if(argv[0][0] == '/')
|
||||||
snprintf(argv0, sizeof(argv0), "%s", argv[0]);
|
snprintf(argv0, sizeof(argv0), "%s", argv[0]);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
getcwd(argv0, sizeof(argv0));
|
getcwd(argv0, sizeof(argv0));
|
||||||
retval = strlen(argv0);
|
retval = strlen(argv0);
|
||||||
snprintf(argv0+retval, sizeof(argv0)-retval, "/%s", argv[0]);
|
snprintf(argv0+retval, sizeof(argv0)-retval, "/%s", argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set an alternate signal stack so SIGSEGVs caused by stack overflows
|
/* Set an alternate signal stack so SIGSEGVs caused by stack overflows
|
||||||
* still run */
|
* still run */
|
||||||
altss.ss_sp = altstack;
|
altss.ss_sp = altstack;
|
||||||
altss.ss_flags = 0;
|
altss.ss_flags = 0;
|
||||||
altss.ss_size = sizeof(altstack);
|
altss.ss_size = sizeof(altstack);
|
||||||
sigaltstack(&altss, NULL);
|
sigaltstack(&altss, NULL);
|
||||||
|
|
||||||
memset(&sa, 0, sizeof(sa));
|
memset(&sa, 0, sizeof(sa));
|
||||||
sa.sa_sigaction = crash_catcher;
|
sa.sa_sigaction = crash_catcher;
|
||||||
sa.sa_flags = SA_RESETHAND | SA_NODEFER | SA_SIGINFO | SA_ONSTACK;
|
sa.sa_flags = SA_RESETHAND | SA_NODEFER | SA_SIGINFO | SA_ONSTACK;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
while(num_signals--)
|
while(num_signals--)
|
||||||
{
|
{
|
||||||
if((*signals != SIGSEGV && *signals != SIGILL && *signals != SIGFPE && *signals != SIGABRT &&
|
if((*signals != SIGSEGV && *signals != SIGILL && *signals != SIGFPE && *signals != SIGABRT &&
|
||||||
*signals != SIGBUS) || sigaction(*signals, &sa, NULL) == -1)
|
*signals != SIGBUS) || sigaction(*signals, &sa, NULL) == -1)
|
||||||
{
|
{
|
||||||
*signals = 0;
|
*signals = 0;
|
||||||
retval = -1;
|
retval = -1;
|
||||||
}
|
}
|
||||||
++signals;
|
++signals;
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -172,6 +172,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
||||||
//kindly ask SDL not to trash our OGL context
|
//kindly ask SDL not to trash our OGL context
|
||||||
//might this be related to http://bugzilla.libsdl.org/show_bug.cgi?id=748 ?
|
//might this be related to http://bugzilla.libsdl.org/show_bug.cgi?id=748 ?
|
||||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
|
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
|
||||||
|
SDL_SetMainReady();
|
||||||
if(SDL_Init(flags) != 0)
|
if(SDL_Init(flags) != 0)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Could not initialize SDL! " + std::string(SDL_GetError()));
|
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);
|
MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr);
|
||||||
|
|
||||||
boost::shared_ptr<MWWorld::Action> action =
|
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);
|
interpreterContext.activate (ptr, action);
|
||||||
|
|
||||||
std::string script = MWWorld::Class::get (ptr).getScript (ptr);
|
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())
|
if (!script.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <boost/iostreams/stream_buffer.hpp>
|
#include <boost/iostreams/stream_buffer.hpp>
|
||||||
|
|
||||||
// For OutputDebugString
|
// For OutputDebugString
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
// makes __argc and __argv available on windows
|
// makes __argc and __argv available on windows
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void persuade (int type) = 0;
|
virtual void persuade (int type) = 0;
|
||||||
virtual int getTemporaryDispositionChange () const = 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;
|
virtual void setPlayerClass (const ESM::Class& class_) = 0;
|
||||||
///< Set player class to custom class.
|
///< Set player class to custom class.
|
||||||
|
|
||||||
virtual void restoreDynamicStats() = 0;
|
virtual void rest(bool sleep) = 0;
|
||||||
///< If the player is sleeping, this should be called every hour.
|
///< 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;
|
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.
|
///< 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;
|
virtual int countDeaths (const std::string& id) const = 0;
|
||||||
///< Return the number of deaths for actors with the given ID.
|
///< 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
|
enum PersuasionType
|
||||||
{
|
{
|
||||||
PT_Admire,
|
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 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 staticMessageBox(const std::string& message) = 0;
|
||||||
virtual void removeStaticMessageBox() = 0;
|
virtual void removeStaticMessageBox() = 0;
|
||||||
|
|
||||||
virtual void enterPressed () = 0;
|
|
||||||
virtual void activateKeyPressed () = 0;
|
|
||||||
virtual int readPressedButton() = 0;
|
virtual int readPressedButton() = 0;
|
||||||
///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox)
|
///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox)
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,6 @@ namespace ESM
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
class ExternalRendering;
|
|
||||||
class Animation;
|
class Animation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +126,7 @@ namespace MWBase
|
||||||
virtual const MWWorld::Fallback *getFallback () const = 0;
|
virtual const MWWorld::Fallback *getFallback () const = 0;
|
||||||
|
|
||||||
virtual MWWorld::Player& getPlayer() = 0;
|
virtual MWWorld::Player& getPlayer() = 0;
|
||||||
|
virtual MWWorld::Ptr getPlayerPtr() = 0;
|
||||||
|
|
||||||
virtual const MWWorld::ESMStore& getStore() const = 0;
|
virtual const MWWorld::ESMStore& getStore() const = 0;
|
||||||
|
|
||||||
|
@ -181,6 +181,10 @@ namespace MWBase
|
||||||
///< Return a pointer to a liveCellRef with the given name.
|
///< Return a pointer to a liveCellRef with the given name.
|
||||||
/// \param activeOnly do non search inactive cells.
|
/// \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;
|
virtual MWWorld::Ptr getPtrViaHandle (const std::string& handle) = 0;
|
||||||
///< Return a pointer to a liveCellRef with the given Ogre handle.
|
///< 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 enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0;
|
||||||
|
|
||||||
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0;
|
|
||||||
|
|
||||||
virtual int canRest() = 0;
|
virtual int canRest() = 0;
|
||||||
///< check if the player is allowed to rest \n
|
///< check if the player is allowed to rest \n
|
||||||
/// 0 - yes \n
|
/// 0 - yes \n
|
||||||
|
@ -466,11 +468,10 @@ namespace MWBase
|
||||||
|
|
||||||
virtual bool findInteriorPositionInWorldSpace(MWWorld::CellStore* cell, Ogre::Vector3& result) = 0;
|
virtual bool findInteriorPositionInWorldSpace(MWWorld::CellStore* cell, Ogre::Vector3& result) = 0;
|
||||||
|
|
||||||
/// Teleports \a ptr to the reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
||||||
/// closest to \a worldPos.
|
|
||||||
/// @note id must be lower case
|
/// @note id must be lower case
|
||||||
virtual void teleportToClosestMarker (const MWWorld::Ptr& ptr,
|
virtual void teleportToClosestMarker (const MWWorld::Ptr& ptr,
|
||||||
const std::string& id, Ogre::Vector3 worldPos) = 0;
|
const std::string& id) = 0;
|
||||||
|
|
||||||
enum DetectionType
|
enum DetectionType
|
||||||
{
|
{
|
||||||
|
@ -483,6 +484,21 @@ namespace MWBase
|
||||||
/// @note This also works for references in containers.
|
/// @note This also works for references in containers.
|
||||||
virtual void listDetectedReferences (const MWWorld::Ptr& ptr, std::vector<MWWorld::Ptr>& out,
|
virtual void listDetectedReferences (const MWWorld::Ptr& ptr, std::vector<MWWorld::Ptr>& out,
|
||||||
DetectionType type) = 0;
|
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;
|
std::string text;
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
|
{
|
||||||
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||||
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||||
|
}
|
||||||
info.text = text;
|
info.text = text;
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
|
|
|
@ -128,6 +128,7 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||||
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||||
}
|
}
|
||||||
info.text = text;
|
info.text = text;
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "../mwworld/physicssystem.hpp"
|
#include "../mwworld/physicssystem.hpp"
|
||||||
#include "../mwworld/nullaction.hpp"
|
#include "../mwworld/nullaction.hpp"
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
|
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
#include "../mwrender/renderinginterface.hpp"
|
#include "../mwrender/renderinginterface.hpp"
|
||||||
|
@ -252,6 +251,7 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||||
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,7 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||||
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
#include "../mwworld/physicssystem.hpp"
|
#include "../mwworld/physicssystem.hpp"
|
||||||
#include "../mwworld/nullaction.hpp"
|
#include "../mwworld/nullaction.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
|
|
||||||
#include "../mwgui/tooltips.hpp"
|
#include "../mwgui/tooltips.hpp"
|
||||||
|
|
||||||
|
@ -195,6 +194,7 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||||
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include "../mwworld/actionopen.hpp"
|
#include "../mwworld/actionopen.hpp"
|
||||||
#include "../mwworld/actiontrap.hpp"
|
#include "../mwworld/actiontrap.hpp"
|
||||||
#include "../mwworld/physicssystem.hpp"
|
#include "../mwworld/physicssystem.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
|
|
||||||
#include "../mwgui/tooltips.hpp"
|
#include "../mwgui/tooltips.hpp"
|
||||||
|
@ -53,7 +52,7 @@ namespace MWClass
|
||||||
ptr.get<ESM::Container>();
|
ptr.get<ESM::Container>();
|
||||||
|
|
||||||
data->mContainerStore.fill(
|
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
|
// store
|
||||||
ptr.getRefData().setCustomData (data.release());
|
ptr.getRefData().setCustomData (data.release());
|
||||||
|
@ -108,7 +107,7 @@ namespace MWClass
|
||||||
const std::string lockedSound = "LockedChest";
|
const std::string lockedSound = "LockedChest";
|
||||||
const std::string trapActivationSound = "Disarm Trap Fail";
|
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);
|
MWWorld::InventoryStore& invStore = MWWorld::Class::get(player).getInventoryStore(player);
|
||||||
|
|
||||||
bool needKey = ptr.getCellRef().mLockLevel>0;
|
bool needKey = ptr.getCellRef().mLockLevel>0;
|
||||||
|
@ -216,6 +215,7 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||||
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,17 @@ namespace MWClass
|
||||||
|
|
||||||
fMinWalkSpeedCreature = gmst.find("fMinWalkSpeedCreature");
|
fMinWalkSpeedCreature = gmst.find("fMinWalkSpeedCreature");
|
||||||
fMaxWalkSpeedCreature = gmst.find("fMaxWalkSpeedCreature");
|
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;
|
inited = true;
|
||||||
}
|
}
|
||||||
|
@ -95,10 +106,12 @@ namespace MWClass
|
||||||
data->mCreatureStats.getSpells().add (*iter);
|
data->mCreatureStats.getSpells().add (*iter);
|
||||||
|
|
||||||
// inventory
|
// inventory
|
||||||
data->mContainerStore.fill(ref->mBase->mInventory, getId(ptr),
|
data->mContainerStore.fill(ref->mBase->mInventory, getId(ptr), "",
|
||||||
MWBase::Environment::get().getWorld()->getStore());
|
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
|
// store
|
||||||
ptr.getRefData().setCustomData (data.release());
|
ptr.getRefData().setCustomData (data.release());
|
||||||
|
@ -163,6 +176,62 @@ namespace MWClass
|
||||||
|
|
||||||
void Creature::hit(const MWWorld::Ptr& ptr, int type) const
|
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
|
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);
|
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(ishealth)
|
||||||
{
|
{
|
||||||
if(damage > 0.0f)
|
if(damage > 0.0f)
|
||||||
|
@ -284,10 +366,51 @@ namespace MWClass
|
||||||
float Creature::getSpeed(const MWWorld::Ptr &ptr) const
|
float Creature::getSpeed(const MWWorld::Ptr &ptr) const
|
||||||
{
|
{
|
||||||
MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
|
MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
|
||||||
|
|
||||||
float walkSpeed = fMinWalkSpeedCreature->getFloat() + 0.01 * stats.getAttribute(ESM::Attribute::Speed).getModified()
|
float walkSpeed = fMinWalkSpeedCreature->getFloat() + 0.01 * stats.getAttribute(ESM::Attribute::Speed).getModified()
|
||||||
* (fMaxWalkSpeedCreature->getFloat() - fMinWalkSpeedCreature->getFloat());
|
* (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
|
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);
|
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::fMinWalkSpeedCreature;
|
||||||
const ESM::GameSetting* Creature::fMaxWalkSpeedCreature;
|
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 *fMinWalkSpeedCreature;
|
||||||
static const ESM::GameSetting *fMaxWalkSpeedCreature;
|
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:
|
public:
|
||||||
|
|
||||||
|
@ -101,6 +113,11 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isFlying (const MWWorld::Ptr &ptr) const;
|
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/windowmanager.hpp"
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
#include "../mwworld/nullaction.hpp"
|
#include "../mwworld/nullaction.hpp"
|
||||||
#include "../mwworld/failedaction.hpp"
|
#include "../mwworld/failedaction.hpp"
|
||||||
|
@ -97,7 +96,7 @@ namespace MWClass
|
||||||
|
|
||||||
if (needKey && hasKey)
|
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}");
|
MWBase::Environment::get().getWindowManager()->messageBox(keyName + " #{sKeyUsed}");
|
||||||
ptr.getCellRef().mLockLevel = 0;
|
ptr.getCellRef().mLockLevel = 0;
|
||||||
// using a key disarms the trap
|
// using a key disarms the trap
|
||||||
|
@ -118,7 +117,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
// teleport door
|
// teleport door
|
||||||
/// \todo remove this if clause once ActionTeleport can also support other actors
|
/// \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));
|
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/cellstore.hpp"
|
||||||
#include "../mwworld/physicssystem.hpp"
|
#include "../mwworld/physicssystem.hpp"
|
||||||
#include "../mwworld/actioneat.hpp"
|
#include "../mwworld/actioneat.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/nullaction.hpp"
|
#include "../mwworld/nullaction.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/npcstats.hpp"
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
@ -149,10 +148,11 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||||
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
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);
|
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||||
int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase();
|
int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase();
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,7 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||||
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,7 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||||
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,9 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
||||||
ptr.get<ESM::Miscellaneous>();
|
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 != "")
|
if (ptr.getCellRef().mSoul != "")
|
||||||
{
|
{
|
||||||
|
@ -184,6 +186,7 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||||
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
|
||||||
|
|
||||||
#include <OgreSceneNode.h>
|
#include <OgreSceneNode.h>
|
||||||
|
|
||||||
#include <components/esm/loadmgef.hpp>
|
#include <components/esm/loadmgef.hpp>
|
||||||
|
@ -242,6 +240,9 @@ namespace MWClass
|
||||||
fJumpAcroMultiplier = gmst.find("fJumpAcroMultiplier");
|
fJumpAcroMultiplier = gmst.find("fJumpAcroMultiplier");
|
||||||
fJumpRunMultiplier = gmst.find("fJumpRunMultiplier");
|
fJumpRunMultiplier = gmst.find("fJumpRunMultiplier");
|
||||||
fWereWolfRunMult = gmst.find("fWereWolfRunMult");
|
fWereWolfRunMult = gmst.find("fWereWolfRunMult");
|
||||||
|
fKnockDownMult = gmst.find("fKnockDownMult");
|
||||||
|
iKnockDownOddsMult = gmst.find("iKnockDownOddsMult");
|
||||||
|
iKnockDownOddsBase = gmst.find("iKnockDownOddsBase");
|
||||||
|
|
||||||
inited = true;
|
inited = true;
|
||||||
}
|
}
|
||||||
|
@ -307,6 +308,17 @@ namespace MWClass
|
||||||
autoCalculateSkills(ref->mBase, data->mNpcStats);
|
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.getAiSequence().fill(ref->mBase->mAiPackage);
|
||||||
|
|
||||||
data->mNpcStats.setAiSetting (MWMechanics::CreatureStats::AI_Hello, ref->mBase->mAiData.mHello);
|
data->mNpcStats.setAiSetting (MWMechanics::CreatureStats::AI_Hello, ref->mBase->mAiData.mHello);
|
||||||
|
@ -320,13 +332,15 @@ namespace MWClass
|
||||||
data->mNpcStats.getSpells().add (*iter);
|
data->mNpcStats.getSpells().add (*iter);
|
||||||
|
|
||||||
// inventory
|
// inventory
|
||||||
data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr),
|
data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr), "",
|
||||||
MWBase::Environment::get().getWorld()->getStore());
|
MWBase::Environment::get().getWorld()->getStore());
|
||||||
|
|
||||||
// store
|
// store
|
||||||
ptr.getRefData().setCustomData (data.release());
|
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);
|
getInventoryStore(ptr).autoEquip(ptr);
|
||||||
}
|
}
|
||||||
|
@ -423,11 +437,27 @@ namespace MWClass
|
||||||
if(!weapon.isEmpty() && weapon.getTypeName() != typeid(ESM::Weapon).name())
|
if(!weapon.isEmpty() && weapon.getTypeName() != typeid(ESM::Weapon).name())
|
||||||
weapon = MWWorld::Ptr();
|
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() ?
|
float dist = 100.0f * (!weapon.isEmpty() ?
|
||||||
weapon.get<ESM::Weapon>()->mBase->mData.mReach :
|
weapon.get<ESM::Weapon>()->mBase->mData.mReach :
|
||||||
gmst.find("fHandToHandReach")->getFloat());
|
gmst.find("fHandToHandReach")->getFloat());
|
||||||
// TODO: Use second to work out the hit angle and where to spawn the blood effect
|
// TODO: Use second to work out the hit angle
|
||||||
MWWorld::Ptr victim = world->getHitContact(ptr, dist).first;
|
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
|
if(victim.isEmpty()) // Didn't hit anything
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -484,12 +514,6 @@ namespace MWClass
|
||||||
weapon.getCellRef().mCharge = weapmaxhealth;
|
weapon.getCellRef().mCharge = weapmaxhealth;
|
||||||
damage *= float(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())
|
if (!MWBase::Environment::get().getWorld()->getGodModeState())
|
||||||
weapon.getCellRef().mCharge -= std::min(std::max(1,
|
weapon.getCellRef().mCharge -= std::min(std::max(1,
|
||||||
|
@ -511,12 +535,6 @@ namespace MWClass
|
||||||
float maxstrike = gmst.find("fMaxHandToHandMult")->getFloat();
|
float maxstrike = gmst.find("fMaxHandToHandMult")->getFloat();
|
||||||
damage = stats.getSkill(weapskill).getModified();
|
damage = stats.getSkill(weapskill).getModified();
|
||||||
damage *= minstrike + ((maxstrike-minstrike)*stats.getAttackStrength());
|
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)
|
healthdmg = (otherstats.getFatigue().getCurrent() < 1.0f)
|
||||||
|| (otherstats.getMagicEffects().get(ESM::MagicEffect::Paralyze).mMagnitude > 0);
|
|| (otherstats.getMagicEffects().get(ESM::MagicEffect::Paralyze).mMagnitude > 0);
|
||||||
|
@ -543,6 +561,16 @@ namespace MWClass
|
||||||
if(ptr.getRefData().getHandle() == "player")
|
if(ptr.getRefData().getHandle() == "player")
|
||||||
skillUsageSucceeded(ptr, weapskill, 0);
|
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
|
// Apply "On hit" enchanted weapons
|
||||||
std::string enchantmentName = !weapon.isEmpty() ? weapon.getClass().getEnchantment(weapon) : "";
|
std::string enchantmentName = !weapon.isEmpty() ? weapon.getClass().getEnchantment(weapon) : "";
|
||||||
if (!enchantmentName.empty())
|
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);
|
othercls.onHit(victim, damage, healthdmg, weapon, ptr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,6 +617,10 @@ namespace MWClass
|
||||||
|
|
||||||
// NOTE: 'object' and/or 'attacker' may be empty.
|
// 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)
|
if(!successful)
|
||||||
{
|
{
|
||||||
// TODO: Handle HitAttemptOnMe script function
|
// TODO: Handle HitAttemptOnMe script function
|
||||||
|
@ -599,7 +635,7 @@ namespace MWClass
|
||||||
|
|
||||||
if(!attacker.isEmpty() && attacker.getRefData().getHandle() == "player")
|
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. */
|
/* Set the OnPCHitMe script variable. The script is responsible for clearing it. */
|
||||||
if(!script.empty())
|
if(!script.empty())
|
||||||
ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1);
|
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
|
// 'ptr' is losing health. Play a 'hit' voiced dialog entry if not already saying
|
||||||
// something, alert the character controller, scripts, etc.
|
// 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())
|
if(object.isEmpty())
|
||||||
{
|
{
|
||||||
|
@ -725,10 +781,10 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
if(getCreatureStats(ptr).isDead())
|
if(getCreatureStats(ptr).isDead())
|
||||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr, true));
|
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())
|
if(get(ptr).getCreatureStats(ptr).isHostile())
|
||||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::FailedAction("#{sActorInCombat}"));
|
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));
|
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionTalk(ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -756,80 +812,6 @@ namespace MWClass
|
||||||
return ref->mBase->mScript;
|
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
|
float Npc::getSpeed(const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
|
@ -838,11 +820,14 @@ namespace MWClass
|
||||||
|
|
||||||
const float normalizedEncumbrance = Npc::getEncumbrance(ptr) / Npc::getCapacity(ptr);
|
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()*
|
float walkSpeed = fMinWalkSpeed->getFloat() + 0.01f*npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified()*
|
||||||
(fMaxWalkSpeed->getFloat() - fMinWalkSpeed->getFloat());
|
(fMaxWalkSpeed->getFloat() - fMinWalkSpeed->getFloat());
|
||||||
walkSpeed *= 1.0f - fEncumberedMoveEffect->getFloat()*normalizedEncumbrance;
|
walkSpeed *= 1.0f - fEncumberedMoveEffect->getFloat()*normalizedEncumbrance;
|
||||||
walkSpeed = std::max(0.0f, walkSpeed);
|
walkSpeed = std::max(0.0f, walkSpeed);
|
||||||
if(Npc::getStance(ptr, Sneak, false))
|
if(sneaking)
|
||||||
walkSpeed *= fSneakSpeedMultiplier->getFloat();
|
walkSpeed *= fSneakSpeedMultiplier->getFloat();
|
||||||
|
|
||||||
float runSpeed = walkSpeed*(0.01f * npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified() *
|
float runSpeed = walkSpeed*(0.01f * npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified() *
|
||||||
|
@ -866,14 +851,14 @@ namespace MWClass
|
||||||
else if(world->isSwimming(ptr))
|
else if(world->isSwimming(ptr))
|
||||||
{
|
{
|
||||||
float swimSpeed = walkSpeed;
|
float swimSpeed = walkSpeed;
|
||||||
if(Npc::getStance(ptr, Run, false))
|
if(running)
|
||||||
swimSpeed = runSpeed;
|
swimSpeed = runSpeed;
|
||||||
swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).mMagnitude;
|
swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).mMagnitude;
|
||||||
swimSpeed *= fSwimRunBase->getFloat() + 0.01f*npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified()*
|
swimSpeed *= fSwimRunBase->getFloat() + 0.01f*npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified()*
|
||||||
fSwimRunAthleticsMult->getFloat();
|
fSwimRunAthleticsMult->getFloat();
|
||||||
moveSpeed = swimSpeed;
|
moveSpeed = swimSpeed;
|
||||||
}
|
}
|
||||||
else if(Npc::getStance(ptr, Run, false) && !Npc::getStance(ptr, Sneak, false))
|
else if(running && !sneaking)
|
||||||
moveSpeed = runSpeed;
|
moveSpeed = runSpeed;
|
||||||
else
|
else
|
||||||
moveSpeed = walkSpeed;
|
moveSpeed = walkSpeed;
|
||||||
|
@ -905,7 +890,7 @@ namespace MWClass
|
||||||
x += mageffects.get(ESM::MagicEffect::Jump).mMagnitude * 64;
|
x += mageffects.get(ESM::MagicEffect::Jump).mMagnitude * 64;
|
||||||
x *= encumbranceTerm;
|
x *= encumbranceTerm;
|
||||||
|
|
||||||
if(Npc::getStance(ptr, Run, false))
|
if(ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run))
|
||||||
x *= fJumpRunMultiplier->getFloat();
|
x *= fJumpRunMultiplier->getFloat();
|
||||||
x *= npcdata->mNpcStats.getFatigueTerm();
|
x *= npcdata->mNpcStats.getFatigueTerm();
|
||||||
x -= -627.2f;/*gravity constant*/
|
x -= -627.2f;/*gravity constant*/
|
||||||
|
@ -1017,7 +1002,8 @@ namespace MWClass
|
||||||
float Npc::getCapacity (const MWWorld::Ptr& ptr) const
|
float Npc::getCapacity (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
|
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
|
float Npc::getEncumbrance (const MWWorld::Ptr& ptr) const
|
||||||
|
@ -1231,6 +1217,22 @@ namespace MWClass
|
||||||
return MWWorld::Ptr(&cell.mNpcs.insert(*ref), &cell);
|
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::fMinWalkSpeed;
|
||||||
const ESM::GameSetting *Npc::fMaxWalkSpeed;
|
const ESM::GameSetting *Npc::fMaxWalkSpeed;
|
||||||
const ESM::GameSetting *Npc::fEncumberedMoveEffect;
|
const ESM::GameSetting *Npc::fEncumberedMoveEffect;
|
||||||
|
@ -1247,4 +1249,7 @@ namespace MWClass
|
||||||
const ESM::GameSetting *Npc::fJumpAcroMultiplier;
|
const ESM::GameSetting *Npc::fJumpAcroMultiplier;
|
||||||
const ESM::GameSetting *Npc::fJumpRunMultiplier;
|
const ESM::GameSetting *Npc::fJumpRunMultiplier;
|
||||||
const ESM::GameSetting *Npc::fWereWolfRunMult;
|
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 *fJumpAcroMultiplier;
|
||||||
static const ESM::GameSetting *fJumpRunMultiplier;
|
static const ESM::GameSetting *fJumpRunMultiplier;
|
||||||
static const ESM::GameSetting *fWereWolfRunMult;
|
static const ESM::GameSetting *fWereWolfRunMult;
|
||||||
|
static const ESM::GameSetting *fKnockDownMult;
|
||||||
|
static const ESM::GameSetting *iKnockDownOddsMult;
|
||||||
|
static const ESM::GameSetting *iKnockDownOddsBase;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -81,16 +84,6 @@ namespace MWClass
|
||||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return name of the script attached to ptr
|
///< 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;
|
virtual float getSpeed (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return movement speed.
|
///< Return movement speed.
|
||||||
|
|
||||||
|
@ -147,6 +140,11 @@ namespace MWClass
|
||||||
|
|
||||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
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 {
|
virtual bool isActor() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
#include "../mwworld/physicssystem.hpp"
|
#include "../mwworld/physicssystem.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/nullaction.hpp"
|
#include "../mwworld/nullaction.hpp"
|
||||||
|
|
||||||
#include "../mwgui/tooltips.hpp"
|
#include "../mwgui/tooltips.hpp"
|
||||||
|
@ -133,7 +132,7 @@ namespace MWClass
|
||||||
info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects);
|
info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects);
|
||||||
|
|
||||||
// hide effects the player doesnt know about
|
// 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);
|
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||||
int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase();
|
int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase();
|
||||||
int i=0;
|
int i=0;
|
||||||
|
@ -153,6 +152,7 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||||
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Potion> *ref =
|
MWWorld::LiveCellRef<ESM::Potion> *ref =
|
||||||
ptr.get<ESM::Potion>();
|
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)
|
// remove used potion (assume it is present in inventory)
|
||||||
ptr.getContainerStore()->remove(ptr, 1, actor);
|
ptr.getContainerStore()->remove(ptr, 1, actor);
|
||||||
|
|
|
@ -144,6 +144,7 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||||
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,6 +148,7 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||||
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -355,6 +355,7 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||||
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction");
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
|
|
||||||
#include "../mwgui/dialogue.hpp"
|
#include "../mwgui/dialogue.hpp"
|
||||||
|
|
||||||
|
@ -126,6 +125,8 @@ namespace MWDialogue
|
||||||
void DialogueManager::startDialogue (const MWWorld::Ptr& actor)
|
void DialogueManager::startDialogue (const MWWorld::Ptr& actor)
|
||||||
{
|
{
|
||||||
mLastTopic = "";
|
mLastTopic = "";
|
||||||
|
mPermanentDispositionChange = 0;
|
||||||
|
mTemporaryDispositionChange = 0;
|
||||||
|
|
||||||
mChoice = -1;
|
mChoice = -1;
|
||||||
mIsInChoice = false;
|
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
|
//setup the list of topics known by the actor. Topics who are also on the knownTopics list will be added to the GUI
|
||||||
updateTopics();
|
updateTopics();
|
||||||
|
updateGlobals();
|
||||||
|
|
||||||
//greeting
|
//greeting
|
||||||
const MWWorld::Store<ESM::Dialogue> &dialogs =
|
const MWWorld::Store<ESM::Dialogue> &dialogs =
|
||||||
|
@ -297,6 +299,11 @@ namespace MWDialogue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogueManager::updateGlobals()
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWorld()->updateDialogueGlobals();
|
||||||
|
}
|
||||||
|
|
||||||
void DialogueManager::updateTopics()
|
void DialogueManager::updateTopics()
|
||||||
{
|
{
|
||||||
std::list<std::string> keywordList;
|
std::list<std::string> keywordList;
|
||||||
|
@ -491,7 +498,7 @@ namespace MWDialogue
|
||||||
else if (curDisp + mTemporaryDispositionChange > 100)
|
else if (curDisp + mTemporaryDispositionChange > 100)
|
||||||
mTemporaryDispositionChange = 100 - curDisp;
|
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);
|
MWWorld::Class::get(player).skillUsageSucceeded(player, ESM::Skill::Speechcraft, success ? 0 : 1);
|
||||||
|
|
||||||
std::string text;
|
std::string text;
|
||||||
|
@ -514,9 +521,19 @@ namespace MWDialogue
|
||||||
return mTemporaryDispositionChange;
|
return mTemporaryDispositionChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::applyTemporaryDispositionChange(int delta)
|
void DialogueManager::applyDispositionChange(int delta)
|
||||||
{
|
{
|
||||||
|
int oldTemp = mTemporaryDispositionChange;
|
||||||
mTemporaryDispositionChange += delta;
|
mTemporaryDispositionChange += delta;
|
||||||
|
// don't allow increasing beyond 100 or decreasing below 0
|
||||||
|
int curDisp = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor);
|
||||||
|
if (curDisp + mTemporaryDispositionChange < 0)
|
||||||
|
mTemporaryDispositionChange = -curDisp;
|
||||||
|
else if (curDisp + mTemporaryDispositionChange > 100)
|
||||||
|
mTemporaryDispositionChange = 100 - curDisp;
|
||||||
|
|
||||||
|
int diff = mTemporaryDispositionChange - oldTemp;
|
||||||
|
mPermanentDispositionChange += diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DialogueManager::checkServiceRefused()
|
bool DialogueManager::checkServiceRefused()
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace MWDialogue
|
||||||
void parseText (const std::string& text);
|
void parseText (const std::string& text);
|
||||||
|
|
||||||
void updateTopics();
|
void updateTopics();
|
||||||
|
void updateGlobals();
|
||||||
|
|
||||||
bool compile (const std::string& cmd,std::vector<Interpreter::Type_Code>& code);
|
bool compile (const std::string& cmd,std::vector<Interpreter::Type_Code>& code);
|
||||||
void executeScript (const std::string& script);
|
void executeScript (const std::string& script);
|
||||||
|
@ -76,7 +77,7 @@ namespace MWDialogue
|
||||||
|
|
||||||
virtual void persuade (int type);
|
virtual void persuade (int type);
|
||||||
virtual int getTemporaryDispositionChange () const;
|
virtual int getTemporaryDispositionChange () const;
|
||||||
virtual void applyTemporaryDispositionChange (int delta);
|
virtual void applyDispositionChange (int delta);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include "../mwbase/dialoguemanager.hpp"
|
#include "../mwbase/dialoguemanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
|
|
||||||
|
@ -25,7 +24,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
|
||||||
// actor id
|
// actor id
|
||||||
if (!info.mActor.empty())
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
else if (isCreature)
|
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>();
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +53,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
|
||||||
|
|
||||||
MWWorld::LiveCellRef<ESM::NPC> *cellRef = mActor.get<ESM::NPC>();
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +92,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
|
||||||
|
|
||||||
bool MWDialogue::Filter::testPlayer (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
|
// check player faction
|
||||||
if (!info.mPcFaction.empty())
|
if (!info.mPcFaction.empty())
|
||||||
|
@ -111,7 +110,7 @@ bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const
|
||||||
|
|
||||||
// check cell
|
// check cell
|
||||||
if (!info.mCell.empty())
|
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 false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -189,7 +188,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (; i<static_cast<int> (script->mVarNames.size()); ++i)
|
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;
|
break;
|
||||||
|
|
||||||
if (i>=static_cast<int> (script->mVarNames.size()))
|
if (i>=static_cast<int> (script->mVarNames.size()))
|
||||||
|
@ -212,7 +211,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
|
||||||
|
|
||||||
case SelectWrapper::Function_PcHealthPercent:
|
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() /
|
float ratio = MWWorld::Class::get (player).getCreatureStats (player).getHealth().getCurrent() /
|
||||||
MWWorld::Class::get (player).getCreatureStats (player).getHealth().getModified();
|
MWWorld::Class::get (player).getCreatureStats (player).getHealth().getModified();
|
||||||
|
@ -222,7 +221,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
|
||||||
|
|
||||||
case SelectWrapper::Function_PcDynamicStat:
|
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).
|
float value = MWWorld::Class::get (player).getCreatureStats (player).
|
||||||
getDynamic (select.getArgument()).getCurrent();
|
getDynamic (select.getArgument()).getCurrent();
|
||||||
|
@ -246,7 +245,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
|
||||||
|
|
||||||
int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) const
|
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())
|
switch (select.getFunction())
|
||||||
{
|
{
|
||||||
|
@ -263,7 +262,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
|
||||||
std::string name = select.getName();
|
std::string name = select.getName();
|
||||||
|
|
||||||
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
|
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();
|
sum += iter->getRefData().getCount();
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
|
@ -420,7 +419,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
|
||||||
|
|
||||||
bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) const
|
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())
|
switch (select.getFunction())
|
||||||
{
|
{
|
||||||
|
@ -430,23 +429,23 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
|
||||||
|
|
||||||
case SelectWrapper::Function_NotId:
|
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:
|
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:
|
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:
|
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:
|
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:
|
case SelectWrapper::Function_NotLocal:
|
||||||
{
|
{
|
||||||
|
@ -463,7 +462,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i < static_cast<int> (script->mVarNames.size()); ++i)
|
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;
|
break;
|
||||||
|
|
||||||
if (i >= static_cast<int> (script->mVarNames.size()))
|
if (i >= static_cast<int> (script->mVarNames.size()))
|
||||||
|
@ -479,8 +478,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
|
||||||
|
|
||||||
case SelectWrapper::Function_SameRace:
|
case SelectWrapper::Function_SameRace:
|
||||||
|
|
||||||
return Misc::StringUtils::lowerCase (mActor.get<ESM::NPC>()->mBase->mRace)!=
|
return !Misc::StringUtils::ciEqual(mActor.get<ESM::NPC>()->mBase->mRace, player.get<ESM::NPC>()->mBase->mRace);
|
||||||
Misc::StringUtils::lowerCase (player.get<ESM::NPC>()->mBase->mRace);
|
|
||||||
|
|
||||||
case SelectWrapper::Function_SameFaction:
|
case SelectWrapper::Function_SameFaction:
|
||||||
|
|
||||||
|
@ -508,9 +506,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
|
||||||
std::string faction =
|
std::string faction =
|
||||||
MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first;
|
MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first;
|
||||||
|
|
||||||
std::set<std::string>& expelled = MWWorld::Class::get (player).getNpcStats (player).getExpelled();
|
return player.getClass().getNpcStats(player).getExpelled(faction);
|
||||||
|
|
||||||
return expelled.find (faction)!=expelled.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case SelectWrapper::Function_PcVampire:
|
case SelectWrapper::Function_PcVampire:
|
||||||
|
@ -528,7 +524,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
|
||||||
|
|
||||||
case SelectWrapper::Function_Detected:
|
case SelectWrapper::Function_Detected:
|
||||||
|
|
||||||
return MWWorld::Class::get (mActor).hasDetected (mActor, player);
|
return MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, mActor);
|
||||||
|
|
||||||
case SelectWrapper::Function_Attacked:
|
case SelectWrapper::Function_Attacked:
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
#include "inventoryitemmodel.hpp"
|
#include "inventoryitemmodel.hpp"
|
||||||
|
@ -143,9 +142,9 @@ namespace MWGui
|
||||||
|
|
||||||
void AlchemyWindow::open()
|
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 = new SortFilterItemModel(model);
|
||||||
mSortModel->setFilter(SortFilterItemModel::Filter_OnlyIngredients);
|
mSortModel->setFilter(SortFilterItemModel::Filter_OnlyIngredients);
|
||||||
mItemView->setModel (mSortModel);
|
mItemView->setModel (mSortModel);
|
||||||
|
@ -154,7 +153,7 @@ namespace MWGui
|
||||||
|
|
||||||
int index = 0;
|
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());
|
for (MWMechanics::Alchemy::TToolsIterator iter (mAlchemy.beginTools());
|
||||||
iter!=mAlchemy.endTools() && index<static_cast<int> (mApparatus.size()); ++iter, ++index)
|
iter!=mAlchemy.endTools() && index<static_cast<int> (mApparatus.size()); ++iter, ++index)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "birth.hpp"
|
#include "birth.hpp"
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
@ -77,7 +76,7 @@ namespace MWGui
|
||||||
size_t count = mBirthList->getItemCount();
|
size_t count = mBirthList->getItemCount();
|
||||||
for (size_t i = 0; i < count; ++i)
|
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);
|
mBirthList->setIndexSelected(i);
|
||||||
MyGUI::Button* okButton;
|
MyGUI::Button* okButton;
|
||||||
|
@ -112,7 +111,7 @@ namespace MWGui
|
||||||
getWidget(okButton, "OKButton");
|
getWidget(okButton, "OKButton");
|
||||||
|
|
||||||
const std::string *birthId = mBirthList->getItemDataAt<std::string>(_index);
|
const std::string *birthId = mBirthList->getItemDataAt<std::string>(_index);
|
||||||
if (boost::iequals(mCurrentBirthId, *birthId))
|
if (Misc::StringUtils::ciEqual(mCurrentBirthId, *birthId))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mCurrentBirthId = *birthId;
|
mCurrentBirthId = *birthId;
|
||||||
|
@ -148,7 +147,7 @@ namespace MWGui
|
||||||
mBirthList->setIndexSelected(index);
|
mBirthList->setIndexSelected(index);
|
||||||
mCurrentBirthId = it2->first;
|
mCurrentBirthId = it2->first;
|
||||||
}
|
}
|
||||||
else if (boost::iequals(it2->first, mCurrentBirthId))
|
else if (Misc::StringUtils::ciEqual(it2->first, mCurrentBirthId))
|
||||||
{
|
{
|
||||||
mBirthList->setIndexSelected(index);
|
mBirthList->setIndexSelected(index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/actiontake.hpp"
|
#include "../mwworld/actiontake.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
|
|
||||||
#include "formatting.hpp"
|
#include "formatting.hpp"
|
||||||
|
|
||||||
|
@ -138,7 +137,7 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getSoundManager()->playSound("Item Book Up", 1.0, 1.0);
|
MWBase::Environment::get().getSoundManager()->playSound("Item Book Up", 1.0, 1.0);
|
||||||
|
|
||||||
MWWorld::ActionTake take(mBook);
|
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);
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Book);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "../mwmechanics/creaturestats.hpp"
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/fallback.hpp"
|
#include "../mwworld/fallback.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -47,7 +46,7 @@ namespace
|
||||||
|
|
||||||
void updatePlayerHealth()
|
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);
|
MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||||
|
|
||||||
creatureStats.updateHealth();
|
creatureStats.updateHealth();
|
||||||
|
@ -220,8 +219,8 @@ namespace MWGui
|
||||||
mReviewDialog->setBirthSign(mPlayerBirthSignId);
|
mReviewDialog->setBirthSign(mPlayerBirthSignId);
|
||||||
|
|
||||||
{
|
{
|
||||||
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);
|
const MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||||
|
|
||||||
mReviewDialog->setHealth ( stats.getHealth() );
|
mReviewDialog->setHealth ( stats.getHealth() );
|
||||||
mReviewDialog->setMagicka( stats.getMagicka() );
|
mReviewDialog->setMagicka( stats.getMagicka() );
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include "class.hpp"
|
#include "class.hpp"
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
@ -29,11 +27,12 @@ namespace MWGui
|
||||||
|
|
||||||
MyGUI::Button* backButton;
|
MyGUI::Button* backButton;
|
||||||
getWidget(backButton, "BackButton");
|
getWidget(backButton, "BackButton");
|
||||||
|
backButton->setCaptionWithReplacing("#{sMessageQuestionAnswer3}");
|
||||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onBackClicked);
|
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onBackClicked);
|
||||||
|
|
||||||
MyGUI::Button* okButton;
|
MyGUI::Button* okButton;
|
||||||
getWidget(okButton, "OKButton");
|
getWidget(okButton, "OKButton");
|
||||||
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
|
okButton->setCaptionWithReplacing("#{sMessageQuestionAnswer2}");
|
||||||
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onOkClicked);
|
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onOkClicked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +126,7 @@ namespace MWGui
|
||||||
size_t count = mClassList->getItemCount();
|
size_t count = mClassList->getItemCount();
|
||||||
for (size_t i = 0; i < count; ++i)
|
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);
|
mClassList->setIndexSelected(i);
|
||||||
MyGUI::Button* okButton;
|
MyGUI::Button* okButton;
|
||||||
|
@ -162,7 +161,7 @@ namespace MWGui
|
||||||
getWidget(okButton, "OKButton");
|
getWidget(okButton, "OKButton");
|
||||||
|
|
||||||
const std::string *classId = mClassList->getItemDataAt<std::string>(_index);
|
const std::string *classId = mClassList->getItemDataAt<std::string>(_index);
|
||||||
if (boost::iequals(mCurrentClassId, *classId))
|
if (Misc::StringUtils::ciEqual(mCurrentClassId, *classId))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mCurrentClassId = *classId;
|
mCurrentClassId = *classId;
|
||||||
|
@ -192,7 +191,7 @@ namespace MWGui
|
||||||
mCurrentClassId = id;
|
mCurrentClassId = id;
|
||||||
mClassList->setIndexSelected(index);
|
mClassList->setIndexSelected(index);
|
||||||
}
|
}
|
||||||
else if (boost::iequals(id, mCurrentClassId))
|
else if (Misc::StringUtils::ciEqual(id, mCurrentClassId))
|
||||||
{
|
{
|
||||||
mClassList->setIndexSelected(index);
|
mClassList->setIndexSelected(index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,13 @@
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
#include "../mwbase/dialoguemanager.hpp"
|
||||||
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
|
||||||
|
#include "../mwmechanics/pickpocket.hpp"
|
||||||
|
|
||||||
#include "countdialog.hpp"
|
#include "countdialog.hpp"
|
||||||
#include "tradewindow.hpp"
|
#include "tradewindow.hpp"
|
||||||
|
@ -123,6 +127,7 @@ namespace MWGui
|
||||||
, mSelectedItem(-1)
|
, mSelectedItem(-1)
|
||||||
, mModel(NULL)
|
, mModel(NULL)
|
||||||
, mSortModel(NULL)
|
, mSortModel(NULL)
|
||||||
|
, mPickpocketDetected(false)
|
||||||
{
|
{
|
||||||
getWidget(mDisposeCorpseButton, "DisposeCorpseButton");
|
getWidget(mDisposeCorpseButton, "DisposeCorpseButton");
|
||||||
getWidget(mTakeButton, "TakeButton");
|
getWidget(mTakeButton, "TakeButton");
|
||||||
|
@ -134,6 +139,7 @@ namespace MWGui
|
||||||
|
|
||||||
mDisposeCorpseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onDisposeCorpseButtonClicked);
|
mDisposeCorpseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onDisposeCorpseButtonClicked);
|
||||||
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onCloseButtonClicked);
|
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onCloseButtonClicked);
|
||||||
|
mCloseButton->eventKeyButtonPressed += MyGUI::newDelegate(this, &ContainerWindow::onKeyPressed);
|
||||||
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onTakeAllButtonClicked);
|
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onTakeAllButtonClicked);
|
||||||
|
|
||||||
setCoord(200,0,600,300);
|
setCoord(200,0,600,300);
|
||||||
|
@ -171,6 +177,9 @@ namespace MWGui
|
||||||
|
|
||||||
void ContainerWindow::dragItem(MyGUI::Widget* sender, int count)
|
void ContainerWindow::dragItem(MyGUI::Widget* sender, int count)
|
||||||
{
|
{
|
||||||
|
if (!onTakeItem(mModel->getItem(mSelectedItem), count))
|
||||||
|
return;
|
||||||
|
|
||||||
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count);
|
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,12 +217,13 @@ namespace MWGui
|
||||||
|
|
||||||
void ContainerWindow::open(const MWWorld::Ptr& container, bool loot)
|
void ContainerWindow::open(const MWWorld::Ptr& container, bool loot)
|
||||||
{
|
{
|
||||||
|
mPickpocketDetected = false;
|
||||||
mPtr = container;
|
mPtr = container;
|
||||||
|
|
||||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name() && !loot)
|
if (mPtr.getTypeName() == typeid(ESM::NPC).name() && !loot)
|
||||||
{
|
{
|
||||||
// we are stealing stuff
|
// 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));
|
mModel = new PickpocketItemModel(player, new InventoryItemModel(container));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -225,11 +235,46 @@ namespace MWGui
|
||||||
|
|
||||||
mItemView->setModel (mSortModel);
|
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
|
// 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.
|
// or we end up using a possibly invalid model.
|
||||||
setTitle(MWWorld::Class::get(container).getName(container));
|
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)
|
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
||||||
|
@ -255,8 +300,13 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
playerModel->copyItem(mModel->getItem(i), mModel->getItem(i).mCount);
|
const ItemStack& item = mModel->getItem(i);
|
||||||
mModel->removeItem(mModel->getItem(i), mModel->getItem(i).mCount);
|
|
||||||
|
if (!onTakeItem(item, item.mCount))
|
||||||
|
break;
|
||||||
|
|
||||||
|
playerModel->copyItem(item, item.mCount);
|
||||||
|
mModel->removeItem(item, item.mCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
||||||
|
@ -283,4 +333,30 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
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);
|
ContainerWindow(DragAndDrop* dragAndDrop);
|
||||||
|
|
||||||
void open(const MWWorld::Ptr& container, bool loot=false);
|
void open(const MWWorld::Ptr& container, bool loot=false);
|
||||||
|
virtual void close();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DragAndDrop* mDragAndDrop;
|
DragAndDrop* mDragAndDrop;
|
||||||
|
|
||||||
|
bool mPickpocketDetected;
|
||||||
|
|
||||||
MWGui::ItemView* mItemView;
|
MWGui::ItemView* mItemView;
|
||||||
SortFilterItemModel* mSortModel;
|
SortFilterItemModel* mSortModel;
|
||||||
ItemModel* mModel;
|
ItemModel* mModel;
|
||||||
|
@ -72,6 +75,10 @@ namespace MWGui
|
||||||
void onCloseButtonClicked(MyGUI::Widget* _sender);
|
void onCloseButtonClicked(MyGUI::Widget* _sender);
|
||||||
void onTakeAllButtonClicked(MyGUI::Widget* _sender);
|
void onTakeAllButtonClicked(MyGUI::Widget* _sender);
|
||||||
void onDisposeCorpseButtonClicked(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();
|
virtual void onReferenceUnavailable();
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include "../mwmechanics/npcstats.hpp"
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
|
||||||
#include "../mwdialogue/dialoguemanagerimp.hpp"
|
#include "../mwdialogue/dialoguemanagerimp.hpp"
|
||||||
|
@ -21,7 +20,6 @@
|
||||||
#include "list.hpp"
|
#include "list.hpp"
|
||||||
#include "tradewindow.hpp"
|
#include "tradewindow.hpp"
|
||||||
#include "spellbuyingwindow.hpp"
|
#include "spellbuyingwindow.hpp"
|
||||||
#include "inventorywindow.hpp"
|
|
||||||
#include "travelwindow.hpp"
|
#include "travelwindow.hpp"
|
||||||
#include "bookpage.hpp"
|
#include "bookpage.hpp"
|
||||||
|
|
||||||
|
@ -69,24 +67,24 @@ namespace MWGui
|
||||||
|
|
||||||
void PersuasionDialog::onPersuade(MyGUI::Widget *sender)
|
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;
|
MWBase::MechanicsManager::PersuasionType type;
|
||||||
if (sender == mAdmireButton) type = MWBase::MechanicsManager::PT_Admire;
|
if (sender == mAdmireButton) type = MWBase::MechanicsManager::PT_Admire;
|
||||||
else if (sender == mIntimidateButton) type = MWBase::MechanicsManager::PT_Intimidate;
|
else if (sender == mIntimidateButton) type = MWBase::MechanicsManager::PT_Intimidate;
|
||||||
else if (sender == mTauntButton) type = MWBase::MechanicsManager::PT_Taunt;
|
else if (sender == mTauntButton) type = MWBase::MechanicsManager::PT_Taunt;
|
||||||
else if (sender == mBribe10Button)
|
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;
|
type = MWBase::MechanicsManager::PT_Bribe10;
|
||||||
}
|
}
|
||||||
else if (sender == mBribe100Button)
|
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;
|
type = MWBase::MechanicsManager::PT_Bribe100;
|
||||||
}
|
}
|
||||||
else /*if (sender == mBribe1000Button)*/
|
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;
|
type = MWBase::MechanicsManager::PT_Bribe1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +98,8 @@ namespace MWGui
|
||||||
WindowModal::open();
|
WindowModal::open();
|
||||||
center();
|
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);
|
mBribe10Button->setEnabled (playerGold >= 10);
|
||||||
mBribe100Button->setEnabled (playerGold >= 100);
|
mBribe100Button->setEnabled (playerGold >= 100);
|
||||||
|
@ -546,7 +545,7 @@ namespace MWGui
|
||||||
for (size_t i=0; i<mTopicsList->getItemCount(); ++i)
|
for (size_t i=0; i<mTopicsList->getItemCount(); ++i)
|
||||||
{
|
{
|
||||||
std::string item = mTopicsList->getItemNameAt(i);
|
std::string item = mTopicsList->getItemNameAt(i);
|
||||||
if (Misc::StringUtils::lowerCase(item) == title)
|
if (Misc::StringUtils::ciEqual(item, title))
|
||||||
{
|
{
|
||||||
realTitle = item;
|
realTitle = item;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -5,13 +5,11 @@
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/manualref.hpp"
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
|
||||||
#include "itemselection.hpp"
|
#include "itemselection.hpp"
|
||||||
#include "container.hpp"
|
#include "container.hpp"
|
||||||
#include "inventorywindow.hpp"
|
|
||||||
|
|
||||||
#include "sortfilteritemmodel.hpp"
|
#include "sortfilteritemmodel.hpp"
|
||||||
|
|
||||||
|
@ -106,7 +104,7 @@ namespace MWGui
|
||||||
|
|
||||||
void EnchantingDialog::startSelfEnchanting(MWWorld::Ptr soulgem)
|
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.setSelfEnchanting(true);
|
||||||
mEnchanting.setEnchanter(player);
|
mEnchanting.setEnchanter(player);
|
||||||
|
@ -149,7 +147,7 @@ namespace MWGui
|
||||||
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onItemSelected);
|
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onItemSelected);
|
||||||
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onItemCancel);
|
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onItemCancel);
|
||||||
mItemSelectionDialog->setVisible(true);
|
mItemSelectionDialog->setVisible(true);
|
||||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||||
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyEnchantable);
|
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyEnchantable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +234,7 @@ namespace MWGui
|
||||||
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onSoulSelected);
|
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onSoulSelected);
|
||||||
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onSoulCancel);
|
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onSoulCancel);
|
||||||
mItemSelectionDialog->setVisible(true);
|
mItemSelectionDialog->setVisible(true);
|
||||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||||
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyChargedSoulstones);
|
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyChargedSoulstones);
|
||||||
|
|
||||||
//MWBase::Environment::get().getWindowManager()->messageBox("#{sInventorySelectNoSoul}");
|
//MWBase::Environment::get().getWindowManager()->messageBox("#{sInventorySelectNoSoul}");
|
||||||
|
@ -259,7 +257,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
if (mEffects.size() <= 0)
|
if (mEffects.size() <= 0)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage30}");
|
MWBase::Environment::get().getWindowManager()->messageBox ("#{sEnchantmentMenu11}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,7 +288,9 @@ namespace MWGui
|
||||||
mEnchanting.setNewItemName(mName->getCaption());
|
mEnchanting.setNewItemName(mName->getCaption());
|
||||||
mEnchanting.setEffect(mEffectList);
|
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}");
|
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage18}");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/creaturestats.hpp"
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
|
@ -242,7 +241,7 @@ namespace MWGui
|
||||||
if (world->canPlaceObject(mouseX, mouseY))
|
if (world->canPlaceObject(mouseX, mouseY))
|
||||||
world->placeObject(object, mouseX, mouseY, mDragAndDrop->mDraggedCount);
|
world->placeObject(object, mouseX, mouseY, mDragAndDrop->mDraggedCount);
|
||||||
else
|
else
|
||||||
world->dropObjectOnGround(world->getPlayer().getPlayer(), object, mDragAndDrop->mDraggedCount);
|
world->dropObjectOnGround(world->getPlayerPtr(), object, mDragAndDrop->mDraggedCount);
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->changePointer("arrow");
|
MWBase::Environment::get().getWindowManager()->changePointer("arrow");
|
||||||
|
|
||||||
|
@ -268,7 +267,8 @@ namespace MWGui
|
||||||
else if ((mode == GM_Container) || (mode == GM_Inventory))
|
else if ((mode == GM_Container) || (mode == GM_Inventory))
|
||||||
{
|
{
|
||||||
// pick up object
|
// 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)
|
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())
|
if (MWWorld::Class::get(player).getNpcStats(player).isWerewolf())
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sWerewolfRefusal}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sWerewolfRefusal}");
|
||||||
|
@ -332,7 +332,7 @@ namespace MWGui
|
||||||
|
|
||||||
void HUD::onMagicClicked(MyGUI::Widget* _sender)
|
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())
|
if (MWWorld::Class::get(player).getNpcStats(player).isWerewolf())
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sWerewolfRefusal}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sWerewolfRefusal}");
|
||||||
|
@ -517,7 +517,7 @@ namespace MWGui
|
||||||
mWeapStatus->setProgressPosition(0);
|
mWeapStatus->setProgressPosition(0);
|
||||||
|
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
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())
|
if (MWWorld::Class::get(player).getNpcStats(player).isWerewolf())
|
||||||
mWeapImage->setImageTexture("icons\\k\\tx_werewolf_hand.dds");
|
mWeapImage->setImageTexture("icons\\k\\tx_werewolf_hand.dds");
|
||||||
else
|
else
|
||||||
|
|
|
@ -8,11 +8,13 @@
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/action.hpp"
|
#include "../mwworld/action.hpp"
|
||||||
|
#include "../mwscript/interpretercontext.hpp"
|
||||||
|
#include "../mwbase/scriptmanager.hpp"
|
||||||
|
|
||||||
#include "bookwindow.hpp"
|
#include "bookwindow.hpp"
|
||||||
#include "scrollwindow.hpp"
|
#include "scrollwindow.hpp"
|
||||||
|
@ -33,7 +35,7 @@ namespace MWGui
|
||||||
, mTrading(false)
|
, mTrading(false)
|
||||||
, mLastXSize(0)
|
, mLastXSize(0)
|
||||||
, mLastYSize(0)
|
, mLastYSize(0)
|
||||||
, mPreview(MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ())
|
, mPreview(MWBase::Environment::get().getWorld ()->getPlayerPtr())
|
||||||
, mPreviewDirty(true)
|
, mPreviewDirty(true)
|
||||||
, mDragAndDrop(dragAndDrop)
|
, mDragAndDrop(dragAndDrop)
|
||||||
, mSelectedItem(-1)
|
, mSelectedItem(-1)
|
||||||
|
@ -84,7 +86,7 @@ namespace MWGui
|
||||||
|
|
||||||
void InventoryWindow::updatePlayer()
|
void InventoryWindow::updatePlayer()
|
||||||
{
|
{
|
||||||
mPtr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ();
|
mPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||||
mTradeModel = new TradeItemModel(new InventoryItemModel(mPtr), MWWorld::Ptr());
|
mTradeModel = new TradeItemModel(new InventoryItemModel(mPtr), MWWorld::Ptr());
|
||||||
mSortModel = new SortFilterItemModel(mTradeModel);
|
mSortModel = new SortFilterItemModel(mTradeModel);
|
||||||
mItemView->setModel(mSortModel);
|
mItemView->setModel(mSortModel);
|
||||||
|
@ -276,7 +278,7 @@ namespace MWGui
|
||||||
|
|
||||||
void InventoryWindow::open()
|
void InventoryWindow::open()
|
||||||
{
|
{
|
||||||
mPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
mPtr = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
|
|
||||||
updateEncumbranceBar();
|
updateEncumbranceBar();
|
||||||
|
|
||||||
|
@ -351,6 +353,48 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getWindowManager()->setWeaponVisibility(!mPinned);
|
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)
|
void InventoryWindow::onAvatarClicked(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||||
|
@ -369,21 +413,7 @@ namespace MWGui
|
||||||
mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount);
|
mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount);
|
||||||
ptr = *it;
|
ptr = *it;
|
||||||
}
|
}
|
||||||
|
useItem(ptr);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -432,7 +462,7 @@ namespace MWGui
|
||||||
|
|
||||||
void InventoryWindow::updateEncumbranceBar()
|
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 capacity = MWWorld::Class::get(player).getCapacity(player);
|
||||||
float encumbrance = MWWorld::Class::get(player).getEncumbrance(player);
|
float encumbrance = MWWorld::Class::get(player).getEncumbrance(player);
|
||||||
|
@ -447,19 +477,6 @@ namespace MWGui
|
||||||
updateEncumbranceBar();
|
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)
|
void InventoryWindow::setTrading(bool trading)
|
||||||
{
|
{
|
||||||
mTrading = trading;
|
mTrading = trading;
|
||||||
|
@ -512,12 +529,10 @@ namespace MWGui
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int count = object.getRefData().getCount();
|
int count = object.getRefData().getCount();
|
||||||
if (object.getCellRef().mGoldValue > 1)
|
|
||||||
count = object.getCellRef().mGoldValue;
|
|
||||||
|
|
||||||
// add to player inventory
|
// add to player inventory
|
||||||
// can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object
|
// 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);
|
MWWorld::Ptr newObject = *player.getClass().getContainerStore (player).add (object, object.getRefData().getCount(), player);
|
||||||
// remove from world
|
// remove from world
|
||||||
MWBase::Environment::get().getWorld()->deleteObject (object);
|
MWBase::Environment::get().getWorld()->deleteObject (object);
|
||||||
|
@ -533,6 +548,8 @@ namespace MWGui
|
||||||
if (i == mTradeModel->getItemCount())
|
if (i == mTradeModel->getItemCount())
|
||||||
throw std::runtime_error("Added item not found");
|
throw std::runtime_error("Added item not found");
|
||||||
mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count);
|
mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count);
|
||||||
|
|
||||||
|
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, newObject, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
MyGUI::IntCoord InventoryWindow::getAvatarScreenCoord ()
|
MyGUI::IntCoord InventoryWindow::getAvatarScreenCoord ()
|
||||||
|
|
|
@ -31,8 +31,6 @@ namespace MWGui
|
||||||
|
|
||||||
void pickUpObject (MWWorld::Ptr object);
|
void pickUpObject (MWWorld::Ptr object);
|
||||||
|
|
||||||
int getPlayerGold();
|
|
||||||
|
|
||||||
MyGUI::IntCoord getAvatarScreenCoord();
|
MyGUI::IntCoord getAvatarScreenCoord();
|
||||||
|
|
||||||
MWWorld::Ptr getAvatarSelectedItem(int x, int y);
|
MWWorld::Ptr getAvatarSelectedItem(int x, int y);
|
||||||
|
@ -48,6 +46,8 @@ namespace MWGui
|
||||||
|
|
||||||
void updatePlayer();
|
void updatePlayer();
|
||||||
|
|
||||||
|
void useItem(const MWWorld::Ptr& ptr);
|
||||||
|
|
||||||
void setGuiMode(GuiMode mode);
|
void setGuiMode(GuiMode mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -76,6 +76,8 @@ namespace MWGui
|
||||||
MyGUI::Button* mFilterMagic;
|
MyGUI::Button* mFilterMagic;
|
||||||
MyGUI::Button* mFilterMisc;
|
MyGUI::Button* mFilterMisc;
|
||||||
|
|
||||||
|
MWWorld::Ptr mSkippedToEquip;
|
||||||
|
|
||||||
GuiMode mGuiMode;
|
GuiMode mGuiMode;
|
||||||
|
|
||||||
int mLastXSize;
|
int mLastXSize;
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/fallback.hpp"
|
#include "../mwworld/fallback.hpp"
|
||||||
|
|
||||||
|
@ -59,7 +58,7 @@ namespace MWGui
|
||||||
|
|
||||||
void LevelupDialog::setAttributeValues()
|
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::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player);
|
||||||
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||||
|
|
||||||
|
@ -115,7 +114,7 @@ namespace MWGui
|
||||||
void LevelupDialog::open()
|
void LevelupDialog::open()
|
||||||
{
|
{
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
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::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player);
|
||||||
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||||
|
|
||||||
|
@ -155,7 +154,7 @@ namespace MWGui
|
||||||
|
|
||||||
void LevelupDialog::onOkButtonClicked (MyGUI::Widget* sender)
|
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::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player);
|
||||||
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||||
|
|
||||||
|
|
|
@ -294,7 +294,7 @@ namespace MWGui
|
||||||
std::vector<MWWorld::Ptr> markers;
|
std::vector<MWWorld::Ptr> markers;
|
||||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
world->listDetectedReferences(
|
world->listDetectedReferences(
|
||||||
world->getPlayer().getPlayer(),
|
world->getPlayerPtr(),
|
||||||
markers, MWBase::World::DetectionType(type));
|
markers, MWBase::World::DetectionType(type));
|
||||||
if (markers.empty())
|
if (markers.empty())
|
||||||
return;
|
return;
|
||||||
|
@ -515,8 +515,8 @@ namespace MWGui
|
||||||
// For interiors, position is set by WindowManager via setGlobalMapPlayerPosition
|
// For interiors, position is set by WindowManager via setGlobalMapPlayerPosition
|
||||||
if (MWBase::Environment::get().getWorld ()->isCellExterior ())
|
if (MWBase::Environment::get().getWorld ()->isCellExterior ())
|
||||||
{
|
{
|
||||||
Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedPosition ();
|
Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayerPtr().getRefData ().getBaseNode ()->_getDerivedPosition ();
|
||||||
Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedOrientation ();
|
Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayerPtr().getRefData ().getBaseNode ()->_getDerivedOrientation ();
|
||||||
Ogre::Vector2 dir (orient.yAxis ().x, orient.yAxis().y);
|
Ogre::Vector2 dir (orient.yAxis ().x, orient.yAxis().y);
|
||||||
|
|
||||||
float worldX, worldY;
|
float worldX, worldY;
|
||||||
|
|
|
@ -8,12 +8,9 @@
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
|
||||||
#include "inventorywindow.hpp"
|
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -36,7 +33,9 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
|
||||||
|
|
||||||
int currentY = 0;
|
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);
|
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
|
||||||
int categories = MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Armor;
|
int categories = MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Armor;
|
||||||
for (MWWorld::ContainerStoreIterator iter (store.begin(categories));
|
for (MWWorld::ContainerStoreIterator iter (store.begin(categories));
|
||||||
|
@ -69,8 +68,7 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
|
||||||
|
|
||||||
|
|
||||||
MyGUI::Button* button =
|
MyGUI::Button* button =
|
||||||
mList->createWidget<MyGUI::Button>(
|
mList->createWidget<MyGUI::Button>("SandTextButton",
|
||||||
(price>MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton",
|
|
||||||
0,
|
0,
|
||||||
currentY,
|
currentY,
|
||||||
0,
|
0,
|
||||||
|
@ -80,7 +78,7 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
|
||||||
|
|
||||||
currentY += 18;
|
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->setUserString("Price", boost::lexical_cast<std::string>(price));
|
||||||
button->setUserData(*iter);
|
button->setUserData(*iter);
|
||||||
button->setCaptionWithReplacing(name);
|
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)));
|
mList->setCanvasSize (MyGUI::IntSize(mList->getWidth(), std::max(mList->getHeight(), currentY)));
|
||||||
|
|
||||||
mGoldLabel->setCaptionWithReplacing("#{sGold}: "
|
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)
|
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"));
|
int price = boost::lexical_cast<int>(sender->getUserString("Price"));
|
||||||
|
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
player.getClass().getContainerStore(player).remove("gold_001", price, player);
|
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player);
|
||||||
|
|
||||||
startRepair(mActor);
|
startRepair(mActor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,12 @@
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
MessageBoxManager::MessageBoxManager ()
|
MessageBoxManager::MessageBoxManager (float timePerChar)
|
||||||
{
|
{
|
||||||
mMessageBoxSpeed = 0.1;
|
|
||||||
mInterMessageBoxe = NULL;
|
mInterMessageBoxe = NULL;
|
||||||
mStaticMessageBox = NULL;
|
mStaticMessageBox = NULL;
|
||||||
mLastButtonPressed = -1;
|
mLastButtonPressed = -1;
|
||||||
|
mMessageBoxSpeed = timePerChar;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageBoxManager::~MessageBoxManager ()
|
MessageBoxManager::~MessageBoxManager ()
|
||||||
|
@ -62,7 +62,8 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
MessageBox *box = new MessageBox(*this, message);
|
MessageBox *box = new MessageBox(*this, message);
|
||||||
box->mCurrentTime = 0;
|
box->mCurrentTime = 0;
|
||||||
box->mMaxTime = message.length()*mMessageBoxSpeed;
|
std::string realMessage = MyGUI::LanguageManager::getInstance().replaceTags(message);
|
||||||
|
box->mMaxTime = realMessage.length()*mMessageBoxSpeed;
|
||||||
|
|
||||||
if(stat)
|
if(stat)
|
||||||
mStaticMessageBox = box;
|
mStaticMessageBox = box;
|
||||||
|
@ -126,12 +127,6 @@ namespace MWGui
|
||||||
mMessageBoxSpeed = speed;
|
mMessageBoxSpeed = speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageBoxManager::okayPressed ()
|
|
||||||
{
|
|
||||||
if(mInterMessageBoxe != NULL)
|
|
||||||
mInterMessageBoxe->okayPressed();
|
|
||||||
}
|
|
||||||
|
|
||||||
int MessageBoxManager::readPressedButton ()
|
int MessageBoxManager::readPressedButton ()
|
||||||
{
|
{
|
||||||
int pressed = mLastButtonPressed;
|
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::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}"));
|
||||||
std::vector<MyGUI::Button*>::const_iterator button;
|
std::vector<MyGUI::Button*>::const_iterator button;
|
||||||
for(button = mButtons.begin(); button != mButtons.end(); ++button)
|
for(button = mButtons.begin(); button != mButtons.end(); ++button)
|
||||||
{
|
{
|
||||||
if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok)
|
if(Misc::StringUtils::ciEqual((*button)->getCaption(), ok))
|
||||||
{
|
{
|
||||||
buttonActivated(*button);
|
MyGUI::InputManager::getInstance().setKeyFocusWidget(*button);
|
||||||
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
|
(*button)->eventKeyButtonPressed += MyGUI::newDelegate(this, &InteractiveMessageBox::onKeyPressed);
|
||||||
break;
|
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)
|
void InteractiveMessageBox::mousePressed (MyGUI::Widget* pressed)
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace MWGui
|
||||||
class MessageBoxManager
|
class MessageBoxManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MessageBoxManager ();
|
MessageBoxManager (float timePerChar);
|
||||||
~MessageBoxManager ();
|
~MessageBoxManager ();
|
||||||
void onFrame (float frameDuration);
|
void onFrame (float frameDuration);
|
||||||
void createMessageBox (const std::string& message, bool stat = false);
|
void createMessageBox (const std::string& message, bool stat = false);
|
||||||
|
@ -33,7 +33,6 @@ namespace MWGui
|
||||||
bool removeMessageBox (MessageBox *msgbox);
|
bool removeMessageBox (MessageBox *msgbox);
|
||||||
void setMessageBoxSpeed (int speed);
|
void setMessageBoxSpeed (int speed);
|
||||||
|
|
||||||
void okayPressed();
|
|
||||||
int readPressedButton ();
|
int readPressedButton ();
|
||||||
|
|
||||||
typedef MyGUI::delegates::CMultiDelegate1<int> EventHandle_Int;
|
typedef MyGUI::delegates::CMultiDelegate1<int> EventHandle_Int;
|
||||||
|
@ -74,7 +73,6 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InteractiveMessageBox (MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons);
|
InteractiveMessageBox (MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons);
|
||||||
void okayPressed ();
|
|
||||||
void mousePressed (MyGUI::Widget* _widget);
|
void mousePressed (MyGUI::Widget* _widget);
|
||||||
int readPressedButton ();
|
int readPressedButton ();
|
||||||
|
|
||||||
|
@ -82,6 +80,7 @@ namespace MWGui
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void buttonActivated (MyGUI::Widget* _widget);
|
void buttonActivated (MyGUI::Widget* _widget);
|
||||||
|
void onKeyPressed(MyGUI::Widget* _sender, MyGUI::KeyCode _key, MyGUI::Char _char);
|
||||||
|
|
||||||
MessageBoxManager& mMessageBoxManager;
|
MessageBoxManager& mMessageBoxManager;
|
||||||
MyGUI::EditBox* mMessageWidget;
|
MyGUI::EditBox* mMessageWidget;
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace MWGui
|
||||||
PickpocketItemModel::PickpocketItemModel(const MWWorld::Ptr& thief, ItemModel *sourceModel)
|
PickpocketItemModel::PickpocketItemModel(const MWWorld::Ptr& thief, ItemModel *sourceModel)
|
||||||
{
|
{
|
||||||
mSourceModel = 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();
|
mSourceModel->update();
|
||||||
for (size_t i = 0; i<mSourceModel->getItemCount(); ++i)
|
for (size_t i = 0; i<mSourceModel->getItemCount(); ++i)
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
#include "../mwworld/actionequip.hpp"
|
#include "../mwworld/actionequip.hpp"
|
||||||
#include "../mwmechanics/spellcasting.hpp"
|
#include "../mwmechanics/spellcasting.hpp"
|
||||||
|
@ -126,7 +125,7 @@ namespace MWGui
|
||||||
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &QuickKeysMenu::onAssignItemCancel);
|
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &QuickKeysMenu::onAssignItemCancel);
|
||||||
}
|
}
|
||||||
mItemSelectionDialog->setVisible(true);
|
mItemSelectionDialog->setVisible(true);
|
||||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||||
|
|
||||||
mAssignDialog->setVisible (false);
|
mAssignDialog->setVisible (false);
|
||||||
}
|
}
|
||||||
|
@ -267,7 +266,7 @@ namespace MWGui
|
||||||
|
|
||||||
QuickKeyType type = *button->getUserData<QuickKeyType>();
|
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);
|
MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
|
||||||
|
|
||||||
if (type == Type_Item || type == Type_MagicItem)
|
if (type == Type_Item || type == Type_MagicItem)
|
||||||
|
@ -302,6 +301,12 @@ namespace MWGui
|
||||||
if (type == Type_Magic)
|
if (type == Type_Magic)
|
||||||
{
|
{
|
||||||
std::string spellId = button->getChildAt(0)->getUserString("Spell");
|
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());
|
store.setSelectedEnchantItem(store.end());
|
||||||
MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player)));
|
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>();
|
MWWorld::Ptr item = *button->getChildAt (0)->getUserData<MWWorld::Ptr>();
|
||||||
|
|
||||||
boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(item).use(item);
|
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->useItem(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();
|
|
||||||
}
|
}
|
||||||
else if (type == Type_MagicItem)
|
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
|
// 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);
|
MWWorld::ActionEquip action(item);
|
||||||
action.execute (MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ());
|
action.execute (MWBase::Environment::get().getWorld ()->getPlayerPtr());
|
||||||
}
|
}
|
||||||
|
|
||||||
store.setSelectedEnchantItem(it);
|
store.setSelectedEnchantItem(it);
|
||||||
|
@ -430,7 +423,7 @@ namespace MWGui
|
||||||
|
|
||||||
const int spellHeight = 18;
|
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);
|
MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
|
||||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||||
MWMechanics::Spells& spells = stats.getSpells();
|
MWMechanics::Spells& spells = stats.getSpells();
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "race.hpp"
|
#include "race.hpp"
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
|
@ -140,7 +139,7 @@ namespace MWGui
|
||||||
size_t count = mRaceList->getItemCount();
|
size_t count = mRaceList->getItemCount();
|
||||||
for (size_t i = 0; i < count; ++i)
|
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);
|
mRaceList->setIndexSelected(i);
|
||||||
MyGUI::Button* okButton;
|
MyGUI::Button* okButton;
|
||||||
|
@ -230,7 +229,7 @@ namespace MWGui
|
||||||
MyGUI::Button* okButton;
|
MyGUI::Button* okButton;
|
||||||
getWidget(okButton, "OKButton");
|
getWidget(okButton, "OKButton");
|
||||||
const std::string *raceId = mRaceList->getItemDataAt<std::string>(_index);
|
const std::string *raceId = mRaceList->getItemDataAt<std::string>(_index);
|
||||||
if (boost::iequals(mCurrentRaceId, *raceId))
|
if (Misc::StringUtils::ciEqual(mCurrentRaceId, *raceId))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mCurrentRaceId = *raceId;
|
mCurrentRaceId = *raceId;
|
||||||
|
@ -320,7 +319,7 @@ namespace MWGui
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mRaceList->addItem(it->mName, it->mId);
|
mRaceList->addItem(it->mName, it->mId);
|
||||||
if (boost::iequals(it->mId, mCurrentRaceId))
|
if (Misc::StringUtils::ciEqual(it->mId, mCurrentRaceId))
|
||||||
mRaceList->setIndexSelected(index);
|
mRaceList->setIndexSelected(index);
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
@ -85,7 +84,7 @@ void Recharge::updateView()
|
||||||
|
|
||||||
int currentY = 0;
|
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);
|
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
|
||||||
for (MWWorld::ContainerStoreIterator iter (store.begin());
|
for (MWWorld::ContainerStoreIterator iter (store.begin());
|
||||||
iter!=store.end(); ++iter)
|
iter!=store.end(); ++iter)
|
||||||
|
@ -141,7 +140,7 @@ void Recharge::onItemClicked(MyGUI::Widget *sender)
|
||||||
|
|
||||||
MWWorld::Ptr item = *sender->getUserData<MWWorld::Ptr>();
|
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::CreatureStats& stats = player.getClass().getCreatureStats(player);
|
||||||
MWMechanics::NpcStats& npcStats = player.getClass().getNpcStats(player);
|
MWMechanics::NpcStats& npcStats = player.getClass().getNpcStats(player);
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
ReferenceInterface::ReferenceInterface()
|
ReferenceInterface::ReferenceInterface()
|
||||||
|
@ -18,7 +16,7 @@ namespace MWGui
|
||||||
|
|
||||||
void ReferenceInterface::checkReferenceAvailable()
|
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
|
// check if player has changed cell, or count of the reference has become 0
|
||||||
if ((playerCell != mCurrentPlayerCell && mCurrentPlayerCell != NULL)
|
if ((playerCell != mCurrentPlayerCell && mCurrentPlayerCell != NULL)
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
@ -88,7 +87,7 @@ void Repair::updateRepairView()
|
||||||
|
|
||||||
int currentY = 0;
|
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);
|
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
|
||||||
int categories = MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Armor;
|
int categories = MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Armor;
|
||||||
for (MWWorld::ContainerStoreIterator iter (store.begin(categories));
|
for (MWWorld::ContainerStoreIterator iter (store.begin(categories));
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/actiontake.hpp"
|
#include "../mwworld/actiontake.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
|
|
||||||
#include "formatting.hpp"
|
#include "formatting.hpp"
|
||||||
|
|
||||||
|
@ -90,7 +89,7 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getSoundManager()->playSound("Item Book Up", 1.0, 1.0);
|
MWBase::Environment::get().getSoundManager()->playSound("Item Book Up", 1.0, 1.0);
|
||||||
|
|
||||||
MWWorld::ActionTake take(mScroll);
|
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);
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,11 @@
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/creaturestats.hpp"
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
|
|
||||||
#include "inventorywindow.hpp"
|
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
const int SpellBuyingWindow::sLineHeight = 18;
|
const int SpellBuyingWindow::sLineHeight = 18;
|
||||||
|
@ -43,15 +40,19 @@ namespace MWGui
|
||||||
int price = spell->mData.mCost*store.get<ESM::GameSetting>().find("fSpellValueMult")->getFloat();
|
int price = spell->mData.mCost*store.get<ESM::GameSetting>().find("fSpellValueMult")->getFloat();
|
||||||
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true);
|
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 =
|
MyGUI::Button* toAdd =
|
||||||
mSpellsView->createWidget<MyGUI::Button>(
|
mSpellsView->createWidget<MyGUI::Button>(
|
||||||
(price>MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton",
|
"SandTextButton",
|
||||||
0,
|
0,
|
||||||
mCurrentY,
|
mCurrentY,
|
||||||
200,
|
200,
|
||||||
sLineHeight,
|
sLineHeight,
|
||||||
MyGUI::Align::Default
|
MyGUI::Align::Default
|
||||||
);
|
);
|
||||||
|
toAdd->setEnabled(price<=playerGold);
|
||||||
|
|
||||||
mCurrentY += sLineHeight;
|
mCurrentY += sLineHeight;
|
||||||
|
|
||||||
|
@ -103,7 +104,7 @@ namespace MWGui
|
||||||
|
|
||||||
bool SpellBuyingWindow::playerHasSpell(const std::string &id)
|
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();
|
MWMechanics::Spells& playerSpells = MWWorld::Class::get (player).getCreatureStats (player).getSpells();
|
||||||
for (MWMechanics::Spells::TIterator it = playerSpells.begin(); it != playerSpells.end(); ++it)
|
for (MWMechanics::Spells::TIterator it = playerSpells.begin(); it != playerSpells.end(); ++it)
|
||||||
{
|
{
|
||||||
|
@ -117,17 +118,14 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
int price = *_sender->getUserData<int>();
|
int price = *_sender->getUserData<int>();
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()>=price)
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
{
|
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
MWMechanics::Spells& spells = stats.getSpells();
|
||||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
spells.add (mSpellsWidgetMap.find(_sender)->second);
|
||||||
MWMechanics::Spells& spells = stats.getSpells();
|
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player);
|
||||||
spells.add (mSpellsWidgetMap.find(_sender)->second);
|
startSpellBuying(mPtr);
|
||||||
player.getClass().getContainerStore(player).remove("gold_001", 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)
|
void SpellBuyingWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
|
||||||
|
@ -137,7 +135,10 @@ namespace MWGui
|
||||||
|
|
||||||
void SpellBuyingWindow::updateLabels()
|
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->setCoord(8,
|
||||||
mPlayerGold->getTop(),
|
mPlayerGold->getTop(),
|
||||||
mPlayerGold->getTextSize().width,
|
mPlayerGold->getTextSize().width,
|
||||||
|
|
|
@ -7,14 +7,12 @@
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/spellcasting.hpp"
|
#include "../mwmechanics/spellcasting.hpp"
|
||||||
|
|
||||||
#include "tooltips.hpp"
|
#include "tooltips.hpp"
|
||||||
#include "class.hpp"
|
#include "class.hpp"
|
||||||
#include "inventorywindow.hpp"
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -334,7 +332,10 @@ namespace MWGui
|
||||||
return;
|
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}");
|
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage18}");
|
||||||
return;
|
return;
|
||||||
|
@ -342,9 +343,7 @@ namespace MWGui
|
||||||
|
|
||||||
mSpell.mName = mNameEdit->getCaption();
|
mSpell.mName = mNameEdit->getCaption();
|
||||||
|
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, boost::lexical_cast<int>(mPriceLabel->getCaption()), player);
|
||||||
|
|
||||||
player.getClass().getContainerStore(player).remove("gold_001", boost::lexical_cast<int>(mPriceLabel->getCaption()), player);
|
|
||||||
|
|
||||||
MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0);
|
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)));
|
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)));
|
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
|
// 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::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||||
MWMechanics::Spells& spells = stats.getSpells();
|
MWMechanics::Spells& spells = stats.getSpells();
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
|
|
||||||
|
@ -40,7 +39,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
// TODO: Tracking add/remove/expire would be better than force updating every frame
|
// 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);
|
const MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
#include "../mwworld/actionequip.hpp"
|
#include "../mwworld/actionequip.hpp"
|
||||||
|
|
||||||
|
@ -81,7 +80,7 @@ namespace MWGui
|
||||||
|
|
||||||
// retrieve all player spells, divide them into Powers and Spells and sort them
|
// retrieve all player spells, divide them into Powers and Spells and sort them
|
||||||
std::vector<std::string> spellList;
|
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);
|
MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
|
||||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||||
MWMechanics::Spells& spells = stats.getSpells();
|
MWMechanics::Spells& spells = stats.getSpells();
|
||||||
|
@ -298,7 +297,7 @@ namespace MWGui
|
||||||
|
|
||||||
void SpellWindow::onEnchantedItemSelected(MyGUI::Widget* _sender)
|
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::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
|
||||||
MWWorld::Ptr item = *_sender->getUserData<MWWorld::Ptr>();
|
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
|
// 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);
|
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
|
// since we changed equipping status, update the inventory window
|
||||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView();
|
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView();
|
||||||
|
@ -335,7 +334,7 @@ namespace MWGui
|
||||||
void SpellWindow::onSpellSelected(MyGUI::Widget* _sender)
|
void SpellWindow::onSpellSelected(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
std::string spellId = _sender->getUserString("Spell");
|
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);
|
MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
|
||||||
|
|
||||||
if (MyGUI::InputManager::getInstance().isShiftPressed())
|
if (MyGUI::InputManager::getInstance().isShiftPressed())
|
||||||
|
@ -389,7 +388,7 @@ namespace MWGui
|
||||||
|
|
||||||
void SpellWindow::onDeleteSpellAccept()
|
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::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||||
MWMechanics::Spells& spells = stats.getSpells();
|
MWMechanics::Spells& spells = stats.getSpells();
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
#include "../mwworld/player.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/npcstats.hpp"
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
|
@ -185,8 +185,8 @@ namespace MWGui
|
||||||
MyGUI::TextBox* widget = mSkillWidgetMap[(int)parSkill];
|
MyGUI::TextBox* widget = mSkillWidgetMap[(int)parSkill];
|
||||||
if (widget)
|
if (widget)
|
||||||
{
|
{
|
||||||
float modified = value.getModified(), base = value.getBase();
|
int modified = value.getModified(), base = value.getBase();
|
||||||
std::string text = boost::lexical_cast<std::string>(std::floor(modified));
|
std::string text = boost::lexical_cast<std::string>(modified);
|
||||||
std::string state = "normal";
|
std::string state = "normal";
|
||||||
if (modified > base)
|
if (modified > base)
|
||||||
state = "increased";
|
state = "increased";
|
||||||
|
@ -224,7 +224,7 @@ namespace MWGui
|
||||||
if (!mMainWidget->getVisible())
|
if (!mMainWidget->getVisible())
|
||||||
return;
|
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);
|
const MWMechanics::NpcStats &PCstats = MWWorld::Class::get(player).getNpcStats(player);
|
||||||
|
|
||||||
// level progress
|
// level progress
|
||||||
|
@ -424,7 +424,7 @@ namespace MWGui
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
const MWWorld::ESMStore &store = world->getStore();
|
const MWWorld::ESMStore &store = world->getStore();
|
||||||
const ESM::NPC *player =
|
const ESM::NPC *player =
|
||||||
world->getPlayer().getPlayer().get<ESM::NPC>()->mBase;
|
world->getPlayerPtr().get<ESM::NPC>()->mBase;
|
||||||
|
|
||||||
// race tooltip
|
// race tooltip
|
||||||
const ESM::Race* playerRace = store.get<ESM::Race>().find(player->mRace);
|
const ESM::Race* playerRace = store.get<ESM::Race>().find(player->mRace);
|
||||||
|
@ -452,7 +452,7 @@ namespace MWGui
|
||||||
if (!mSkillWidgets.empty())
|
if (!mSkillWidgets.empty())
|
||||||
addSeparator(coord1, coord2);
|
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 MWMechanics::NpcStats &PCstats = MWWorld::Class::get(player).getNpcStats(player);
|
||||||
const std::set<std::string> &expelled = PCstats.getExpelled();
|
const std::set<std::string> &expelled = PCstats.getExpelled();
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ namespace MWGui
|
||||||
if(!mMerchant.isEmpty())
|
if(!mMerchant.isEmpty())
|
||||||
{
|
{
|
||||||
MWWorld::Ptr base = item.mBase;
|
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;
|
continue;
|
||||||
if(!MWWorld::Class::get(base).canSell(base, services))
|
if(!MWWorld::Class::get(base).canSell(base, services))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
#include "../mwmechanics/creaturestats.hpp"
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
#include "../mwmechanics/npcstats.hpp"
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
|
|
||||||
#include "inventorywindow.hpp"
|
#include "inventorywindow.hpp"
|
||||||
#include "itemview.hpp"
|
#include "itemview.hpp"
|
||||||
#include "sortfilteritemmodel.hpp"
|
#include "sortfilteritemmodel.hpp"
|
||||||
|
@ -212,11 +210,11 @@ namespace MWGui
|
||||||
|
|
||||||
if (amount > 0)
|
if (amount > 0)
|
||||||
{
|
{
|
||||||
store.add("gold_001", amount, actor);
|
store.add(MWWorld::ContainerStore::sGoldId, amount, actor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
store.remove("gold_001", - amount, actor);
|
store.remove(MWWorld::ContainerStore::sGoldId, - amount, actor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,8 +251,11 @@ namespace MWGui
|
||||||
return;
|
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
|
// 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
|
// user notification
|
||||||
MWBase::Environment::get().getWindowManager()->
|
MWBase::Environment::get().getWindowManager()->
|
||||||
|
@ -271,8 +272,6 @@ namespace MWGui
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
|
||||||
|
|
||||||
if(mCurrentBalance > mCurrentMerchantOffer)
|
if(mCurrentBalance > mCurrentMerchantOffer)
|
||||||
{
|
{
|
||||||
//if npc is a creature: reject (no haggle)
|
//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)
|
float clampedDisposition = std::max<int>(0,std::min<int>(int(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)
|
||||||
+ MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()),100));
|
+ MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()),100));
|
||||||
|
|
||||||
const MWMechanics::NpcStats &sellerStats = MWWorld::Class::get(mPtr).getNpcStats(mPtr);
|
const MWMechanics::NpcStats &sellerStats = mPtr.getClass().getNpcStats(mPtr);
|
||||||
const MWMechanics::NpcStats &playerStats = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr);
|
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 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 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 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);
|
float f1 = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
|
||||||
|
|
||||||
|
@ -319,16 +318,18 @@ namespace MWGui
|
||||||
messageBox("#{sNotifyMessage9}");
|
messageBox("#{sNotifyMessage9}");
|
||||||
|
|
||||||
int iBarterFailDisposition = gmst.find("iBarterFailDisposition")->getInt();
|
int iBarterFailDisposition = gmst.find("iBarterFailDisposition")->getInt();
|
||||||
MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterFailDisposition);
|
if (mPtr.getClass().isNpc())
|
||||||
|
MWBase::Environment::get().getDialogueManager()->applyDispositionChange(iBarterFailDisposition);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//skill use!
|
//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();
|
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
|
// make the item transfer
|
||||||
mTradeModel->transferItems();
|
mTradeModel->transferItems();
|
||||||
|
@ -337,7 +338,7 @@ namespace MWGui
|
||||||
// transfer the gold
|
// transfer the gold
|
||||||
if (mCurrentBalance != 0)
|
if (mCurrentBalance != 0)
|
||||||
{
|
{
|
||||||
addOrRemoveGold(mCurrentBalance, playerPtr);
|
addOrRemoveGold(mCurrentBalance, player);
|
||||||
addOrRemoveGold(-mCurrentBalance, mPtr);
|
addOrRemoveGold(-mCurrentBalance, mPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,7 +399,10 @@ namespace MWGui
|
||||||
|
|
||||||
void TradeWindow::updateLabels()
|
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)
|
if (mCurrentBalance > 0)
|
||||||
{
|
{
|
||||||
|
@ -447,7 +451,7 @@ namespace MWGui
|
||||||
MWWorld::ContainerStore store = mPtr.getClass().getContainerStore(mPtr);
|
MWWorld::ContainerStore store = mPtr.getClass().getContainerStore(mPtr);
|
||||||
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
||||||
{
|
{
|
||||||
if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, "gold_001"))
|
if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, MWWorld::ContainerStore::sGoldId))
|
||||||
merchantGold += it->getRefData().getCount();
|
merchantGold += it->getRefData().getCount();
|
||||||
}
|
}
|
||||||
return merchantGold;
|
return merchantGold;
|
||||||
|
|
|
@ -28,8 +28,6 @@ namespace MWGui
|
||||||
|
|
||||||
void startTrade(const MWWorld::Ptr& actor);
|
void startTrade(const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
void addOrRemoveGold(int gold, const MWWorld::Ptr& actor);
|
|
||||||
|
|
||||||
void onFrame(float frameDuration);
|
void onFrame(float frameDuration);
|
||||||
|
|
||||||
void borrowItem (int index, size_t count);
|
void borrowItem (int index, size_t count);
|
||||||
|
@ -95,6 +93,8 @@ namespace MWGui
|
||||||
void onIncreaseButtonTriggered();
|
void onIncreaseButtonTriggered();
|
||||||
void onDecreaseButtonTriggered();
|
void onDecreaseButtonTriggered();
|
||||||
|
|
||||||
|
void addOrRemoveGold(int gold, const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
void updateLabels();
|
void updateLabels();
|
||||||
|
|
||||||
virtual void onReferenceUnavailable();
|
virtual void onReferenceUnavailable();
|
||||||
|
|
|
@ -9,13 +9,11 @@
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/npcstats.hpp"
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
#include "inventorywindow.hpp"
|
|
||||||
#include "tooltips.hpp"
|
#include "tooltips.hpp"
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
|
@ -41,7 +39,10 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
mPtr = actor;
|
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);
|
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats (actor);
|
||||||
|
|
||||||
|
@ -72,7 +73,6 @@ namespace MWGui
|
||||||
MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator ();
|
MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator ();
|
||||||
MyGUI::Gui::getInstance ().destroyWidgets (widgets);
|
MyGUI::Gui::getInstance ().destroyWidgets (widgets);
|
||||||
|
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ();
|
|
||||||
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||||
|
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
|
@ -83,11 +83,10 @@ namespace MWGui
|
||||||
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer
|
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer
|
||||||
(mPtr,pcStats.getSkill (bestSkills[i].first).getBase() * gmst.find("iTrainingMod")->getInt (),true);
|
(mPtr,pcStats.getSkill (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>("SandTextButton",
|
||||||
|
|
||||||
MyGUI::Button* button = mTrainingOptions->createWidget<MyGUI::Button>(skin,
|
|
||||||
MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default);
|
MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default);
|
||||||
|
|
||||||
|
button->setEnabled(price <= playerGold);
|
||||||
button->setUserData(bestSkills[i].first);
|
button->setUserData(bestSkills[i].first);
|
||||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected);
|
button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected);
|
||||||
|
|
||||||
|
@ -115,7 +114,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
int skillId = *sender->getUserData<int>();
|
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);
|
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||||
|
|
||||||
const MWWorld::ESMStore &store =
|
const MWWorld::ESMStore &store =
|
||||||
|
@ -124,9 +123,6 @@ namespace MWGui
|
||||||
int price = pcStats.getSkill (skillId).getBase() * store.get<ESM::GameSetting>().find("iTrainingMod")->getInt ();
|
int price = pcStats.getSkill (skillId).getBase() * store.get<ESM::GameSetting>().find("iTrainingMod")->getInt ();
|
||||||
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true);
|
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);
|
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(mPtr).getNpcStats (mPtr);
|
||||||
if (npcStats.getSkill (skillId).getBase () <= pcStats.getSkill (skillId).getBase ())
|
if (npcStats.getSkill (skillId).getBase () <= pcStats.getSkill (skillId).getBase ())
|
||||||
{
|
{
|
||||||
|
@ -134,6 +130,14 @@ namespace MWGui
|
||||||
return;
|
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
|
// increase skill
|
||||||
MWWorld::LiveCellRef<ESM::NPC> *playerRef = player.get<ESM::NPC>();
|
MWWorld::LiveCellRef<ESM::NPC> *playerRef = player.get<ESM::NPC>();
|
||||||
|
|
||||||
|
@ -142,7 +146,7 @@ namespace MWGui
|
||||||
pcStats.increaseSkill (skillId, *class_, true);
|
pcStats.increaseSkill (skillId, *class_, true);
|
||||||
|
|
||||||
// remove gold
|
// 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
|
// go back to game mode
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Training);
|
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Training);
|
||||||
|
@ -150,6 +154,8 @@ namespace MWGui
|
||||||
|
|
||||||
// advance time
|
// advance time
|
||||||
MWBase::Environment::get().getWorld ()->advanceTime (2);
|
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);
|
MWBase::Environment::get().getWorld ()->getFader()->fadeOut(0.25);
|
||||||
mFadeTimeRemaining = 0.5;
|
mFadeTimeRemaining = 0.5;
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
#include <OgreVector3.h>
|
||||||
|
|
||||||
#include <libs/openengine/ogre/fader.hpp>
|
#include <libs/openengine/ogre/fader.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
@ -9,12 +11,9 @@
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
|
||||||
#include "inventorywindow.hpp"
|
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
const int TravelWindow::sLineHeight = 18;
|
const int TravelWindow::sLineHeight = 18;
|
||||||
|
@ -51,13 +50,15 @@ namespace MWGui
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
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)
|
if(interior)
|
||||||
{
|
{
|
||||||
price = gmst.find("fMagesGuildTravel")->getFloat();
|
price = gmst.find("fMagesGuildTravel")->getFloat();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
|
||||||
ESM::Position PlayerPos = player.getRefData().getPosition();
|
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) );
|
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();
|
price = d/gmst.find("fTravelMult")->getFloat();
|
||||||
|
@ -65,7 +66,8 @@ namespace MWGui
|
||||||
|
|
||||||
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true);
|
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;
|
mCurrentY += sLineHeight;
|
||||||
if(interior)
|
if(interior)
|
||||||
toAdd->setUserString("interior","y");
|
toAdd->setUserString("interior","y");
|
||||||
|
@ -121,13 +123,14 @@ namespace MWGui
|
||||||
int price;
|
int price;
|
||||||
iss >> 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;
|
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);
|
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1);
|
||||||
ESM::Position pos = *_sender->getUserData<ESM::Position>();
|
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());
|
int hours = static_cast<int>(d /MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fTravelTimeMult")->getFloat());
|
||||||
for(int i = 0;i < hours;i++)
|
for(int i = 0;i < hours;i++)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getMechanicsManager ()->restoreDynamicStats ();
|
MWBase::Environment::get().getMechanicsManager ()->rest (true);
|
||||||
}
|
}
|
||||||
MWBase::Environment::get().getWorld()->advanceTime(hours);
|
MWBase::Environment::get().getWorld()->advanceTime(hours);
|
||||||
|
|
||||||
|
@ -166,7 +169,10 @@ namespace MWGui
|
||||||
|
|
||||||
void TravelWindow::updateLabels()
|
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->setCoord(8,
|
||||||
mPlayerGold->getTop(),
|
mPlayerGold->getTop(),
|
||||||
mPlayerGold->getTextSize().width,
|
mPlayerGold->getTextSize().width,
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/creaturestats.hpp"
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
|
@ -49,6 +48,7 @@ namespace MWGui
|
||||||
, mRemainingTime(0.05)
|
, mRemainingTime(0.05)
|
||||||
, mCurHour(0)
|
, mCurHour(0)
|
||||||
, mManualHours(1)
|
, mManualHours(1)
|
||||||
|
, mInterruptAt(-1)
|
||||||
{
|
{
|
||||||
getWidget(mDateTimeText, "DateTimeText");
|
getWidget(mDateTimeText, "DateTimeText");
|
||||||
getWidget(mRestText, "RestText");
|
getWidget(mRestText, "RestText");
|
||||||
|
@ -103,43 +103,7 @@ namespace MWGui
|
||||||
|
|
||||||
void WaitDialog::onUntilHealedButtonClicked(MyGUI::Widget* sender)
|
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
|
int autoHours = MWBase::Environment::get().getMechanicsManager()->getHoursToRest();
|
||||||
// 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
|
|
||||||
|
|
||||||
startWaiting(autoHours);
|
startWaiting(autoHours);
|
||||||
}
|
}
|
||||||
|
@ -151,7 +115,8 @@ namespace MWGui
|
||||||
|
|
||||||
void WaitDialog::startWaiting(int hoursToWait)
|
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);
|
setVisible(false);
|
||||||
mProgressBar.setVisible (true);
|
mProgressBar.setVisible (true);
|
||||||
|
|
||||||
|
@ -159,6 +124,30 @@ namespace MWGui
|
||||||
mCurHour = 0;
|
mCurHour = 0;
|
||||||
mHours = hoursToWait;
|
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;
|
mRemainingTime = 0.05;
|
||||||
mProgressBar.setProgress (0, mHours);
|
mProgressBar.setProgress (0, mHours);
|
||||||
}
|
}
|
||||||
|
@ -176,7 +165,7 @@ namespace MWGui
|
||||||
|
|
||||||
void WaitDialog::setCanRest (bool canRest)
|
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);
|
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||||
bool full = (stats.getFatigue().getCurrent() >= stats.getFatigue().getModified())
|
bool full = (stats.getFatigue().getCurrent() >= stats.getFatigue().getModified())
|
||||||
&& (stats.getHealth().getCurrent() >= stats.getHealth().getModified())
|
&& (stats.getHealth().getCurrent() >= stats.getHealth().getModified())
|
||||||
|
@ -201,6 +190,13 @@ namespace MWGui
|
||||||
if (!mWaiting)
|
if (!mWaiting)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (mCurHour == mInterruptAt)
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sSleepInterrupt}");
|
||||||
|
MWBase::Environment::get().getWorld()->spawnRandomCreature(mInterruptCreatureList);
|
||||||
|
stopWaiting();
|
||||||
|
}
|
||||||
|
|
||||||
mRemainingTime -= dt;
|
mRemainingTime -= dt;
|
||||||
|
|
||||||
while (mRemainingTime < 0)
|
while (mRemainingTime < 0)
|
||||||
|
@ -212,8 +208,7 @@ namespace MWGui
|
||||||
if (mCurHour <= mHours)
|
if (mCurHour <= mHours)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWorld ()->advanceTime (1);
|
MWBase::Environment::get().getWorld ()->advanceTime (1);
|
||||||
if (mSleeping)
|
MWBase::Environment::get().getMechanicsManager ()->rest (mSleeping);
|
||||||
MWBase::Environment::get().getMechanicsManager ()->restoreDynamicStats ();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,7 +225,7 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_RestBed);
|
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_RestBed);
|
||||||
mWaiting = false;
|
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);
|
const MWMechanics::NpcStats &pcstats = MWWorld::Class::get(player).getNpcStats(player);
|
||||||
|
|
||||||
// trigger levelup if possible
|
// trigger levelup if possible
|
||||||
|
|
|
@ -51,6 +51,9 @@ namespace MWGui
|
||||||
int mManualHours; // stores the hours to rest selected via slider
|
int mManualHours; // stores the hours to rest selected via slider
|
||||||
float mRemainingTime;
|
float mRemainingTime;
|
||||||
|
|
||||||
|
int mInterruptAt;
|
||||||
|
std::string mInterruptCreatureList;
|
||||||
|
|
||||||
WaitDialogProgressBar mProgressBar;
|
WaitDialogProgressBar mProgressBar;
|
||||||
|
|
||||||
void onUntilHealedButtonClicked(MyGUI::Widget* sender);
|
void onUntilHealedButtonClicked(MyGUI::Widget* sender);
|
||||||
|
|
|
@ -208,7 +208,8 @@ namespace MWGui
|
||||||
mConsole = new Console(w,h, mConsoleOnlyScripts);
|
mConsole = new Console(w,h, mConsoleOnlyScripts);
|
||||||
trackWindow(mConsole, "console");
|
trackWindow(mConsole, "console");
|
||||||
mJournal = JournalWindow::create(JournalViewModel::create ());
|
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);
|
mInventoryWindow = new InventoryWindow(mDragAndDrop);
|
||||||
mTradeWindow = new TradeWindow();
|
mTradeWindow = new TradeWindow();
|
||||||
trackWindow(mTradeWindow, "barter");
|
trackWindow(mTradeWindow, "barter");
|
||||||
|
@ -677,17 +678,6 @@ namespace MWGui
|
||||||
mMessageBoxManager->removeStaticMessageBox();
|
mMessageBoxManager->removeStaticMessageBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowManager::enterPressed ()
|
|
||||||
{
|
|
||||||
mMessageBoxManager->okayPressed();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowManager::activateKeyPressed ()
|
|
||||||
{
|
|
||||||
mMessageBoxManager->okayPressed();
|
|
||||||
mCountDialog->cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
int WindowManager::readPressedButton ()
|
int WindowManager::readPressedButton ()
|
||||||
{
|
{
|
||||||
return mMessageBoxManager->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 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 staticMessageBox(const std::string& message);
|
||||||
virtual void removeStaticMessageBox();
|
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 int readPressedButton (); ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox)
|
||||||
|
|
||||||
virtual void onFrame (float frameDuration);
|
virtual void onFrame (float frameDuration);
|
||||||
|
|
|
@ -198,14 +198,7 @@ namespace MWInput
|
||||||
case A_Activate:
|
case A_Activate:
|
||||||
resetIdleTime();
|
resetIdleTime();
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
if (!MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||||
{
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_Container)
|
|
||||||
toggleContainer ();
|
|
||||||
else
|
|
||||||
MWBase::Environment::get().getWindowManager()->activateKeyPressed();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
activate();
|
activate();
|
||||||
break;
|
break;
|
||||||
case A_Journal:
|
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 player tried to start moving, but can't (due to being overencumbered), display a notification.
|
||||||
if (triedToMove)
|
if (triedToMove)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||||
mOverencumberedMessageDelay -= dt;
|
mOverencumberedMessageDelay -= dt;
|
||||||
if (MWWorld::Class::get(player).getEncumbrance(player) >= MWWorld::Class::get(player).getCapacity(player))
|
if (MWWorld::Class::get(player).getEncumbrance(player) >= MWWorld::Class::get(player).getCapacity(player))
|
||||||
{
|
{
|
||||||
|
@ -516,13 +509,6 @@ namespace MWInput
|
||||||
|
|
||||||
mInputBinder->keyPressed (arg);
|
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);
|
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
|
||||||
|
|
||||||
if (kc != OIS::KC_UNASSIGNED)
|
if (kc != OIS::KC_UNASSIGNED)
|
||||||
|
@ -560,7 +546,7 @@ namespace MWInput
|
||||||
if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0)
|
if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0)
|
||||||
{
|
{
|
||||||
MyGUI::Button* b = MyGUI::InputManager::getInstance ().getMouseFocusWidget ()->castType<MyGUI::Button>(false);
|
MyGUI::Button* b = MyGUI::InputManager::getInstance ().getMouseFocusWidget ()->castType<MyGUI::Button>(false);
|
||||||
if (b)
|
if (b && b->getEnabled())
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getSoundManager ()->playSound ("Menu Click", 1.f, 1.f);
|
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.
|
// .. 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()
|
void InputManager::toggleConsole()
|
||||||
{
|
{
|
||||||
if (MyGUI::InputManager::getInstance ().isModalAny())
|
if (MyGUI::InputManager::getInstance ().isModalAny())
|
||||||
|
|
|
@ -173,7 +173,6 @@ namespace MWInput
|
||||||
void toggleSpell();
|
void toggleSpell();
|
||||||
void toggleWeapon();
|
void toggleWeapon();
|
||||||
void toggleInventory();
|
void toggleInventory();
|
||||||
void toggleContainer();
|
|
||||||
void toggleConsole();
|
void toggleConsole();
|
||||||
void screenshot();
|
void screenshot();
|
||||||
void toggleJournal();
|
void toggleJournal();
|
||||||
|
|
|
@ -205,4 +205,22 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
mSpellsChanged = true;
|
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)
|
/// Remove all active effects, if roll succeeds (for each effect)
|
||||||
void purgeAll (float chance);
|
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;
|
bool isSpellActive (std::string id) const;
|
||||||
///< case insensitive
|
///< case insensitive
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/manualref.hpp"
|
#include "../mwworld/manualref.hpp"
|
||||||
#include "../mwworld/actionequip.hpp"
|
#include "../mwworld/actionequip.hpp"
|
||||||
|
|
||||||
|
@ -80,9 +79,26 @@ bool disintegrateSlot (MWWorld::Ptr ptr, int slot, float disintegrate)
|
||||||
return true;
|
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);
|
calculateDynamicStats (ptr);
|
||||||
calculateCreatureStatModifiers (ptr, duration);
|
calculateCreatureStatModifiers (ptr, duration);
|
||||||
|
|
||||||
if(!MWBase::Environment::get().getWindowManager()->isGuiMode())
|
// AI
|
||||||
|
if(MWBase::Environment::get().getMechanicsManager()->isAIActive())
|
||||||
{
|
{
|
||||||
// AI
|
CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
|
||||||
if(MWBase::Environment::get().getMechanicsManager()->isAIActive())
|
//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);
|
ESM::Position playerpos = player.getRefData().getPosition();
|
||||||
//engage combat or not?
|
ESM::Position actorpos = ptr.getRefData().getPosition();
|
||||||
if(ptr != MWBase::Environment::get().getWorld()->getPlayer().getPlayer() && !creatureStats.isHostile())
|
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();
|
disp = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(ptr);
|
||||||
ESM::Position actorpos = ptr.getRefData().getPosition();
|
}
|
||||||
float d = sqrt((actorpos.pos[0] - playerpos.pos[0])*(actorpos.pos[0] - playerpos.pos[0])
|
bool LOS = MWBase::Environment::get().getWorld()->getLOS(ptr,player)
|
||||||
+(actorpos.pos[1] - playerpos.pos[1])*(actorpos.pos[1] - playerpos.pos[1])
|
&& MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr);
|
||||||
+(actorpos.pos[2] - playerpos.pos[2])*(actorpos.pos[2] - playerpos.pos[2]));
|
if( ( (fight == 100 )
|
||||||
float fight = ptr.getClass().getCreatureStats(ptr).getAiSetting(CreatureStats::AI_Fight).getModified();
|
|| (fight >= 95 && d <= 3000)
|
||||||
float disp = 100; //creatures don't have disposition, so set it to 100 by default
|
|| (fight >= 90 && d <= 2000)
|
||||||
if(ptr.getTypeName() == typeid(ESM::NPC).name())
|
|| (fight >= 80 && d <= 1000)
|
||||||
{
|
|| (fight >= 80 && disp <= 40)
|
||||||
disp = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(ptr);
|
|| (fight >= 70 && disp <= 35 && d <= 1000)
|
||||||
}
|
|| (fight >= 60 && disp <= 30 && d <= 1000)
|
||||||
bool LOS = MWBase::Environment::get().getWorld()->getLOS(ptr,MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
|| (fight >= 50 && disp == 0)
|
||||||
if( ( (fight == 100 )
|
|| (fight >= 40 && disp <= 10 && d <= 500) )
|
||||||
|| (fight >= 95 && d <= 3000)
|
&& LOS
|
||||||
|| (fight >= 90 && d <= 2000)
|
)
|
||||||
|| (fight >= 80 && d <= 1000)
|
{
|
||||||
|| (fight >= 80 && disp <= 40)
|
creatureStats.getAiSequence().stack(AiCombat("player"));
|
||||||
|| (fight >= 70 && disp <= 35 && d <= 1000)
|
creatureStats.setHostile(true);
|
||||||
|| (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
|
creatureStats.getAiSequence().execute (ptr,duration);
|
||||||
calculateRestoration(ptr, duration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fatigue restoration
|
||||||
|
calculateRestoration(ptr, duration, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused)
|
void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused)
|
||||||
|
@ -259,44 +274,37 @@ namespace MWMechanics
|
||||||
creatureStats.setFatigue(fatigue);
|
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())
|
if (ptr.getClass().getCreatureStats(ptr).isDead())
|
||||||
return;
|
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>();
|
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 ();
|
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
|
||||||
|
|
||||||
float capacity = MWWorld::Class::get(ptr).getCapacity(ptr);
|
float capacity = ptr.getClass().getCapacity(ptr);
|
||||||
float encumbrance = MWWorld::Class::get(ptr).getEncumbrance(ptr);
|
float encumbrance = ptr.getClass().getEncumbrance(ptr);
|
||||||
float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity);
|
float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity);
|
||||||
if (normalizedEncumbrance > 1)
|
if (normalizedEncumbrance > 1)
|
||||||
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
|
// restore fatigue
|
||||||
|
|
||||||
float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat ();
|
float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat ();
|
||||||
float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat ();
|
float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat ();
|
||||||
float fEndFatigueMult = settings.find("fEndFatigueMult")->getFloat ();
|
float fEndFatigueMult = settings.find("fEndFatigueMult")->getFloat ();
|
||||||
|
@ -307,6 +315,7 @@ namespace MWMechanics
|
||||||
DynamicStat<float> fatigue = stats.getFatigue();
|
DynamicStat<float> fatigue = stats.getFatigue();
|
||||||
fatigue.setCurrent (fatigue.getCurrent() + duration * x);
|
fatigue.setCurrent (fatigue.getCurrent() + duration * x);
|
||||||
stats.setFatigue (fatigue);
|
stats.setFatigue (fatigue);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr, float duration)
|
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
|
float currentDiff = creatureStats.getMagicEffects().get(ESM::MagicEffect::RestoreHealth+i).mMagnitude
|
||||||
- creatureStats.getMagicEffects().get(ESM::MagicEffect::DamageHealth+i).mMagnitude
|
- creatureStats.getMagicEffects().get(ESM::MagicEffect::DamageHealth+i).mMagnitude
|
||||||
- creatureStats.getMagicEffects().get(ESM::MagicEffect::AbsorbHealth+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);
|
creatureStats.setDynamic(i, stat);
|
||||||
}
|
}
|
||||||
|
@ -506,7 +515,7 @@ namespace MWMechanics
|
||||||
if (magnitude > 0)
|
if (magnitude > 0)
|
||||||
{
|
{
|
||||||
ESM::Position ipos = ptr.getRefData().getPosition();
|
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);
|
Ogre::Quaternion rot(Ogre::Radian(-ipos.rot[2]), Ogre::Vector3::UNIT_Z);
|
||||||
const float distance = 50;
|
const float distance = 50;
|
||||||
pos = pos + distance*rot.yAxis();
|
pos = pos + distance*rot.yAxis();
|
||||||
|
@ -527,7 +536,7 @@ namespace MWMechanics
|
||||||
ref.getPtr().getCellRef().mPos = ipos;
|
ref.getPtr().getCellRef().mPos = ipos;
|
||||||
|
|
||||||
// TODO: Add AI to follow player and fight for him
|
// TODO: Add AI to follow player and fight for him
|
||||||
|
// TODO: VFX_SummonStart, VFX_SummonEnd
|
||||||
creatureStats.mSummonedCreatures.insert(std::make_pair(it->first,
|
creatureStats.mSummonedCreatures.insert(std::make_pair(it->first,
|
||||||
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),*store,ipos).getRefData().getHandle()));
|
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),*store,ipos).getRefData().getHandle()));
|
||||||
}
|
}
|
||||||
|
@ -583,10 +592,11 @@ namespace MWMechanics
|
||||||
if(timeLeft == 0.0f)
|
if(timeLeft == 0.0f)
|
||||||
{
|
{
|
||||||
// If drowning, apply 3 points of damage per second
|
// 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
|
// 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();
|
MWBase::SoundManager *sndmgr = MWBase::Environment::get().getSoundManager();
|
||||||
if(!sndmgr->getSoundPlaying(MWWorld::Ptr(), "drown"))
|
if(!sndmgr->getSoundPlaying(MWWorld::Ptr(), "drown"))
|
||||||
|
@ -595,7 +605,10 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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)
|
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())
|
if (iter->second->kill())
|
||||||
{
|
{
|
||||||
++mDeathCount[cls.getId(iter->first)];
|
++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)
|
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
|
int Actors::countDeaths (const std::string& id) const
|
||||||
|
|
|
@ -25,9 +25,6 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
class Actors
|
class Actors
|
||||||
{
|
{
|
||||||
typedef std::map<MWWorld::Ptr,CharacterController*> PtrControllerMap;
|
|
||||||
PtrControllerMap mActors;
|
|
||||||
|
|
||||||
std::map<std::string, int> mDeathCount;
|
std::map<std::string, int> mDeathCount;
|
||||||
|
|
||||||
void updateNpc(const MWWorld::Ptr &ptr, float duration, bool paused);
|
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 calculateCreatureStatModifiers (const MWWorld::Ptr& ptr, float duration);
|
||||||
void calculateNpcStatModifiers (const MWWorld::Ptr& ptr);
|
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);
|
void updateDrowning (const MWWorld::Ptr& ptr, float duration);
|
||||||
|
|
||||||
|
@ -50,6 +47,11 @@ namespace MWMechanics
|
||||||
Actors();
|
Actors();
|
||||||
~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
|
/// 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)
|
/// paused we may want to do it manually (after equipping permanent enchantment)
|
||||||
void updateMagicEffects (const MWWorld::Ptr& ptr) { adjustMagicEffects(ptr); }
|
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
|
///< This function is normally called automatically during the update process, but it can
|
||||||
/// also be called explicitly at any time to force an update.
|
/// 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.
|
///< 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;
|
int countDeaths (const std::string& id) const;
|
||||||
///< Return the number of deaths for actors with the given ID.
|
///< 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 playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
|
||||||
void skipAnimation(const MWWorld::Ptr& ptr);
|
void skipAnimation(const MWWorld::Ptr& ptr);
|
||||||
bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName);
|
bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PtrControllerMap mActors;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
#include "aiactivate.hpp"
|
#include "aiactivate.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
MWMechanics::AiActivate::AiActivate(const std::string &objectId)
|
MWMechanics::AiActivate::AiActivate(const std::string &objectId)
|
||||||
: mObjectId(objectId)
|
: mObjectId(objectId)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
MWMechanics::AiActivate *MWMechanics::AiActivate::clone() const
|
MWMechanics::AiActivate *MWMechanics::AiActivate::clone() const
|
||||||
{
|
{
|
||||||
return new AiActivate(*this);
|
return new AiActivate(*this);
|
||||||
}
|
}
|
||||||
bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration)
|
bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration)
|
||||||
{
|
{
|
||||||
std::cout << "AiActivate completed.\n";
|
std::cout << "AiActivate completed.\n";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MWMechanics::AiActivate::getTypeId() const
|
int MWMechanics::AiActivate::getTypeId() const
|
||||||
{
|
{
|
||||||
return 4;
|
return TypeIdActivate;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,22 +3,22 @@
|
||||||
#include "movement.hpp"
|
#include "movement.hpp"
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/timestamp.hpp"
|
#include "../mwworld/timestamp.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
#include "../mwbase/dialoguemanager.hpp"
|
||||||
|
|
||||||
#include "creaturestats.hpp"
|
#include "creaturestats.hpp"
|
||||||
#include "npcstats.hpp"
|
#include "npcstats.hpp"
|
||||||
|
|
||||||
#include "OgreMath.h"
|
#include <OgreMath.h>
|
||||||
|
|
||||||
namespace
|
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;
|
||||||
return -1.0;
|
return -1.0;
|
||||||
}
|
}
|
||||||
|
@ -40,13 +40,13 @@ namespace MWMechanics
|
||||||
|
|
||||||
if(MWWorld::Class::get(actor).getCreatureStats(actor).getHealth().getCurrent() <= 0) return true;
|
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())
|
if(actor.getTypeName() == typeid(ESM::NPC).name())
|
||||||
{
|
{
|
||||||
MWWorld::Class::get(actor).
|
MWMechanics::DrawState_ state = actor.getClass().getNpcStats(actor).getDrawState();
|
||||||
MWWorld::Class::get(actor).setStance(actor, MWWorld::Class::Run,true);
|
|
||||||
MWMechanics::DrawState_ state = MWWorld::Class::get(actor).getNpcStats(actor).getDrawState();
|
|
||||||
if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing)
|
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);
|
//MWWorld::Class::get(actor).getCreatureStats(actor).setAttackingOrSpell(true);
|
||||||
}
|
}
|
||||||
ESM::Position pos = actor.getRefData().getPosition();
|
ESM::Position pos = actor.getRefData().getPosition();
|
||||||
|
@ -106,7 +106,7 @@ namespace MWMechanics
|
||||||
float directionY = dest.mY - start.mY;
|
float directionY = dest.mY - start.mY;
|
||||||
float directionResult = sqrt(directionX * directionX + directionY * directionY);
|
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
|
// TODO: use movement settings instead of rotating directly
|
||||||
MWBase::Environment::get().getWorld()->rotateObject(actor, 0, 0, zAngle, false);
|
MWBase::Environment::get().getWorld()->rotateObject(actor, 0, 0, zAngle, false);
|
||||||
|
|
||||||
|
@ -119,6 +119,17 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
if( mTimer > 1)
|
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);
|
MWWorld::Class::get(actor).getCreatureStats(actor).setAttackingOrSpell(true);
|
||||||
mTimer = 0;
|
mTimer = 0;
|
||||||
}
|
}
|
||||||
|
@ -135,7 +146,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
int AiCombat::getTypeId() const
|
int AiCombat::getTypeId() const
|
||||||
{
|
{
|
||||||
return 5;
|
return TypeIdCombat;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int AiCombat::getPriority() const
|
unsigned int AiCombat::getPriority() const
|
||||||
|
@ -143,6 +154,11 @@ namespace MWMechanics
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string &AiCombat::getTargetId() const
|
||||||
|
{
|
||||||
|
return mTargetId;
|
||||||
|
}
|
||||||
|
|
||||||
AiCombat *MWMechanics::AiCombat::clone() const
|
AiCombat *MWMechanics::AiCombat::clone() const
|
||||||
{
|
{
|
||||||
return new AiCombat(*this);
|
return new AiCombat(*this);
|
||||||
|
|
|
@ -23,6 +23,8 @@ namespace MWMechanics
|
||||||
|
|
||||||
virtual unsigned int getPriority() const;
|
virtual unsigned int getPriority() const;
|
||||||
|
|
||||||
|
const std::string &getTargetId() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string mTargetId;
|
std::string mTargetId;
|
||||||
|
|
||||||
|
@ -33,4 +35,4 @@ namespace MWMechanics
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include "movement.hpp"
|
#include "movement.hpp"
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
#include "../mwworld/timestamp.hpp"
|
#include "../mwworld/timestamp.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
@ -83,7 +82,7 @@ namespace MWMechanics
|
||||||
return true;
|
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();
|
ESM::Position pos = actor.getRefData().getPosition();
|
||||||
bool cellChange = actor.getCell()->mCell->mData.mX != cellX || actor.getCell()->mCell->mData.mY != cellY;
|
bool cellChange = actor.getCell()->mCell->mData.mX != cellX || actor.getCell()->mCell->mData.mY != cellY;
|
||||||
const ESM::Pathgrid *pathgrid =
|
const ESM::Pathgrid *pathgrid =
|
||||||
|
@ -179,7 +178,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
int AiEscort::getTypeId() const
|
int AiEscort::getTypeId() const
|
||||||
{
|
{
|
||||||
return 2;
|
return TypeIdEscort;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "aifollow.hpp"
|
#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)
|
: 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
|
MWMechanics::AiFollow *MWMechanics::AiFollow::clone() const
|
||||||
{
|
{
|
||||||
return new AiFollow(*this);
|
return new AiFollow(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
|
bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
|
||||||
{
|
{
|
||||||
std::cout << "AiFollow completed.\n";
|
std::cout << "AiFollow completed.\n";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MWMechanics::AiFollow::getTypeId() const
|
int MWMechanics::AiFollow::getTypeId() const
|
||||||
{
|
{
|
||||||
return 3;
|
return TypeIdFollow;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,16 @@ namespace MWMechanics
|
||||||
class AiPackage
|
class AiPackage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum TypeId {
|
||||||
|
TypeIdNone = -1,
|
||||||
|
TypeIdWander = 0,
|
||||||
|
TypeIdTravel = 1,
|
||||||
|
TypeIdEscort = 2,
|
||||||
|
TypeIdFollow = 3,
|
||||||
|
TypeIdActivate = 4,
|
||||||
|
TypeIdCombat = 5
|
||||||
|
};
|
||||||
|
|
||||||
virtual ~AiPackage();
|
virtual ~AiPackage();
|
||||||
|
|
||||||
virtual AiPackage *clone() const = 0;
|
virtual AiPackage *clone() const = 0;
|
||||||
|
@ -21,7 +30,7 @@ namespace MWMechanics
|
||||||
///< \return Package completed?
|
///< \return Package completed?
|
||||||
|
|
||||||
virtual int getTypeId() const = 0;
|
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;}
|
virtual unsigned int getPriority() const {return 0;}
|
||||||
///< higher number is higher priority (0 beeing the lowest)
|
///< higher number is higher priority (0 beeing the lowest)
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "npcstats.hpp"
|
#include "npcstats.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
|
||||||
|
|
||||||
void MWMechanics::AiSequence::copy (const AiSequence& sequence)
|
void MWMechanics::AiSequence::copy (const AiSequence& sequence)
|
||||||
{
|
{
|
||||||
|
@ -56,6 +55,24 @@ int MWMechanics::AiSequence::getTypeId() const
|
||||||
return mPackages.front()->getTypeId();
|
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
|
bool MWMechanics::AiSequence::isPackageDone() const
|
||||||
{
|
{
|
||||||
return mDone;
|
return mDone;
|
||||||
|
@ -63,12 +80,13 @@ bool MWMechanics::AiSequence::isPackageDone() const
|
||||||
|
|
||||||
void MWMechanics::AiSequence::execute (const MWWorld::Ptr& actor,float duration)
|
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.empty())
|
||||||
{
|
{
|
||||||
if (mPackages.front()->execute (actor,duration))
|
if (mPackages.front()->execute (actor,duration))
|
||||||
{
|
{
|
||||||
|
delete *mPackages.begin();
|
||||||
mPackages.erase (mPackages.begin());
|
mPackages.erase (mPackages.begin());
|
||||||
mDone = true;
|
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++)
|
for(std::list<AiPackage *>::iterator it = mPackages.begin(); it != mPackages.end(); it++)
|
||||||
{
|
{
|
||||||
if(mPackages.front()->getPriority() <= package.getPriority())
|
if(mPackages.front()->getPriority() <= package.getPriority())
|
||||||
|
{
|
||||||
mPackages.insert(it,package.clone());
|
mPackages.insert(it,package.clone());
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mPackages.empty())
|
if(mPackages.empty())
|
||||||
|
@ -114,7 +135,7 @@ void MWMechanics::AiSequence::fill(const ESM::AIPackageList &list)
|
||||||
std::vector<int> idles;
|
std::vector<int> idles;
|
||||||
for (int i=0; i<8; ++i)
|
for (int i=0; i<8; ++i)
|
||||||
idles.push_back(data.mIdle[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)
|
else if (it->mType == ESM::AI_Escort)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,14 @@ namespace MWMechanics
|
||||||
virtual ~AiSequence();
|
virtual ~AiSequence();
|
||||||
|
|
||||||
int getTypeId() const;
|
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;
|
bool isPackageDone() const;
|
||||||
///< Has a package been completed during the last update?
|
///< 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