Merge branch 'master' of https://github.com/zinnschlag/openmw into videoplayback

Conflicts:
	apps/openmw/mwrender/renderingmanager.cpp
	apps/openmw/mwscript/miscextensions.cpp
actorid
scrawl 12 years ago
commit 5f676f9c6b

@ -15,7 +15,7 @@ include (OpenMWMacros)
# Version # Version
set (OPENMW_VERSION_MAJOR 0) set (OPENMW_VERSION_MAJOR 0)
set (OPENMW_VERSION_MINOR 19) set (OPENMW_VERSION_MINOR 20)
set (OPENMW_VERSION_RELEASE 0) set (OPENMW_VERSION_RELEASE 0)
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
@ -25,7 +25,8 @@ set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VE
configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp") configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp")
option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE) option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE)
option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE) option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE)
option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE)
# Apps and tools # Apps and tools
option(BUILD_ESMTOOL "build ESM inspector" ON) option(BUILD_ESMTOOL "build ESM inspector" ON)
@ -168,9 +169,9 @@ if (WIN32)
set(PLATFORM_INCLUDE_DIR "platform") set(PLATFORM_INCLUDE_DIR "platform")
add_definitions(-DBOOST_ALL_NO_LIB) add_definitions(-DBOOST_ALL_NO_LIB)
else (WIN32) else (WIN32)
set(PLATFORM_INCLUDE_DIR "") set(PLATFORM_INCLUDE_DIR "")
find_path (UUID_INCLUDE_DIR uuid/uuid.h) find_path (UUID_INCLUDE_DIR uuid/uuid.h)
include_directories(${UUID_INCLUDE_DIR}) include_directories(${UUID_INCLUDE_DIR})
endif (WIN32) endif (WIN32)
if (MSVC10) if (MSVC10)
set(PLATFORM_INCLUDE_DIR "") set(PLATFORM_INCLUDE_DIR "")
@ -184,7 +185,7 @@ endif (APPLE)
# Fix for not visible pthreads functions for linker with glibc 2.15 # Fix for not visible pthreads functions for linker with glibc 2.15
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
find_package (Threads) find_package (Threads)
endif() endif()
# find boost without components so we can use Boost_VERSION # find boost without components so we can use Boost_VERSION
@ -197,6 +198,10 @@ if (Boost_VERSION LESS 104900)
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} wave) set(BOOST_COMPONENTS ${BOOST_COMPONENTS} wave)
endif() endif()
IF(BOOST_STATIC)
set(Boost_USE_STATIC_LIBS ON)
endif()
find_package(OGRE REQUIRED) find_package(OGRE REQUIRED)
find_package(MyGUI REQUIRED) find_package(MyGUI REQUIRED)
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
@ -245,7 +250,7 @@ if (APPLE)
else () else ()
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG}) set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG})
endif () endif ()
#set(OGRE_PLUGIN_DIR "${OGRE_PLUGIN_DIR}/") #set(OGRE_PLUGIN_DIR "${OGRE_PLUGIN_DIR}/")
configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist

@ -131,9 +131,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
->default_value(false), "enable console-only script functionality") ->default_value(false), "enable console-only script functionality")
("script-run", bpo::value<std::string>()->default_value(""), ("script-run", bpo::value<std::string>()->default_value(""),
"select a file that is executed in the console on startup\n\n" "select a file containing a list of console commands that is executed on startup")
"Note: The file contains a list of script lines, but not a complete scripts. "
"That means no begin/end and no variable declarations.")
("new-game", bpo::value<bool>()->implicit_value(true) ("new-game", bpo::value<bool>()->implicit_value(true)
->default_value(false), "activate char gen/new game mechanics") ->default_value(false), "activate char gen/new game mechanics")

@ -110,14 +110,7 @@ namespace MWDialogue
size_t pos = find_str_ci(text,*it,0); size_t pos = find_str_ci(text,*it,0);
if(pos !=std::string::npos) if(pos !=std::string::npos)
{ {
if(pos==0) mKnownTopics[*it] = true;
{
mKnownTopics[*it] = true;
}
else if(text.substr(pos -1,1) == " ")
{
mKnownTopics[*it] = true;
}
} }
} }
updateTopics(); updateTopics();
@ -245,6 +238,44 @@ namespace MWDialogue
} }
} }
void DialogueManager::executeTopic (const std::string& topic)
{
Filter filter (mActor, mChoice, mTalkedTo);
const MWWorld::Store<ESM::Dialogue> &dialogues =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
const ESM::Dialogue& dialogue = *dialogues.find (topic);
if (const ESM::DialInfo *info = filter.search (dialogue))
{
parseText (info->mResponse);
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
if (dialogue.mType==ESM::Dialogue::Persuasion)
{
std::string modifiedTopic = "s" + topic;
modifiedTopic.erase (std::remove (modifiedTopic.begin(), modifiedTopic.end(), ' '), modifiedTopic.end());
const MWWorld::Store<ESM::GameSetting>& gmsts =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
win->addTitle (gmsts.find (modifiedTopic)->getString());
}
else
win->addTitle (topic);
win->addText (info->mResponse);
executeScript (info->mResultScript);
mLastTopic = topic;
mLastDialogue = *info;
}
}
void DialogueManager::updateTopics() void DialogueManager::updateTopics()
{ {
std::list<std::string> keywordList; std::list<std::string> keywordList;
@ -339,24 +370,7 @@ namespace MWDialogue
ESM::Dialogue ndialogue = mDialogueMap[keyword]; ESM::Dialogue ndialogue = mDialogueMap[keyword];
if (mDialogueMap[keyword].mType == ESM::Dialogue::Topic) if (mDialogueMap[keyword].mType == ESM::Dialogue::Topic)
{ {
Filter filter (mActor, mChoice, mTalkedTo); executeTopic (keyword);
if (const ESM::DialInfo *info = filter.search (mDialogueMap[keyword]))
{
std::string text = info->mResponse;
std::string script = info->mResultScript;
parseText (text);
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->addTitle (keyword);
win->addText (info->mResponse);
executeScript (script);
mLastTopic = keyword;
mLastDialogue = *info;
}
} }
} }
} }
@ -452,30 +466,22 @@ namespace MWDialogue
else if (curDisp + mTemporaryDispositionChange > 100) else if (curDisp + mTemporaryDispositionChange > 100)
mTemporaryDispositionChange = 100 - curDisp; mTemporaryDispositionChange = 100 - curDisp;
// practice skill
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWWorld::Class::get(player).skillUsageSucceeded(player, ESM::Skill::Speechcraft, success ? 0 : 1);
if (success)
MWWorld::Class::get(player).skillUsageSucceeded(player, ESM::Skill::Speechcraft, 0);
// add status message to dialogue window
std::string text; std::string text;
if (type == MWBase::MechanicsManager::PT_Admire) if (type == MWBase::MechanicsManager::PT_Admire)
text = "sAdmire"; text = "Admire";
else if (type == MWBase::MechanicsManager::PT_Taunt) else if (type == MWBase::MechanicsManager::PT_Taunt)
text = "sTaunt"; text = "Taunt";
else if (type == MWBase::MechanicsManager::PT_Intimidate) else if (type == MWBase::MechanicsManager::PT_Intimidate)
text = "sIntimidate"; text = "Intimidate";
else else{
text = "sBribe"; text = "Bribe";
}
text += (success ? "Success" : "Fail");
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->addTitle(MyGUI::LanguageManager::getInstance().replaceTags("#{"+text+"}"));
/// \todo text from INFO record, how to get the ID? executeTopic (text + (success ? " Success" : " Fail"));
} }
int DialogueManager::getTemporaryDispositionChange() const int DialogueManager::getTemporaryDispositionChange() const

@ -23,7 +23,7 @@ namespace MWDialogue
MWScript::CompilerContext mCompilerContext; MWScript::CompilerContext mCompilerContext;
std::ostream mErrorStream; std::ostream mErrorStream;
Compiler::StreamErrorHandler mErrorHandler; Compiler::StreamErrorHandler mErrorHandler;
MWWorld::Ptr mActor; MWWorld::Ptr mActor;
bool mTalkedTo; bool mTalkedTo;
@ -46,6 +46,8 @@ namespace MWDialogue
void printError (const std::string& error); void printError (const std::string& error);
void executeTopic (const std::string& topic);
public: public:
DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose); DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose);

@ -63,7 +63,7 @@ namespace MWGui
void AlchemyWindow::onCancelButtonClicked(MyGUI::Widget* _sender) void AlchemyWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
{ {
mAlchemy.clear(); mAlchemy.clear();
mWindowManager.removeGuiMode(GM_Alchemy); mWindowManager.removeGuiMode(GM_Alchemy);
mWindowManager.removeGuiMode(GM_Inventory); mWindowManager.removeGuiMode(GM_Inventory);
} }
@ -119,7 +119,6 @@ namespace MWGui
if (mIngredients[i]->isUserString("ToolTipType")) if (mIngredients[i]->isUserString("ToolTipType"))
{ {
MWWorld::Ptr ingred = *mIngredients[i]->getUserData<MWWorld::Ptr>(); MWWorld::Ptr ingred = *mIngredients[i]->getUserData<MWWorld::Ptr>();
ingred.getRefData().setCount(ingred.getRefData().getCount()-1);
if (ingred.getRefData().getCount() == 0) if (ingred.getRefData().getCount() == 0)
removeIngredient(mIngredients[i]); removeIngredient(mIngredients[i]);
} }

@ -48,6 +48,11 @@ std::string::size_type find_str_ci(const std::string& str, const std::string& su
return lower_string(str).find(lower_string(substr),pos); return lower_string(str).find(lower_string(substr),pos);
} }
bool sortByLength (const std::string& left, const std::string& right)
{
return left.size() > right.size();
}
} }
@ -287,7 +292,7 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
if (mServices & Service_Training) if (mServices & Service_Training)
mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString()); mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString());
if (anyService) if (anyService || mPtr.getTypeName() == typeid(ESM::NPC).name())
mTopicsList->addSeparator(); mTopicsList->addSeparator();
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it) for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it)
@ -311,43 +316,52 @@ void addColorInString(std::string& str, const std::string& keyword,std::string c
size_t pos = 0; size_t pos = 0;
while((pos = find_str_ci(str,keyword, pos)) != std::string::npos) while((pos = find_str_ci(str,keyword, pos)) != std::string::npos)
{ {
if(pos==0) // do not add color if this portion of text is already colored.
{
str.insert(pos,color1);
pos += color1.length();
pos += keyword.length();
str.insert(pos,color2);
pos+= color2.length();
}
else
{ {
if(str.substr(pos -1,1) == " ") MyGUI::TextIterator iterator (str);
{ MyGUI::UString colour;
str.insert(pos,color1); while(iterator.moveNext())
pos += color1.length();
pos += keyword.length();
str.insert(pos,color2);
pos+= color2.length();
}
else
{ {
pos += keyword.length(); size_t iteratorPos = iterator.getPosition();
iterator.getTagColour(colour);
if (iteratorPos == pos)
break;
} }
if (colour == color1)
return;
} }
str.insert(pos,color1);
pos += color1.length();
pos += keyword.length();
str.insert(pos,color2);
pos+= color2.length();
} }
} }
std::string DialogueWindow::parseText(std::string text) std::string DialogueWindow::parseText(std::string text)
{ {
bool separatorReached = false; // only parse topics that are below the separator (this prevents actions like "Barter" that are not topics from getting blue-colored) bool separatorReached = false; // only parse topics that are below the separator (this prevents actions like "Barter" that are not topics from getting blue-colored)
std::vector<std::string> topics;
for(unsigned int i = 0;i<mTopicsList->getItemCount();i++) for(unsigned int i = 0;i<mTopicsList->getItemCount();i++)
{ {
std::string keyWord = mTopicsList->getItemNameAt(i); std::string keyWord = mTopicsList->getItemNameAt(i);
if (separatorReached && keyWord != "") if (separatorReached)
addColorInString(text,keyWord,"#686EBA","#B29154"); topics.push_back(keyWord);
else else if (keyWord == "")
separatorReached = true; separatorReached = true;
} }
// sort by length to make sure longer topics are replaced first
std::sort(topics.begin(), topics.end(), sortByLength);
for(std::vector<std::string>::const_iterator it = topics.begin(); it != topics.end(); ++it)
{
addColorInString(text,*it,"#686EBA","#B29154");
}
return text; return text;
} }

@ -226,9 +226,14 @@ namespace MWGui
if (start == "splash") if (start == "splash")
splash.push_back (*it); splash.push_back (*it);
} }
std::string randomSplash = splash[rand() % splash.size()]; if (splash.size())
{
std::string randomSplash = splash[rand() % splash.size()];
Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton ().load (randomSplash, "General"); Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton ().load (randomSplash, "General");
mBackgroundImage->setImageTexture (randomSplash); mBackgroundImage->setImageTexture (randomSplash);
}
else
std::cerr << "No loading screens found!" << std::endl;
} }
} }

@ -252,11 +252,14 @@ void StatsWindow::onFrame ()
} }
setFactions(PCstats.getFactionRanks()); setFactions(PCstats.getFactionRanks());
setExpelled(PCstats.getExpelled ());
const std::string &signId = const std::string &signId =
MWBase::Environment::get().getWorld()->getPlayer().getBirthSign(); MWBase::Environment::get().getWorld()->getPlayer().getBirthSign();
setBirthSign(signId); setBirthSign(signId);
setReputation (PCstats.getReputation ());
setBounty (PCstats.getBounty ());
if (mChanged) if (mChanged)
updateSkillArea(); updateSkillArea();
@ -271,6 +274,15 @@ void StatsWindow::setFactions (const FactionList& factions)
} }
} }
void StatsWindow::setExpelled (const std::set<std::string>& expelled)
{
if (mExpelled != expelled)
{
mExpelled = expelled;
mChanged = true;
}
}
void StatsWindow::setBirthSign (const std::string& signId) void StatsWindow::setBirthSign (const std::string& signId)
{ {
if (signId != mBirthSignId) if (signId != mBirthSignId)
@ -460,6 +472,10 @@ void StatsWindow::updateSkillArea()
if (!mSkillWidgets.empty()) if (!mSkillWidgets.empty())
addSeparator(coord1, coord2); addSeparator(coord1, coord2);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWMechanics::NpcStats PCstats = MWWorld::Class::get(player).getNpcStats(player);
std::set<std::string>& expelled = PCstats.getExpelled ();
addGroup(mWindowManager.getGameSettingString("sFaction", "Faction"), coord1, coord2); addGroup(mWindowManager.getGameSettingString("sFaction", "Faction"), coord1, coord2);
FactionList::const_iterator end = mFactions.end(); FactionList::const_iterator end = mFactions.end();
for (FactionList::const_iterator it = mFactions.begin(); it != end; ++it) for (FactionList::const_iterator it = mFactions.begin(); it != end; ++it)
@ -471,36 +487,42 @@ void StatsWindow::updateSkillArea()
std::string text; std::string text;
text += std::string("#DDC79E") + faction->mName; text += std::string("#DDC79E") + faction->mName;
text += std::string("\n#BF9959") + faction->mRanks[it->second];
if (it->second < 9) if (expelled.find(it->first) != expelled.end())
text += "\n#{sExpelled}";
else
{ {
// player doesn't have max rank yet text += std::string("\n#BF9959") + faction->mRanks[it->second];
text += std::string("\n\n#DDC79E#{sNextRank} ") + faction->mRanks[it->second+1];
ESM::RankData rankData = faction->mData.mRankData[it->second+1];
const ESM::Attribute* attr1 = store.get<ESM::Attribute>().find(faction->mData.mAttribute1);
const ESM::Attribute* attr2 = store.get<ESM::Attribute>().find(faction->mData.mAttribute2);
assert(attr1 && attr2);
text += "\n#BF9959#{" + attr1->mName + "}: " + boost::lexical_cast<std::string>(rankData.mAttribute1) if (it->second < 9)
+ ", #{" + attr2->mName + "}: " + boost::lexical_cast<std::string>(rankData.mAttribute2);
text += "\n\n#DDC79E#{sFavoriteSkills}";
text += "\n#BF9959";
for (int i=0; i<6; ++i)
{ {
text += "#{"+ESM::Skill::sSkillNameIds[faction->mData.mSkillID[i]]+"}"; // player doesn't have max rank yet
if (i<5) text += std::string("\n\n#DDC79E#{sNextRank} ") + faction->mRanks[it->second+1];
text += ", ";
ESM::RankData rankData = faction->mData.mRankData[it->second+1];
const ESM::Attribute* attr1 = store.get<ESM::Attribute>().find(faction->mData.mAttribute1);
const ESM::Attribute* attr2 = store.get<ESM::Attribute>().find(faction->mData.mAttribute2);
assert(attr1 && attr2);
text += "\n#BF9959#{" + attr1->mName + "}: " + boost::lexical_cast<std::string>(rankData.mAttribute1)
+ ", #{" + attr2->mName + "}: " + boost::lexical_cast<std::string>(rankData.mAttribute2);
text += "\n\n#DDC79E#{sFavoriteSkills}";
text += "\n#BF9959";
for (int i=0; i<6; ++i)
{
text += "#{"+ESM::Skill::sSkillNameIds[faction->mData.mSkillID[i]]+"}";
if (i<5)
text += ", ";
}
text += "\n";
if (rankData.mSkill1 > 0)
text += "\n#{sNeedOneSkill} " + boost::lexical_cast<std::string>(rankData.mSkill1);
if (rankData.mSkill2 > 0)
text += "\n#{sNeedTwoSkills} " + boost::lexical_cast<std::string>(rankData.mSkill2);
} }
text += "\n";
if (rankData.mSkill1 > 0)
text += "\n#{sNeedOneSkill} " + boost::lexical_cast<std::string>(rankData.mSkill1);
if (rankData.mSkill2 > 0)
text += "\n#{sNeedTwoSkills} " + boost::lexical_cast<std::string>(rankData.mSkill2);
} }
w->setUserString("ToolTipType", "Layout"); w->setUserString("ToolTipType", "Layout");

@ -38,8 +38,8 @@ namespace MWGui
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value); void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
void configureSkills (const SkillList& major, const SkillList& minor); void configureSkills (const SkillList& major, const SkillList& minor);
void setReputation (int reputation) { this->mReputation = reputation; } void setReputation (int reputation) { if (reputation != mReputation) mChanged = true; this->mReputation = reputation; }
void setBounty (int bounty) { this->mBounty = bounty; } void setBounty (int bounty) { if (bounty != mBounty) mChanged = true; this->mBounty = bounty; }
void updateSkillArea(); void updateSkillArea();
private: private:
@ -50,6 +50,7 @@ namespace MWGui
MyGUI::Widget* addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); MyGUI::Widget* addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void setFactions (const FactionList& factions); void setFactions (const FactionList& factions);
void setExpelled (const std::set<std::string>& expelled);
void setBirthSign (const std::string &signId); void setBirthSign (const std::string &signId);
void onWindowResize(MyGUI::Window* window); void onWindowResize(MyGUI::Window* window);
@ -71,6 +72,7 @@ namespace MWGui
std::string mBirthSignId; std::string mBirthSignId;
int mReputation, mBounty; int mReputation, mBounty;
std::vector<MyGUI::WidgetPtr> mSkillWidgets; //< Skills and other information std::vector<MyGUI::WidgetPtr> mSkillWidgets; //< Skills and other information
std::set<std::string> mExpelled;
bool mChanged; bool mChanged;

@ -31,6 +31,7 @@ ToolTips::ToolTips(MWBase::WindowManager* windowManager) :
, mRemainingDelay(0.0) , mRemainingDelay(0.0)
, mLastMouseX(0) , mLastMouseX(0)
, mLastMouseY(0) , mLastMouseY(0)
, mHorizontalScrollIndex(0)
{ {
getWidget(mDynamicToolTipBox, "DynamicToolTipBox"); getWidget(mDynamicToolTipBox, "DynamicToolTipBox");
@ -52,6 +53,7 @@ void ToolTips::setEnabled(bool enabled)
void ToolTips::onFrame(float frameDuration) void ToolTips::onFrame(float frameDuration)
{ {
while (mDynamicToolTipBox->getChildCount()) while (mDynamicToolTipBox->getChildCount())
{ {
MyGUI::Gui::getInstance().destroyWidget(mDynamicToolTipBox->getChildAt(0)); MyGUI::Gui::getInstance().destroyWidget(mDynamicToolTipBox->getChildAt(0));
@ -103,7 +105,7 @@ void ToolTips::onFrame(float frameDuration)
else else
{ {
const MyGUI::IntPoint& lastPressed = InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left); const MyGUI::IntPoint& lastPressed = InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left);
if (mousePos == lastPressed) // mouseclick makes tooltip disappear if (mousePos == lastPressed) // mouseclick makes tooltip disappear
return; return;
@ -114,11 +116,13 @@ void ToolTips::onFrame(float frameDuration)
} }
else else
{ {
mHorizontalScrollIndex = 0;
mRemainingDelay = mDelay; mRemainingDelay = mDelay;
} }
mLastMouseX = mousePos.left; mLastMouseX = mousePos.left;
mLastMouseY = mousePos.top; mLastMouseY = mousePos.top;
if (mRemainingDelay > 0) if (mRemainingDelay > 0)
return; return;
@ -148,7 +152,8 @@ void ToolTips::onFrame(float frameDuration)
{ {
return; return;
} }
// special handling for markers on the local map: the tooltip should only be visible // special handling for markers on the local map: the tooltip should only be visible
// if the marker is not hidden due to the fog of war. // if the marker is not hidden due to the fog of war.
if (focus->getUserString ("IsMarker") == "true") if (focus->getUserString ("IsMarker") == "true")
@ -354,7 +359,7 @@ void ToolTips::findImageExtension(std::string& image)
} }
IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
{ {
mDynamicToolTipBox->setVisible(true); mDynamicToolTipBox->setVisible(true);
std::string caption = info.caption; std::string caption = info.caption;
@ -388,6 +393,8 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
setCoord(0, 0, 300, 300); setCoord(0, 0, 300, 300);
const IntPoint padding(8, 8); const IntPoint padding(8, 8);
const int maximumWidth = 500;
const int imageCaptionHPadding = (caption != "" ? 8 : 0); const int imageCaptionHPadding = (caption != "" ? 8 : 0);
const int imageCaptionVPadding = (caption != "" ? 4 : 0); const int imageCaptionVPadding = (caption != "" ? 4 : 0);
@ -411,7 +418,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
IntSize textSize = textWidget->getTextSize(); IntSize textSize = textWidget->getTextSize();
captionSize += IntSize(imageSize, 0); // adjust for image captionSize += IntSize(imageSize, 0); // adjust for image
IntSize totalSize = IntSize( std::max(textSize.width, captionSize.width + ((image != "") ? imageCaptionHPadding : 0)), IntSize totalSize = IntSize( std::min(std::max(textSize.width,captionSize.width + ((image != "") ? imageCaptionHPadding : 0)),maximumWidth),
((text != "") ? textSize.height + imageCaptionVPadding : 0) + captionHeight ); ((text != "") ? textSize.height + imageCaptionVPadding : 0) + captionHeight );
if (!info.effects.empty()) if (!info.effects.empty())
@ -499,8 +506,24 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
(captionHeight-captionSize.height)/2, (captionHeight-captionSize.height)/2,
captionSize.width-imageSize, captionSize.width-imageSize,
captionSize.height); captionSize.height);
//if its too long we do hscroll with the caption
if (captionSize.width > maximumWidth){
mHorizontalScrollIndex = mHorizontalScrollIndex + 2;
if (mHorizontalScrollIndex > captionSize.width){
mHorizontalScrollIndex = -totalSize.width;
}
int horizontal_scroll = mHorizontalScrollIndex;
if (horizontal_scroll < 40){
horizontal_scroll = 40;
}else{
horizontal_scroll = 80 - mHorizontalScrollIndex;
}
captionWidget->setPosition (IntPoint(horizontal_scroll, captionWidget->getPosition().top + padding.top));
} else {
captionWidget->setPosition (captionWidget->getPosition() + padding);
}
captionWidget->setPosition (captionWidget->getPosition() + padding);
textWidget->setPosition (textWidget->getPosition() + IntPoint(0, padding.top)); // only apply vertical padding, the horizontal works automatically due to Align::HCenter textWidget->setPosition (textWidget->getPosition() + IntPoint(0, padding.top)); // only apply vertical padding, the horizontal works automatically due to Align::HCenter
if (image != "") if (image != "")

@ -90,6 +90,9 @@ namespace MWGui
float mFocusToolTipX; float mFocusToolTipX;
float mFocusToolTipY; float mFocusToolTipY;
int mHorizontalScrollIndex;
float mDelay; float mDelay;
float mRemainingDelay; // remaining time until tooltip will show float mRemainingDelay; // remaining time until tooltip will show

@ -211,7 +211,7 @@ namespace MWGui
+ MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()),100)); + MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()),100));
MWMechanics::NpcStats sellerSkill = MWWorld::Class::get(mPtr).getNpcStats(mPtr); MWMechanics::NpcStats sellerSkill = MWWorld::Class::get(mPtr).getNpcStats(mPtr);
MWMechanics::CreatureStats sellerStats = MWWorld::Class::get(mPtr).getCreatureStats(mPtr); MWMechanics::CreatureStats sellerStats = MWWorld::Class::get(mPtr).getCreatureStats(mPtr);
MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWMechanics::NpcStats playerSkill = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); MWMechanics::NpcStats playerSkill = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr);
MWMechanics::CreatureStats playerStats = MWWorld::Class::get(playerPtr).getCreatureStats(playerPtr); MWMechanics::CreatureStats playerStats = MWWorld::Class::get(playerPtr).getCreatureStats(playerPtr);
@ -239,7 +239,10 @@ namespace MWGui
MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterFailDisposition); MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterFailDisposition);
return; return;
} }
}
//skill use!
MWWorld::Class::get(playerPtr).skillUsageSucceeded(playerPtr, ESM::Skill::Mercantile, 0);
}
int iBarterSuccessDisposition = gmst.find("iBarterSuccessDisposition")->getInt(); int iBarterSuccessDisposition = gmst.find("iBarterSuccessDisposition")->getInt();
MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterSuccessDisposition); MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterSuccessDisposition);

@ -204,6 +204,7 @@ namespace MWGui
MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(0.2); MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(0.2);
mProgressBar.setVisible (false); mProgressBar.setVisible (false);
mWindowManager.removeGuiMode (GM_Rest); mWindowManager.removeGuiMode (GM_Rest);
mWindowManager.removeGuiMode (GM_RestBed);
mWaiting = false; mWaiting = false;
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();

@ -624,7 +624,9 @@ namespace MWInput
void InputManager::toggleAutoMove() void InputManager::toggleAutoMove()
{ {
if (mWindows.isGuiMode()) return; if (mWindows.isGuiMode()) return;
mPlayer.setAutoMove (!mPlayer.getAutoMove());
if (mControlSwitch["playercontrols"])
mPlayer.setAutoMove (!mPlayer.getAutoMove());
} }
void InputManager::toggleWalking() void InputManager::toggleWalking()

@ -3,6 +3,8 @@
#include <cstdlib> #include <cstdlib>
#include <boost/algorithm/string.hpp>
#include <components/esm/loadalch.hpp> #include <components/esm/loadalch.hpp>
#include <components/esm/loadspel.hpp> #include <components/esm/loadspel.hpp>
#include <components/esm/loadingr.hpp> #include <components/esm/loadingr.hpp>
@ -258,4 +260,18 @@ namespace MWMechanics
return scaledDuration-usedUp; return scaledDuration-usedUp;
} }
bool ActiveSpells::isSpellActive(std::string id) const
{
boost::algorithm::to_lower(id);
for (TContainer::iterator iter = mSpells.begin(); iter != mSpells.end(); ++iter)
{
std::string left = iter->first;
boost::algorithm::to_lower(left);
if (iter->first == id)
return true;
}
return false;
}
} }

@ -58,6 +58,9 @@ namespace MWMechanics
void removeSpell (const std::string& id); void removeSpell (const std::string& id);
bool isSpellActive (std::string id) const;
///< case insensitive
const MagicEffects& getMagicEffects() const; const MagicEffects& getMagicEffects() const;
TIterator begin() const; TIterator begin() const;

@ -203,7 +203,7 @@ const ESM::Potion *MWMechanics::Alchemy::getRecord() const
bool mismatch = false; bool mismatch = false;
for (int i=0; i<static_cast<int> (iter->mEffects.mList.size()); ++iter) for (int i=0; i<static_cast<int> (iter->mEffects.mList.size()); ++i)
{ {
const ESM::ENAMstruct& first = iter->mEffects.mList[i]; const ESM::ENAMstruct& first = iter->mEffects.mList[i];
const ESM::ENAMstruct& second = mEffects[i]; const ESM::ENAMstruct& second = mEffects[i];

@ -38,7 +38,7 @@ namespace MWMechanics
creatureStats.getAttribute(5).setBase (player->mNpdt52.mEndurance); creatureStats.getAttribute(5).setBase (player->mNpdt52.mEndurance);
creatureStats.getAttribute(6).setBase (player->mNpdt52.mPersonality); creatureStats.getAttribute(6).setBase (player->mNpdt52.mPersonality);
creatureStats.getAttribute(7).setBase (player->mNpdt52.mLuck); creatureStats.getAttribute(7).setBase (player->mNpdt52.mLuck);
const MWWorld::ESMStore &esmStore = const MWWorld::ESMStore &esmStore =
MWBase::Environment::get().getWorld()->getStore(); MWBase::Environment::get().getWorld()->getStore();
@ -46,7 +46,7 @@ namespace MWMechanics
if (mRaceSelected) if (mRaceSelected)
{ {
const ESM::Race *race = const ESM::Race *race =
esmStore.get<ESM::Race>().find(player->mRace); esmStore.get<ESM::Race>().find(player->mRace);
bool male = (player->mFlags & ESM::NPC::Female) == 0; bool male = (player->mFlags & ESM::NPC::Female) == 0;
@ -72,14 +72,14 @@ namespace MWMechanics
for (int i=0; i<27; ++i) for (int i=0; i<27; ++i)
{ {
int bonus = 0; int bonus = 0;
for (int i2=0; i2<7; ++i2) for (int i2=0; i2<7; ++i2)
if (race->mData.mBonus[i2].mSkill==i) if (race->mData.mBonus[i2].mSkill==i)
{ {
bonus = race->mData.mBonus[i2].mBonus; bonus = race->mData.mBonus[i2].mBonus;
break; break;
} }
npcStats.getSkill (i).setBase (5 + bonus); npcStats.getSkill (i).setBase (5 + bonus);
} }
@ -270,7 +270,7 @@ namespace MWMechanics
// basic player profile; should not change anymore after the creation phase is finished. // basic player profile; should not change anymore after the creation phase is finished.
MWBase::WindowManager *winMgr = MWBase::WindowManager *winMgr =
MWBase::Environment::get().getWindowManager(); MWBase::Environment::get().getWindowManager();
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
const ESM::NPC *player = const ESM::NPC *player =
world->getPlayer().getPlayer().get<ESM::NPC>()->mBase; world->getPlayer().getPlayer().get<ESM::NPC>()->mBase;
@ -442,7 +442,7 @@ namespace MWMechanics
if (playerStats.hasCommonDisease() || playerStats.hasBlightDisease()) if (playerStats.hasCommonDisease() || playerStats.hasBlightDisease())
x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispDiseaseMod")->getFloat(); x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispDiseaseMod")->getFloat();
if (playerNpcStats.getDrawState() == MWMechanics::DrawState_::DrawState_Weapon) if (playerNpcStats.getDrawState() == MWMechanics::DrawState_Weapon)
x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispWeaponDrawn")->getFloat(); x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispWeaponDrawn")->getFloat();
int effective_disposition = std::max(0,std::min(int(x),100));//, normally clamped to [0..100] when used int effective_disposition = std::max(0,std::min(int(x),100));//, normally clamped to [0..100] when used
@ -455,7 +455,7 @@ namespace MWMechanics
return basePrice; return basePrice;
MWMechanics::NpcStats sellerSkill = MWWorld::Class::get(ptr).getNpcStats(ptr); MWMechanics::NpcStats sellerSkill = MWWorld::Class::get(ptr).getNpcStats(ptr);
MWMechanics::CreatureStats sellerStats = MWWorld::Class::get(ptr).getCreatureStats(ptr); MWMechanics::CreatureStats sellerStats = MWWorld::Class::get(ptr).getCreatureStats(ptr);
MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWMechanics::NpcStats playerSkill = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); MWMechanics::NpcStats playerSkill = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr);
@ -471,13 +471,13 @@ namespace MWMechanics
float d = std::min(sellerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100.f); float d = std::min(sellerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100.f);
float e = std::min(0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f); float e = std::min(0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
float f = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f); float f = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
float pcTerm = (clampedDisposition - 50 + a + b + c) * playerStats.getFatigueTerm(); float pcTerm = (clampedDisposition - 50 + a + b + c) * playerStats.getFatigueTerm();
float npcTerm = (d + e + f) * sellerStats.getFatigueTerm(); float npcTerm = (d + e + f) * sellerStats.getFatigueTerm();
float buyTerm = 0.01 * (100 - 0.5 * (pcTerm - npcTerm)); float buyTerm = 0.01 * (100 - 0.5 * (pcTerm - npcTerm));
float sellTerm = 0.01 * (50 - 0.5 * (npcTerm - pcTerm)); float sellTerm = 0.01 * (50 - 0.5 * (npcTerm - pcTerm));
float x; float x;
if(buying) x = buyTerm; if(buying) x = buyTerm;
else x = std::min(buyTerm, sellTerm); else x = std::min(buyTerm, sellTerm);
int offerPrice; int offerPrice;

@ -117,12 +117,15 @@ float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& cla
if (usageType>=4) if (usageType>=4)
throw std::runtime_error ("skill usage type out of range"); throw std::runtime_error ("skill usage type out of range");
if (usageType>0) if (usageType>=0)
{ {
skillFactor = skill->mData.mUseValue[usageType]; skillFactor = skill->mData.mUseValue[usageType];
if (skillFactor<=0) if (skillFactor<0)
throw std::runtime_error ("invalid skill gain factor"); throw std::runtime_error ("invalid skill gain factor");
if (skillFactor==0)
return 0;
} }
const MWWorld::Store<ESM::GameSetting> &gmst = const MWWorld::Store<ESM::GameSetting> &gmst =
@ -217,7 +220,7 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas
std::stringstream message; std::stringstream message;
message << boost::format(MWBase::Environment::get().getWindowManager ()->getGameSettingString ("sNotifyMessage39", "")) message << boost::format(MWBase::Environment::get().getWindowManager ()->getGameSettingString ("sNotifyMessage39", ""))
% std::string("#{" + ESM::Skill::sSkillNameIds[skillIndex] + "}") % std::string("#{" + ESM::Skill::sSkillNameIds[skillIndex] + "}")
% base; % static_cast<int> (base);
MWBase::Environment::get().getWindowManager ()->messageBox(message.str(), std::vector<std::string>()); MWBase::Environment::get().getWindowManager ()->messageBox(message.str(), std::vector<std::string>());
if (mLevelProgress >= 10) if (mLevelProgress >= 10)
@ -350,4 +353,4 @@ void MWMechanics::NpcStats::setWerewolf (bool set)
int MWMechanics::NpcStats::getWerewolfKills() const int MWMechanics::NpcStats::getWerewolfKills() const
{ {
return mWerewolfKills; return mWerewolfKills;
} }

@ -337,6 +337,8 @@ void RenderingManager::update (float duration, bool paused)
mVideoPlayer->update (); mVideoPlayer->update ();
mRendering.update(duration);
if(paused) if(paused)
{ {
Ogre::ControllerManager::getSingleton().setTimeFactor(0.f); Ogre::ControllerManager::getSingleton().setTimeFactor(0.f);
@ -355,8 +357,6 @@ void RenderingManager::update (float duration, bool paused)
mSkyManager->setGlare(mOcclusionQuery->getSunVisibility()); mSkyManager->setGlare(mOcclusionQuery->getSunVisibility());
mRendering.update(duration);
MWWorld::RefData &data = MWWorld::RefData &data =
MWBase::Environment::get() MWBase::Environment::get()
.getWorld() .getWorld()

@ -114,71 +114,56 @@ namespace MWScript
// discard additional arguments (reset), because we have no idea what they mean. // discard additional arguments (reset), because we have no idea what they mean.
for (unsigned int i=0; i<arg0; ++i) runtime.pop(); for (unsigned int i=0; i<arg0; ++i) runtime.pop();
std::cout << "AiWanter" << std::endl; std::cout << "AiWander" << std::endl;
} }
}; };
template<class R> template<class R>
class OpSetHello : public Interpreter::Opcode0 class OpGetAiSetting : public Interpreter::Opcode0
{ {
int mIndex;
public: public:
OpGetAiSetting(int index) : mIndex(index) {}
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
MWWorld::Ptr ptr = R()(runtime); MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Integer value = runtime[0].mInteger; runtime.push(MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSetting (mIndex));
runtime.pop();
MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (0, value);
} }
}; };
template<class R> template<class R>
class OpSetFight : public Interpreter::Opcode0 class OpModAiSetting : public Interpreter::Opcode0
{ {
int mIndex;
public: public:
OpModAiSetting(int index) : mIndex(index) {}
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
MWWorld::Ptr ptr = R()(runtime); MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Integer value = runtime[0].mInteger; Interpreter::Type_Integer value = runtime[0].mInteger;
runtime.pop(); runtime.pop();
MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (1, value); MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (mIndex,
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSetting (mIndex) + value);
} }
}; };
template<class R> template<class R>
class OpSetFlee : public Interpreter::Opcode0 class OpSetAiSetting : public Interpreter::Opcode0
{ {
int mIndex;
public: public:
OpSetAiSetting(int index) : mIndex(index) {}
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
MWWorld::Ptr ptr = R()(runtime); MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Integer value = runtime[0].mInteger;
runtime.pop();
MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (2, value);
}
};
template<class R>
class OpSetAlarm : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Integer value = runtime[0].mInteger; Interpreter::Type_Integer value = runtime[0].mInteger;
runtime.pop(); runtime.pop();
MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (3, value); MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (mIndex,
value);
} }
}; };
@ -199,6 +184,22 @@ namespace MWScript
const int opcodeSetFleeExplicit = 0x2000161; const int opcodeSetFleeExplicit = 0x2000161;
const int opcodeSetAlarm = 0x2000162; const int opcodeSetAlarm = 0x2000162;
const int opcodeSetAlarmExplicit = 0x2000163; const int opcodeSetAlarmExplicit = 0x2000163;
const int opcodeModHello = 0x20001b7;
const int opcodeModHelloExplicit = 0x20001b8;
const int opcodeModFight = 0x20001b9;
const int opcodeModFightExplicit = 0x20001ba;
const int opcodeModFlee = 0x20001bb;
const int opcodeModFleeExplicit = 0x20001bc;
const int opcodeModAlarm = 0x20001bd;
const int opcodeModAlarmExplicit = 0x20001be;
const int opcodeGetHello = 0x20001bf;
const int opcodeGetHelloExplicit = 0x20001c0;
const int opcodeGetFight = 0x20001c1;
const int opcodeGetFightExplicit = 0x20001c2;
const int opcodeGetFlee = 0x20001c3;
const int opcodeGetFleeExplicit = 0x20001c4;
const int opcodeGetAlarm = 0x20001c5;
const int opcodeGetAlarmExplicit = 0x20001c6;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {
@ -216,6 +217,14 @@ namespace MWScript
extensions.registerInstruction ("setfight", "l", opcodeSetFight, opcodeSetFightExplicit); extensions.registerInstruction ("setfight", "l", opcodeSetFight, opcodeSetFightExplicit);
extensions.registerInstruction ("setflee", "l", opcodeSetFlee, opcodeSetFleeExplicit); extensions.registerInstruction ("setflee", "l", opcodeSetFlee, opcodeSetFleeExplicit);
extensions.registerInstruction ("setalarm", "l", opcodeSetAlarm, opcodeSetAlarmExplicit); extensions.registerInstruction ("setalarm", "l", opcodeSetAlarm, opcodeSetAlarmExplicit);
extensions.registerInstruction ("modhello", "l", opcodeModHello, opcodeModHelloExplicit);
extensions.registerInstruction ("modfight", "l", opcodeModFight, opcodeModFightExplicit);
extensions.registerInstruction ("modflee", "l", opcodeModFlee, opcodeModFleeExplicit);
extensions.registerInstruction ("modalarm", "l", opcodeModAlarm, opcodeModAlarmExplicit);
extensions.registerFunction ("gethello", 'l', "", opcodeGetHello, opcodeGetHelloExplicit);
extensions.registerFunction ("getfight", 'l', "", opcodeGetFight, opcodeGetFightExplicit);
extensions.registerFunction ("getflee", 'l', "", opcodeGetFlee, opcodeGetFleeExplicit);
extensions.registerFunction ("getalarm", 'l', "", opcodeGetAlarm, opcodeGetAlarmExplicit);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -229,14 +238,32 @@ namespace MWScript
interpreter.installSegment5 (opcodeGetAiPackageDone, new OpGetAiPackageDone<ImplicitRef>); interpreter.installSegment5 (opcodeGetAiPackageDone, new OpGetAiPackageDone<ImplicitRef>);
interpreter.installSegment5 (opcodeGetAiPackageDoneExplicit, interpreter.installSegment5 (opcodeGetAiPackageDoneExplicit,
new OpGetAiPackageDone<ExplicitRef>); new OpGetAiPackageDone<ExplicitRef>);
interpreter.installSegment5 (opcodeSetHello, new OpSetHello<ImplicitRef>); interpreter.installSegment5 (opcodeSetHello, new OpSetAiSetting<ImplicitRef>(0));
interpreter.installSegment5 (opcodeSetHelloExplicit, new OpSetHello<ExplicitRef>); interpreter.installSegment5 (opcodeSetHelloExplicit, new OpSetAiSetting<ExplicitRef>(0));
interpreter.installSegment5 (opcodeSetFight, new OpSetFight<ImplicitRef>); interpreter.installSegment5 (opcodeSetFight, new OpSetAiSetting<ImplicitRef>(1));
interpreter.installSegment5 (opcodeSetFightExplicit, new OpSetFight<ExplicitRef>); interpreter.installSegment5 (opcodeSetFightExplicit, new OpSetAiSetting<ExplicitRef>(1));
interpreter.installSegment5 (opcodeSetFlee, new OpSetFlee<ImplicitRef>); interpreter.installSegment5 (opcodeSetFlee, new OpSetAiSetting<ImplicitRef>(2));
interpreter.installSegment5 (opcodeSetFleeExplicit, new OpSetFlee<ExplicitRef>); interpreter.installSegment5 (opcodeSetFleeExplicit, new OpSetAiSetting<ExplicitRef>(2));
interpreter.installSegment5 (opcodeSetAlarm, new OpSetAlarm<ImplicitRef>); interpreter.installSegment5 (opcodeSetAlarm, new OpSetAiSetting<ImplicitRef>(3));
interpreter.installSegment5 (opcodeSetAlarmExplicit, new OpSetAlarm<ExplicitRef>); interpreter.installSegment5 (opcodeSetAlarmExplicit, new OpSetAiSetting<ExplicitRef>(3));
interpreter.installSegment5 (opcodeModHello, new OpModAiSetting<ImplicitRef>(0));
interpreter.installSegment5 (opcodeModHelloExplicit, new OpModAiSetting<ExplicitRef>(0));
interpreter.installSegment5 (opcodeModFight, new OpModAiSetting<ImplicitRef>(1));
interpreter.installSegment5 (opcodeModFightExplicit, new OpModAiSetting<ExplicitRef>(1));
interpreter.installSegment5 (opcodeModFlee, new OpModAiSetting<ImplicitRef>(2));
interpreter.installSegment5 (opcodeModFleeExplicit, new OpModAiSetting<ExplicitRef>(2));
interpreter.installSegment5 (opcodeModAlarm, new OpModAiSetting<ImplicitRef>(3));
interpreter.installSegment5 (opcodeModAlarmExplicit, new OpModAiSetting<ExplicitRef>(3));
interpreter.installSegment5 (opcodeGetHello, new OpGetAiSetting<ImplicitRef>(0));
interpreter.installSegment5 (opcodeGetHelloExplicit, new OpGetAiSetting<ExplicitRef>(0));
interpreter.installSegment5 (opcodeGetFight, new OpGetAiSetting<ImplicitRef>(1));
interpreter.installSegment5 (opcodeGetFightExplicit, new OpGetAiSetting<ExplicitRef>(1));
interpreter.installSegment5 (opcodeGetFlee, new OpGetAiSetting<ImplicitRef>(2));
interpreter.installSegment5 (opcodeGetFleeExplicit, new OpGetAiSetting<ExplicitRef>(2));
interpreter.installSegment5 (opcodeGetAlarm, new OpGetAiSetting<ImplicitRef>(3));
interpreter.installSegment5 (opcodeGetAlarmExplicit, new OpGetAiSetting<ExplicitRef>(3));
} }
} }
} }

@ -14,6 +14,8 @@
#include "../mwworld/manualref.hpp" #include "../mwworld/manualref.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "../mwworld/actionequip.hpp"
#include "../mwworld/inventorystore.hpp"
#include "interpretercontext.hpp" #include "interpretercontext.hpp"
#include "ref.hpp" #include "ref.hpp"
@ -128,12 +130,196 @@ namespace MWScript
} }
}; };
template <class R>
class OpEquip : public Interpreter::Opcode0
{
public:
virtual void execute(Interpreter::Runtime &runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string item = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore (ptr);
MWWorld::ContainerStoreIterator it = invStore.begin();
for (; it != invStore.end(); ++it)
{
if (toLower(it->getCellRef().mRefID) == toLower(item))
break;
}
if (it == invStore.end())
throw std::runtime_error("Item to equip not found");
MWWorld::ActionEquip action (*it);
action.execute(ptr);
}
};
template <class R>
class OpGetArmorType : public Interpreter::Opcode0
{
public:
virtual void execute(Interpreter::Runtime &runtime)
{
MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Integer location = runtime[0].mInteger;
runtime.pop();
int slot;
switch (location)
{
case 0:
slot = MWWorld::InventoryStore::Slot_Helmet;
break;
case 1:
slot = MWWorld::InventoryStore::Slot_Cuirass;
break;
case 2:
slot = MWWorld::InventoryStore::Slot_LeftPauldron;
break;
case 3:
slot = MWWorld::InventoryStore::Slot_RightPauldron;
break;
case 4:
slot = MWWorld::InventoryStore::Slot_Greaves;
break;
case 5:
slot = MWWorld::InventoryStore::Slot_Boots;
break;
case 6:
slot = MWWorld::InventoryStore::Slot_LeftGauntlet;
break;
case 7:
slot = MWWorld::InventoryStore::Slot_RightGauntlet;
break;
case 8:
slot = MWWorld::InventoryStore::Slot_CarriedLeft; // shield
break;
case 9:
slot = MWWorld::InventoryStore::Slot_LeftGauntlet;
break;
case 10:
slot = MWWorld::InventoryStore::Slot_RightGauntlet;
break;
default:
throw std::runtime_error ("armor index out of range");
}
MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore (ptr);
MWWorld::ContainerStoreIterator it = invStore.getSlot (slot);
if (it == invStore.end() || it->getTypeName () != typeid(ESM::Armor).name())
{
runtime.push(-1);
return;
}
int skill = MWWorld::Class::get(*it).getEquipmentSkill (*it) ;
if (skill == ESM::Skill::HeavyArmor)
runtime.push(2);
else if (skill == ESM::Skill::MediumArmor)
runtime.push(1);
else if (skill == ESM::Skill::LightArmor)
runtime.push(0);
else
runtime.push(-1);
}
};
template <class R>
class OpHasItemEquipped : public Interpreter::Opcode0
{
public:
virtual void execute(Interpreter::Runtime &runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string item = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore (ptr);
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
{
MWWorld::ContainerStoreIterator it = invStore.getSlot (slot);
if (it != invStore.end() && toLower(it->getCellRef().mRefID) == toLower(item))
{
runtime.push(1);
return;
}
}
runtime.push(0);
}
};
template <class R>
class OpHasSoulGem : public Interpreter::Opcode0
{
public:
virtual void execute(Interpreter::Runtime &runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string creatureName = toLower (runtime.getStringLiteral (runtime[0].mInteger));
runtime.pop();
MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore (ptr);
for (MWWorld::ContainerStoreIterator it = invStore.begin(MWWorld::ContainerStore::Type_Miscellaneous);
it != invStore.end(); ++it)
{
if (toLower(it->getCellRef().mSoul) == toLower(creatureName))
{
runtime.push(1);
return;
}
}
runtime.push(0);
}
};
template <class R>
class OpGetWeaponType : public Interpreter::Opcode0
{
public:
virtual void execute(Interpreter::Runtime &runtime)
{
MWWorld::Ptr ptr = R()(runtime);
MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore (ptr);
MWWorld::ContainerStoreIterator it = invStore.getSlot (MWWorld::InventoryStore::Slot_CarriedRight);
if (it == invStore.end() || it->getTypeName () != typeid(ESM::Weapon).name())
{
runtime.push(-1);
return;
}
runtime.push(it->get<ESM::Weapon>()->mBase->mData.mType);
}
};
const int opcodeAddItem = 0x2000076; const int opcodeAddItem = 0x2000076;
const int opcodeAddItemExplicit = 0x2000077; const int opcodeAddItemExplicit = 0x2000077;
const int opcodeGetItemCount = 0x2000078; const int opcodeGetItemCount = 0x2000078;
const int opcodeGetItemCountExplicit = 0x2000079; const int opcodeGetItemCountExplicit = 0x2000079;
const int opcodeRemoveItem = 0x200007a; const int opcodeRemoveItem = 0x200007a;
const int opcodeRemoveItemExplicit = 0x200007b; const int opcodeRemoveItemExplicit = 0x200007b;
const int opcodeEquip = 0x20001b3;
const int opcodeEquipExplicit = 0x20001b4;
const int opcodeGetArmorType = 0x20001d1;
const int opcodeGetArmorTypeExplicit = 0x20001d2;
const int opcodeHasItemEquipped = 0x20001d5;
const int opcodeHasItemEquippedExplicit = 0x20001d6;
const int opcodeHasSoulGem = 0x20001de;
const int opcodeHasSoulGemExplicit = 0x20001df;
const int opcodeGetWeaponType = 0x20001e0;
const int opcodeGetWeaponTypeExplicit = 0x20001e1;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {
@ -142,6 +328,11 @@ namespace MWScript
opcodeGetItemCountExplicit); opcodeGetItemCountExplicit);
extensions.registerInstruction ("removeitem", "cl", opcodeRemoveItem, extensions.registerInstruction ("removeitem", "cl", opcodeRemoveItem,
opcodeRemoveItemExplicit); opcodeRemoveItemExplicit);
extensions.registerInstruction ("equip", "c", opcodeEquip, opcodeEquipExplicit);
extensions.registerFunction ("getarmortype", 'l', "l", opcodeGetArmorType, opcodeGetArmorTypeExplicit);
extensions.registerFunction ("hasitemequipped", 'l', "c", opcodeHasItemEquipped, opcodeHasItemEquippedExplicit);
extensions.registerFunction ("hassoulgem", 'l', "c", opcodeHasSoulGem, opcodeHasSoulGemExplicit);
extensions.registerFunction ("getweapontype", 'l', "", opcodeGetWeaponType, opcodeGetWeaponTypeExplicit);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -152,6 +343,16 @@ namespace MWScript
interpreter.installSegment5 (opcodeGetItemCountExplicit, new OpGetItemCount<ExplicitRef>); interpreter.installSegment5 (opcodeGetItemCountExplicit, new OpGetItemCount<ExplicitRef>);
interpreter.installSegment5 (opcodeRemoveItem, new OpRemoveItem<ImplicitRef>); interpreter.installSegment5 (opcodeRemoveItem, new OpRemoveItem<ImplicitRef>);
interpreter.installSegment5 (opcodeRemoveItemExplicit, new OpRemoveItem<ExplicitRef>); interpreter.installSegment5 (opcodeRemoveItemExplicit, new OpRemoveItem<ExplicitRef>);
interpreter.installSegment5 (opcodeEquip, new OpEquip<ImplicitRef>);
interpreter.installSegment5 (opcodeEquipExplicit, new OpEquip<ExplicitRef>);
interpreter.installSegment5 (opcodeGetArmorType, new OpGetArmorType<ImplicitRef>);
interpreter.installSegment5 (opcodeGetArmorTypeExplicit, new OpGetArmorType<ExplicitRef>);
interpreter.installSegment5 (opcodeHasItemEquipped, new OpHasItemEquipped<ImplicitRef>);
interpreter.installSegment5 (opcodeHasItemEquippedExplicit, new OpHasItemEquipped<ExplicitRef>);
interpreter.installSegment5 (opcodeHasSoulGem, new OpHasSoulGem<ImplicitRef>);
interpreter.installSegment5 (opcodeHasSoulGemExplicit, new OpHasSoulGem<ExplicitRef>);
interpreter.installSegment5 (opcodeGetWeaponType, new OpGetWeaponType<ImplicitRef>);
interpreter.installSegment5 (opcodeGetWeaponTypeExplicit, new OpGetWeaponType<ExplicitRef>);
} }
} }
} }

@ -106,6 +106,58 @@ namespace MWScript
} }
}; };
template <class R>
class OpGetForceRun : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(ptr).getNpcStats (ptr);
runtime.push (npcStats.getMovementFlag (MWMechanics::NpcStats::Flag_ForceRun));
}
};
template <class R>
class OpGetForceSneak : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(ptr).getNpcStats (ptr);
runtime.push (npcStats.getMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak));
}
};
class OpGetPcRunning : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer();
runtime.push (MWWorld::Class::get(ptr).getStance (ptr, MWWorld::Class::Run));
}
};
class OpGetPcSneaking : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer();
runtime.push (MWWorld::Class::get(ptr).getStance (ptr, MWWorld::Class::Sneak));
}
};
const int numberOfControls = 7; const int numberOfControls = 7;
const int opcodeEnable = 0x200007e; const int opcodeEnable = 0x200007e;
@ -120,6 +172,12 @@ namespace MWScript
const int opcodeForceSneak = 0x200015a; const int opcodeForceSneak = 0x200015a;
const int opcodeForceSneakExplicit = 0x200015b; const int opcodeForceSneakExplicit = 0x200015b;
const int opcodeGetDisabled = 0x2000175; const int opcodeGetDisabled = 0x2000175;
const int opcodeGetPcRunning = 0x20001c9;
const int opcodeGetPcSneaking = 0x20001ca;
const int opcodeGetForceRun = 0x20001cb;
const int opcodeGetForceSneak = 0x20001cc;
const int opcodeGetForceRunExplicit = 0x20001cd;
const int opcodeGetForceSneakExplicit = 0x20001ce;
const char *controls[numberOfControls] = const char *controls[numberOfControls] =
{ {
@ -151,6 +209,10 @@ namespace MWScript
opcodeClearForceSneakExplicit); opcodeClearForceSneakExplicit);
extensions.registerInstruction ("forcesneak", "", opcodeForceSneak, extensions.registerInstruction ("forcesneak", "", opcodeForceSneak,
opcodeForceSneakExplicit); opcodeForceSneakExplicit);
extensions.registerFunction ("getpcrunning", 'l', "", opcodeGetPcRunning);
extensions.registerFunction ("getpcsneaking", 'l', "", opcodeGetPcSneaking);
extensions.registerFunction ("getforcerun", 'l', "", opcodeGetForceRun, opcodeGetForceRunExplicit);
extensions.registerFunction ("getforcesneak", 'l', "", opcodeGetForceSneak, opcodeGetForceSneakExplicit);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -181,6 +243,12 @@ namespace MWScript
new OpClearMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak)); new OpClearMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak));
interpreter.installSegment5 (opcodeForceSneakExplicit, interpreter.installSegment5 (opcodeForceSneakExplicit,
new OpSetMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak)); new OpSetMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak));
interpreter.installSegment5 (opcodeGetPcRunning, new OpGetPcRunning);
interpreter.installSegment5 (opcodeGetPcSneaking, new OpGetPcSneaking);
interpreter.installSegment5 (opcodeGetForceRun, new OpGetForceRun<ImplicitRef>);
interpreter.installSegment5 (opcodeGetForceRunExplicit, new OpGetForceRun<ExplicitRef>);
interpreter.installSegment5 (opcodeGetForceSneak, new OpGetForceSneak<ImplicitRef>);
interpreter.installSegment5 (opcodeGetForceSneakExplicit, new OpGetForceSneak<ExplicitRef>);
} }
} }
} }

@ -11,6 +11,10 @@
#include "../mwbase/dialoguemanager.hpp" #include "../mwbase/dialoguemanager.hpp"
#include "../mwbase/journal.hpp" #include "../mwbase/journal.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "interpretercontext.hpp" #include "interpretercontext.hpp"
#include "ref.hpp" #include "ref.hpp"
@ -126,6 +130,64 @@ namespace MWScript
} }
}; };
template<class R>
class OpModReputation : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Integer value = runtime[0].mInteger;
runtime.pop();
MWWorld::Class::get(ptr).getNpcStats (ptr).setReputation (MWWorld::Class::get(ptr).getNpcStats (ptr).getReputation () + value);
}
};
template<class R>
class OpSetReputation : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Integer value = runtime[0].mInteger;
runtime.pop();
MWWorld::Class::get(ptr).getNpcStats (ptr).setReputation (value);
}
};
template<class R>
class OpGetReputation : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
runtime.push (MWWorld::Class::get(ptr).getNpcStats (ptr).getReputation ());
}
};
template<class R>
class OpSameFaction : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer();
runtime.push (MWWorld::Class::get(ptr).getNpcStats (ptr).isSameFaction (MWWorld::Class::get(player).getNpcStats (player)));
}
};
const int opcodeJournal = 0x2000133; const int opcodeJournal = 0x2000133;
const int opcodeSetJournalIndex = 0x2000134; const int opcodeSetJournalIndex = 0x2000134;
const int opcodeGetJournalIndex = 0x2000135; const int opcodeGetJournalIndex = 0x2000135;
@ -134,6 +196,14 @@ namespace MWScript
const int opcodeForceGreeting = 0x200014f; const int opcodeForceGreeting = 0x200014f;
const int opcodeForceGreetingExplicit = 0x2000150; const int opcodeForceGreetingExplicit = 0x2000150;
const int opcodeGoodbye = 0x2000152; const int opcodeGoodbye = 0x2000152;
const int opcodeSetReputation = 0x20001ad;
const int opcodeModReputation = 0x20001ae;
const int opcodeSetReputationExplicit = 0x20001af;
const int opcodeModReputationExplicit = 0x20001b0;
const int opcodeGetReputation = 0x20001b1;
const int opcodeGetReputationExplicit = 0x20001b2;
const int opcodeSameFaction = 0x20001b5;
const int opcodeSameFactionExplicit = 0x20001b6;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {
@ -146,6 +216,14 @@ namespace MWScript
extensions.registerInstruction("forcegreeting","",opcodeForceGreeting, extensions.registerInstruction("forcegreeting","",opcodeForceGreeting,
opcodeForceGreetingExplicit); opcodeForceGreetingExplicit);
extensions.registerInstruction("goodbye", "", opcodeGoodbye); extensions.registerInstruction("goodbye", "", opcodeGoodbye);
extensions.registerInstruction("setreputation", "l", opcodeSetReputation,
opcodeSetReputationExplicit);
extensions.registerInstruction("modreputation", "l", opcodeModReputation,
opcodeModReputationExplicit);
extensions.registerFunction("getreputation", 'l', "", opcodeGetReputation,
opcodeGetReputationExplicit);
extensions.registerFunction("samefaction", 'l', "", opcodeSameFaction,
opcodeSameFactionExplicit);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -158,6 +236,14 @@ namespace MWScript
interpreter.installSegment5 (opcodeForceGreeting, new OpForceGreeting<ImplicitRef>); interpreter.installSegment5 (opcodeForceGreeting, new OpForceGreeting<ImplicitRef>);
interpreter.installSegment5 (opcodeForceGreetingExplicit, new OpForceGreeting<ExplicitRef>); interpreter.installSegment5 (opcodeForceGreetingExplicit, new OpForceGreeting<ExplicitRef>);
interpreter.installSegment5 (opcodeGoodbye, new OpGoodbye); interpreter.installSegment5 (opcodeGoodbye, new OpGoodbye);
interpreter.installSegment5 (opcodeGetReputation, new OpGetReputation<ImplicitRef>);
interpreter.installSegment5 (opcodeSetReputation, new OpSetReputation<ImplicitRef>);
interpreter.installSegment5 (opcodeModReputation, new OpModReputation<ImplicitRef>);
interpreter.installSegment5 (opcodeSetReputationExplicit, new OpSetReputation<ExplicitRef>);
interpreter.installSegment5 (opcodeModReputationExplicit, new OpModReputation<ExplicitRef>);
interpreter.installSegment5 (opcodeGetReputationExplicit, new OpGetReputation<ExplicitRef>);
interpreter.installSegment5 (opcodeSameFaction, new OpSameFaction<ImplicitRef>);
interpreter.installSegment5 (opcodeSameFactionExplicit, new OpSameFaction<ExplicitRef>);
} }
} }

@ -37,7 +37,13 @@ op 0x20014: SetPCFacRep
op 0x20015: SetPCFacRep, explicit reference op 0x20015: SetPCFacRep, explicit reference
op 0x20016: ModPCFacRep op 0x20016: ModPCFacRep
op 0x20017: ModPCFacRep, explicit reference op 0x20017: ModPCFacRep, explicit reference
op s 0x20018-0x3ffff unused op 0x20018: PcExpelled
op 0x20019: PcExpelled, explicit
op 0x2001a: PcExpell
op 0x2001b: PcExpell, explicit
op 0x2001c: PcClearExpelled
op 0x2001d: PcClearExpelled, explicit
op s 0x2001e-0x3ffff unused
Segment 4: Segment 4:
(not implemented yet) (not implemented yet)
@ -222,5 +228,72 @@ op 0x20001a9: CommonDisease, explicit reference
op 0x20001aa: BlightDisease op 0x20001aa: BlightDisease
op 0x20001ab: BlightDisease, explicit reference op 0x20001ab: BlightDisease, explicit reference
op 0x20001ac: ToggleCollisionBoxes op 0x20001ac: ToggleCollisionBoxes
opcodes 0x20001ac-0x3ffffff unused op 0x20001ad: SetReputation
op 0x20001ae: ModReputation
op 0x20001af: SetReputation, explicit
op 0x20001b0: ModReputation, explicit
op 0x20001b1: GetReputation
op 0x20001b2: GetReputation, explicit
op 0x20001b3: Equip
op 0x20001b4: Equip, explicit
op 0x20001b5: SameFaction
op 0x20001b6: SameFaction, explicit
op 0x20001b7: ModHello
op 0x20001b8: ModHello, explicit reference
op 0x20001b9: ModFight
op 0x20001ba: ModFight, explicit reference
op 0x20001bb: ModFlee
op 0x20001bc: ModFlee, explicit reference
op 0x20001bd: ModAlarm
op 0x20001be: ModAlarm, explicit reference
op 0x20001bf: GetHello
op 0x20001c0: GetHello, explicit reference
op 0x20001c1: GetFight
op 0x20001c2: GetFight, explicit reference
op 0x20001c3: GetFlee
op 0x20001c4: GetFlee, explicit reference
op 0x20001c5: GetAlarm
op 0x20001c6: GetAlarm, explicit reference
op 0x20001c7: GetLocked
op 0x20001c8: GetLocked, explicit reference
op 0x20001c9: GetPcRunning
op 0x20001ca: GetPcSneaking
op 0x20001cb: GetForceRun
op 0x20001cc: GetForceSneak
op 0x20001cd: GetForceRun, explicit
op 0x20001ce: GetForceSneak, explicit
op 0x20001cf: GetEffect
op 0x20001d0: GetEffect, explicit
op 0x20001d1: GetArmorType
op 0x20001d2: GetArmorType, explicit
op 0x20001d3: GetAttacked
op 0x20001d4: GetAttacked, explicit
op 0x20001d5: HasItemEquipped
op 0x20001d6: HasItemEquipped, explicit
op 0x20001d7: GetWeaponDrawn
op 0x20001d8: GetWeaponDrawn, explicit
op 0x20001d9: GetRace
op 0x20001da: GetRace, explicit
op 0x20001db: GetSpellEffects
op 0x20001dc: GetSpellEffects, explicit
op 0x20001dd: GetCurrentTime
op 0x20001de: HasSoulGem
op 0x20001df: HasSoulGem, explicit
op 0x20001e0: GetWeaponType
op 0x20001e1: GetWeaponType, explicit
op 0x20001e2: GetWerewolfKills
op 0x20001e3: ModScale
op 0x20001e4: ModScale, explicit
op 0x20001e5: SetDelete
op 0x20001e6: SetDelete, explicit
op 0x20001e7: GetSquareRoot
op 0x20001e8: RaiseRank
op 0x20001e9: RaiseRank, explicit
op 0x20001ea: LowerRank
op 0x20001eb: LowerRank, explicit
op 0x20001ec: PlayBink
opcodes 0x20001ed-0x3ffffff unused

@ -13,6 +13,10 @@
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "interpretercontext.hpp" #include "interpretercontext.hpp"
#include "ref.hpp" #include "ref.hpp"
@ -285,6 +289,121 @@ namespace MWScript
}; };
bool OpToggleVanityMode::sActivate = true; bool OpToggleVanityMode::sActivate = true;
template <class R>
class OpGetLocked : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
runtime.push (ptr.getCellRef ().mLockLevel > 0);
}
};
template <class R>
class OpGetEffect : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
int key = runtime[0].mInteger;
runtime.pop();
runtime.push (MWWorld::Class::get(ptr).getCreatureStats (ptr).getMagicEffects ().get (
MWMechanics::EffectKey(key)).mMagnitude > 0);
}
};
template <class R>
class OpGetAttacked : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
runtime.push(MWWorld::Class::get(ptr).getCreatureStats (ptr).getAttacked ());
}
};
template <class R>
class OpGetWeaponDrawn : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
runtime.push(MWWorld::Class::get(ptr).getNpcStats (ptr).getDrawState () == MWMechanics::DrawState_Weapon);
}
};
template <class R>
class OpGetSpellEffects : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string id = runtime.getStringLiteral(runtime[0].mInteger);
runtime.pop();
runtime.push(MWWorld::Class::get(ptr).getCreatureStats(ptr).getActiveSpells().isSpellActive(id));
}
};
class OpGetCurrentTime : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
runtime.push(MWBase::Environment::get().getWorld()->getTimeStamp().getHour());
}
};
template <class R>
class OpSetDelete : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
int parameter = runtime[0].mInteger;
runtime.pop();
if (parameter == 1)
{
if (ptr.isInCell())
MWBase::Environment::get().getWorld()->deleteObject (ptr);
else
ptr.getRefData().setCount(0);
}
}
};
class OpGetSquareRoot : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
float param = runtime[0].mFloat;
runtime.pop();
runtime.push(std::sqrt (param));
}
};
const int opcodeXBox = 0x200000c; const int opcodeXBox = 0x200000c;
const int opcodeOnActivate = 0x200000d; const int opcodeOnActivate = 0x200000d;
const int opcodeActivate = 0x2000075; const int opcodeActivate = 0x2000075;
@ -304,8 +423,22 @@ namespace MWScript
const int opcodeToggleVanityMode = 0x2000174; const int opcodeToggleVanityMode = 0x2000174;
const int opcodeGetPcSleep = 0x200019f; const int opcodeGetPcSleep = 0x200019f;
const int opcodeWakeUpPc = 0x20001a2; const int opcodeWakeUpPc = 0x20001a2;
const int opcodeGetLocked = 0x20001c7;
const int opcodePlayBink = 0x20001a3; const int opcodeGetLockedExplicit = 0x20001c8;
const int opcodeGetEffect = 0x20001cf;
const int opcodeGetEffectExplicit = 0x20001d0;
const int opcodeGetAttacked = 0x20001d3;
const int opcodeGetAttackedExplicit = 0x20001d4;
const int opcodeGetWeaponDrawn = 0x20001d7;
const int opcodeGetWeaponDrawnExplicit = 0x20001d8;
const int opcodeGetSpellEffects = 0x20001db;
const int opcodeGetSpellEffectsExplicit = 0x20001dc;
const int opcodeGetCurrentTime = 0x20001dd;
const int opcodeSetDelete = 0x20001e5;
const int opcodeSetDeleteExplicit = 0x20001e6;
const int opcodeGetSquareRoot = 0x20001e7;
const int opcodePlayBink = 0x20001ec;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {
@ -332,8 +465,15 @@ namespace MWScript
extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode); extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode);
extensions.registerFunction ("getpcsleep", 'l', "", opcodeGetPcSleep); extensions.registerFunction ("getpcsleep", 'l', "", opcodeGetPcSleep);
extensions.registerInstruction ("wakeuppc", "", opcodeWakeUpPc); extensions.registerInstruction ("wakeuppc", "", opcodeWakeUpPc);
extensions.registerInstruction ("playbink", "S", opcodePlayBink); extensions.registerInstruction ("playbink", "S", opcodePlayBink);
extensions.registerFunction ("getlocked", 'l', "", opcodeGetLocked, opcodeGetLockedExplicit);
extensions.registerFunction ("geteffect", 'l', "l", opcodeGetEffect, opcodeGetEffectExplicit);
extensions.registerFunction ("getattacked", 'l', "", opcodeGetAttacked, opcodeGetAttackedExplicit);
extensions.registerFunction ("getweapondrawn", 'l', "", opcodeGetWeaponDrawn, opcodeGetWeaponDrawnExplicit);
extensions.registerFunction ("getspelleffects", 'l', "c", opcodeGetSpellEffects, opcodeGetSpellEffectsExplicit);
extensions.registerFunction ("getcurrenttime", 'f', "", opcodeGetCurrentTime);
extensions.registerInstruction ("setdelete", "l", opcodeSetDelete, opcodeSetDeleteExplicit);
extensions.registerFunction ("getsquareroot", 'f', "f", opcodeGetSquareRoot);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -357,8 +497,21 @@ namespace MWScript
interpreter.installSegment5 (opcodeToggleVanityMode, new OpToggleVanityMode); interpreter.installSegment5 (opcodeToggleVanityMode, new OpToggleVanityMode);
interpreter.installSegment5 (opcodeGetPcSleep, new OpGetPcSleep); interpreter.installSegment5 (opcodeGetPcSleep, new OpGetPcSleep);
interpreter.installSegment5 (opcodeWakeUpPc, new OpWakeUpPc); interpreter.installSegment5 (opcodeWakeUpPc, new OpWakeUpPc);
interpreter.installSegment5 (opcodePlayBink, new OpPlayBink); interpreter.installSegment5 (opcodePlayBink, new OpPlayBink);
interpreter.installSegment5 (opcodeGetLocked, new OpGetLocked<ImplicitRef>);
interpreter.installSegment5 (opcodeGetLockedExplicit, new OpGetLocked<ExplicitRef>);
interpreter.installSegment5 (opcodeGetEffect, new OpGetEffect<ImplicitRef>);
interpreter.installSegment5 (opcodeGetEffectExplicit, new OpGetEffect<ExplicitRef>);
interpreter.installSegment5 (opcodeGetAttacked, new OpGetAttacked<ImplicitRef>);
interpreter.installSegment5 (opcodeGetAttackedExplicit, new OpGetAttacked<ExplicitRef>);
interpreter.installSegment5 (opcodeGetWeaponDrawn, new OpGetWeaponDrawn<ImplicitRef>);
interpreter.installSegment5 (opcodeGetWeaponDrawnExplicit, new OpGetWeaponDrawn<ExplicitRef>);
interpreter.installSegment5 (opcodeGetSpellEffects, new OpGetSpellEffects<ImplicitRef>);
interpreter.installSegment5 (opcodeGetSpellEffectsExplicit, new OpGetSpellEffects<ExplicitRef>);
interpreter.installSegment5 (opcodeGetCurrentTime, new OpGetCurrentTime);
interpreter.installSegment5 (opcodeSetDelete, new OpSetDelete<ImplicitRef>);
interpreter.installSegment5 (opcodeSetDeleteExplicit, new OpSetDelete<ExplicitRef>);
interpreter.installSegment5 (opcodeGetSquareRoot, new OpGetSquareRoot);
} }
} }
} }

@ -780,6 +780,210 @@ namespace MWScript
} }
}; };
template<class R>
class OpGetRace : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string race = runtime.getStringLiteral(runtime[0].mInteger);
boost::algorithm::to_lower(race);
runtime.pop();
std::string npcRace = ptr.get<ESM::NPC>()->mBase->mRace;
boost::algorithm::to_lower(npcRace);
runtime.push (npcRace == race);
}
};
class OpGetWerewolfKills : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ();
runtime.push (MWWorld::Class::get(ptr).getNpcStats (ptr).getWerewolfKills ());
}
};
template <class R>
class OpPcExpelled : public Interpreter::Opcode1
{
public:
virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0)
{
MWWorld::Ptr ptr = R()(runtime);
std::string factionID = "";
if(arg0 >0 )
{
factionID = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
}
else
{
if(MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().empty())
{
factionID = "";
}
else
{
factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().begin()->first;
}
}
boost::algorithm::to_lower(factionID);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
if(factionID!="")
{
std::set<std::string>& expelled = MWWorld::Class::get(player).getNpcStats(player).getExpelled ();
if (expelled.find (factionID) != expelled.end())
{
runtime.push(1);
}
else
{
runtime.push(0);
}
}
else
{
runtime.push(0);
}
}
};
template <class R>
class OpPcExpell : public Interpreter::Opcode1
{
public:
virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0)
{
MWWorld::Ptr ptr = R()(runtime);
std::string factionID = "";
if(arg0 >0 )
{
factionID = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
}
else
{
if(MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().empty())
{
factionID = "";
}
else
{
factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().begin()->first;
}
}
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
if(factionID!="")
{
std::set<std::string>& expelled = MWWorld::Class::get(player).getNpcStats(player).getExpelled ();
boost::algorithm::to_lower(factionID);
expelled.insert(factionID);
}
}
};
template <class R>
class OpPcClearExpelled : public Interpreter::Opcode1
{
public:
virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0)
{
MWWorld::Ptr ptr = R()(runtime);
std::string factionID = "";
if(arg0 >0 )
{
factionID = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
}
else
{
if(MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().empty())
{
factionID = "";
}
else
{
factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().begin()->first;
}
}
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
if(factionID!="")
{
std::set<std::string>& expelled = MWWorld::Class::get(player).getNpcStats(player).getExpelled ();
boost::algorithm::to_lower(factionID);
expelled.erase (factionID);
}
}
};
template <class R>
class OpRaiseRank : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string factionID = "";
if(MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().empty())
return;
else
{
factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().begin()->first;
}
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
// no-op when executed on the player
if (ptr == player)
return;
std::map<std::string, int>& ranks = MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks ();
ranks[factionID] = ranks[factionID]+1;
}
};
template <class R>
class OpLowerRank : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string factionID = "";
if(MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().empty())
return;
else
{
factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().begin()->first;
}
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
// no-op when executed on the player
if (ptr == player)
return;
std::map<std::string, int>& ranks = MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks ();
ranks[factionID] = ranks[factionID]-1;
}
};
const int numberOfAttributes = 8; const int numberOfAttributes = 8;
@ -850,6 +1054,22 @@ namespace MWScript
const int opcodeGetBlightDisease = 0x20001aa; const int opcodeGetBlightDisease = 0x20001aa;
const int opcodeGetBlightDiseaseExplicit = 0x20001ab; const int opcodeGetBlightDiseaseExplicit = 0x20001ab;
const int opcodeGetRace = 0x20001d9;
const int opcodeGetRaceExplicit = 0x20001da;
const int opcodeGetWerewolfKills = 0x20001e2;
const int opcodePcExpelled = 0x20018;
const int opcodePcExpelledExplicit = 0x20019;
const int opcodePcExpell = 0x2001a;
const int opcodePcExpellExplicit = 0x2001b;
const int opcodePcClearExpelled = 0x2001c;
const int opcodePcClearExpelledExplicit = 0x2001d;
const int opcodeRaiseRank = 0x20001e8;
const int opcodeRaiseRankExplicit = 0x20001e9;
const int opcodeLowerRank = 0x20001ea;
const int opcodeLowerRankExplicit = 0x20001eb;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {
static const char *attributes[numberOfAttributes] = static const char *attributes[numberOfAttributes] =
@ -870,7 +1090,7 @@ namespace MWScript
"alteration", "illusion", "conjuration", "mysticism", "alteration", "illusion", "conjuration", "mysticism",
"restoration", "alchemy", "unarmored", "security", "sneak", "restoration", "alchemy", "unarmored", "security", "sneak",
"acrobatics", "lightarmor", "shortblade", "marksman", "acrobatics", "lightarmor", "shortblade", "marksman",
"merchantile", "speechcraft", "handtohand" "mercantile", "speechcraft", "handtohand"
}; };
std::string get ("get"); std::string get ("get");
@ -950,6 +1170,15 @@ namespace MWScript
opcodeGetCommonDiseaseExplicit); opcodeGetCommonDiseaseExplicit);
extensions.registerFunction ("getblightdisease", 'l', "", opcodeGetBlightDisease, extensions.registerFunction ("getblightdisease", 'l', "", opcodeGetBlightDisease,
opcodeGetBlightDiseaseExplicit); opcodeGetBlightDiseaseExplicit);
extensions.registerFunction ("getrace", 'l', "c", opcodeGetRace,
opcodeGetRaceExplicit);
extensions.registerFunction ("getwerewolfkills", 'f', "", opcodeGetWerewolfKills);
extensions.registerFunction ("pcexpelled", 'l', "/S", opcodePcExpelled, opcodePcExpelledExplicit);
extensions.registerInstruction ("pcexpell", "/S", opcodePcExpell, opcodePcExpellExplicit);
extensions.registerInstruction ("pcclearexpelled", "/S", opcodePcClearExpelled, opcodePcClearExpelledExplicit);
extensions.registerInstruction ("raiserank", "", opcodeRaiseRank, opcodeRaiseRankExplicit);
extensions.registerInstruction ("lowerrank", "", opcodeLowerRank, opcodeLowerRankExplicit);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -1045,6 +1274,21 @@ namespace MWScript
interpreter.installSegment5 (opcodeGetCommonDiseaseExplicit, new OpGetCommonDisease<ExplicitRef>); interpreter.installSegment5 (opcodeGetCommonDiseaseExplicit, new OpGetCommonDisease<ExplicitRef>);
interpreter.installSegment5 (opcodeGetBlightDisease, new OpGetBlightDisease<ImplicitRef>); interpreter.installSegment5 (opcodeGetBlightDisease, new OpGetBlightDisease<ImplicitRef>);
interpreter.installSegment5 (opcodeGetBlightDiseaseExplicit, new OpGetBlightDisease<ExplicitRef>); interpreter.installSegment5 (opcodeGetBlightDiseaseExplicit, new OpGetBlightDisease<ExplicitRef>);
interpreter.installSegment5 (opcodeGetRace, new OpGetRace<ImplicitRef>);
interpreter.installSegment5 (opcodeGetRaceExplicit, new OpGetRace<ExplicitRef>);
interpreter.installSegment5 (opcodeGetWerewolfKills, new OpGetWerewolfKills);
interpreter.installSegment3 (opcodePcExpelled, new OpPcExpelled<ImplicitRef>);
interpreter.installSegment3 (opcodePcExpelledExplicit, new OpPcExpelled<ExplicitRef>);
interpreter.installSegment3 (opcodePcExpell, new OpPcExpell<ImplicitRef>);
interpreter.installSegment3 (opcodePcExpellExplicit, new OpPcExpell<ExplicitRef>);
interpreter.installSegment3 (opcodePcClearExpelled, new OpPcClearExpelled<ImplicitRef>);
interpreter.installSegment3 (opcodePcClearExpelledExplicit, new OpPcClearExpelled<ExplicitRef>);
interpreter.installSegment5 (opcodeRaiseRank, new OpRaiseRank<ImplicitRef>);
interpreter.installSegment5 (opcodeRaiseRankExplicit, new OpRaiseRank<ExplicitRef>);
interpreter.installSegment5 (opcodeLowerRank, new OpLowerRank<ImplicitRef>);
interpreter.installSegment5 (opcodeLowerRankExplicit, new OpLowerRank<ExplicitRef>);
} }
} }
} }

@ -53,6 +53,23 @@ namespace MWScript
} }
}; };
template<class R>
class OpModScale : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Float scale = runtime[0].mFloat;
runtime.pop();
// add the parameter to the object's scale.
MWBase::Environment::get().getWorld()->scaleObject(ptr,ptr.getCellRef().mScale + scale);
}
};
template<class R> template<class R>
class OpSetAngle : public Interpreter::Opcode0 class OpSetAngle : public Interpreter::Opcode0
{ {
@ -532,6 +549,8 @@ namespace MWScript
const int opcodePlaceAtPc = 0x200019c; const int opcodePlaceAtPc = 0x200019c;
const int opcodePlaceAtMe = 0x200019d; const int opcodePlaceAtMe = 0x200019d;
const int opcodePlaceAtMeExplicit = 0x200019e; const int opcodePlaceAtMeExplicit = 0x200019e;
const int opcodeModScale = 0x20001e3;
const int opcodeModScaleExplicit = 0x20001e4;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {
@ -548,6 +567,7 @@ namespace MWScript
extensions.registerInstruction("placeitem","cffff",opcodePlaceItem); extensions.registerInstruction("placeitem","cffff",opcodePlaceItem);
extensions.registerInstruction("placeatpc","clfl",opcodePlaceAtPc); extensions.registerInstruction("placeatpc","clfl",opcodePlaceAtPc);
extensions.registerInstruction("placeatme","clfl",opcodePlaceAtMe,opcodePlaceAtMeExplicit); extensions.registerInstruction("placeatme","clfl",opcodePlaceAtMe,opcodePlaceAtMeExplicit);
extensions.registerInstruction("modscale","f",opcodeModScale,opcodeModScaleExplicit);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -574,7 +594,9 @@ namespace MWScript
interpreter.installSegment5(opcodePlaceItem,new OpPlaceItem<ImplicitRef>); interpreter.installSegment5(opcodePlaceItem,new OpPlaceItem<ImplicitRef>);
interpreter.installSegment5(opcodePlaceAtPc,new OpPlaceAtPc<ImplicitRef>); interpreter.installSegment5(opcodePlaceAtPc,new OpPlaceAtPc<ImplicitRef>);
interpreter.installSegment5(opcodePlaceAtMe,new OpPlaceAtMe<ImplicitRef>); interpreter.installSegment5(opcodePlaceAtMe,new OpPlaceAtMe<ImplicitRef>);
interpreter.installSegment5(opcodePlaceAtMeExplicit,new OpPlaceAtMe<ExplicitRef>); interpreter.installSegment5(opcodePlaceAtMeExplicit,new OpPlaceAtMe<ExplicitRef>);
interpreter.installSegment5(opcodeModScale,new OpModScale<ImplicitRef>);
interpreter.installSegment5(opcodeModScaleExplicit,new OpModScale<ExplicitRef>);
} }
} }
} }

@ -313,7 +313,12 @@ void FFmpeg_Decoder::close()
mStreams.erase(mStreams.begin()); mStreams.erase(mStreams.begin());
} }
if(mFormatCtx) if(mFormatCtx)
{
AVIOContext* context = mFormatCtx->pb;
av_free(context);
mFormatCtx->pb = NULL;
av_close_input_file(mFormatCtx); av_close_input_file(mFormatCtx);
}
mFormatCtx = NULL; mFormatCtx = NULL;
mDataStream.setNull(); mDataStream.setNull();

@ -287,6 +287,16 @@ namespace MWWorld
public: public:
typedef SharedIterator<ESM::Land> iterator; typedef SharedIterator<ESM::Land> iterator;
virtual ~Store<ESM::Land>()
{
for (std::vector<ESM::Land *>::const_iterator it =
mStatic.begin(); it != mStatic.end(); ++it)
{
delete *it;
}
}
int getSize() const { int getSize() const {
return mStatic.size(); return mStatic.size();
} }

@ -193,7 +193,7 @@ namespace MWWorld
mRendering->attachCameraTo(mPlayer->getPlayer()); mRendering->attachCameraTo(mPlayer->getPlayer());
mPhysics->addActor(mPlayer->getPlayer()); mPhysics->addActor(mPlayer->getPlayer());
// global variables // global variables
mGlobalVariables = new Globals (mStore); mGlobalVariables = new Globals (mStore);
@ -203,6 +203,8 @@ namespace MWWorld
mGlobalVariables->setInt ("chargenstate", 1); mGlobalVariables->setInt ("chargenstate", 1);
} }
mGlobalVariables->setInt ("pcrace", 3);
mWorldScene = new Scene(*mRendering, mPhysics); mWorldScene = new Scene(*mRendering, mPhysics);
setFallbackValues(fallbackMap); setFallbackValues(fallbackMap);
@ -660,7 +662,7 @@ namespace MWWorld
{ {
MWWorld::Class::get(ptr).adjustScale(ptr,scale); MWWorld::Class::get(ptr).adjustScale(ptr,scale);
ptr.getCellRef().mScale = scale; ptr.getCellRef().mScale = scale;
if(ptr.getRefData().getBaseNode() == 0) if(ptr.getRefData().getBaseNode() == 0)
return; return;
mRendering->scaleObject(ptr, Vector3(scale,scale,scale)); mRendering->scaleObject(ptr, Vector3(scale,scale,scale));
@ -673,7 +675,7 @@ namespace MWWorld
rot.x = Ogre::Degree(x).valueRadians(); rot.x = Ogre::Degree(x).valueRadians();
rot.y = Ogre::Degree(y).valueRadians(); rot.y = Ogre::Degree(y).valueRadians();
rot.z = Ogre::Degree(z).valueRadians(); rot.z = Ogre::Degree(z).valueRadians();
float *objRot = ptr.getRefData().getPosition().rot; float *objRot = ptr.getRefData().getPosition().rot;
if(ptr.getRefData().getBaseNode() == 0 || !mRendering->rotateObject(ptr, rot, adjust)) if(ptr.getRefData().getBaseNode() == 0 || !mRendering->rotateObject(ptr, rot, adjust))
{ {
@ -781,7 +783,7 @@ namespace MWWorld
const ESM::Potion *World::createRecord (const ESM::Potion& record) const ESM::Potion *World::createRecord (const ESM::Potion& record)
{ {
return mStore.insert(record); return mStore.insert(record);
} }
const ESM::Class *World::createRecord (const ESM::Class& record) const ESM::Class *World::createRecord (const ESM::Class& record)
@ -802,7 +804,23 @@ namespace MWWorld
const ESM::NPC *World::createRecord(const ESM::NPC &record) const ESM::NPC *World::createRecord(const ESM::NPC &record)
{ {
bool update = false; bool update = false;
if (StringUtils::ciEqual(record.mId, "player")) {
if (StringUtils::ciEqual(record.mId, "player"))
{
static const char *sRaces[] =
{
"Argonian", "Breton", "Dark Elf", "High Elf", "Imperial", "Khajiit", "Nord", "Orc", "Redguard",
"Woodelf", 0
};
int i=0;
for (; sRaces[i]; ++i)
if (StringUtils::ciEqual (sRaces[i], record.mRace))
break;
mGlobalVariables->setInt ("pcrace", sRaces[i] ? i+1 : 0);
const ESM::NPC *player = const ESM::NPC *player =
mPlayer->getPlayer().get<ESM::NPC>()->mBase; mPlayer->getPlayer().get<ESM::NPC>()->mBase;
@ -834,7 +852,7 @@ namespace MWWorld
/// \todo split this function up into subfunctions /// \todo split this function up into subfunctions
mWorldScene->update (duration, paused); mWorldScene->update (duration, paused);
float pitch, yaw; float pitch, yaw;
Ogre::Vector3 eyepos; Ogre::Vector3 eyepos;
mRendering->getPlayerData(eyepos, pitch, yaw); mRendering->getPlayerData(eyepos, pitch, yaw);

@ -1,5 +1,6 @@
#define gammaCorrectRead(v) pow(v, float3(gammaCorrection,gammaCorrection,gammaCorrection)) #define gammaCorrectRead(v) pow(max(v, 0.00001f), float3(gammaCorrection,gammaCorrection,gammaCorrection))
#define gammaCorrectOutput(v) pow(v, float3(1.f/gammaCorrection,1.f/gammaCorrection,1.f/gammaCorrection)) #define gammaCorrectOutput(v) pow(max(v, 0.00001f), float3(1.f/gammaCorrection,1.f/gammaCorrection,1.f/gammaCorrection))
#if SH_HLSL == 1 || SH_CG == 1 #if SH_HLSL == 1 || SH_CG == 1

@ -3,7 +3,7 @@ OpenMW: A reimplementation of The Elder Scrolls III: Morrowind
OpenMW is an attempt at recreating the engine for the popular role-playing game OpenMW is an attempt at recreating the engine for the popular role-playing game
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work. Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
Version: 0.19.0 Version: 0.20.0
License: GPL (see GPL3.txt for more information) License: GPL (see GPL3.txt for more information)
Website: http://www.openmw.org Website: http://www.openmw.org
@ -69,12 +69,9 @@ Allowed options:
--script-all [=arg(=1)] (=0) compile all scripts (excluding dialogue scri --script-all [=arg(=1)] (=0) compile all scripts (excluding dialogue scri
pts) at startup pts) at startup
--script-console [=arg(=1)] (=0) enable console-only script functionality --script-console [=arg(=1)] (=0) enable console-only script functionality
--script-run arg select a file that is executed in the consol --script-run arg select a file containing a list of console
e on startup commands that is executed on startup
Note: The file contains a list of script
lines, but not a complete scripts. That mean
s no begin/end and no variable declarations.
--new-game [=arg(=1)] (=0) activate char gen/new game mechanics --new-game [=arg(=1)] (=0) activate char gen/new game mechanics
--fs-strict [=arg(=1)] (=0) strict file system handling (no case folding --fs-strict [=arg(=1)] (=0) strict file system handling (no case folding
) )
@ -97,6 +94,36 @@ Allowed options:
CHANGELOG CHANGELOG
0.20.0
Bug #366: Changing the player's race during character creation does not change the look of the player character
Bug #430: Teleporting and using loading doors linking within the same cell reloads the cell
Bug #437: Stop animations when paused
Bug #438: Time displays as "0 a.m." when it should be "12 a.m."
Bug #439: Text in "name" field of potion/spell creation window is persistent
Bug #440: Starting date at a new game is off by one day
Bug #442: Console window doesn't close properly sometimes
Bug #448: Do not break container window formatting when item names are very long
Bug #458: Topics sometimes not automatically added to known topic list
Bug #476: Auto-Moving allows player movement after using DisablePlayerControls
Bug #478: After sleeping in a bed the rest dialogue window opens automtically again
Bug #492: On creating potions the ingredients are removed twice
Feature #63: Mercantile skill
Feature #82: Persuasion Dialogue
Feature #219: Missing dialogue filters/functions
Feature #369: Add a FailedAction
Feature #377: Select head/hair on character creation
Feature #391: Dummy AI package classes
Feature #435: Global Map, 2nd Layer
Feature #450: Persuasion
Feature #457: Add more script instructions
Feature #474: update the global variable pcrace when the player's race is changed
Task #158: Move dynamically generated classes from Player class to World Class
Task #159: ESMStore rework and cleanup
Task #163: More Component Namespace Cleanup
Task #402: Move player data from MWWorld::Player to the player's NPC record
Task #446: Fix no namespace in BulletShapeLoader
0.19.0 0.19.0
Bug #374: Character shakes in 3rd person mode near the origin Bug #374: Character shakes in 3rd person mode near the origin

Loading…
Cancel
Save