From 3060fbee603cc8b4dcaff65a00b70b9da722a200 Mon Sep 17 00:00:00 2001 From: gugus Date: Wed, 26 Sep 2012 18:30:47 +0200 Subject: [PATCH 01/45] TravelGUI, not completly finished. --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwbase/windowmanager.hpp | 2 + apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 4 + apps/openmw/mwgui/dialogue.cpp | 14 +- apps/openmw/mwgui/dialogue.hpp | 2 + apps/openmw/mwgui/mode.hpp | 1 + apps/openmw/mwgui/travelwindow.cpp | 159 ++++++++++++++++++ apps/openmw/mwgui/travelwindow.hpp | 57 +++++++ apps/openmw/mwgui/windowmanagerimp.cpp | 9 + apps/openmw/mwgui/windowmanagerimp.hpp | 2 + 10 files changed, 249 insertions(+), 3 deletions(-) create mode 100644 apps/openmw/mwgui/travelwindow.cpp create mode 100644 apps/openmw/mwgui/travelwindow.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 66844b280..e140f0db2 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -29,7 +29,7 @@ add_openmw_dir (mwgui map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list formatting inventorywindow container hud countdialog tradewindow settingswindow confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu - itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog + itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog travelwindow ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 429163136..e6b9c6455 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -42,6 +42,7 @@ namespace MWGui class Console; class SpellWindow; class TradeWindow; + class TravelWindow; class SpellBuyingWindow; class ConfirmationDialog; class CountDialog; @@ -108,6 +109,7 @@ namespace MWBase virtual MWGui::ConfirmationDialog* getConfirmationDialog() = 0; virtual MWGui::TradeWindow* getTradeWindow() = 0; virtual MWGui::SpellBuyingWindow* getSpellBuyingWindow() = 0; + virtual MWGui::TravelWindow* getTravelWindow() = 0; virtual MWGui::SpellWindow* getSpellWindow() = 0; virtual MWGui::Console* getConsole() = 0; diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 1b7532d0a..34d4a7981 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -798,6 +798,10 @@ namespace MWDialogue win->setShowSpells(true); else win->setShowSpells(false); + if( !mActor.get()->base->mTransport.empty()) + win->setShowTravel(true); + else + win->setShowTravel(false); // sort again, because the previous sort was case-sensitive keywordList.sort(stringCompareNoCase); diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 245487a04..860da5125 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -19,6 +19,7 @@ #include "tradewindow.hpp" #include "spellbuyingwindow.hpp" #include "inventorywindow.hpp" +#include "travelwindow.hpp" using namespace MWGui; using namespace Widgets; @@ -134,7 +135,13 @@ void DialogueWindow::onSelectTopic(std::string topic) mWindowManager.pushGuiMode(GM_SpellBuying); mWindowManager.getSpellBuyingWindow()->startSpellBuying(mPtr); } - + else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sTravel")->getString()) + { + std::cout << "travel!"; + mWindowManager.pushGuiMode(GM_Travel); + mWindowManager.getTravelWindow()->startTravel(mPtr); + //mWindowManager.getSpellBuyingWindow()->startSpellBuying(mPtr); + } else MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic)); } @@ -163,7 +170,10 @@ void DialogueWindow::setKeywords(std::list keyWords) if (mShowSpells) mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sSpells")->getString()); - if (anyService) + if(mShowTravel) + mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sTravel")->getString()); + + if (anyService || mShowTravel) mTopicsList->addSeparator(); for(std::list::iterator it = keyWords.begin(); it != keyWords.end(); ++it) diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index a43b0d5a7..caa5c7dc4 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -52,6 +52,7 @@ namespace MWGui // make sure to call these before setKeywords() void setShowTrade(bool show) { mShowTrade = show; } void setShowSpells(bool show) { mShowSpells = show; } + void setShowTravel(bool show) { mShowTravel = show; } protected: void onSelectTopic(std::string topic); @@ -72,6 +73,7 @@ namespace MWGui // various service button visibilities, depending if the npc/creature talked to has these services bool mShowTrade; bool mShowSpells; + bool mShowTravel; bool mEnabled; diff --git a/apps/openmw/mwgui/mode.hpp b/apps/openmw/mwgui/mode.hpp index 64aa1dc21..4dd642f6d 100644 --- a/apps/openmw/mwgui/mode.hpp +++ b/apps/openmw/mwgui/mode.hpp @@ -22,6 +22,7 @@ namespace MWGui GM_Rest, GM_RestBed, GM_SpellBuying, + GM_Travel, GM_Levelup, diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp new file mode 100644 index 000000000..91966e19b --- /dev/null +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -0,0 +1,159 @@ +#include "travelwindow.hpp" + +#include + +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" +#include "../mwbase/windowmanager.hpp" + +#include "../mwworld/player.hpp" +#include "../mwworld/manualref.hpp" + +#include "../mwmechanics/spells.hpp" +#include "../mwmechanics/creaturestats.hpp" + +#include "inventorywindow.hpp" +#include "tradewindow.hpp" + +namespace MWGui +{ + const int TravelWindow::sLineHeight = 18; + + TravelWindow::TravelWindow(MWBase::WindowManager& parWindowManager) : + WindowBase("openmw_spell_buying_window.layout", parWindowManager) + , ContainerBase(NULL) // no drag&drop + , mCurrentY(0) + , mLastPos(0) + { + setCoord(0, 0, 450, 300); + + getWidget(mCancelButton, "CancelButton"); + getWidget(mPlayerGold, "PlayerGold"); + getWidget(mSelect, "Select"); + getWidget(mDestinations, "Spells"); + getWidget(mDestinationsView, "SpellsView"); + + mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onCancelButtonClicked); + + mDestinations->setCoord(450/2-mDestinations->getTextSize().width/2, + mDestinations->getTop(), + mDestinations->getTextSize().width, + mDestinations->getHeight()); + mSelect->setCoord(8, + mSelect->getTop(), + mSelect->getTextSize().width, + mSelect->getHeight()); + } + + void TravelWindow::addDestination(const std::string& travelId) + { + //std::cout << "travel to" << travelId; + /*const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); + int price = spell->data.cost*MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fSpellValueMult")->getFloat();*/ + int price = 0; + MyGUI::Button* toAdd = mDestinationsView->createWidget((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SpellText", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); + mCurrentY += sLineHeight; + /// \todo price adjustment depending on merchantile skill + toAdd->setUserData(price); + toAdd->setCaptionWithReplacing(travelId+" - "+boost::lexical_cast(price)+"#{sgp}"); + toAdd->setSize(toAdd->getTextSize().width,sLineHeight); + toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel); + toAdd->setUserString("ToolTipType", "Spell"); + toAdd->setUserString("Spell", travelId); + toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onTravelButtonClick); + mDestinationsWidgetMap.insert(std::make_pair (toAdd, travelId)); + } + + void TravelWindow::clearDestinations() + { + mDestinationsView->setViewOffset(MyGUI::IntPoint(0,0)); + mCurrentY = 0; + while (mDestinationsView->getChildCount()) + MyGUI::Gui::getInstance().destroyWidget(mDestinationsView->getChildAt(0)); + mDestinationsWidgetMap.clear(); + } + + void TravelWindow::startTravel(const MWWorld::Ptr& actor) + { + center(); + mActor = actor; + clearDestinations(); + + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + + /*MWMechanics::Spells& playerSpells = MWWorld::Class::get (player).getCreatureStats (player).getSpells(); + MWMechanics::Spells& merchantSpells = MWWorld::Class::get (actor).getCreatureStats (actor).getSpells(); + + for (MWMechanics::Spells::TIterator iter = merchantSpells.begin(); iter!=merchantSpells.end(); ++iter) + { + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find (*iter); + + if (spell->data.type!=ESM::Spell::ST_Spell) + continue; // don't try to sell diseases, curses or powers + + if (std::find (playerSpells.begin(), playerSpells.end(), *iter)!=playerSpells.end()) + continue; // we have that spell already + + addDestination (*iter); + }*/ + + for(int i = 0;i()->base->mTransport.size();i++) + { + addDestination(mActor.get()->base->mTransport[i].mCellName); + } + + updateLabels(); + + mDestinationsView->setCanvasSize (MyGUI::IntSize(mDestinationsView->getWidth(), std::max(mDestinationsView->getHeight(), mCurrentY))); + } + + void TravelWindow::onTravelButtonClick(MyGUI::Widget* _sender) + { + /*int price = *_sender->getUserData(); + + if (mWindowManager.getInventoryWindow()->getPlayerGold()>=price) + { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); + MWMechanics::Spells& spells = stats.getSpells(); + spells.add (mSpellsWidgetMap.find(_sender)->second); + mWindowManager.getTradeWindow()->addOrRemoveGold(-price); + startSpellBuying(mActor); + + MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); + }*/ + } + + void TravelWindow::onCancelButtonClicked(MyGUI::Widget* _sender) + { + mWindowManager.removeGuiMode(GM_Travel); + } + + void TravelWindow::updateLabels() + { + mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast(mWindowManager.getInventoryWindow()->getPlayerGold())); + mPlayerGold->setCoord(8, + mPlayerGold->getTop(), + mPlayerGold->getTextSize().width, + mPlayerGold->getHeight()); + } + + void TravelWindow::onReferenceUnavailable() + { + // remove both Spells and Dialogue (since you always trade with the NPC/creature that you have previously talked to) + mWindowManager.removeGuiMode(GM_Travel); + mWindowManager.removeGuiMode(GM_Dialogue); + } + + void TravelWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel) + { + if (mDestinationsView->getViewOffset().top + _rel*0.3 > 0) + mDestinationsView->setViewOffset(MyGUI::IntPoint(0, 0)); + else + mDestinationsView->setViewOffset(MyGUI::IntPoint(0, mDestinationsView->getViewOffset().top + _rel*0.3)); + } +} + diff --git a/apps/openmw/mwgui/travelwindow.hpp b/apps/openmw/mwgui/travelwindow.hpp new file mode 100644 index 000000000..07a516ce8 --- /dev/null +++ b/apps/openmw/mwgui/travelwindow.hpp @@ -0,0 +1,57 @@ +#ifndef MWGUI_TravelWINDOW_H +#define MWGUI_TravelWINDOW_H + +#include "container.hpp" +#include "window_base.hpp" + +#include "../mwworld/ptr.hpp" + +namespace MyGUI +{ + class Gui; + class Widget; +} + +namespace MWGui +{ + class WindowManager; +} + + +namespace MWGui +{ + class TravelWindow : public ContainerBase, public WindowBase + { + public: + TravelWindow(MWBase::WindowManager& parWindowManager); + + void startTravel(const MWWorld::Ptr& actor); + + protected: + MyGUI::Button* mCancelButton; + MyGUI::TextBox* mPlayerGold; + MyGUI::TextBox* mDestinations; + MyGUI::TextBox* mSelect; + + MyGUI::ScrollView* mDestinationsView; + + MWWorld::Ptr mActor; + + std::map mDestinationsWidgetMap; + + void onCancelButtonClicked(MyGUI::Widget* _sender); + void onTravelButtonClick(MyGUI::Widget* _sender); + void onMouseWheel(MyGUI::Widget* _sender, int _rel); + void addDestination(const std::string& destinationID); + void clearDestinations(); + int mLastPos,mCurrentY; + + static const int sLineHeight; + + void updateLabels(); + + virtual void onReferenceUnavailable(); + }; +} + +#endif diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 5a04a90c0..811edcba0 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -38,6 +38,7 @@ #include "countdialog.hpp" #include "tradewindow.hpp" #include "spellbuyingwindow.hpp" +#include "travelwindow.hpp" #include "settingswindow.hpp" #include "confirmationdialog.hpp" #include "alchemywindow.hpp" @@ -67,6 +68,7 @@ WindowManager::WindowManager( , mCountDialog(NULL) , mTradeWindow(NULL) , mSpellBuyingWindow(NULL) + , mTravelWindow(NULL) , mSettingsWindow(NULL) , mConfirmationDialog(NULL) , mAlchemyWindow(NULL) @@ -141,6 +143,7 @@ WindowManager::WindowManager( mInventoryWindow = new InventoryWindow(*this,mDragAndDrop); mTradeWindow = new TradeWindow(*this); mSpellBuyingWindow = new SpellBuyingWindow(*this); + mTravelWindow = new TravelWindow(*this); mDialogueWindow = new DialogueWindow(*this); mContainerWindow = new ContainerWindow(*this,mDragAndDrop); mHud = new HUD(w,h, mShowFPSLevel, mDragAndDrop); @@ -203,6 +206,7 @@ WindowManager::~WindowManager() delete mScrollWindow; delete mTradeWindow; delete mSpellBuyingWindow; + delete mTravelWindow; delete mSettingsWindow; delete mConfirmationDialog; delete mAlchemyWindow; @@ -253,6 +257,7 @@ void WindowManager::updateVisible() mBookWindow->setVisible(false); mTradeWindow->setVisible(false); mSpellBuyingWindow->setVisible(false); + mTravelWindow->setVisible(false); mSettingsWindow->setVisible(false); mAlchemyWindow->setVisible(false); mSpellWindow->setVisible(false); @@ -359,6 +364,9 @@ void WindowManager::updateVisible() case GM_SpellBuying: mSpellBuyingWindow->setVisible(true); break; + case GM_Travel: + mTravelWindow->setVisible(true); + break; case GM_InterMessageBox: break; case GM_Journal: @@ -844,6 +852,7 @@ MWGui::CountDialog* WindowManager::getCountDialog() { return mCountDialog; } MWGui::ConfirmationDialog* WindowManager::getConfirmationDialog() { return mConfirmationDialog; } MWGui::TradeWindow* WindowManager::getTradeWindow() { return mTradeWindow; } MWGui::SpellBuyingWindow* WindowManager::getSpellBuyingWindow() { return mSpellBuyingWindow; } +MWGui::TravelWindow* WindowManager::getTravelWindow() { return mTravelWindow; } MWGui::SpellWindow* WindowManager::getSpellWindow() { return mSpellWindow; } MWGui::Console* WindowManager::getConsole() { return mConsole; } diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index d7773e261..635a7483c 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -111,6 +111,7 @@ namespace MWGui virtual MWGui::ConfirmationDialog* getConfirmationDialog(); virtual MWGui::TradeWindow* getTradeWindow(); virtual MWGui::SpellBuyingWindow* getSpellBuyingWindow(); + virtual MWGui::TravelWindow* getTravelWindow(); virtual MWGui::SpellWindow* getSpellWindow(); virtual MWGui::Console* getConsole(); @@ -229,6 +230,7 @@ namespace MWGui CountDialog* mCountDialog; TradeWindow* mTradeWindow; SpellBuyingWindow* mSpellBuyingWindow; + TravelWindow* mTravelWindow; SettingsWindow* mSettingsWindow; ConfirmationDialog* mConfirmationDialog; AlchemyWindow* mAlchemyWindow; From cd343c4fbd5a99d12126fdc99fa61c03e60e0409 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 27 Sep 2012 11:59:40 +0200 Subject: [PATCH 02/45] Issue #61: Basic alchemy class (doesn't do anything yet) --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwgui/alchemywindow.cpp | 4 +++- apps/openmw/mwgui/alchemywindow.hpp | 6 ++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 66844b280..69cfb2fd5 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -61,7 +61,7 @@ add_openmw_dir (mwclass add_openmw_dir (mwmechanics mechanicsmanagerimp stat creaturestats magiceffects movement actors drawstate spells - activespells npcstats aipackage aisequence + activespells npcstats aipackage aisequence alchemy ) add_openmw_dir (mwbase diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index 308029810..6fd88d5ca 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -253,8 +253,10 @@ namespace MWGui void AlchemyWindow::open() { - openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); // this sets mPtr setFilter(ContainerBase::Filter_Ingredients); + + mAlchemy.setAlchemist (mPtr); // pick the best available apparatus MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr); diff --git a/apps/openmw/mwgui/alchemywindow.hpp b/apps/openmw/mwgui/alchemywindow.hpp index 53e7178d5..67378d7de 100644 --- a/apps/openmw/mwgui/alchemywindow.hpp +++ b/apps/openmw/mwgui/alchemywindow.hpp @@ -1,6 +1,8 @@ #ifndef MWGUI_ALCHEMY_H #define MWGUI_ALCHEMY_H +#include "../mwmechanics/alchemy.hpp" + #include "window_base.hpp" #include "container.hpp" #include "widgets.hpp" @@ -46,6 +48,10 @@ namespace MWGui virtual void onReferenceUnavailable() { ; } void update(); + + private: + + MWMechanics::Alchemy mAlchemy; }; } From 1971ba66f18cccd06b60b63b7b29c06e46ebf7de Mon Sep 17 00:00:00 2001 From: gugus Date: Thu, 27 Sep 2012 13:08:38 +0200 Subject: [PATCH 03/45] destination name is now OK for every trave services --- apps/openmw/mwgui/travelwindow.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 91966e19b..9e7b0a975 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -102,7 +102,12 @@ namespace MWGui for(int i = 0;i()->base->mTransport.size();i++) { - addDestination(mActor.get()->base->mTransport[i].mCellName); + std::string cellname = mActor.get()->base->mTransport[i].mCellName; + int x,y; + MWBase::Environment::get().getWorld()->positionToIndex(mActor.get()->base->mTransport[i].mPos.pos[0], + mActor.get()->base->mTransport[i].mPos.pos[1],x,y); + if(cellname == "") cellname = MWBase::Environment::get().getWorld()->getExterior(x,y)->cell->name; + addDestination(cellname); } updateLabels(); From 4d496c11880d8f41dda20e5e2c0e36e60ab052e3 Mon Sep 17 00:00:00 2001 From: gugus Date: Fri, 28 Sep 2012 17:02:27 +0200 Subject: [PATCH 04/45] correction1 --- apps/openmw/mwgui/tradewindow.cpp | 2 +- apps/openmw/mwgui/tradewindow.hpp | 2 +- apps/openmw/mwgui/travelwindow.cpp | 14 +++++++------- apps/openmw/mwrender/globalmap.cpp | 5 +++-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index fc4220fc3..74cae380b 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -16,7 +16,7 @@ namespace MWGui { TradeWindow::TradeWindow(MWBase::WindowManager& parWindowManager) : WindowBase("openmw_trade_window.layout", parWindowManager) - , ContainerBase(NULL) // no drag&drop + , ReferenceInterface(NULL) // no drag&drop , mCurrentBalance(0) { MyGUI::ScrollView* itemView; diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index 4ec55045c..7ca3a97b4 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -20,7 +20,7 @@ namespace MWGui namespace MWGui { - class TradeWindow : public ContainerBase, public WindowBase + class TradeWindow : public ReferenceInterface, public WindowBase { public: TradeWindow(MWBase::WindowManager& parWindowManager); diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 9e7b0a975..f561a2c99 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -79,7 +79,7 @@ namespace MWGui void TravelWindow::startTravel(const MWWorld::Ptr& actor) { center(); - mActor = actor; + mPtr = actor; clearDestinations(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); @@ -100,18 +100,18 @@ namespace MWGui addDestination (*iter); }*/ - for(int i = 0;i()->base->mTransport.size();i++) + for(int i = 0;i()->base->mTransport.size();i++) { - std::string cellname = mActor.get()->base->mTransport[i].mCellName; + std::string cellname = mPtr.get()->base->mTransport[i].mCellName; int x,y; - MWBase::Environment::get().getWorld()->positionToIndex(mActor.get()->base->mTransport[i].mPos.pos[0], - mActor.get()->base->mTransport[i].mPos.pos[1],x,y); + MWBase::Environment::get().getWorld()->positionToIndex(mPtr.get()->base->mTransport[i].mPos.pos[0], + mPtr.get()->base->mTransport[i].mPos.pos[1],x,y); if(cellname == "") cellname = MWBase::Environment::get().getWorld()->getExterior(x,y)->cell->name; addDestination(cellname); } updateLabels(); - + mPtr.get()->base->mTransport[0]. mDestinationsView->setCanvasSize (MyGUI::IntSize(mDestinationsView->getWidth(), std::max(mDestinationsView->getHeight(), mCurrentY))); } @@ -126,7 +126,7 @@ namespace MWGui MWMechanics::Spells& spells = stats.getSpells(); spells.add (mSpellsWidgetMap.find(_sender)->second); mWindowManager.getTradeWindow()->addOrRemoveGold(-price); - startSpellBuying(mActor); + startSpellBuying(mPtr); MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); }*/ diff --git a/apps/openmw/mwrender/globalmap.cpp b/apps/openmw/mwrender/globalmap.cpp index 5e0a63c77..dd30a68f7 100644 --- a/apps/openmw/mwrender/globalmap.cpp +++ b/apps/openmw/mwrender/globalmap.cpp @@ -53,7 +53,8 @@ namespace MWRender { Ogre::Image image; - Ogre::uchar data[mWidth * mHeight * 3]; + std::vector data; + data.resize(mWidth * mHeight * 3); for (int x = mMinX; x <= mMaxX; ++x) { @@ -150,7 +151,7 @@ namespace MWRender } } - image.loadDynamicImage (data, mWidth, mHeight, Ogre::PF_B8G8R8); + image.loadDynamicImage (data.data(), mWidth, mHeight, Ogre::PF_B8G8R8); //image.save (mCacheDir + "/GlobalMap.png"); From c6fd864a76e010807a512e85f4a1c4a5078de4db Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 29 Sep 2012 10:02:46 +0200 Subject: [PATCH 05/45] Issue #61: Forgot to add some files --- apps/openmw/mwmechanics/alchemy.cpp | 7 +++++++ apps/openmw/mwmechanics/alchemy.hpp | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 apps/openmw/mwmechanics/alchemy.cpp create mode 100644 apps/openmw/mwmechanics/alchemy.hpp diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp new file mode 100644 index 000000000..ea5cbe965 --- /dev/null +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -0,0 +1,7 @@ + +#include "alchemy.hpp" + +void MWMechanics::Alchemy::setAlchemist (const MWWorld::Ptr& npc) +{ + mNpc = npc; +} diff --git a/apps/openmw/mwmechanics/alchemy.hpp b/apps/openmw/mwmechanics/alchemy.hpp new file mode 100644 index 000000000..93c50f1ff --- /dev/null +++ b/apps/openmw/mwmechanics/alchemy.hpp @@ -0,0 +1,22 @@ +#ifndef GAME_MWMECHANICS_ALCHEMY_H +#define GAME_MWMECHANICS_ALCHEMY_H + +#include "../mwworld/ptr.hpp" + +namespace MWMechanics +{ + /// \brief Potion creatin via alchemy skill + class Alchemy + { + MWWorld::Ptr mNpc; + + public: + + void setAlchemist (const MWWorld::Ptr& npc); + ///< Set alchemist and configure alchemy setup accordingly. \a npc may be empty to indicate that + /// there is no alchemist (alchemy session has ended). + }; +} + +#endif + From 42f02f3ccd2b11e06868587871174661448865e3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 30 Sep 2012 18:54:20 +0200 Subject: [PATCH 06/45] Issue #61: Re-implemented tool selection in Alchemy class --- apps/openmw/mwmechanics/alchemy.cpp | 39 +++++++++++++++++++++++++++++ apps/openmw/mwmechanics/alchemy.hpp | 14 +++++++++++ 2 files changed, 53 insertions(+) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index ea5cbe965..0a0189190 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -1,7 +1,46 @@ #include "alchemy.hpp" +#include +#include + +#include "../mwworld/containerstore.hpp" +#include "../mwworld/class.hpp" + void MWMechanics::Alchemy::setAlchemist (const MWWorld::Ptr& npc) { mNpc = npc; + + mTools.resize (4); + + std::fill (mTools.begin(), mTools.end(), MWWorld::Ptr()); + + MWWorld::ContainerStore& store = MWWorld::Class::get (npc).getContainerStore (npc); + + for (MWWorld::ContainerStoreIterator iter (store.begin (MWWorld::ContainerStore::Type_Apparatus)); + iter!=store.end(); ++iter) + { + MWWorld::LiveCellRef* ref = iter->get(); + + int type = ref->base->data.type; + + if (type<0 || type>=static_cast (mTools.size())) + throw std::runtime_error ("invalid apparatus type"); + + if (!mTools[type].isEmpty()) + if (ref->base->data.quality<=mTools[type].get()->base->data.quality) + continue; + + mTools[type] = *iter; + } +} + +MWMechanics::Alchemy::TToolsIterator MWMechanics::Alchemy::beginTools() const +{ + return mTools.begin(); +} + +MWMechanics::Alchemy::TToolsIterator MWMechanics::Alchemy::endTools() const +{ + return mTools.end(); } diff --git a/apps/openmw/mwmechanics/alchemy.hpp b/apps/openmw/mwmechanics/alchemy.hpp index 93c50f1ff..fcaba9012 100644 --- a/apps/openmw/mwmechanics/alchemy.hpp +++ b/apps/openmw/mwmechanics/alchemy.hpp @@ -1,6 +1,8 @@ #ifndef GAME_MWMECHANICS_ALCHEMY_H #define GAME_MWMECHANICS_ALCHEMY_H +#include + #include "../mwworld/ptr.hpp" namespace MWMechanics @@ -8,13 +10,25 @@ namespace MWMechanics /// \brief Potion creatin via alchemy skill class Alchemy { + public: + + typedef std::vector TToolsContainer; + typedef TToolsContainer::const_iterator TToolsIterator; + + private: + MWWorld::Ptr mNpc; + TToolsContainer mTools; public: void setAlchemist (const MWWorld::Ptr& npc); ///< Set alchemist and configure alchemy setup accordingly. \a npc may be empty to indicate that /// there is no alchemist (alchemy session has ended). + + TToolsIterator beginTools() const; + + TToolsIterator endTools() const; }; } From 10c8360e07c1a31862f162d234c731829a0aba52 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 30 Sep 2012 19:05:45 +0200 Subject: [PATCH 07/45] Issue #61: Replaced apparatus handling in alchemy GUI with new implementation in Alchemy class --- apps/openmw/mwgui/alchemywindow.cpp | 72 +++++++---------------------- apps/openmw/mwgui/alchemywindow.hpp | 9 ++-- 2 files changed, 21 insertions(+), 60 deletions(-) diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index 6fd88d5ca..26bd9668e 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -28,7 +28,7 @@ namespace MWGui { AlchemyWindow::AlchemyWindow(MWBase::WindowManager& parWindowManager) : WindowBase("openmw_alchemy_window.layout", parWindowManager) - , ContainerBase(0) + , ContainerBase(0), mApparatus (4) { getWidget(mCreateButton, "CreateButton"); getWidget(mCancelButton, "CancelButton"); @@ -36,10 +36,10 @@ namespace MWGui getWidget(mIngredient2, "Ingredient2"); getWidget(mIngredient3, "Ingredient3"); getWidget(mIngredient4, "Ingredient4"); - getWidget(mApparatus1, "Apparatus1"); - getWidget(mApparatus2, "Apparatus2"); - getWidget(mApparatus3, "Apparatus3"); - getWidget(mApparatus4, "Apparatus4"); + getWidget(mApparatus[0], "Apparatus1"); + getWidget(mApparatus[1], "Apparatus2"); + getWidget(mApparatus[2], "Apparatus3"); + getWidget(mApparatus[3], "Apparatus4"); getWidget(mEffectsBox, "CreatedEffects"); getWidget(mNameEdit, "NameEdit"); @@ -70,7 +70,7 @@ namespace MWGui { // check if mortar & pestle is available (always needed) /// \todo check albemic, calcinator, retort (sometimes needed) - if (!mApparatus1->isUserString("ToolTipType")) + if (!mApparatus[0]->isUserString("ToolTipType")) { mWindowManager.messageBox("#{sNotifyMessage45}", std::vector()); return; @@ -253,60 +253,22 @@ namespace MWGui void AlchemyWindow::open() { - openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); // this sets mPtr - setFilter(ContainerBase::Filter_Ingredients); + openContainer (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); // this sets mPtr + setFilter (ContainerBase::Filter_Ingredients); mAlchemy.setAlchemist (mPtr); - // pick the best available apparatus - MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr); + int index = 0; - MWWorld::Ptr bestAlbemic; - MWWorld::Ptr bestMortarPestle; - MWWorld::Ptr bestCalcinator; - MWWorld::Ptr bestRetort; - - for (MWWorld::ContainerStoreIterator it(store.begin(MWWorld::ContainerStore::Type_Apparatus)); - it != store.end(); ++it) + for (MWMechanics::Alchemy::TToolsIterator iter (mAlchemy.beginTools()); + iter!=mAlchemy.endTools() && index (mApparatus.size()); ++iter, ++index) { - MWWorld::LiveCellRef* ref = it->get(); - if (ref->base->data.type == ESM::Apparatus::Albemic - && (bestAlbemic.isEmpty() || ref->base->data.quality > bestAlbemic.get()->base->data.quality)) - bestAlbemic = *it; - else if (ref->base->data.type == ESM::Apparatus::MortarPestle - && (bestMortarPestle.isEmpty() || ref->base->data.quality > bestMortarPestle.get()->base->data.quality)) - bestMortarPestle = *it; - else if (ref->base->data.type == ESM::Apparatus::Calcinator - && (bestCalcinator.isEmpty() || ref->base->data.quality > bestCalcinator.get()->base->data.quality)) - bestCalcinator = *it; - else if (ref->base->data.type == ESM::Apparatus::Retort - && (bestRetort.isEmpty() || ref->base->data.quality > bestRetort.get()->base->data.quality)) - bestRetort = *it; - } - - if (!bestMortarPestle.isEmpty()) - { - mApparatus1->setUserString("ToolTipType", "ItemPtr"); - mApparatus1->setUserData(bestMortarPestle); - mApparatus1->setImageTexture(getIconPath(bestMortarPestle)); - } - if (!bestAlbemic.isEmpty()) - { - mApparatus2->setUserString("ToolTipType", "ItemPtr"); - mApparatus2->setUserData(bestAlbemic); - mApparatus2->setImageTexture(getIconPath(bestAlbemic)); - } - if (!bestCalcinator.isEmpty()) - { - mApparatus3->setUserString("ToolTipType", "ItemPtr"); - mApparatus3->setUserData(bestCalcinator); - mApparatus3->setImageTexture(getIconPath(bestCalcinator)); - } - if (!bestRetort.isEmpty()) - { - mApparatus4->setUserString("ToolTipType", "ItemPtr"); - mApparatus4->setUserData(bestRetort); - mApparatus4->setImageTexture(getIconPath(bestRetort)); + if (!iter->isEmpty()) + { + mApparatus[index]->setUserString ("ToolTipType", "ItemPtr"); + mApparatus[index]->setUserData (*iter); + mApparatus[index]->setImageTexture (getIconPath (*iter)); + } } } diff --git a/apps/openmw/mwgui/alchemywindow.hpp b/apps/openmw/mwgui/alchemywindow.hpp index 67378d7de..5091fb57a 100644 --- a/apps/openmw/mwgui/alchemywindow.hpp +++ b/apps/openmw/mwgui/alchemywindow.hpp @@ -1,6 +1,8 @@ #ifndef MWGUI_ALCHEMY_H #define MWGUI_ALCHEMY_H +#include + #include "../mwmechanics/alchemy.hpp" #include "window_base.hpp" @@ -25,11 +27,6 @@ namespace MWGui MyGUI::ImageBox* mIngredient3; MyGUI::ImageBox* mIngredient4; - MyGUI::ImageBox* mApparatus1; - MyGUI::ImageBox* mApparatus2; - MyGUI::ImageBox* mApparatus3; - MyGUI::ImageBox* mApparatus4; - MyGUI::Widget* mEffectsBox; MyGUI::EditBox* mNameEdit; @@ -52,6 +49,8 @@ namespace MWGui private: MWMechanics::Alchemy mAlchemy; + + std::vector mApparatus; }; } From 1cc2c2055f41a0d68757972fb27e077290490360 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 2 Oct 2012 10:20:26 +0200 Subject: [PATCH 08/45] Issue #61: Implemented basic ingredient handling in Alchemy class --- apps/openmw/mwmechanics/alchemy.cpp | 52 +++++++++++++++++++++++++++++ apps/openmw/mwmechanics/alchemy.hpp | 22 +++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index c7e5da70a..6d3deed3c 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -11,6 +11,10 @@ void MWMechanics::Alchemy::setAlchemist (const MWWorld::Ptr& npc) { mNpc = npc; + mIngredients.resize (4); + + std::fill (mIngredients.begin(), mIngredients.end(), MWWorld::Ptr()); + mTools.resize (4); std::fill (mTools.begin(), mTools.end(), MWWorld::Ptr()); @@ -44,3 +48,51 @@ MWMechanics::Alchemy::TToolsIterator MWMechanics::Alchemy::endTools() const { return mTools.end(); } + +MWMechanics::Alchemy::TIngredientsIterator MWMechanics::Alchemy::beginIngredients() const +{ + return mIngredients.begin(); +} + +MWMechanics::Alchemy::TIngredientsIterator MWMechanics::Alchemy::endIngredients() const +{ + return mIngredients.end(); +} + +void MWMechanics::Alchemy::clear() +{ + mNpc = MWWorld::Ptr(); + mTools.clear(); + mIngredients.clear(); +} + +int MWMechanics::Alchemy::addIngredient (const MWWorld::Ptr& ingredient) +{ + // find a free slot + int slot = -1; + + for (int i=0; i (mIngredients.size()); ++i) + if (mIngredients[i].isEmpty()) + { + slot = i; + break; + } + + if (slot==-1) + return -1; + + for (TIngredientsIterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter) + if (!iter->isEmpty() && ingredient.get()==iter->get()) + return -1; + + mIngredients[slot] = ingredient; + + return slot; +} + +void MWMechanics::Alchemy::removeIngredient (int index) +{ + if (index>=0 && index (mIngredients.size())) + mIngredients[index] = MWWorld::Ptr(); +} + diff --git a/apps/openmw/mwmechanics/alchemy.hpp b/apps/openmw/mwmechanics/alchemy.hpp index fcaba9012..7c3cf9e68 100644 --- a/apps/openmw/mwmechanics/alchemy.hpp +++ b/apps/openmw/mwmechanics/alchemy.hpp @@ -7,7 +7,7 @@ namespace MWMechanics { - /// \brief Potion creatin via alchemy skill + /// \brief Potion creation via alchemy skill class Alchemy { public: @@ -15,10 +15,14 @@ namespace MWMechanics typedef std::vector TToolsContainer; typedef TToolsContainer::const_iterator TToolsIterator; + typedef std::vector TIngredientsContainer; + typedef TIngredientsContainer::const_iterator TIngredientsIterator; + private: MWWorld::Ptr mNpc; TToolsContainer mTools; + TIngredientsContainer mIngredients; public: @@ -29,6 +33,22 @@ namespace MWMechanics TToolsIterator beginTools() const; TToolsIterator endTools() const; + + TIngredientsIterator beginIngredients() const; + + TIngredientsIterator endIngredients() const; + + void clear(); + ///< Remove alchemist, tools and ingredients. + + int addIngredient (const MWWorld::Ptr& ingredient); + ///< Add ingredient into the next free slot. + /// + /// \return Slot index or -1, if adding failed because of no free slot or the ingredient type being + /// listed already. + + void removeIngredient (int index); + ///< Remove ingredient from slot (calling this function on an empty slot is a no-op). }; } From 14833a4c3abbae15a5d000e00f80649f8117acb1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 2 Oct 2012 10:20:49 +0200 Subject: [PATCH 09/45] Issue #61: More robust tools handling in alchemy window --- apps/openmw/mwgui/alchemywindow.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index 93eee60ee..2aa46fda0 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -62,6 +62,8 @@ namespace MWGui void AlchemyWindow::onCancelButtonClicked(MyGUI::Widget* _sender) { + mAlchemy.clear(); + mWindowManager.removeGuiMode(GM_Alchemy); mWindowManager.removeGuiMode(GM_Inventory); } @@ -265,9 +267,9 @@ namespace MWGui { if (!iter->isEmpty()) { - mApparatus[index]->setUserString ("ToolTipType", "ItemPtr"); - mApparatus[index]->setUserData (*iter); - mApparatus[index]->setImageTexture (getIconPath (*iter)); + mApparatus.at (index)->setUserString ("ToolTipType", "ItemPtr"); + mApparatus.at (index)->setUserData (*iter); + mApparatus.at (index)->setImageTexture (getIconPath (*iter)); } } } From 332039da10d303b611d85298a690ddf23392fbf5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 2 Oct 2012 10:29:47 +0200 Subject: [PATCH 10/45] Issue #61: replaced 4 ingredient member variables with vector in alchemy GUI --- apps/openmw/mwgui/alchemywindow.cpp | 148 ++++++++-------------------- apps/openmw/mwgui/alchemywindow.hpp | 6 +- 2 files changed, 44 insertions(+), 110 deletions(-) diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index 2aa46fda0..cef5d6e2e 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -28,14 +28,14 @@ namespace MWGui { AlchemyWindow::AlchemyWindow(MWBase::WindowManager& parWindowManager) : WindowBase("openmw_alchemy_window.layout", parWindowManager) - , ContainerBase(0), mApparatus (4) + , ContainerBase(0), mApparatus (4), mIngredients (4) { getWidget(mCreateButton, "CreateButton"); getWidget(mCancelButton, "CancelButton"); - getWidget(mIngredient1, "Ingredient1"); - getWidget(mIngredient2, "Ingredient2"); - getWidget(mIngredient3, "Ingredient3"); - getWidget(mIngredient4, "Ingredient4"); + getWidget(mIngredients[0], "Ingredient1"); + getWidget(mIngredients[1], "Ingredient2"); + getWidget(mIngredients[2], "Ingredient3"); + getWidget(mIngredients[3], "Ingredient4"); getWidget(mApparatus[0], "Apparatus1"); getWidget(mApparatus[1], "Apparatus2"); getWidget(mApparatus[2], "Apparatus3"); @@ -43,10 +43,10 @@ namespace MWGui getWidget(mEffectsBox, "CreatedEffects"); getWidget(mNameEdit, "NameEdit"); - mIngredient1->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); - mIngredient2->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); - mIngredient3->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); - mIngredient4->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); + mIngredients[0]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); + mIngredients[1]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); + mIngredients[2]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); + mIngredients[3]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); mCreateButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCreateButtonClicked); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCancelButtonClicked); @@ -80,14 +80,10 @@ namespace MWGui // make sure 2 or more ingredients were selected int numIngreds = 0; - if (mIngredient1->isUserString("ToolTipType")) - ++numIngreds; - if (mIngredient2->isUserString("ToolTipType")) - ++numIngreds; - if (mIngredient3->isUserString("ToolTipType")) - ++numIngreds; - if (mIngredient4->isUserString("ToolTipType")) - ++numIngreds; + for (int i=0; i<4; ++i) + if (mIngredients[i]->isUserString("ToolTipType")) + ++numIngreds; + if (numIngreds < 2) { mWindowManager.messageBox("#{sNotifyMessage6a}", std::vector()); @@ -138,14 +134,9 @@ namespace MWGui // note by scrawl: not rounding down here, I can't imagine a created potion to // have 0 weight when using ingredients with 0.1 weight respectively float weight = 0; - if (mIngredient1->isUserString("ToolTipType")) - weight += mIngredient1->getUserData()->get()->base->mData.mWeight; - if (mIngredient2->isUserString("ToolTipType")) - weight += mIngredient2->getUserData()->get()->base->mData.mWeight; - if (mIngredient3->isUserString("ToolTipType")) - weight += mIngredient3->getUserData()->get()->base->mData.mWeight; - if (mIngredient4->isUserString("ToolTipType")) - weight += mIngredient4->getUserData()->get()->base->mData.mWeight; + for (int i=0; i<4; ++i) + if (mIngredients[i]->isUserString("ToolTipType")) + weight += mIngredients[i]->getUserData()->get()->base->mData.mWeight; newPotion.mData.mWeight = weight / float(numIngreds); newPotion.mData.mValue = 100; /// \todo @@ -222,34 +213,15 @@ namespace MWGui } // reduce count of the ingredients - if (mIngredient1->isUserString("ToolTipType")) - { - MWWorld::Ptr ingred = *mIngredient1->getUserData(); - ingred.getRefData().setCount(ingred.getRefData().getCount()-1); - if (ingred.getRefData().getCount() == 0) - removeIngredient(mIngredient1); - } - if (mIngredient2->isUserString("ToolTipType")) - { - MWWorld::Ptr ingred = *mIngredient2->getUserData(); - ingred.getRefData().setCount(ingred.getRefData().getCount()-1); - if (ingred.getRefData().getCount() == 0) - removeIngredient(mIngredient2); - } - if (mIngredient3->isUserString("ToolTipType")) - { - MWWorld::Ptr ingred = *mIngredient3->getUserData(); - ingred.getRefData().setCount(ingred.getRefData().getCount()-1); - if (ingred.getRefData().getCount() == 0) - removeIngredient(mIngredient3); - } - if (mIngredient4->isUserString("ToolTipType")) - { - MWWorld::Ptr ingred = *mIngredient4->getUserData(); - ingred.getRefData().setCount(ingred.getRefData().getCount()-1); - if (ingred.getRefData().getCount() == 0) - removeIngredient(mIngredient4); + for (int i=0; i<4; ++i) + if (mIngredients[i]->isUserString("ToolTipType")) + { + MWWorld::Ptr ingred = *mIngredients[i]->getUserData(); + ingred.getRefData().setCount(ingred.getRefData().getCount()-1); + if (ingred.getRefData().getCount() == 0) + removeIngredient(mIngredients[i]); } + update(); } @@ -289,45 +261,24 @@ namespace MWGui // (which could happen if two similiar ingredients don't stack because of script / owner) bool alreadyAdded = false; std::string name = MWWorld::Class::get(item).getName(item); - if (mIngredient1->isUserString("ToolTipType")) - { - MWWorld::Ptr item2 = *mIngredient1->getUserData(); - std::string name2 = MWWorld::Class::get(item2).getName(item2); - if (name == name2) - alreadyAdded = true; - } - if (mIngredient2->isUserString("ToolTipType")) - { - MWWorld::Ptr item2 = *mIngredient2->getUserData(); - std::string name2 = MWWorld::Class::get(item2).getName(item2); - if (name == name2) - alreadyAdded = true; - } - if (mIngredient3->isUserString("ToolTipType")) - { - MWWorld::Ptr item2 = *mIngredient3->getUserData(); - std::string name2 = MWWorld::Class::get(item2).getName(item2); - if (name == name2) - alreadyAdded = true; - } - if (mIngredient4->isUserString("ToolTipType")) - { - MWWorld::Ptr item2 = *mIngredient4->getUserData(); - std::string name2 = MWWorld::Class::get(item2).getName(item2); - if (name == name2) - alreadyAdded = true; - } + for (int i=0; i<4; ++i) + if (mIngredients[i]->isUserString("ToolTipType")) + { + MWWorld::Ptr item2 = *mIngredients[i]->getUserData(); + std::string name2 = MWWorld::Class::get(item2).getName(item2); + if (name == name2) + alreadyAdded = true; + } + if (alreadyAdded) return; - if (!mIngredient1->isUserString("ToolTipType")) - add = mIngredient1; - if (add == NULL && !mIngredient2->isUserString("ToolTipType")) - add = mIngredient2; - if (add == NULL && !mIngredient3->isUserString("ToolTipType")) - add = mIngredient3; - if (add == NULL && !mIngredient4->isUserString("ToolTipType")) - add = mIngredient4; + for (int i=0; i<4; ++i) + if (!mIngredients[i]->isUserString("ToolTipType")) + { + add = mIngredients[i]; + break; + } if (add != NULL) { @@ -346,14 +297,9 @@ namespace MWGui { std::vector ignore; // don't show ingredients that are currently selected in the "available ingredients" box. - if (mIngredient1->isUserString("ToolTipType")) - ignore.push_back(*mIngredient1->getUserData()); - if (mIngredient2->isUserString("ToolTipType")) - ignore.push_back(*mIngredient2->getUserData()); - if (mIngredient3->isUserString("ToolTipType")) - ignore.push_back(*mIngredient3->getUserData()); - if (mIngredient4->isUserString("ToolTipType")) - ignore.push_back(*mIngredient4->getUserData()); + for (int i=0; i<4; ++i) + if (mIngredients[i]->isUserString("ToolTipType")) + ignore.push_back(*mIngredients[i]->getUserData()); return ignore; } @@ -364,15 +310,7 @@ namespace MWGui for (int i=0; i<4; ++i) { - MyGUI::ImageBox* ingredient; - if (i==0) - ingredient = mIngredient1; - else if (i==1) - ingredient = mIngredient2; - else if (i==2) - ingredient = mIngredient3; - else if (i==3) - ingredient = mIngredient4; + MyGUI::ImageBox* ingredient = mIngredients[i]; if (!ingredient->isUserString("ToolTipType")) continue; diff --git a/apps/openmw/mwgui/alchemywindow.hpp b/apps/openmw/mwgui/alchemywindow.hpp index 5091fb57a..179cdd174 100644 --- a/apps/openmw/mwgui/alchemywindow.hpp +++ b/apps/openmw/mwgui/alchemywindow.hpp @@ -22,11 +22,6 @@ namespace MWGui MyGUI::Button* mCreateButton; MyGUI::Button* mCancelButton; - MyGUI::ImageBox* mIngredient1; - MyGUI::ImageBox* mIngredient2; - MyGUI::ImageBox* mIngredient3; - MyGUI::ImageBox* mIngredient4; - MyGUI::Widget* mEffectsBox; MyGUI::EditBox* mNameEdit; @@ -51,6 +46,7 @@ namespace MWGui MWMechanics::Alchemy mAlchemy; std::vector mApparatus; + std::vector mIngredients; }; } From 85d9357e3ae71a04493e87113c0805a5b7794287 Mon Sep 17 00:00:00 2001 From: gugus Date: Sat, 6 Oct 2012 17:52:46 +0200 Subject: [PATCH 11/45] Travel GUI --- apps/openmw/mwgui/tradewindow.cpp | 2 +- apps/openmw/mwgui/tradewindow.hpp | 2 +- apps/openmw/mwgui/travelwindow.cpp | 14 +++++++------- apps/openmw/mwgui/travelwindow.hpp | 4 +--- apps/openmw/mwgui/windowmanagerimp.cpp | 1 + files/mygui/CMakeLists.txt | 1 + 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 74cae380b..fc4220fc3 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -16,7 +16,7 @@ namespace MWGui { TradeWindow::TradeWindow(MWBase::WindowManager& parWindowManager) : WindowBase("openmw_trade_window.layout", parWindowManager) - , ReferenceInterface(NULL) // no drag&drop + , ContainerBase(NULL) // no drag&drop , mCurrentBalance(0) { MyGUI::ScrollView* itemView; diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index 7ca3a97b4..4ec55045c 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -20,7 +20,7 @@ namespace MWGui namespace MWGui { - class TradeWindow : public ReferenceInterface, public WindowBase + class TradeWindow : public ContainerBase, public WindowBase { public: TradeWindow(MWBase::WindowManager& parWindowManager); diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index f561a2c99..674517ace 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -23,8 +23,7 @@ namespace MWGui const int TravelWindow::sLineHeight = 18; TravelWindow::TravelWindow(MWBase::WindowManager& parWindowManager) : - WindowBase("openmw_spell_buying_window.layout", parWindowManager) - , ContainerBase(NULL) // no drag&drop + WindowBase("openmw_travel_window.layout", parWindowManager) , mCurrentY(0) , mLastPos(0) { @@ -33,8 +32,8 @@ namespace MWGui getWidget(mCancelButton, "CancelButton"); getWidget(mPlayerGold, "PlayerGold"); getWidget(mSelect, "Select"); - getWidget(mDestinations, "Spells"); - getWidget(mDestinationsView, "SpellsView"); + getWidget(mDestinations, "Travel"); + getWidget(mDestinationsView, "DestinationsView"); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onCancelButtonClicked); @@ -61,8 +60,8 @@ namespace MWGui toAdd->setCaptionWithReplacing(travelId+" - "+boost::lexical_cast(price)+"#{sgp}"); toAdd->setSize(toAdd->getTextSize().width,sLineHeight); toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel); - toAdd->setUserString("ToolTipType", "Spell"); - toAdd->setUserString("Spell", travelId); + //toAdd->setUserString("ToolTipType", "Spell"); + toAdd->setUserString("Destination", travelId); toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onTravelButtonClick); mDestinationsWidgetMap.insert(std::make_pair (toAdd, travelId)); } @@ -111,12 +110,13 @@ namespace MWGui } updateLabels(); - mPtr.get()->base->mTransport[0]. + //mPtr.get()->base->mTransport[0]. mDestinationsView->setCanvasSize (MyGUI::IntSize(mDestinationsView->getWidth(), std::max(mDestinationsView->getHeight(), mCurrentY))); } void TravelWindow::onTravelButtonClick(MyGUI::Widget* _sender) { + std::cout << "traveling to:" << _sender->getUserString("Destination"); /*int price = *_sender->getUserData(); if (mWindowManager.getInventoryWindow()->getPlayerGold()>=price) diff --git a/apps/openmw/mwgui/travelwindow.hpp b/apps/openmw/mwgui/travelwindow.hpp index 07a516ce8..66360b05b 100644 --- a/apps/openmw/mwgui/travelwindow.hpp +++ b/apps/openmw/mwgui/travelwindow.hpp @@ -20,7 +20,7 @@ namespace MWGui namespace MWGui { - class TravelWindow : public ContainerBase, public WindowBase + class TravelWindow : public ReferenceInterface, public WindowBase { public: TravelWindow(MWBase::WindowManager& parWindowManager); @@ -35,8 +35,6 @@ namespace MWGui MyGUI::ScrollView* mDestinationsView; - MWWorld::Ptr mActor; - std::map mDestinationsWidgetMap; void onCancelButtonClicked(MyGUI::Widget* _sender); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 5f76e76cf..7054b6ba8 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -376,6 +376,7 @@ void WindowManager::updateVisible() break; case GM_Travel: mTravelWindow->setVisible(true); + break; case GM_SpellCreation: mSpellCreationDialog->setVisible(true); break; diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index a33d59ef6..2135df348 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -78,6 +78,7 @@ set(MYGUI_FILES openmw_spellcreation_dialog.layout openmw_edit_effect.layout openmw_enchanting_dialog.layout + openmw_travel_window.layout smallbars.png VeraMono.ttf markers.png From 1f4de03613841da56b28d265516626a4d01756fb Mon Sep 17 00:00:00 2001 From: gugus Date: Sat, 6 Oct 2012 22:33:10 +0200 Subject: [PATCH 12/45] oooups --- files/mygui/openmw_travel_window.layout | 35 +++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 files/mygui/openmw_travel_window.layout diff --git a/files/mygui/openmw_travel_window.layout b/files/mygui/openmw_travel_window.layout new file mode 100644 index 000000000..07a6daf48 --- /dev/null +++ b/files/mygui/openmw_travel_window.layout @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 5a611b66d76669b1d564601fc568d071d1f3af5c Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 8 Oct 2012 11:14:22 +0200 Subject: [PATCH 13/45] traveling. --- apps/openmw/mwgui/travelwindow.cpp | 38 ++++++++++++++++++++---------- apps/openmw/mwgui/travelwindow.hpp | 2 +- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 674517ace..7414b148a 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -47,7 +47,7 @@ namespace MWGui mSelect->getHeight()); } - void TravelWindow::addDestination(const std::string& travelId) + void TravelWindow::addDestination(const std::string& travelId,ESM::Position pos,bool interior) { //std::cout << "travel to" << travelId; /*const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); @@ -56,12 +56,17 @@ namespace MWGui MyGUI::Button* toAdd = mDestinationsView->createWidget((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SpellText", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); mCurrentY += sLineHeight; /// \todo price adjustment depending on merchantile skill - toAdd->setUserData(price); + std::ostringstream oss; + oss << price; + toAdd->setUserString("price",oss.str()); + if(interior) toAdd->setUserString("interior","y"); + else toAdd->setUserString("interior","n"); toAdd->setCaptionWithReplacing(travelId+" - "+boost::lexical_cast(price)+"#{sgp}"); toAdd->setSize(toAdd->getTextSize().width,sLineHeight); toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel); //toAdd->setUserString("ToolTipType", "Spell"); toAdd->setUserString("Destination", travelId); + toAdd->setUserData(pos); toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onTravelButtonClick); mDestinationsWidgetMap.insert(std::make_pair (toAdd, travelId)); } @@ -102,11 +107,12 @@ namespace MWGui for(int i = 0;i()->base->mTransport.size();i++) { std::string cellname = mPtr.get()->base->mTransport[i].mCellName; + bool interior = true; int x,y; MWBase::Environment::get().getWorld()->positionToIndex(mPtr.get()->base->mTransport[i].mPos.pos[0], mPtr.get()->base->mTransport[i].mPos.pos[1],x,y); - if(cellname == "") cellname = MWBase::Environment::get().getWorld()->getExterior(x,y)->cell->name; - addDestination(cellname); + if(cellname == "") {cellname = MWBase::Environment::get().getWorld()->getExterior(x,y)->cell->name; interior= false;} + addDestination(cellname,mPtr.get()->base->mTransport[i].mPos,interior); } updateLabels(); @@ -117,19 +123,25 @@ namespace MWGui void TravelWindow::onTravelButtonClick(MyGUI::Widget* _sender) { std::cout << "traveling to:" << _sender->getUserString("Destination"); - /*int price = *_sender->getUserData(); + std::istringstream iss(_sender->getUserString("price")); + int price; + iss >> price; if (mWindowManager.getInventoryWindow()->getPlayerGold()>=price) { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); - MWMechanics::Spells& spells = stats.getSpells(); - spells.add (mSpellsWidgetMap.find(_sender)->second); - mWindowManager.getTradeWindow()->addOrRemoveGold(-price); - startSpellBuying(mPtr); - - MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); - }*/ + ESM::Position pos = *_sender->getUserData(); + std::string cellname = _sender->getUserString("Destination"); + int x,y; + bool interior = _sender->getUserString("interior") == "y"; + MWBase::Environment::get().getWorld()->positionToIndex(pos.pos[0],pos.pos[1],x,y); + MWWorld::CellStore* cell; + if(interior) cell = MWBase::Environment::get().getWorld()->getInterior(cellname); + else cell = MWBase::Environment::get().getWorld()->getExterior(x,y); + MWBase::Environment::get().getWorld()->moveObject(player,*cell,pos.pos[0],pos.pos[1],pos.pos[2]); + mWindowManager.removeGuiMode(GM_Travel); + mWindowManager.removeGuiMode(GM_Dialogue); + } } void TravelWindow::onCancelButtonClicked(MyGUI::Widget* _sender) diff --git a/apps/openmw/mwgui/travelwindow.hpp b/apps/openmw/mwgui/travelwindow.hpp index 66360b05b..cc3d6a31f 100644 --- a/apps/openmw/mwgui/travelwindow.hpp +++ b/apps/openmw/mwgui/travelwindow.hpp @@ -40,7 +40,7 @@ namespace MWGui void onCancelButtonClicked(MyGUI::Widget* _sender); void onTravelButtonClick(MyGUI::Widget* _sender); void onMouseWheel(MyGUI::Widget* _sender, int _rel); - void addDestination(const std::string& destinationID); + void addDestination(const std::string& destinationID,ESM::Position pos,bool interior); void clearDestinations(); int mLastPos,mCurrentY; From 27a3487d78499876ee0e91449c1f91b7330c8470 Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 8 Oct 2012 15:51:36 +0200 Subject: [PATCH 14/45] right prices --- apps/openmw/mwgui/travelwindow.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 7414b148a..c2eb33c6c 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -56,11 +56,23 @@ namespace MWGui MyGUI::Button* toAdd = mDestinationsView->createWidget((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SpellText", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); mCurrentY += sLineHeight; /// \todo price adjustment depending on merchantile skill + if(interior) + { + toAdd->setUserString("interior","y"); + price = MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fMagesGuildTravel")->getFloat(); + } + else + { + toAdd->setUserString("interior","n"); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + ESM::Position PlayerPos = player.getRefData().getPosition(); + float d = sqrt( pow(pos.pos[0] - PlayerPos.pos[0],2) + pow(pos.pos[1] - PlayerPos.pos[1],2) + pow(pos.pos[2] - PlayerPos.pos[2],2) ); + price = d/MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fTravelMult")->getFloat(); + } std::ostringstream oss; oss << price; toAdd->setUserString("price",oss.str()); - if(interior) toAdd->setUserString("interior","y"); - else toAdd->setUserString("interior","n"); + toAdd->setCaptionWithReplacing(travelId+" - "+boost::lexical_cast(price)+"#{sgp}"); toAdd->setSize(toAdd->getTextSize().width,sLineHeight); toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel); From 57f3b50dc8fe93cf13bfa7ab0b0465bd88450815 Mon Sep 17 00:00:00 2001 From: cfcohen Date: Tue, 9 Oct 2012 01:33:47 -0400 Subject: [PATCH 15/45] Add more detail to ESMTool record dumping. --- apps/esmtool/esmtool.cpp | 32 +- apps/esmtool/record.cpp | 625 ++++++++++++++++++++++++++++++++++++--- apps/esmtool/record.hpp | 6 +- 3 files changed, 618 insertions(+), 45 deletions(-) diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index 88709f58b..944bc7d8c 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -57,6 +57,8 @@ struct Arguments std::string encoding; std::string filename; std::string outname; + + std::vector types; ESMData data; ESM::ESMReader reader; @@ -71,6 +73,8 @@ bool parseOptions (int argc, char** argv, Arguments &info) ("help,h", "print help message.") ("version,v", "print version information and quit.") ("raw,r", "Show an unformattet list of all records and subrecords.") + ("type,t", bpo::value< std::vector >(), + "Show only records of this type.") ("quiet,q", "Supress all record information. Useful for speed tests.") ("loadcells,C", "Browse through contents of all cells.") @@ -122,6 +126,9 @@ bool parseOptions (int argc, char** argv, Arguments &info) return false; } + if (variables.count("type") > 0) + info.types = variables["type"].as< std::vector >(); + info.mode = variables["mode"].as(); if (!(info.mode == "dump" || info.mode == "clone" || info.mode == "comp")) { @@ -306,14 +313,23 @@ int load(Arguments& info) uint32_t flags; esm.getRecHeader(flags); + // Is the user interested in this record type? + bool interested = true; + if (info.types.size() > 0) + { + std::vector::iterator match; + match = std::find(info.types.begin(), info.types.end(), + n.toString()); + if (match == info.types.end()) interested = false; + } + std::string id = esm.getHNOString("NAME"); - if(!quiet) + if(!quiet && interested) std::cout << "\nRecord: " << n.toString() << " '" << id << "'\n"; - EsmTool::RecordBase *record = - EsmTool::RecordBase::create(n.val); + EsmTool::RecordBase *record = EsmTool::RecordBase::create(n); if (record == 0) { if (std::find(skipped.begin(), skipped.end(), n.val) == skipped.end()) @@ -326,18 +342,16 @@ int load(Arguments& info) if (quiet) break; std::cout << " Skipping\n"; } else { - if (record->getType() == ESM::REC_GMST) { + if (record->getType().val == ESM::REC_GMST) { // preset id for GameSetting record record->cast()->get().mId = id; } record->setId(id); record->setFlags((int) flags); record->load(esm); - if (!quiet) { - record->print(); - } + if (!quiet && interested) record->print(); - if (record->getType() == ESM::REC_CELL && loadCells) { + if (record->getType().val == ESM::REC_CELL && loadCells) { loadCell(record->cast()->get(), esm, info); } @@ -434,7 +448,7 @@ int clone(Arguments& info) { EsmTool::RecordBase *record = *it; - name.val = record->getType(); + name.val = record->getType().val; esm.startRecord(name.toString(), record->getFlags()); diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index 9609e5242..38615b240 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -1,15 +1,64 @@ #include "record.hpp" #include +#include + +void printAIPackage(ESM::AIPackage p) +{ + if (p.mType == ESM::AI_Wander) + { + std::cout << " AIType Wander:" << std::endl; + std::cout << " Distance: " << p.mWander.mDistance << std::endl; + std::cout << " Duration: " << p.mWander.mDuration << std::endl; + std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl; + if (p.mWander.mUnk != 1) + std::cout << " Unknown: " << (int)p.mWander.mUnk << std::endl; + + std::cout << " Idle: "; + for (int i = 0; i != 8; i++) + std::cout << (int)p.mWander.mIdle[i] << " "; + std::cout << std::endl; + } + else if (p.mType == ESM::AI_Travel) + { + std::cout << " AIType Travel:" << std::endl; + std::cout << " Travel Coordinates: (" << p.mTravel.mX << "," + << p.mTravel.mY << "," << p.mTravel.mZ << ")" << std::endl; + std::cout << " Travel Unknown: " << (int)p.mTravel.mUnk << std::endl; + } + else if (p.mType == ESM::AI_Follow || p.mType == ESM::AI_Escort) + { + if (p.mType == ESM::AI_Follow) std::cout << " AIType Follow:" << std::endl; + else std::cout << " AIType Escort:" << std::endl; + + std::cout << " Follow Coordinates: (" << p.mTarget.mX << "," + << p.mTarget.mY << "," << p.mTarget.mZ << ")" << std::endl; + std::cout << " Duration: " << p.mTarget.mDuration << std::endl; + std::cout << " Target ID: " << p.mTarget.mId.toString() << std::endl; + std::cout << " Unknown: " << (int)p.mTarget.mUnk << std::endl; + } + else if (p.mType == ESM::AI_Activate) + { + std::cout << " AIType Activate:" << std::endl; + std::cout << " Name: " << p.mActivate.mName.toString() << std::endl; + std::cout << " Activate Unknown: " << (int)p.mActivate.mUnk << std::endl; + } + else { + std::cout << " BadPackage: " << boost::format("0x%08x") % p.mType << std::endl; + } + + if (p.mCellName != "") + std::cout << " Cell Name: " << p.mCellName << std::endl; +} namespace EsmTool { RecordBase * -RecordBase::create(int type) +RecordBase::create(ESM::NAME type) { RecordBase *record = 0; - switch (type) { + switch (type.val) { case ESM::REC_ACTI: { record = new EsmTool::Record; @@ -233,7 +282,7 @@ template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Mesh: " << mData.mModel << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Script: " << mData.mScript << std::endl; } @@ -241,38 +290,75 @@ template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " AutoCalc: " << mData.mData.mAutoCalc << std::endl; + // mEffects missing } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Mesh: " << mData.mModel << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; - std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Enchantment: " << mData.mEnchant << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + if (mData.mEnchant != "") + std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Type: " << mData.mData.mType << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Health: " << mData.mData.mHealth << std::endl; + std::cout << " Armor: " << mData.mData.mArmor << std::endl; + std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; + // mParts missing } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Quality: " << mData.mData.mQuality << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Mesh: " << mData.mModel << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Type: " << (int)mData.mData.mType << std::endl; + std::cout << " Flags: " << (int)mData.mData.mFlags << std::endl; + std::cout << " Part: " << (int)mData.mData.mPart << std::endl; + std::cout << " Vampire: " << (int)mData.mData.mVampire << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Mesh: " << mData.mModel << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + if (mData.mEnchant != "") + std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " IsScroll: " << mData.mData.mIsScroll << std::endl; + std::cout << " SkillID: " << mData.mData.mSkillID << std::endl; + std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; + // mText missing } template<> @@ -281,13 +367,38 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Texture: " << mData.mTexture << std::endl; std::cout << " Description: " << mData.mDescription << std::endl; + std::vector::iterator pit; + for (pit = mData.mPowers.mList.begin(); pit != mData.mPowers.mList.end(); pit++) + std::cout << " Power: " << *pit << std::endl; } template<> void Record::print() { - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Region: " << mData.mRegion << std::endl; + // None of the cells have names... + if (mData.mName != "") + std::cout << " Name: " << mData.mName << std::endl; + if (mData.mRegion != "") + std::cout << " Region: " << mData.mRegion << std::endl; + std::cout << " Flags: " << (int)mData.mData.mFlags << std::endl; + + std::cout << " Coordinates: " << " (" << mData.getGridX() << "," + << mData.getGridY() << ")" << std::endl; + + if (mData.mData.mFlags & ESM::Cell::Interior && + !(mData.mData.mFlags & ESM::Cell::QuasiEx)) + { + std::cout << " Ambient Light Color: " << mData.mAmbi.mAmbient << std::endl; + std::cout << " Sunlight Color: " << mData.mAmbi.mSunlight << std::endl; + std::cout << " Fog Color: " << mData.mAmbi.mFog << std::endl; + std::cout << " Fog Density: " << mData.mAmbi.mFogDensity << std::endl; + std::cout << " Water Level: " << mData.mWater << std::endl; + } + else + std::cout << " Map Color: " << boost::format("0x%08X") % mData.mMapColor << std::endl; + std::cout << " Water Level Int: " << mData.mWaterInt << std::endl; + std::cout << " NAM0: " << mData.mNAM0 << std::endl; + } template<> @@ -295,37 +406,120 @@ void Record::print() { std::cout << " Name: " << mData.mName << std::endl; std::cout << " Description: " << mData.mDescription << std::endl; + std::cout << " Playable: " << mData.mData.mIsPlayable << std::endl; + std::cout << " AutoCalc: " << mData.mData.mCalc << std::endl; + std::cout << " Attribute1: " << mData.mData.mAttribute[0] << std::endl; + std::cout << " Attribute2: " << mData.mData.mAttribute[1] << std::endl; + std::cout << " Specialization: " << mData.mData.mSpecialization << std::endl; + for (int i = 0; i != 5; i++) + std::cout << " Major Skill: " << mData.mData.mSkills[i][0] << std::endl; + for (int i = 0; i != 5; i++) + std::cout << " Minor Skill: " << mData.mData.mSkills[i][1] << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + if (mData.mEnchant != "") + std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + // mEnchant also in CTDTstruct? } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Weight: " << mData.mWeight << std::endl; + // mInventory missing } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Original: " << mData.mOriginal << std::endl; + std::cout << " Scale: " << mData.mScale << std::endl; + + std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Level: " << mData.mData.mLevel << std::endl; + + std::cout << " Attributes:" << std::endl; + std::cout << " Strength: " << mData.mData.mStrength << std::endl; + std::cout << " Intelligence: " << mData.mData.mIntelligence << std::endl; + std::cout << " Willpower: " << mData.mData.mWillpower << std::endl; + std::cout << " Agility: " << mData.mData.mAgility << std::endl; + std::cout << " Speed: " << mData.mData.mSpeed << std::endl; + std::cout << " Endurance: " << mData.mData.mEndurance << std::endl; + std::cout << " Personality: " << mData.mData.mPersonality << std::endl; + std::cout << " Luck: " << mData.mData.mLuck << std::endl; + + std::cout << " Health: " << mData.mData.mHealth << std::endl; + std::cout << " Magicka: " << mData.mData.mMana << std::endl; + std::cout << " Fatigue: " << mData.mData.mFatigue << std::endl; + std::cout << " Soul: " << mData.mData.mSoul << std::endl; + std::cout << " Combat: " << mData.mData.mCombat << std::endl; + std::cout << " Magic: " << mData.mData.mMagic << std::endl; + std::cout << " Stealth: " << mData.mData.mStealth << std::endl; + std::cout << " Attack1: " << mData.mData.mAttack[0] + << "-" << mData.mData.mAttack[1] << std::endl; + std::cout << " Attack2: " << mData.mData.mAttack[2] + << "-" << mData.mData.mAttack[3] << std::endl; + std::cout << " Attack3: " << mData.mData.mAttack[4] + << "-" << mData.mData.mAttack[5] << std::endl; + std::cout << " Gold: " << mData.mData.mGold << std::endl; + + std::vector::iterator cit; + for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++) + std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount + << " Item: " << cit->mItem.toString() << std::endl; + + std::vector::iterator sit; + for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); sit++) + std::cout << " Spell: " << *sit << std::endl; + + std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl; + std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; + std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl; + std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl; + std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl; + std::cout << " AI U1:" << (int)mData.mAiData.mU1 << std::endl; + std::cout << " AI U2:" << (int)mData.mAiData.mU2 << std::endl; + std::cout << " AI U3:" << (int)mData.mAiData.mU3 << std::endl; + std::cout << " AI U4:" << (int)mData.mAiData.mU4 << std::endl; + std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl; + + std::vector::iterator pit; + for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); pit++) + printAIPackage(*pit); } template<> void Record::print() { - // nothing to print + std::cout << " Type: " << (int)mData.mType << std::endl; + // mInfo missing } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Mesh: " << mData.mModel << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Script: " << mData.mScript << std::endl; std::cout << " OpenSound: " << mData.mOpenSound << std::endl; std::cout << " CloseSound: " << mData.mCloseSound << std::endl; @@ -334,22 +528,51 @@ void Record::print() template<> void Record::print() { - // nothing to print + std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Cost: " << mData.mData.mCost << std::endl; + std::cout << " Charge: " << mData.mData.mCharge << std::endl; + std::cout << " AutoCalc: " << mData.mData.mAutocalc << std::endl; + // mEffects missing } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Attr1: " << mData.mData.mAttribute1 << std::endl; - std::cout << " Attr2: " << mData.mData.mAttribute2 << std::endl; std::cout << " Hidden: " << mData.mData.mIsHidden << std::endl; + if (mData.mData.mUnknown != -1) + std::cout << " Unknown: " << mData.mData.mUnknown << std::endl; + std::cout << " Attribute1: " << mData.mData.mAttribute1 << std::endl; + std::cout << " Attribute2: " << mData.mData.mAttribute2 << std::endl; + for (int i = 0; i != 6; i++) + if (mData.mData.mSkillID[i] != -1) + std::cout << " Skill: " << mData.mData.mSkillID[i] << std::endl; + for (int i = 0; i != 10; i++) + if (mData.mRanks[i] != "") + { + std::cout << " Rank: " << mData.mRanks[i] << std::endl; + std::cout << " Attribute1 Requirement: " + << mData.mData.mRankData[i].mAttribute1 << std::endl; + std::cout << " Attribute2 Requirement: " + << mData.mData.mRankData[i].mAttribute2 << std::endl; + std::cout << " One Skill at Level: " + << mData.mData.mRankData[i].mSkill1 << std::endl; + std::cout << " Two Skills at Level: " + << mData.mData.mRankData[i].mSkill2 << std::endl; + std::cout << " Faction Reaction: " + << mData.mData.mRankData[i].mFactReaction << std::endl; + } + std::vector::iterator rit; + for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); rit++) + std::cout << " Reaction: " << rit->mReaction << " = " << rit->mFaction << std::endl; } template<> void Record::print() { - // nothing to print + // nothing to print (well, nothing that's correct anyway) + std::cout << " Type: " << mData.mType << std::endl; + std::cout << " Value: " << mData.mValue << std::endl; } template<> @@ -380,67 +603,130 @@ void Record::print() { std::cout << " Id: " << mData.mId << std::endl; std::cout << " Text: " << mData.mResponse << std::endl; + // Lots missing, more coming } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; + for (int i = 0; i !=4; i++) + { + // A value of -1 means no effect + if (mData.mData.mEffectID[i] == -1) continue; + std::cout << " Effect: " << mData.mData.mEffectID[i] << std::endl; + std::cout << " Skill: " << mData.mData.mSkills[i] << std::endl; + std::cout << " Attribute: " << mData.mData.mAttributes[i] << std::endl; + } } template<> void Record::print() { - std::cout << " Coords: [" << mData.mX << "," << mData.mY << "]" << std::endl; + std::cout << " Coordinates: (" << mData.mX << "," << mData.mY << ")" << std::endl; + // Lots missing, more coming } template<> void Record::print() { + std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; + std::cout << " Flags: " << mData.mFlags << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl; + std::vector::iterator iit; + for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) + std::cout << " Creature: Level: " << iit->mLevel + << " Creature: " << iit->mId << std::endl; } template<> void Record::print() { + std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; + std::cout << " Flags: " << mData.mFlags << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl; + std::vector::iterator iit; + for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) + std::cout << " Inventory: Count: " << iit->mLevel + << " Item: " << iit->mId << std::endl; } template<> void Record::print() { - std::cout << " Name: " << mData.mName << std::endl; + if (mData.mName != "") + std::cout << " Name: " << mData.mName << std::endl; + if (mData.mModel != "") + std::cout << " Model: " << mData.mModel << std::endl; + if (mData.mIcon != "") + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Flags: " << mData.mData.mFlags << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Sound: " << mData.mSound << std::endl; + std::cout << " Duration: " << mData.mData.mTime << std::endl; + std::cout << " Radius: " << mData.mData.mRadius << std::endl; + std::cout << " Color: " << mData.mData.mColor << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Type: " << mData.mType << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Quality: " << mData.mData.mQuality << std::endl; + std::cout << " Uses: " << mData.mData.mUses << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Type: " << mData.mType << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Quality: " << mData.mData.mQuality << std::endl; + std::cout << " Uses: " << mData.mData.mUses << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Type: " << mData.mType << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Quality: " << mData.mData.mQuality << std::endl; + std::cout << " Uses: " << mData.mData.mUses << std::endl; } template<> void Record::print() { std::cout << " Id: " << mData.mId << std::endl; + std::cout << " Index: " << mData.mIndex << std::endl; std::cout << " Texture: " << mData.mTexture << std::endl; } @@ -448,53 +734,294 @@ template<> void Record::print() { std::cout << " Index: " << mData.mIndex << std::endl; - - const char *text = "Positive"; - if (mData.mData.mFlags & ESM::MagicEffect::Negative) { - text = "Negative"; - } - std::cout << " " << text << std::endl; + std::cout << " Description: " << mData.mDescription << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Particle Texture: " << mData.mParticle << std::endl; + if (mData.mCasting != "") + std::cout << " Casting Static: " << mData.mCasting << std::endl; + if (mData.mCastSound != "") + std::cout << " Casting Sound: " << mData.mCastSound << std::endl; + if (mData.mBolt != "") + std::cout << " Bolt Static: " << mData.mBolt << std::endl; + if (mData.mBoltSound != "") + std::cout << " Bolt Sound: " << mData.mBoltSound << std::endl; + if (mData.mHit != "") + std::cout << " Hit Static: " << mData.mHit << std::endl; + if (mData.mHitSound != "") + std::cout << " Hit Sound: " << mData.mHitSound << std::endl; + if (mData.mArea != "") + std::cout << " Area Static: " << mData.mArea << std::endl; + if (mData.mAreaSound != "") + std::cout << " Area Sound: " << mData.mAreaSound << std::endl; + std::cout << " School: " << mData.mData.mSchool << std::endl; + std::cout << " Base Cost: " << mData.mData.mBaseCost << std::endl; + std::cout << " Speed: " << mData.mData.mSpeed << std::endl; + std::cout << " Size: " << mData.mData.mSize << std::endl; + std::cout << " Size Cap: " << mData.mData.mSizeCap << std::endl; + std::cout << " RGB Color: " << "(" + << mData.mData.mRed << "," + << mData.mData.mGreen << "," + << mData.mData.mGreen << ")" << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Is Key: " << mData.mData.mIsKey << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Animation: " << mData.mModel << std::endl; + std::cout << " Hair Model: " << mData.mHair << std::endl; + std::cout << " Head Model: " << mData.mHead << std::endl; std::cout << " Race: " << mData.mRace << std::endl; + std::cout << " Class: " << mData.mClass << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + if (mData.mFaction != "") + std::cout << " Faction: " << mData.mFaction << std::endl; + std::cout << " Flags: " << mData.mFlags << std::endl; + + // Seriously? + if (mData.mNpdt52.mGold == -10) + { + std::cout << " Level: " << mData.mNpdt12.mLevel << std::endl; + std::cout << " Reputation: " << (int)mData.mNpdt12.mReputation << std::endl; + std::cout << " Disposition: " << (int)mData.mNpdt12.mDisposition << std::endl; + std::cout << " Faction: " << (int)mData.mNpdt52.mFactionID << std::endl; + std::cout << " Rank: " << (int)mData.mNpdt12.mRank << std::endl; + std::cout << " Unknown1: " + << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown1) << std::endl; + std::cout << " Unknown2: " + << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl; + std::cout << " Unknown3: " + << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl; + std::cout << " Gold: " << (int)mData.mNpdt12.mGold << std::endl; + } + else { + std::cout << " Level: " << mData.mNpdt52.mLevel << std::endl; + std::cout << " Reputation: " << (int)mData.mNpdt52.mReputation << std::endl; + std::cout << " Disposition: " << (int)mData.mNpdt52.mDisposition << std::endl; + std::cout << " Rank: " << (int)mData.mNpdt52.mRank << std::endl; + + std::cout << " Attributes:" << std::endl; + std::cout << " Strength: " << (int)mData.mNpdt52.mStrength << std::endl; + std::cout << " Intelligence: " << (int)mData.mNpdt52.mIntelligence << std::endl; + std::cout << " Willpower: " << (int)mData.mNpdt52.mWillpower << std::endl; + std::cout << " Agility: " << (int)mData.mNpdt52.mAgility << std::endl; + std::cout << " Speed: " << (int)mData.mNpdt52.mSpeed << std::endl; + std::cout << " Endurance: " << (int)mData.mNpdt52.mEndurance << std::endl; + std::cout << " Personality: " << (int)mData.mNpdt52.mPersonality << std::endl; + std::cout << " Luck: " << (int)mData.mNpdt52.mLuck << std::endl; + + std::cout << " Skills:" << std::endl; + for (int i = 0; i != 27; i++) + std::cout << " " << i << " = " + << (int)((unsigned char)mData.mNpdt52.mSkills[i]) << std::endl; + + std::cout << " Health: " << mData.mNpdt52.mHealth << std::endl; + std::cout << " Magicka: " << mData.mNpdt52.mMana << std::endl; + std::cout << " Fatigue: " << mData.mNpdt52.mFatigue << std::endl; + std::cout << " Unknown: " << (int)mData.mNpdt52.mUnknown << std::endl; + std::cout << " Gold: " << mData.mNpdt52.mGold << std::endl; + } + + std::vector::iterator cit; + for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++) + std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount + << " Item: " << cit->mItem.toString() << std::endl; + + std::vector::iterator sit; + for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); sit++) + std::cout << " Spell: " << *sit << std::endl; + + std::vector::iterator dit; + for (dit = mData.mTransport.begin(); dit != mData.mTransport.end(); dit++) + { + std::cout << " Destination Position: " + << boost::format("%12.3f") % dit->mPos.pos[0] << "," + << boost::format("%12.3f") % dit->mPos.pos[1] << "," + << boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl; + std::cout << " Destination Rotation: " + << boost::format("%9.6f") % dit->mPos.rot[0] << "," + << boost::format("%9.6f") % dit->mPos.rot[1] << "," + << boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl; + if (dit->mCellName != "") + std::cout << " Destination Cell: " << dit->mCellName << std::endl; + } + + std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl; + std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; + std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl; + std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl; + std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl; + std::cout << " AI U1:" << (int)mData.mAiData.mU1 << std::endl; + std::cout << " AI U2:" << (int)mData.mAiData.mU2 << std::endl; + std::cout << " AI U3:" << (int)mData.mAiData.mU3 << std::endl; + std::cout << " AI U4:" << (int)mData.mAiData.mU4 << std::endl; + std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl; + + std::vector::iterator pit; + for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); pit++) + printAIPackage(*pit); } template<> void Record::print() { std::cout << " Cell: " << mData.mCell << std::endl; - std::cout << " Point count: " << mData.mPoints.size() << std::endl; - std::cout << " Edge count: " << mData.mEdges.size() << std::endl; + std::cout << " Coordinates: (" << mData.mData.mX << "," << mData.mData.mY << ")" << std::endl; + std::cout << " Unknown S1: " << mData.mData.mS1 << std::endl; + if ((unsigned int)mData.mData.mS2 != mData.mPoints.size()) + std::cout << " Reported Point Count: " << mData.mData.mS2 << std::endl; + std::cout << " Point Count: " << mData.mPoints.size() << std::endl; + std::cout << " Edge Count: " << mData.mEdges.size() << std::endl; + + int i = 0; + ESM::Pathgrid::PointList::iterator pit; + for (pit = mData.mPoints.begin(); pit != mData.mPoints.end(); pit++) + { + std::cout << " Point[" << i << "]:" << std::endl; + std::cout << " Coordinates: (" << pit->mX << "," + << pit->mY << "," << pit->mZ << ")" << std::endl; + std::cout << " Auto-Generated: " << (int)pit->mAutogenerated << std::endl; + std::cout << " Connections: " << (int)pit->mConnectionNum << std::endl; + std::cout << " Unknown: " << pit->mUnknown << std::endl; + i++; + } + i = 0; + ESM::Pathgrid::EdgeList::iterator eit; + for (eit = mData.mEdges.begin(); eit != mData.mEdges.end(); eit++) + { + std::cout << " Edge[" << i << "]: " << eit->mV0 << " -> " << eit->mV1 << std::endl; + if (eit->mV0 >= mData.mData.mS2 || eit->mV1 >= mData.mData.mS2) + std::cout << " BAD POINT IN EDGE!" << std::endl; + i++; + } } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Length: " << mData.mData.mHeight.mMale << "m " << mData.mData.mHeight.mFemale << "f" << std::endl; + std::cout << " Description: " << mData.mDescription << std::endl; + std::cout << " Flags: " << mData.mData.mFlags << std::endl; + + std::cout << " Male:" << std::endl; + std::cout << " Strength: " + << mData.mData.mStrength.mMale << std::endl; + std::cout << " Intelligence: " + << mData.mData.mIntelligence.mMale << std::endl; + std::cout << " Willpower: " + << mData.mData.mWillpower.mMale << std::endl; + std::cout << " Agility: " + << mData.mData.mAgility.mMale << std::endl; + std::cout << " Speed: " + << mData.mData.mSpeed.mMale << std::endl; + std::cout << " Endurance: " + << mData.mData.mEndurance.mMale << std::endl; + std::cout << " Personality: " + << mData.mData.mPersonality.mMale << std::endl; + std::cout << " Luck: " + << mData.mData.mLuck.mMale << std::endl; + std::cout << " Height: " + << mData.mData.mHeight.mMale << std::endl; + std::cout << " Weight: " + << mData.mData.mWeight.mMale << std::endl; + + std::cout << " Female:" << std::endl; + std::cout << " Strength: " + << mData.mData.mStrength.mFemale << std::endl; + std::cout << " Intelligence: " + << mData.mData.mIntelligence.mFemale << std::endl; + std::cout << " Willpower: " + << mData.mData.mWillpower.mFemale << std::endl; + std::cout << " Agility: " + << mData.mData.mAgility.mFemale << std::endl; + std::cout << " Speed: " + << mData.mData.mSpeed.mFemale << std::endl; + std::cout << " Endurance: " + << mData.mData.mEndurance.mFemale << std::endl; + std::cout << " Personality: " + << mData.mData.mPersonality.mFemale << std::endl; + std::cout << " Luck: " + << mData.mData.mLuck.mFemale << std::endl; + std::cout << " Height: " + << mData.mData.mHeight.mFemale << std::endl; + std::cout << " Weight: " + << mData.mData.mWeight.mFemale << std::endl; + + for (int i = 0; i != 7; i++) + // Not all races have 7 skills. + if (mData.mData.mBonus[i].mSkill != -1) + std::cout << " Skill: " << mData.mData.mBonus[i].mSkill + << " = " << mData.mData.mBonus[i].mBonus << std::endl; + + std::vector::iterator sit; + for (sit = mData.mPowers.mList.begin(); sit != mData.mPowers.mList.end(); sit++) + std::cout << " Power: " << *sit << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + + std::cout << " Weather:" << std::endl; + std::cout << " Clear: " << (int)mData.mData.mClear << std::endl; + std::cout << " Cloudy: " << (int)mData.mData.mCloudy << std::endl; + std::cout << " Foggy: " << (int)mData.mData.mFoggy << std::endl; + std::cout << " Overcast: " << (int)mData.mData.mOvercast << std::endl; + std::cout << " Rain: " << (int)mData.mData.mOvercast << std::endl; + std::cout << " Thunder: " << (int)mData.mData.mThunder << std::endl; + std::cout << " Ash: " << (int)mData.mData.mAsh << std::endl; + std::cout << " Blight: " << (int)mData.mData.mBlight << std::endl; + std::cout << " UnknownA: " << (int)mData.mData.mA << std::endl; + std::cout << " UnknownB: " << (int)mData.mData.mB << std::endl; + std::cout << " Map Color: " << mData.mMapColor << std::endl; + if (mData.mSleepList != "") + std::cout << " Sleep List: " << mData.mSleepList << std::endl; + std::vector::iterator sit; + for (sit = mData.mSoundList.begin(); sit != mData.mSoundList.end(); sit++) + std::cout << " Sound: " << (int)sit->mChance << " = " << sit->mSound.toString() << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mData.mName.toString() << std::endl; + + std::cout << " Num Shorts: " << mData.mData.mNumShorts << std::endl; + std::cout << " Num Longs: " << mData.mData.mNumLongs << std::endl; + std::cout << " Num Floats: " << mData.mData.mNumFloats << std::endl; + std::cout << " Script Data Size: " << mData.mData.mScriptDataSize << std::endl; + std::cout << " Table Size: " << mData.mData.mStringTableSize << std::endl; + + std::cout << " Script: [skipped]" << std::endl; + // Skip until multi-line field is controllable by a command line option. + //std::cout << "-------------------------------------------" << std::endl; + //std::cout << s->scriptText << std::endl; + //std::cout << "-------------------------------------------" << std::endl; + std::vector::iterator vit; + for (vit = mData.mVarNames.begin(); vit != mData.mVarNames.end(); vit++) + std::cout << " Variable: " << *vit << std::endl; + + std::cout << " ByteCode: "; + std::vector::iterator cit; + for (cit = mData.mScriptData.begin(); cit != mData.mScriptData.end(); cit++) + std::cout << boost::format("%02X") % (int)(*cit); + std::cout << std::endl; } template<> @@ -519,25 +1046,34 @@ void Record::print() { std::cout << " Creature: " << mData.mCreature << std::endl; std::cout << " Sound: " << mData.mSound << std::endl; + std::cout << " Type: " << mData.mType << std::endl; } template<> void Record::print() { std::cout << " Sound: " << mData.mSound << std::endl; - std::cout << " Volume: " << mData.mData.mVolume << std::endl; + std::cout << " Volume: " << (int)mData.mData.mVolume << std::endl; + if (mData.mData.mMinRange != 0 && mData.mData.mMaxRange != 0) + std::cout << " Range: " << (int)mData.mData.mMinRange << " - " + << (int)mData.mData.mMaxRange << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Cost: " << mData.mData.mCost << std::endl; + // mEffect missing } template<> void Record::print() { - std::cout << "Start script: " << mData.mScript << std::endl; + std::cout << "Start Script: " << mData.mScript << std::endl; + std::cout << "Start Data: " << mData.mData << std::endl; } template<> @@ -549,11 +1085,34 @@ void Record::print() template<> void Record::print() { - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Chop: " << mData.mData.mChop[0] << "-" << mData.mData.mChop[1] << std::endl; - std::cout << " Slash: " << mData.mData.mSlash[0] << "-" << mData.mData.mSlash[1] << std::endl; - std::cout << " Thrust: " << mData.mData.mThrust[0] << "-" << mData.mData.mThrust[1] << std::endl; + // No names on VFX bolts + if (mData.mName != "") + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + // No icons on VFX bolts or magic bolts + if (mData.mIcon != "") + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + if (mData.mEnchant != "") + std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Health: " << mData.mData.mHealth << std::endl; + std::cout << " Speed: " << mData.mData.mSpeed << std::endl; + std::cout << " Reach: " << mData.mData.mReach << std::endl; + std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; + if (mData.mData.mChop[0] != 0 && mData.mData.mChop[1] != 0) + std::cout << " Chop: " << (int)mData.mData.mChop[0] << "-" + << (int)mData.mData.mChop[1] << std::endl; + if (mData.mData.mSlash[0] != 0 && mData.mData.mSlash[1] != 0) + std::cout << " Slash: " << (int)mData.mData.mSlash[0] << "-" + << (int)mData.mData.mSlash[1] << std::endl; + if (mData.mData.mThrust[0] != 0 && mData.mData.mThrust[1] != 0) + std::cout << " Thrust: " << (int)mData.mData.mThrust[0] << "-" + << (int)mData.mData.mThrust[1] << std::endl; } template<> diff --git a/apps/esmtool/record.hpp b/apps/esmtool/record.hpp index 3cd7f5b54..e75870ab6 100644 --- a/apps/esmtool/record.hpp +++ b/apps/esmtool/record.hpp @@ -20,7 +20,7 @@ namespace EsmTool protected: std::string mId; int mFlags; - int mType; + ESM::NAME mType; public: RecordBase () {} @@ -42,7 +42,7 @@ namespace EsmTool mFlags = flags; } - int getType() const { + ESM::NAME getType() const { return mType; } @@ -50,7 +50,7 @@ namespace EsmTool virtual void save(ESM::ESMWriter &esm) = 0; virtual void print() = 0; - static RecordBase *create(int type); + static RecordBase *create(ESM::NAME type); // just make it a bit shorter template From 35d099a63856bc37ce381388f2135066a4460836 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 9 Oct 2012 17:10:25 +0200 Subject: [PATCH 16/45] disabling gcc extensions --- CMakeLists.txt | 2 +- apps/launcher/pluginsview.hpp | 4 ++-- apps/mwiniimporter/importer.cpp | 8 ++++---- apps/openmw/main.cpp | 2 +- apps/openmw/mwbase/soundmanager.hpp | 2 +- apps/openmw/mwmechanics/drawstate.hpp | 2 +- apps/openmw/mwrender/globalmap.cpp | 4 ++-- apps/openmw/mwrender/water.hpp | 2 +- apps/openmw/mwscript/scriptmanagerimp.hpp | 2 +- apps/openmw/mwsound/mpgsnd_decoder.hpp | 2 +- apps/openmw/mwsound/openal_output.hpp | 2 +- apps/openmw/mwsound/soundmanagerimp.hpp | 2 +- components/esm/aipackage.hpp | 2 +- components/esm_store/reclists.hpp | 4 ++-- libs/openengine/bullet/CMotionState.cpp | 2 +- libs/openengine/bullet/physic.cpp | 2 +- 16 files changed, 22 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 614a840c4..b10562eef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -306,7 +306,7 @@ endif() # Compiler settings if (CMAKE_COMPILER_IS_GNUCC) - add_definitions (-Wall -Wextra -Wno-unused-parameter -Wno-reorder) + add_definitions (-Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++0x -pedantic) # Silence warnings in OGRE headers. Remove once OGRE got fixed! add_definitions (-Wno-ignored-qualifiers) diff --git a/apps/launcher/pluginsview.hpp b/apps/launcher/pluginsview.hpp index b3dfb79ff..484351e33 100644 --- a/apps/launcher/pluginsview.hpp +++ b/apps/launcher/pluginsview.hpp @@ -24,6 +24,6 @@ public slots: }; -Q_DECLARE_METATYPE(QVector); +Q_DECLARE_METATYPE(QVector) -#endif \ No newline at end of file +#endif diff --git a/apps/mwiniimporter/importer.cpp b/apps/mwiniimporter/importer.cpp index d396df648..19b69794f 100644 --- a/apps/mwiniimporter/importer.cpp +++ b/apps/mwiniimporter/importer.cpp @@ -78,7 +78,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(std::string filename) { multistrmap::iterator it; if((it = map.find(key)) == map.end()) { - map.insert( std::make_pair > (key, std::vector() ) ); + map.insert( std::make_pair (key, std::vector() ) ); } map[key].push_back(value); } @@ -115,7 +115,7 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(std::string filename) { multistrmap::iterator it; if((it = map.find(key)) == map.end()) { - map.insert( std::make_pair > (key, std::vector() ) ); + map.insert( std::make_pair (key, std::vector() ) ); } map[key].push_back(value); } @@ -152,12 +152,12 @@ void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) { } } } -}; +} void MwIniImporter::insertMultistrmap(multistrmap &cfg, std::string key, std::string value) { multistrmap::iterator it = cfg.find(key); if(it == cfg.end()) { - cfg.insert(std::make_pair >(key, std::vector() )); + cfg.insert(std::make_pair (key, std::vector() )); } cfg[key].push_back(value); } diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 5c2ba2f80..2da52311f 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -68,7 +68,7 @@ void validate(boost::any &v, std::vector const &tokens, FallbackMap if((mapIt = map->mMap.find(key)) == map->mMap.end()) { - map->mMap.insert(std::make_pair(key,value)); + map->mMap.insert(std::make_pair (key,value)); } } } diff --git a/apps/openmw/mwbase/soundmanager.hpp b/apps/openmw/mwbase/soundmanager.hpp index 745832583..92c177ff3 100644 --- a/apps/openmw/mwbase/soundmanager.hpp +++ b/apps/openmw/mwbase/soundmanager.hpp @@ -37,7 +37,7 @@ namespace MWBase Play_Normal = 0, /* tracked, non-looping, multi-instance, environment */ Play_Loop = 1<<0, /* Sound will continually loop until explicitly stopped */ Play_NoEnv = 1<<1, /* Do not apply environment effects (eg, underwater filters) */ - Play_NoTrack = 1<<2, /* (3D only) Play the sound at the given object's position + Play_NoTrack = 1<<2 /* (3D only) Play the sound at the given object's position * but do not keep it updated (the sound will not move with * the object and will not stop when the object is deleted. */ }; diff --git a/apps/openmw/mwmechanics/drawstate.hpp b/apps/openmw/mwmechanics/drawstate.hpp index 112b6e4f9..5be00505c 100644 --- a/apps/openmw/mwmechanics/drawstate.hpp +++ b/apps/openmw/mwmechanics/drawstate.hpp @@ -8,7 +8,7 @@ namespace MWMechanics { DrawState_Weapon = 0, DrawState_Spell = 1, - DrawState_Nothing = 2, + DrawState_Nothing = 2 }; } diff --git a/apps/openmw/mwrender/globalmap.cpp b/apps/openmw/mwrender/globalmap.cpp index c23fdc1a3..7a799a2e4 100644 --- a/apps/openmw/mwrender/globalmap.cpp +++ b/apps/openmw/mwrender/globalmap.cpp @@ -53,7 +53,7 @@ namespace MWRender { Ogre::Image image; - Ogre::uchar data[mWidth * mHeight * 3]; + std::vector data (mWidth * mHeight * 3); for (int x = mMinX; x <= mMaxX; ++x) { @@ -150,7 +150,7 @@ namespace MWRender } } - image.loadDynamicImage (data, mWidth, mHeight, Ogre::PF_B8G8R8); + image.loadDynamicImage (&data[0], mWidth, mHeight, Ogre::PF_B8G8R8); //image.save (mCacheDir + "/GlobalMap.png"); diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index dcb76533b..f1e3d7a3b 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -23,7 +23,7 @@ namespace Ogre class Entity; class Vector3; struct RenderTargetEvent; -}; +} namespace MWRender { diff --git a/apps/openmw/mwscript/scriptmanagerimp.hpp b/apps/openmw/mwscript/scriptmanagerimp.hpp index bacc232b2..a97310ae5 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.hpp +++ b/apps/openmw/mwscript/scriptmanagerimp.hpp @@ -74,6 +74,6 @@ namespace MWScript ///< Return index of the variable of the given name and type in the given script. Will /// throw an exception, if there is no such script or variable or the type does not match. }; -}; +} #endif diff --git a/apps/openmw/mwsound/mpgsnd_decoder.hpp b/apps/openmw/mwsound/mpgsnd_decoder.hpp index 870773edc..09082c2f4 100644 --- a/apps/openmw/mwsound/mpgsnd_decoder.hpp +++ b/apps/openmw/mwsound/mpgsnd_decoder.hpp @@ -52,6 +52,6 @@ namespace MWSound #ifndef DEFAULT_DECODER #define DEFAULT_DECODER (::MWSound::MpgSnd_Decoder) #endif -}; +} #endif diff --git a/apps/openmw/mwsound/openal_output.hpp b/apps/openmw/mwsound/openal_output.hpp index 90917c53c..fecffa575 100644 --- a/apps/openmw/mwsound/openal_output.hpp +++ b/apps/openmw/mwsound/openal_output.hpp @@ -66,6 +66,6 @@ namespace MWSound #ifndef DEFAULT_OUTPUT #define DEFAULT_OUTPUT (::MWSound::OpenAL_Output) #endif -}; +} #endif diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index f91e291ef..a84aa3b9a 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -26,7 +26,7 @@ namespace MWSound enum Environment { Env_Normal, - Env_Underwater, + Env_Underwater }; class SoundManager : public MWBase::SoundManager diff --git a/components/esm/aipackage.hpp b/components/esm/aipackage.hpp index 3046a6a98..8e55b6889 100644 --- a/components/esm/aipackage.hpp +++ b/components/esm/aipackage.hpp @@ -60,7 +60,7 @@ namespace ESM AI_Travel = 0x545f4941, AI_Follow = 0x465f4941, AI_Escort = 0x455f4941, - AI_Activate = 0x415f4941, + AI_Activate = 0x415f4941 }; /// \note Used for storaging packages in a single container diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index 24580a79c..0b265a566 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -331,7 +331,7 @@ namespace ESMS // Find land for the given coordinates. Return null if no mData. Land *search(int x, int y) const { - LandMap::const_iterator itr = lands.find(std::make_pair(x, y)); + LandMap::const_iterator itr = lands.find(std::make_pair (x, y)); if ( itr == lands.end() ) { return NULL; @@ -350,7 +350,7 @@ namespace ESMS land->load(esm); // Store the structure - lands[std::make_pair(land->mX, land->mY)] = land; + lands[std::make_pair (land->mX, land->mY)] = land; } }; diff --git a/libs/openengine/bullet/CMotionState.cpp b/libs/openengine/bullet/CMotionState.cpp index dc28d9e5f..6be615dfb 100644 --- a/libs/openengine/bullet/CMotionState.cpp +++ b/libs/openengine/bullet/CMotionState.cpp @@ -16,7 +16,7 @@ namespace Physic pEng = eng; tr.setIdentity(); pName = name; - }; + } void CMotionState::getWorldTransform(btTransform &worldTrans) const { diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index b42ffb84c..4f16a4143 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -626,4 +626,4 @@ namespace Physic shape->Shape->getAabb(trans, min, max); } -}}; +}} From 3fd887c030c4b4e9848356c1d4cb79645f457ee1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 9 Oct 2012 17:11:41 +0200 Subject: [PATCH 17/45] silenced some warnings --- components/esm/esmwriter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esm/esmwriter.cpp b/components/esm/esmwriter.cpp index 24658a40b..c1ae06490 100644 --- a/components/esm/esmwriter.cpp +++ b/components/esm/esmwriter.cpp @@ -138,11 +138,11 @@ void ESMWriter::writeHNString(const std::string& name, const std::string& data) void ESMWriter::writeHNString(const std::string& name, const std::string& data, int size) { - assert(data.size() <= size); + assert(static_cast (data.size()) <= size); startSubRecord(name); writeHString(data); - if (data.size() < size) + if (static_cast (data.size()) < size) { for (int i = data.size(); i < size; ++i) write("\0",1); From 50e259c060b3666c4d28e919474a3bbea14c922a Mon Sep 17 00:00:00 2001 From: cfcohen Date: Tue, 9 Oct 2012 19:41:45 -0400 Subject: [PATCH 18/45] Remove tabs as requested. Sorry about that, thought I already had. :-) I updated the help to better document the --type option, although I did not finish reasoning through it's interaction with the new loading framework. I also expanded the print() methods of a few more of the record types to make a more consistent commit. --- apps/esmtool/esmtool.cpp | 29 ++- apps/esmtool/record.cpp | 495 +++++++++++++++++++++++---------------- apps/esmtool/record.hpp | 4 +- 3 files changed, 317 insertions(+), 211 deletions(-) diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index 944bc7d8c..4f6d9dbfc 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -13,7 +13,7 @@ #include "record.hpp" -#define ESMTOOL_VERSION 1.1 +#define ESMTOOL_VERSION 1.2 // Create a local alias for brevity namespace bpo = boost::program_options; @@ -72,9 +72,12 @@ bool parseOptions (int argc, char** argv, Arguments &info) desc.add_options() ("help,h", "print help message.") ("version,v", "print version information and quit.") - ("raw,r", "Show an unformattet list of all records and subrecords.") - ("type,t", bpo::value< std::vector >(), - "Show only records of this type.") + ("raw,r", "Show an unformatted list of all records and subrecords.") + // The intention is that this option would interact better + // with other modes including clone, dump, and raw. + ("type,t", bpo::value< std::vector >(), + "Show only records of this type (four character record code). May " + "be specified multiple times. Only affects dump mode.") ("quiet,q", "Supress all record information. Useful for speed tests.") ("loadcells,C", "Browse through contents of all cells.") @@ -313,15 +316,15 @@ int load(Arguments& info) uint32_t flags; esm.getRecHeader(flags); - // Is the user interested in this record type? - bool interested = true; - if (info.types.size() > 0) - { - std::vector::iterator match; - match = std::find(info.types.begin(), info.types.end(), - n.toString()); - if (match == info.types.end()) interested = false; - } + // Is the user interested in this record type? + bool interested = true; + if (info.types.size() > 0) + { + std::vector::iterator match; + match = std::find(info.types.begin(), info.types.end(), + n.toString()); + if (match == info.types.end()) interested = false; + } std::string id = esm.getHNOString("NAME"); diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index 38615b240..c679a1c4d 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -12,18 +12,18 @@ void printAIPackage(ESM::AIPackage p) std::cout << " Duration: " << p.mWander.mDuration << std::endl; std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl; if (p.mWander.mUnk != 1) - std::cout << " Unknown: " << (int)p.mWander.mUnk << std::endl; + std::cout << " Unknown: " << (int)p.mWander.mUnk << std::endl; std::cout << " Idle: "; for (int i = 0; i != 8; i++) - std::cout << (int)p.mWander.mIdle[i] << " "; + std::cout << (int)p.mWander.mIdle[i] << " "; std::cout << std::endl; } else if (p.mType == ESM::AI_Travel) { std::cout << " AIType Travel:" << std::endl; std::cout << " Travel Coordinates: (" << p.mTravel.mX << "," - << p.mTravel.mY << "," << p.mTravel.mZ << ")" << std::endl; + << p.mTravel.mY << "," << p.mTravel.mZ << ")" << std::endl; std::cout << " Travel Unknown: " << (int)p.mTravel.mUnk << std::endl; } else if (p.mType == ESM::AI_Follow || p.mType == ESM::AI_Escort) @@ -32,7 +32,7 @@ void printAIPackage(ESM::AIPackage p) else std::cout << " AIType Escort:" << std::endl; std::cout << " Follow Coordinates: (" << p.mTarget.mX << "," - << p.mTarget.mY << "," << p.mTarget.mZ << ")" << std::endl; + << p.mTarget.mY << "," << p.mTarget.mZ << ")" << std::endl; std::cout << " Duration: " << p.mTarget.mDuration << std::endl; std::cout << " Target ID: " << p.mTarget.mId.toString() << std::endl; std::cout << " Unknown: " << (int)p.mTarget.mUnk << std::endl; @@ -51,6 +51,27 @@ void printAIPackage(ESM::AIPackage p) std::cout << " Cell Name: " << p.mCellName << std::endl; } +void printEffectList(ESM::EffectList effects) +{ + int i = 0; + std::vector::iterator eit; + for (eit = effects.mList.begin(); eit != effects.mList.end(); eit++) + { + std::cout << " Effect[" << i << "]: " << eit->mEffectID << std::endl; + if (eit->mSkill != -1) + std::cout << " Skill: " << (int)eit->mSkill << std::endl; + if (eit->mAttribute != -1) + std::cout << " Attribute: " << (int)eit->mAttribute << std::endl; + std::cout << " Range: " << eit->mRange << std::endl; + // Area is always zero if range type is "Self" + if (eit->mRange != ESM::RT_Self) + std::cout << " Area: " << eit->mArea << std::endl; + std::cout << " Duration: " << eit->mDuration << std::endl; + std::cout << " Magnitude: " << eit->mMagnMin << "-" << eit->mMagnMax << std::endl; + i++; + } +} + namespace EsmTool { RecordBase * @@ -293,11 +314,11 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " AutoCalc: " << mData.mData.mAutoCalc << std::endl; - // mEffects missing + printEffectList(mData.mEffects); } template<> @@ -307,16 +328,23 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; if (mData.mEnchant != "") - std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Type: " << mData.mData.mType << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Health: " << mData.mData.mHealth << std::endl; std::cout << " Armor: " << mData.mData.mArmor << std::endl; std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; - // mParts missing + std::vector::iterator pit; + for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); pit++) + { + std::cout << " Body Part: " << (int)(pit->mPart) << std::endl; + std::cout << " Male Name: " << pit->mMale << std::endl; + if (pit->mFemale != "") + std::cout << " Female Name: " << pit->mFemale << std::endl; + } } template<> @@ -350,15 +378,20 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; if (mData.mEnchant != "") - std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " IsScroll: " << mData.mData.mIsScroll << std::endl; std::cout << " SkillID: " << mData.mData.mSkillID << std::endl; std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; - // mText missing + std::cout << " Text: [skipped]" << std::endl; + // Skip until multi-line fields is controllable by a command line option. + // Mildly problematic because there are no parameter to print() currently. + // std::cout << "-------------------------------------------" << std::endl; + // std::cout << mData.mText << std::endl; + // std::cout << "-------------------------------------------" << std::endl; } template<> @@ -369,7 +402,7 @@ void Record::print() std::cout << " Description: " << mData.mDescription << std::endl; std::vector::iterator pit; for (pit = mData.mPowers.mList.begin(); pit != mData.mPowers.mList.end(); pit++) - std::cout << " Power: " << *pit << std::endl; + std::cout << " Power: " << *pit << std::endl; } template<> @@ -377,25 +410,25 @@ void Record::print() { // None of the cells have names... if (mData.mName != "") - std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Name: " << mData.mName << std::endl; if (mData.mRegion != "") - std::cout << " Region: " << mData.mRegion << std::endl; + std::cout << " Region: " << mData.mRegion << std::endl; std::cout << " Flags: " << (int)mData.mData.mFlags << std::endl; std::cout << " Coordinates: " << " (" << mData.getGridX() << "," - << mData.getGridY() << ")" << std::endl; + << mData.getGridY() << ")" << std::endl; if (mData.mData.mFlags & ESM::Cell::Interior && - !(mData.mData.mFlags & ESM::Cell::QuasiEx)) + !(mData.mData.mFlags & ESM::Cell::QuasiEx)) { - std::cout << " Ambient Light Color: " << mData.mAmbi.mAmbient << std::endl; - std::cout << " Sunlight Color: " << mData.mAmbi.mSunlight << std::endl; - std::cout << " Fog Color: " << mData.mAmbi.mFog << std::endl; - std::cout << " Fog Density: " << mData.mAmbi.mFogDensity << std::endl; - std::cout << " Water Level: " << mData.mWater << std::endl; + std::cout << " Ambient Light Color: " << mData.mAmbi.mAmbient << std::endl; + std::cout << " Sunlight Color: " << mData.mAmbi.mSunlight << std::endl; + std::cout << " Fog Color: " << mData.mAmbi.mFog << std::endl; + std::cout << " Fog Density: " << mData.mAmbi.mFogDensity << std::endl; + std::cout << " Water Level: " << mData.mWater << std::endl; } else - std::cout << " Map Color: " << boost::format("0x%08X") % mData.mMapColor << std::endl; + std::cout << " Map Color: " << boost::format("0x%08X") % mData.mMapColor << std::endl; std::cout << " Water Level Int: " << mData.mWaterInt << std::endl; std::cout << " NAM0: " << mData.mNAM0 << std::endl; @@ -412,9 +445,9 @@ void Record::print() std::cout << " Attribute2: " << mData.mData.mAttribute[1] << std::endl; std::cout << " Specialization: " << mData.mData.mSpecialization << std::endl; for (int i = 0; i != 5; i++) - std::cout << " Major Skill: " << mData.mData.mSkills[i][0] << std::endl; + std::cout << " Major Skill: " << mData.mData.mSkills[i][0] << std::endl; for (int i = 0; i != 5; i++) - std::cout << " Minor Skill: " << mData.mData.mSkills[i][1] << std::endl; + std::cout << " Minor Skill: " << mData.mData.mSkills[i][1] << std::endl; } template<> @@ -424,9 +457,9 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; if (mData.mEnchant != "") - std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Type: " << mData.mData.mType << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -439,10 +472,13 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Flags: " << mData.mFlags << std::endl; std::cout << " Weight: " << mData.mWeight << std::endl; - // mInventory missing + std::vector::iterator cit; + for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++) + std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount + << " Item: " << cit->mItem.toString() << std::endl; } template<> @@ -476,21 +512,21 @@ void Record::print() std::cout << " Magic: " << mData.mData.mMagic << std::endl; std::cout << " Stealth: " << mData.mData.mStealth << std::endl; std::cout << " Attack1: " << mData.mData.mAttack[0] - << "-" << mData.mData.mAttack[1] << std::endl; + << "-" << mData.mData.mAttack[1] << std::endl; std::cout << " Attack2: " << mData.mData.mAttack[2] - << "-" << mData.mData.mAttack[3] << std::endl; + << "-" << mData.mData.mAttack[3] << std::endl; std::cout << " Attack3: " << mData.mData.mAttack[4] - << "-" << mData.mData.mAttack[5] << std::endl; + << "-" << mData.mData.mAttack[5] << std::endl; std::cout << " Gold: " << mData.mData.mGold << std::endl; std::vector::iterator cit; for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++) - std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount - << " Item: " << cit->mItem.toString() << std::endl; + std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount + << " Item: " << cit->mItem.toString() << std::endl; std::vector::iterator sit; for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); sit++) - std::cout << " Spell: " << *sit << std::endl; + std::cout << " Spell: " << *sit << std::endl; std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl; std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; @@ -505,14 +541,19 @@ void Record::print() std::vector::iterator pit; for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); pit++) - printAIPackage(*pit); + printAIPackage(*pit); } template<> void Record::print() { std::cout << " Type: " << (int)mData.mType << std::endl; - // mInfo missing + // Sadly, there are no DialInfos, because the loader dumps as it + // loads, rather than loading and then dumping. :-( Anyone mind if + // I change this? + std::vector::iterator iit; + for (iit = mData.mInfo.begin(); iit != mData.mInfo.end(); iit++) + std::cout << "INFO!" << iit->mId << std::endl; } template<> @@ -532,7 +573,7 @@ void Record::print() std::cout << " Cost: " << mData.mData.mCost << std::endl; std::cout << " Charge: " << mData.mData.mCharge << std::endl; std::cout << " AutoCalc: " << mData.mData.mAutocalc << std::endl; - // mEffects missing + printEffectList(mData.mEffects); } template<> @@ -541,30 +582,30 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Hidden: " << mData.mData.mIsHidden << std::endl; if (mData.mData.mUnknown != -1) - std::cout << " Unknown: " << mData.mData.mUnknown << std::endl; + std::cout << " Unknown: " << mData.mData.mUnknown << std::endl; std::cout << " Attribute1: " << mData.mData.mAttribute1 << std::endl; std::cout << " Attribute2: " << mData.mData.mAttribute2 << std::endl; for (int i = 0; i != 6; i++) - if (mData.mData.mSkillID[i] != -1) - std::cout << " Skill: " << mData.mData.mSkillID[i] << std::endl; + if (mData.mData.mSkillID[i] != -1) + std::cout << " Skill: " << mData.mData.mSkillID[i] << std::endl; for (int i = 0; i != 10; i++) - if (mData.mRanks[i] != "") - { - std::cout << " Rank: " << mData.mRanks[i] << std::endl; - std::cout << " Attribute1 Requirement: " - << mData.mData.mRankData[i].mAttribute1 << std::endl; - std::cout << " Attribute2 Requirement: " - << mData.mData.mRankData[i].mAttribute2 << std::endl; - std::cout << " One Skill at Level: " - << mData.mData.mRankData[i].mSkill1 << std::endl; - std::cout << " Two Skills at Level: " - << mData.mData.mRankData[i].mSkill2 << std::endl; - std::cout << " Faction Reaction: " - << mData.mData.mRankData[i].mFactReaction << std::endl; - } + if (mData.mRanks[i] != "") + { + std::cout << " Rank: " << mData.mRanks[i] << std::endl; + std::cout << " Attribute1 Requirement: " + << mData.mData.mRankData[i].mAttribute1 << std::endl; + std::cout << " Attribute2 Requirement: " + << mData.mData.mRankData[i].mAttribute2 << std::endl; + std::cout << " One Skill at Level: " + << mData.mData.mRankData[i].mSkill1 << std::endl; + std::cout << " Two Skills at Level: " + << mData.mData.mRankData[i].mSkill2 << std::endl; + std::cout << " Faction Reaction: " + << mData.mData.mRankData[i].mFactReaction << std::endl; + } std::vector::iterator rit; for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); rit++) - std::cout << " Reaction: " << rit->mReaction << " = " << rit->mFaction << std::endl; + std::cout << " Reaction: " << rit->mReaction << " = " << rit->mFaction << std::endl; } template<> @@ -602,8 +643,53 @@ template<> void Record::print() { std::cout << " Id: " << mData.mId << std::endl; + if (mData.mPrev != "") + std::cout << " Previous ID: " << mData.mPrev << std::endl; + if (mData.mNext != "") + std::cout << " Next ID: " << mData.mNext << std::endl; std::cout << " Text: " << mData.mResponse << std::endl; - // Lots missing, more coming + if (mData.mActor != "") + std::cout << " Actor: " << mData.mActor << std::endl; + if (mData.mRace != "") + std::cout << " Race: " << mData.mRace << std::endl; + if (mData.mClass != "") + std::cout << " Class: " << mData.mClass << std::endl; + std::cout << " Factionless: " << mData.mFactionLess << std::endl; + if (mData.mNpcFaction != "") + std::cout << " NPC Faction: " << mData.mNpcFaction << std::endl; + if (mData.mData.mRank != -1) + std::cout << " NPC Rank: " << (int)mData.mData.mRank << std::endl; + if (mData.mPcFaction != "") + std::cout << " PC Faction: " << mData.mPcFaction << std::endl; + // CHANGE? non-standard capitalization mPCrank -> mPCRank (mPcRank?) + if (mData.mData.mPCrank != -1) + std::cout << " PC Rank: " << (int)mData.mData.mPCrank << std::endl; + if (mData.mCell != "") + std::cout << " Cell: " << mData.mCell << std::endl; + if (mData.mData.mDisposition > 0) + std::cout << " Disposition: " << mData.mData.mDisposition << std::endl; + if (mData.mData.mGender != ESM::DialInfo::NA) + std::cout << " Gender: " << mData.mData.mGender << std::endl; + if (mData.mSound != "") + std::cout << " Sound File: " << mData.mSound << std::endl; + + if (mData.mResultScript != "") + { + std::cout << " Result Script: [skipped]" << std::endl; + // Skip until multi-line fields is controllable by a command line option. + // Mildly problematic because there are no parameter to print() currently. + // std::cout << "-------------------------------------------" << std::endl; + // std::cout << mData.mResultScript << std::endl; + // std::cout << "-------------------------------------------" << std::endl; + } + + std::cout << " Quest Status: " << mData.mQuestStatus << std::endl; + std::cout << " Unknown1: " << mData.mData.mUnknown1 << std::endl; + std::cout << " Unknown2: " << (int)mData.mData.mUnknown2 << std::endl; + + std::vector::iterator sit; + for (sit = mData.mSelects.begin(); sit != mData.mSelects.end(); sit++) + std::cout << " Select Rule: " << sit->mType << " " << sit->mSelectRule << std::endl; } template<> @@ -613,16 +699,16 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; for (int i = 0; i !=4; i++) { - // A value of -1 means no effect - if (mData.mData.mEffectID[i] == -1) continue; - std::cout << " Effect: " << mData.mData.mEffectID[i] << std::endl; - std::cout << " Skill: " << mData.mData.mSkills[i] << std::endl; - std::cout << " Attribute: " << mData.mData.mAttributes[i] << std::endl; + // A value of -1 means no effect + if (mData.mData.mEffectID[i] == -1) continue; + std::cout << " Effect: " << mData.mData.mEffectID[i] << std::endl; + std::cout << " Skill: " << mData.mData.mSkills[i] << std::endl; + std::cout << " Attribute: " << mData.mData.mAttributes[i] << std::endl; } } @@ -630,7 +716,23 @@ template<> void Record::print() { std::cout << " Coordinates: (" << mData.mX << "," << mData.mY << ")" << std::endl; - // Lots missing, more coming + std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " HasData: " << mData.mHasData << std::endl; + std::cout << " DataTypes: " << mData.mDataTypes << std::endl; + + // Seems like this should done with reference counting in the + // loader to me. But I'm not really knowledgable about this + // record type yet. --Cory + bool wasLoaded = mData.mDataLoaded; + if (mData.mDataTypes) mData.loadData(mData.mDataTypes); + if (mData.mDataLoaded) + { + std::cout << " Height Offset: " << mData.mLandData->mHeightOffset << std::endl; + // Lots of missing members. + std::cout << " Unknown1: " << mData.mLandData->mUnk1 << std::endl; + std::cout << " Unknown2: " << mData.mLandData->mUnk2 << std::endl; + } + if (!wasLoaded) mData.unloadData(); } template<> @@ -641,8 +743,8 @@ void Record::print() std::cout << " Number of items: " << mData.mList.size() << std::endl; std::vector::iterator iit; for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) - std::cout << " Creature: Level: " << iit->mLevel - << " Creature: " << iit->mId << std::endl; + std::cout << " Creature: Level: " << iit->mLevel + << " Creature: " << iit->mId << std::endl; } template<> @@ -653,21 +755,21 @@ void Record::print() std::cout << " Number of items: " << mData.mList.size() << std::endl; std::vector::iterator iit; for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) - std::cout << " Inventory: Count: " << iit->mLevel - << " Item: " << iit->mId << std::endl; + std::cout << " Inventory: Count: " << iit->mLevel + << " Item: " << iit->mId << std::endl; } template<> void Record::print() { if (mData.mName != "") - std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Name: " << mData.mName << std::endl; if (mData.mModel != "") - std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; if (mData.mIcon != "") - std::cout << " Icon: " << mData.mIcon << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Flags: " << mData.mData.mFlags << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -684,7 +786,7 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Type: " << mData.mType << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -699,7 +801,7 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Type: " << mData.mType << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -714,7 +816,7 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Type: " << mData.mType << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -739,30 +841,30 @@ void Record::print() std::cout << " Flags: " << mData.mData.mFlags << std::endl; std::cout << " Particle Texture: " << mData.mParticle << std::endl; if (mData.mCasting != "") - std::cout << " Casting Static: " << mData.mCasting << std::endl; + std::cout << " Casting Static: " << mData.mCasting << std::endl; if (mData.mCastSound != "") - std::cout << " Casting Sound: " << mData.mCastSound << std::endl; + std::cout << " Casting Sound: " << mData.mCastSound << std::endl; if (mData.mBolt != "") - std::cout << " Bolt Static: " << mData.mBolt << std::endl; + std::cout << " Bolt Static: " << mData.mBolt << std::endl; if (mData.mBoltSound != "") - std::cout << " Bolt Sound: " << mData.mBoltSound << std::endl; + std::cout << " Bolt Sound: " << mData.mBoltSound << std::endl; if (mData.mHit != "") - std::cout << " Hit Static: " << mData.mHit << std::endl; + std::cout << " Hit Static: " << mData.mHit << std::endl; if (mData.mHitSound != "") - std::cout << " Hit Sound: " << mData.mHitSound << std::endl; + std::cout << " Hit Sound: " << mData.mHitSound << std::endl; if (mData.mArea != "") - std::cout << " Area Static: " << mData.mArea << std::endl; + std::cout << " Area Static: " << mData.mArea << std::endl; if (mData.mAreaSound != "") - std::cout << " Area Sound: " << mData.mAreaSound << std::endl; + std::cout << " Area Sound: " << mData.mAreaSound << std::endl; std::cout << " School: " << mData.mData.mSchool << std::endl; std::cout << " Base Cost: " << mData.mData.mBaseCost << std::endl; std::cout << " Speed: " << mData.mData.mSpeed << std::endl; std::cout << " Size: " << mData.mData.mSize << std::endl; std::cout << " Size Cap: " << mData.mData.mSizeCap << std::endl; std::cout << " RGB Color: " << "(" - << mData.mData.mRed << "," - << mData.mData.mGreen << "," - << mData.mData.mGreen << ")" << std::endl; + << mData.mData.mRed << "," + << mData.mData.mGreen << "," + << mData.mData.mGreen << ")" << std::endl; } template<> @@ -772,7 +874,7 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Is Key: " << mData.mData.mIsKey << std::endl; @@ -788,77 +890,77 @@ void Record::print() std::cout << " Race: " << mData.mRace << std::endl; std::cout << " Class: " << mData.mClass << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; if (mData.mFaction != "") - std::cout << " Faction: " << mData.mFaction << std::endl; + std::cout << " Faction: " << mData.mFaction << std::endl; std::cout << " Flags: " << mData.mFlags << std::endl; // Seriously? if (mData.mNpdt52.mGold == -10) { - std::cout << " Level: " << mData.mNpdt12.mLevel << std::endl; - std::cout << " Reputation: " << (int)mData.mNpdt12.mReputation << std::endl; - std::cout << " Disposition: " << (int)mData.mNpdt12.mDisposition << std::endl; - std::cout << " Faction: " << (int)mData.mNpdt52.mFactionID << std::endl; - std::cout << " Rank: " << (int)mData.mNpdt12.mRank << std::endl; - std::cout << " Unknown1: " - << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown1) << std::endl; - std::cout << " Unknown2: " - << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl; - std::cout << " Unknown3: " - << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl; - std::cout << " Gold: " << (int)mData.mNpdt12.mGold << std::endl; + std::cout << " Level: " << mData.mNpdt12.mLevel << std::endl; + std::cout << " Reputation: " << (int)mData.mNpdt12.mReputation << std::endl; + std::cout << " Disposition: " << (int)mData.mNpdt12.mDisposition << std::endl; + std::cout << " Faction: " << (int)mData.mNpdt52.mFactionID << std::endl; + std::cout << " Rank: " << (int)mData.mNpdt12.mRank << std::endl; + std::cout << " Unknown1: " + << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown1) << std::endl; + std::cout << " Unknown2: " + << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl; + std::cout << " Unknown3: " + << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl; + std::cout << " Gold: " << (int)mData.mNpdt12.mGold << std::endl; } else { - std::cout << " Level: " << mData.mNpdt52.mLevel << std::endl; - std::cout << " Reputation: " << (int)mData.mNpdt52.mReputation << std::endl; - std::cout << " Disposition: " << (int)mData.mNpdt52.mDisposition << std::endl; - std::cout << " Rank: " << (int)mData.mNpdt52.mRank << std::endl; + std::cout << " Level: " << mData.mNpdt52.mLevel << std::endl; + std::cout << " Reputation: " << (int)mData.mNpdt52.mReputation << std::endl; + std::cout << " Disposition: " << (int)mData.mNpdt52.mDisposition << std::endl; + std::cout << " Rank: " << (int)mData.mNpdt52.mRank << std::endl; - std::cout << " Attributes:" << std::endl; - std::cout << " Strength: " << (int)mData.mNpdt52.mStrength << std::endl; - std::cout << " Intelligence: " << (int)mData.mNpdt52.mIntelligence << std::endl; - std::cout << " Willpower: " << (int)mData.mNpdt52.mWillpower << std::endl; - std::cout << " Agility: " << (int)mData.mNpdt52.mAgility << std::endl; - std::cout << " Speed: " << (int)mData.mNpdt52.mSpeed << std::endl; - std::cout << " Endurance: " << (int)mData.mNpdt52.mEndurance << std::endl; - std::cout << " Personality: " << (int)mData.mNpdt52.mPersonality << std::endl; - std::cout << " Luck: " << (int)mData.mNpdt52.mLuck << std::endl; + std::cout << " Attributes:" << std::endl; + std::cout << " Strength: " << (int)mData.mNpdt52.mStrength << std::endl; + std::cout << " Intelligence: " << (int)mData.mNpdt52.mIntelligence << std::endl; + std::cout << " Willpower: " << (int)mData.mNpdt52.mWillpower << std::endl; + std::cout << " Agility: " << (int)mData.mNpdt52.mAgility << std::endl; + std::cout << " Speed: " << (int)mData.mNpdt52.mSpeed << std::endl; + std::cout << " Endurance: " << (int)mData.mNpdt52.mEndurance << std::endl; + std::cout << " Personality: " << (int)mData.mNpdt52.mPersonality << std::endl; + std::cout << " Luck: " << (int)mData.mNpdt52.mLuck << std::endl; - std::cout << " Skills:" << std::endl; - for (int i = 0; i != 27; i++) - std::cout << " " << i << " = " - << (int)((unsigned char)mData.mNpdt52.mSkills[i]) << std::endl; - - std::cout << " Health: " << mData.mNpdt52.mHealth << std::endl; - std::cout << " Magicka: " << mData.mNpdt52.mMana << std::endl; - std::cout << " Fatigue: " << mData.mNpdt52.mFatigue << std::endl; - std::cout << " Unknown: " << (int)mData.mNpdt52.mUnknown << std::endl; - std::cout << " Gold: " << mData.mNpdt52.mGold << std::endl; + std::cout << " Skills:" << std::endl; + for (int i = 0; i != 27; i++) + std::cout << " " << i << " = " + << (int)((unsigned char)mData.mNpdt52.mSkills[i]) << std::endl; + + std::cout << " Health: " << mData.mNpdt52.mHealth << std::endl; + std::cout << " Magicka: " << mData.mNpdt52.mMana << std::endl; + std::cout << " Fatigue: " << mData.mNpdt52.mFatigue << std::endl; + std::cout << " Unknown: " << (int)mData.mNpdt52.mUnknown << std::endl; + std::cout << " Gold: " << mData.mNpdt52.mGold << std::endl; } std::vector::iterator cit; for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++) - std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount - << " Item: " << cit->mItem.toString() << std::endl; + std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount + << " Item: " << cit->mItem.toString() << std::endl; std::vector::iterator sit; for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); sit++) - std::cout << " Spell: " << *sit << std::endl; + std::cout << " Spell: " << *sit << std::endl; std::vector::iterator dit; for (dit = mData.mTransport.begin(); dit != mData.mTransport.end(); dit++) { - std::cout << " Destination Position: " - << boost::format("%12.3f") % dit->mPos.pos[0] << "," - << boost::format("%12.3f") % dit->mPos.pos[1] << "," - << boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl; - std::cout << " Destination Rotation: " - << boost::format("%9.6f") % dit->mPos.rot[0] << "," - << boost::format("%9.6f") % dit->mPos.rot[1] << "," - << boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl; - if (dit->mCellName != "") - std::cout << " Destination Cell: " << dit->mCellName << std::endl; + std::cout << " Destination Position: " + << boost::format("%12.3f") % dit->mPos.pos[0] << "," + << boost::format("%12.3f") % dit->mPos.pos[1] << "," + << boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl; + std::cout << " Destination Rotation: " + << boost::format("%9.6f") % dit->mPos.rot[0] << "," + << boost::format("%9.6f") % dit->mPos.rot[1] << "," + << boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl; + if (dit->mCellName != "") + std::cout << " Destination Cell: " << dit->mCellName << std::endl; } std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl; @@ -874,7 +976,7 @@ void Record::print() std::vector::iterator pit; for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); pit++) - printAIPackage(*pit); + printAIPackage(*pit); } template<> @@ -884,7 +986,7 @@ void Record::print() std::cout << " Coordinates: (" << mData.mData.mX << "," << mData.mData.mY << ")" << std::endl; std::cout << " Unknown S1: " << mData.mData.mS1 << std::endl; if ((unsigned int)mData.mData.mS2 != mData.mPoints.size()) - std::cout << " Reported Point Count: " << mData.mData.mS2 << std::endl; + std::cout << " Reported Point Count: " << mData.mData.mS2 << std::endl; std::cout << " Point Count: " << mData.mPoints.size() << std::endl; std::cout << " Edge Count: " << mData.mEdges.size() << std::endl; @@ -892,22 +994,22 @@ void Record::print() ESM::Pathgrid::PointList::iterator pit; for (pit = mData.mPoints.begin(); pit != mData.mPoints.end(); pit++) { - std::cout << " Point[" << i << "]:" << std::endl; - std::cout << " Coordinates: (" << pit->mX << "," - << pit->mY << "," << pit->mZ << ")" << std::endl; - std::cout << " Auto-Generated: " << (int)pit->mAutogenerated << std::endl; - std::cout << " Connections: " << (int)pit->mConnectionNum << std::endl; - std::cout << " Unknown: " << pit->mUnknown << std::endl; - i++; + std::cout << " Point[" << i << "]:" << std::endl; + std::cout << " Coordinates: (" << pit->mX << "," + << pit->mY << "," << pit->mZ << ")" << std::endl; + std::cout << " Auto-Generated: " << (int)pit->mAutogenerated << std::endl; + std::cout << " Connections: " << (int)pit->mConnectionNum << std::endl; + std::cout << " Unknown: " << pit->mUnknown << std::endl; + i++; } i = 0; ESM::Pathgrid::EdgeList::iterator eit; for (eit = mData.mEdges.begin(); eit != mData.mEdges.end(); eit++) { - std::cout << " Edge[" << i << "]: " << eit->mV0 << " -> " << eit->mV1 << std::endl; - if (eit->mV0 >= mData.mData.mS2 || eit->mV1 >= mData.mData.mS2) - std::cout << " BAD POINT IN EDGE!" << std::endl; - i++; + std::cout << " Edge[" << i << "]: " << eit->mV0 << " -> " << eit->mV1 << std::endl; + if (eit->mV0 >= mData.mData.mS2 || eit->mV1 >= mData.mData.mS2) + std::cout << " BAD POINT IN EDGE!" << std::endl; + i++; } } @@ -920,57 +1022,57 @@ void Record::print() std::cout << " Male:" << std::endl; std::cout << " Strength: " - << mData.mData.mStrength.mMale << std::endl; + << mData.mData.mStrength.mMale << std::endl; std::cout << " Intelligence: " - << mData.mData.mIntelligence.mMale << std::endl; + << mData.mData.mIntelligence.mMale << std::endl; std::cout << " Willpower: " - << mData.mData.mWillpower.mMale << std::endl; + << mData.mData.mWillpower.mMale << std::endl; std::cout << " Agility: " - << mData.mData.mAgility.mMale << std::endl; + << mData.mData.mAgility.mMale << std::endl; std::cout << " Speed: " - << mData.mData.mSpeed.mMale << std::endl; + << mData.mData.mSpeed.mMale << std::endl; std::cout << " Endurance: " - << mData.mData.mEndurance.mMale << std::endl; + << mData.mData.mEndurance.mMale << std::endl; std::cout << " Personality: " - << mData.mData.mPersonality.mMale << std::endl; + << mData.mData.mPersonality.mMale << std::endl; std::cout << " Luck: " - << mData.mData.mLuck.mMale << std::endl; + << mData.mData.mLuck.mMale << std::endl; std::cout << " Height: " - << mData.mData.mHeight.mMale << std::endl; + << mData.mData.mHeight.mMale << std::endl; std::cout << " Weight: " - << mData.mData.mWeight.mMale << std::endl; + << mData.mData.mWeight.mMale << std::endl; std::cout << " Female:" << std::endl; std::cout << " Strength: " - << mData.mData.mStrength.mFemale << std::endl; + << mData.mData.mStrength.mFemale << std::endl; std::cout << " Intelligence: " - << mData.mData.mIntelligence.mFemale << std::endl; + << mData.mData.mIntelligence.mFemale << std::endl; std::cout << " Willpower: " - << mData.mData.mWillpower.mFemale << std::endl; + << mData.mData.mWillpower.mFemale << std::endl; std::cout << " Agility: " - << mData.mData.mAgility.mFemale << std::endl; + << mData.mData.mAgility.mFemale << std::endl; std::cout << " Speed: " - << mData.mData.mSpeed.mFemale << std::endl; + << mData.mData.mSpeed.mFemale << std::endl; std::cout << " Endurance: " - << mData.mData.mEndurance.mFemale << std::endl; + << mData.mData.mEndurance.mFemale << std::endl; std::cout << " Personality: " - << mData.mData.mPersonality.mFemale << std::endl; + << mData.mData.mPersonality.mFemale << std::endl; std::cout << " Luck: " - << mData.mData.mLuck.mFemale << std::endl; + << mData.mData.mLuck.mFemale << std::endl; std::cout << " Height: " - << mData.mData.mHeight.mFemale << std::endl; + << mData.mData.mHeight.mFemale << std::endl; std::cout << " Weight: " - << mData.mData.mWeight.mFemale << std::endl; + << mData.mData.mWeight.mFemale << std::endl; for (int i = 0; i != 7; i++) - // Not all races have 7 skills. - if (mData.mData.mBonus[i].mSkill != -1) - std::cout << " Skill: " << mData.mData.mBonus[i].mSkill - << " = " << mData.mData.mBonus[i].mBonus << std::endl; + // Not all races have 7 skills. + if (mData.mData.mBonus[i].mSkill != -1) + std::cout << " Skill: " << mData.mData.mBonus[i].mSkill + << " = " << mData.mData.mBonus[i].mBonus << std::endl; std::vector::iterator sit; for (sit = mData.mPowers.mList.begin(); sit != mData.mPowers.mList.end(); sit++) - std::cout << " Power: " << *sit << std::endl; + std::cout << " Power: " << *sit << std::endl; } template<> @@ -991,10 +1093,10 @@ void Record::print() std::cout << " UnknownB: " << (int)mData.mData.mB << std::endl; std::cout << " Map Color: " << mData.mMapColor << std::endl; if (mData.mSleepList != "") - std::cout << " Sleep List: " << mData.mSleepList << std::endl; + std::cout << " Sleep List: " << mData.mSleepList << std::endl; std::vector::iterator sit; for (sit = mData.mSoundList.begin(); sit != mData.mSoundList.end(); sit++) - std::cout << " Sound: " << (int)sit->mChance << " = " << sit->mSound.toString() << std::endl; + std::cout << " Sound: " << (int)sit->mChance << " = " << sit->mSound.toString() << std::endl; } template<> @@ -1009,18 +1111,19 @@ void Record::print() std::cout << " Table Size: " << mData.mData.mStringTableSize << std::endl; std::cout << " Script: [skipped]" << std::endl; - // Skip until multi-line field is controllable by a command line option. - //std::cout << "-------------------------------------------" << std::endl; - //std::cout << s->scriptText << std::endl; - //std::cout << "-------------------------------------------" << std::endl; + // Skip until multi-line fields is controllable by a command line option. + // Mildly problematic because there are no parameter to print() currently. + // std::cout << "-------------------------------------------" << std::endl; + // std::cout << s->scriptText << std::endl; + // std::cout << "-------------------------------------------" << std::endl; std::vector::iterator vit; for (vit = mData.mVarNames.begin(); vit != mData.mVarNames.end(); vit++) - std::cout << " Variable: " << *vit << std::endl; + std::cout << " Variable: " << *vit << std::endl; std::cout << " ByteCode: "; std::vector::iterator cit; for (cit = mData.mScriptData.begin(); cit != mData.mScriptData.end(); cit++) - std::cout << boost::format("%02X") % (int)(*cit); + std::cout << boost::format("%02X") % (int)(*cit); std::cout << std::endl; } @@ -1055,8 +1158,8 @@ void Record::print() std::cout << " Sound: " << mData.mSound << std::endl; std::cout << " Volume: " << (int)mData.mData.mVolume << std::endl; if (mData.mData.mMinRange != 0 && mData.mData.mMaxRange != 0) - std::cout << " Range: " << (int)mData.mData.mMinRange << " - " - << (int)mData.mData.mMaxRange << std::endl; + std::cout << " Range: " << (int)mData.mData.mMinRange << " - " + << (int)mData.mData.mMaxRange << std::endl; } template<> @@ -1066,7 +1169,7 @@ void Record::print() std::cout << " Type: " << mData.mData.mType << std::endl; std::cout << " Flags: " << mData.mData.mFlags << std::endl; std::cout << " Cost: " << mData.mData.mCost << std::endl; - // mEffect missing + printEffectList(mData.mEffects); } template<> @@ -1087,15 +1190,15 @@ void Record::print() { // No names on VFX bolts if (mData.mName != "") - std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; // No icons on VFX bolts or magic bolts if (mData.mIcon != "") - std::cout << " Icon: " << mData.mIcon << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; if (mData.mEnchant != "") - std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Type: " << mData.mData.mType << std::endl; std::cout << " Flags: " << mData.mData.mFlags << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; @@ -1105,14 +1208,14 @@ void Record::print() std::cout << " Reach: " << mData.mData.mReach << std::endl; std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; if (mData.mData.mChop[0] != 0 && mData.mData.mChop[1] != 0) - std::cout << " Chop: " << (int)mData.mData.mChop[0] << "-" - << (int)mData.mData.mChop[1] << std::endl; + std::cout << " Chop: " << (int)mData.mData.mChop[0] << "-" + << (int)mData.mData.mChop[1] << std::endl; if (mData.mData.mSlash[0] != 0 && mData.mData.mSlash[1] != 0) - std::cout << " Slash: " << (int)mData.mData.mSlash[0] << "-" - << (int)mData.mData.mSlash[1] << std::endl; + std::cout << " Slash: " << (int)mData.mData.mSlash[0] << "-" + << (int)mData.mData.mSlash[1] << std::endl; if (mData.mData.mThrust[0] != 0 && mData.mData.mThrust[1] != 0) - std::cout << " Thrust: " << (int)mData.mData.mThrust[0] << "-" - << (int)mData.mData.mThrust[1] << std::endl; + std::cout << " Thrust: " << (int)mData.mData.mThrust[0] << "-" + << (int)mData.mData.mThrust[1] << std::endl; } template<> diff --git a/apps/esmtool/record.hpp b/apps/esmtool/record.hpp index e75870ab6..c3daa9d0c 100644 --- a/apps/esmtool/record.hpp +++ b/apps/esmtool/record.hpp @@ -20,7 +20,7 @@ namespace EsmTool protected: std::string mId; int mFlags; - ESM::NAME mType; + ESM::NAME mType; public: RecordBase () {} @@ -42,7 +42,7 @@ namespace EsmTool mFlags = flags; } - ESM::NAME getType() const { + ESM::NAME getType() const { return mType; } From 68a856ff6fe8f86a7de123e69eaf4061e1764828 Mon Sep 17 00:00:00 2001 From: cfcohen Date: Wed, 10 Oct 2012 22:00:44 -0400 Subject: [PATCH 19/45] Human readable labels for many records types. Human readable flags for many record types. Improved DialInfo rule parsing. Discovered several issues involving the assignment of various flag bits. --- apps/esmtool/CMakeLists.txt | 2 + apps/esmtool/labels.cpp | 884 ++++++++++++++++++++++++++++++++++++ apps/esmtool/labels.hpp | 64 +++ apps/esmtool/record.cpp | 313 +++++++++---- 4 files changed, 1162 insertions(+), 101 deletions(-) create mode 100644 apps/esmtool/labels.cpp create mode 100644 apps/esmtool/labels.hpp diff --git a/apps/esmtool/CMakeLists.txt b/apps/esmtool/CMakeLists.txt index f48aa41bf..5c588fb29 100644 --- a/apps/esmtool/CMakeLists.txt +++ b/apps/esmtool/CMakeLists.txt @@ -1,5 +1,7 @@ set(ESMTOOL esmtool.cpp + labels.hpp + labels.cpp record.hpp record.cpp ) diff --git a/apps/esmtool/labels.cpp b/apps/esmtool/labels.cpp new file mode 100644 index 000000000..1ebed1d55 --- /dev/null +++ b/apps/esmtool/labels.cpp @@ -0,0 +1,884 @@ +#include "labels.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +std::string bodyPartLabel(char idx) +{ + const char *bodyPartLabels[] = { + "Head", + "Hair", + "Neck", + "Cuirass", + "Groin", + "Skirt", + "Right Hand", + "Left Hand", + "Right Wrist", + "Left Wrist", + "Shield", + "Right Forearm", + "Left Forearm", + "Right Upperarm", + "Left Upperarm", + "Right Foot", + "Left Foot", + "Right Ankle", + "Left Ankle", + "Right Knee", + "Left Knee", + "Right Leg", + "Left Leg", + "Right Shoulder", + "Left Shoulder", + "Weapon", + "Tail" + }; + + // BUG? idx should probably be unsigned char instead + if ((int)idx >= 0 && (int)(idx) <= 26) + return bodyPartLabels[(int)(idx)]; + else + return "Invalid"; +} + +std::string meshPartLabel(char idx) +{ + const char *meshPartLabels[] = { + "Head", + "Hair", + "Neck", + "Chest", + "Groin", + "Hand", + "Wrist", + "Forearm", + "Upperarm", + "Foot", + "Ankle", + "Knee", + "Upper Leg", + "Clavicle", + "Tail" + }; + + if ((int)(idx) >= 0 && (int)(idx) <= ESM::BodyPart::MP_Tail) + return meshPartLabels[(int)(idx)]; + else + return "Invalid"; +} + +std::string meshTypeLabel(char idx) +{ + const char *meshTypeLabels[] = { + "Skin", + "Clothing", + "Armor" + }; + + if ((int)(idx) >= 0 && (int)(idx) <= ESM::BodyPart::MT_Armor) + return meshTypeLabels[(int)(idx)]; + else + return "Invalid"; +} + +std::string clothingTypeLabel(int idx) +{ + const char *clothingTypeLabels[] = { + "Pants", + "Shoes", + "Shirt", + "Belt", + "Robe", + "Right Glove", + "Left Glove", + "Skirt", + "Ring", + "Amulet" + }; + + if (idx >= 0 && idx <= 9) + return clothingTypeLabels[idx]; + else + return "Invalid"; +} + +std::string armorTypeLabel(int idx) +{ + const char *armorTypeLabels[] = { + "Helmet", + "Cuirass", + "Left Pauldron", + "Right Pauldron", + "Greaves", + "Boots", + "Left Gauntlet", + "Right Gauntlet", + "Shield", + "Left Bracer", + "Right Bracer" + }; + + if (idx >= 0 && idx <= 10) + return armorTypeLabels[idx]; + else + return "Invalid"; +} + +std::string dialogTypeLabel(int idx) +{ + const char *dialogTypeLabels[] = { + "Topic", + "Voice", + "Greeting", + "Persuasion", + "Journal" + }; + + if (idx >= 0 && idx <= 4) + return dialogTypeLabels[idx]; + else if (idx == -1) + return "Deleted"; + else + return "Invalid"; +} + +std::string questStatusLabel(int idx) +{ + const char *questStatusLabels[] = { + "None", + "Name", + "Finished", + "Restart", + "Deleted" + }; + + if (idx >= 0 && idx <= 4) + return questStatusLabels[idx]; + else + return "Invalid"; +} + +std::string creatureTypeLabel(int idx) +{ + const char *creatureTypeLabels[] = { + "Creature", + "Daedra", + "Undead", + "Humanoid", + }; + + if (idx >= 0 && idx <= 3) + return creatureTypeLabels[idx]; + else + return "Invalid"; +} + +std::string soundTypeLabel(int idx) +{ + const char *soundTypeLabels[] = { + "Left Foot", + "Right Foot", + "Swim Left", + "Swim Right", + "Moan", + "Roar", + "Scream", + "Land" + }; + + if (idx >= 0 && idx <= 7) + return soundTypeLabels[idx]; + else + return "Invalid"; +} + +std::string weaponTypeLabel(int idx) +{ + const char *weaponTypeLabels[] = { + "Short Blade One Hand", + "Long Blade One Hand", + "Long Blade Two Hand", + "Blunt One Hand", + "Blunt Two Close", + "Blunt Two Wide", + "Spear Two Wide", + "Axe One Hand", + "Axe Two Hand", + "Marksman Bow", + "Marksman Crossbow", + "Marksman Thrown", + "Arrow", + "Bolt" + }; + + if (idx >= 0 && idx <= 13) + return weaponTypeLabels[idx]; + else + return "Invalid"; +} + +std::string aiTypeLabel(int type) +{ + if (type == ESM::AI_Wander) return "Wander"; + else if (type == ESM::AI_Travel) return "Travel"; + else if (type == ESM::AI_Follow) return "Follow"; + else if (type == ESM::AI_Escort) return "Escort"; + else if (type == ESM::AI_Activate) return "Activate"; + else return "Invalid"; +} + +std::string magicEffectLabel(int idx) +{ + const char* magicEffectLabels [] = { + "Water Breathing", + "Swift Swim", + "Water Walking", + "Shield", + "Fire Shield", + "Lightning Shield", + "Frost Shield", + "Burden", + "Feather", + "Jump", + "Levitate", + "SlowFall", + "Lock", + "Open", + "Fire Damage", + "Shock Damage", + "Frost Damage", + "Drain Attribute", + "Drain Health", + "Drain Magicka", + "Drain Fatigue", + "Drain Skill", + "Damage Attribute", + "Damage Health", + "Damage Magicka", + "Damage Fatigue", + "Damage Skill", + "Poison", + "Weakness to Fire", + "Weakness to Frost", + "Weakness to Shock", + "Weakness to Magicka", + "Weakness to Common Disease", + "Weakness to Blight Disease", + "Weakness to Corprus Disease", + "Weakness to Poison", + "Weakness to Normal Weapons", + "Disintegrate Weapon", + "Disintegrate Armor", + "Invisibility", + "Chameleon", + "Light", + "Sanctuary", + "Night Eye", + "Charm", + "Paralyze", + "Silence", + "Blind", + "Sound", + "Calm Humanoid", + "Calm Creature", + "Frenzy Humanoid", + "Frenzy Creature", + "Demoralize Humanoid", + "Demoralize Creature", + "Rally Humanoid", + "Rally Creature", + "Dispel", + "Soultrap", + "Telekinesis", + "Mark", + "Recall", + "Divine Intervention", + "Almsivi Intervention", + "Detect Animal", + "Detect Enchantment", + "Detect Key", + "Spell Absorption", + "Reflect", + "Cure Common Disease", + "Cure Blight Disease", + "Cure Corprus Disease", + "Cure Poison", + "Cure Paralyzation", + "Restore Attribute", + "Restore Health", + "Restore Magicka", + "Restore Fatigue", + "Restore Skill", + "Fortify Attribute", + "Fortify Health", + "Fortify Magicka", + "Fortify Fatigue", + "Fortify Skill", + "Fortify Maximum Magicka", + "Absorb Attribute", + "Absorb Health", + "Absorb Magicka", + "Absorb Fatigue", + "Absorb Skill", + "Resist Fire", + "Resist Frost", + "Resist Shock", + "Resist Magicka", + "Resist Common Disease", + "Resist Blight Disease", + "Resist Corprus Disease", + "Resist Poison", + "Resist Normal Weapons", + "Resist Paralysis", + "Remove Curse", + "Turn Undead", + "Summon Scamp", + "Summon Clannfear", + "Summon Daedroth", + "Summon Dremora", + "Summon Ancestral Ghost", + "Summon Skeletal Minion", + "Summon Bonewalker", + "Summon Greater Bonewalker", + "Summon Bonelord", + "Summon Winged Twilight", + "Summon Hunger", + "Summon Golden Saint", + "Summon Flame Atronach", + "Summon Frost Atronach", + "Summon Storm Atronach", + "Fortify Attack", + "Command Creature", + "Command Humanoid", + "Bound Dagger", + "Bound Longsword", + "Bound Mace", + "Bound Battle Axe", + "Bound Spear", + "Bound Longbow", + "EXTRA SPELL", + "Bound Cuirass", + "Bound Helm", + "Bound Boots", + "Bound Shield", + "Bound Gloves", + "Corprus", + "Vampirism", + "Summon Centurion Sphere", + "Sun Damage", + "Stunted Magicka", + "Summon Fabricant", + "sEffectSummonCreature01", + "sEffectSummonCreature02", + "sEffectSummonCreature03", + "sEffectSummonCreature04", + "sEffectSummonCreature05" + }; + if (idx >= 0 && idx <= 143) + return magicEffectLabels[idx]; + else + return "Invalid"; +} + +std::string attributeLabel(int idx) +{ + const char* attributeLabels [] = { + "Strength", + "Intelligence", + "Willpower", + "Agility", + "Speed", + "Endurance", + "Personality", + "Luck" + }; + if (idx >= 0 && idx <= 7) + return attributeLabels[idx]; + else + return "Invalid"; +} + +std::string spellTypeLabel(int idx) +{ + const char* spellTypeLabels [] = { + "Spells", + "Abilities", + "Blight Disease", + "Disease", + "Curse", + "Powers" + }; + if (idx >= 0 && idx <= 5) + return spellTypeLabels[idx]; + else + return "Invalid"; +} + +std::string specializationLabel(int idx) +{ + const char* specializationLabels [] = { + "Combat", + "Magic", + "Stealth" + }; + if (idx >= 0 && idx <= 2) + return specializationLabels[idx]; + else + return "Invalid"; +} + +std::string skillLabel(int idx) +{ + const char* skillLabels [] = { + "Block", + "Armorer", + "Medium Armor", + "Heavy Armor", + "Blunt Weapon", + "Long Blade", + "Axe", + "Spear", + "Athletics", + "Enchant", + "Destruction", + "Alteration", + "Illusion", + "Conjuration", + "Mysticism", + "Restoration", + "Alchemy", + "Unarmored", + "Security", + "Sneak", + "Acrobatics", + "Light Armor", + "Short Blade", + "Marksman", + "Mercantile", + "Speechcraft", + "Hand-to-hand" + }; + if (idx >= 0 && idx <= 27) + return skillLabels[idx]; + else + return "Invalid"; +} + +std::string apparatusTypeLabel(int idx) +{ + const char* apparatusTypeLabels [] = { + "Mortar", + "Alembic", + "Calcinator", + "Retort", + }; + if (idx >= 0 && idx <= 3) + return apparatusTypeLabels[idx]; + else + return "Invalid"; +} + +std::string rangeTypeLabel(int idx) +{ + const char* rangeTypeLabels [] = { + "Self", + "Touch", + "Target" + }; + if (idx >= 0 && idx <= 3) + return rangeTypeLabels[idx]; + else + return "Invalid"; +} + +std::string schoolLabel(int idx) +{ + const char* schoolLabels [] = { + "Alteration", + "Conjuration", + "Destruction", + "Illusion", + "Mysticism", + "Restoration" + }; + if (idx >= 0 && idx <= 5) + return schoolLabels[idx]; + else + return "Invalid"; +} + +std::string enchantTypeLabel(int idx) +{ + const char* enchantTypeLabels [] = { + "Cast Once", + "Cast When Strikes", + "Cast When Used", + "Constant Effect" + }; + if (idx >= 0 && idx <= 3) + return enchantTypeLabels[idx]; + else + return "Invalid"; +} + +std::string ruleFunction(int idx) +{ + std::string ruleFunctions[] = { + "Reaction Low", + "Reaction High", + "Rank Requirement", + "NPC? Reputation", + "Health Percent", + "Player Reputation", + "NPC Level", + "Player Health Percent", + "Player Magicka", + "Player Fatigue", + "Player Attribute Strength", + "Player Skill Block", + "Player Skill Armorer", + "Player Skill Medium Armor", + "Player Skill Heavy Armor", + "Player Skill Blunt Weapon", + "Player Skill Long Blade", + "Player Skill Axe", + "Player Skill Spear", + "Player Skill Athletics", + "Player Skill Enchant", + "Player Skill Destruction", + "Player Skill Alteration", + "Player Skill Illusion", + "Player Skill Conjuration", + "Player Skill Mysticism", + "Player SKill Restoration", + "Player Skill Alchemy", + "Player Skill Unarmored", + "Player Skill Security", + "Player Skill Sneak", + "Player Skill Acrobatics", + "Player Skill Light Armor", + "Player Skill Short Blade", + "Player Skill Marksman", + "Player Skill Mercantile", + "Player Skill Speechcraft", + "Player Skill Hand to Hand", +// Unknown1=0->Male, Unknown1=1->Female + "Player Gender", + "Player Expelled from Faction", + "Player Diseased (Common)", + "Player Diseased (Blight)", + "Player Clothing Modifier", + "Player Crime Level", + "Player Same Sex", + "Player Same Race", + "Player Same Faction", + "Faction Rank Difference", + "Player Detected", + "Alarmed", + "Choice Selected", + "Player Attribute Intelligence", + "Player Attribute Willpower", + "Player Attribute Agility", + "Player Attribute Speed", + "Player Attribute Endurance", + "Player Attribute Personality", + "Player Attribute Luck", + "Player Diseased (Corprus)", + "Weather", + "Player is a Vampire", + "Player Level", + "Attacked", + "NPC Talked to Player", + "Player Health", + "Creature Target", + "Friend Hit", + "Fight", + "Hello", + "Alarm", + "Flee", + "Should Attack", + //Unkown but causes NPCs to growl and roar. + "UNKNOWN 72" + }; + if (idx >= 0 && idx <= 72) + return ruleFunctions[idx]; + else + return "Invalid"; +} + +// The "unused flag bits" should probably be defined alongside the +// defined bits in the ESM component. The names of the flag bits are +// very inconsistent. + +std::string bodyPartFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + if (flags & ESM::BodyPart::BPF_Female) properties += "Female "; + if (flags & ESM::BodyPart::BPF_Playable) properties += "Playable "; + int unused = (0xFFFFFFFF ^ + (ESM::BodyPart::BPF_Female| + ESM::BodyPart::BPF_Playable)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string cellFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + if (flags & ESM::Cell::HasWater) properties += "HasWater "; + if (flags & ESM::Cell::Interior) properties += "Interior "; + if (flags & ESM::Cell::NoSleep) properties += "NoSleep "; + if (flags & ESM::Cell::QuasiEx) properties += "QuasiEx "; + // CHANGE? This used value is not in the ESM component. + if (flags & 0x00000040) properties += "Unknown "; + int unused = (0xFFFFFFFF ^ + (ESM::Cell::HasWater| + ESM::Cell::Interior| + ESM::Cell::NoSleep| + ESM::Cell::QuasiEx| + 0x00000040)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string containerFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + if (flags & ESM::Container::Unknown) properties += "Unknown "; + if (flags & ESM::Container::Organic) properties += "Organic "; + if (flags & ESM::Container::Respawn) properties += "Respawn "; + int unused = (0xFFFFFFFF ^ + (ESM::Container::Unknown| + ESM::Container::Organic| + ESM::Container::Respawn)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string creatureFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + if (flags & ESM::Creature::None) properties += "All "; + if (flags & ESM::Creature::Walks) properties += "Walks "; + if (flags & ESM::Creature::Swims) properties += "Swims "; + if (flags & ESM::Creature::Flies) properties += "Flies "; + if (flags & ESM::Creature::Biped) properties += "Biped "; + if (flags & ESM::Creature::Respawn) properties += "Respawn "; + if (flags & ESM::Creature::Weapon) properties += "Weapon "; + if (flags & ESM::Creature::Skeleton) properties += "Skeleton "; + if (flags & ESM::Creature::Metal) properties += "Metal "; + if (flags & ESM::Creature::Essential) properties += "Essential "; + int unused = (0xFFFFFFFF ^ + (ESM::Creature::None| + ESM::Creature::Walks| + ESM::Creature::Swims| + ESM::Creature::Flies| + ESM::Creature::Biped| + ESM::Creature::Respawn| + ESM::Creature::Weapon| + ESM::Creature::Skeleton| + ESM::Creature::Metal| + ESM::Creature::Essential)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string landFlags(int flags) +{ + std::string properties = ""; + // The ESM component says that this first four bits are used, but + // only the first three bits are used as far as I can tell. + // There's also no enumeration of the bit in the ESM component. + if (flags == 0) properties += "[None] "; + if (flags & 0x00000001) properties += "Unknown1 "; + if (flags & 0x00000004) properties += "Unknown3 "; + if (flags & 0x00000002) properties += "Unknown2 "; + if (flags & 0xFFFFFFF8) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string leveledListFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + if (flags & ESM::LeveledListBase::AllLevels) properties += "AllLevels "; + // BUG? This flag apparently not present on creature lists... + if (flags & ESM::LeveledListBase::Each) properties += "Each "; + // BUG! The unsused bits should be defined in LeveledListBase. + int unused = (0xFFFFFFFF ^ + (ESM::LeveledListBase::AllLevels| + ESM::LeveledListBase::Each)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string lightFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + if (flags & ESM::Light::Dynamic) properties += "Dynamic "; + if (flags & ESM::Light::Fire) properties += "Fire "; + if (flags & ESM::Light::Carry) properties += "Carry "; + if (flags & ESM::Light::Flicker) properties += "Flicker "; + if (flags & ESM::Light::FlickerSlow) properties += "FlickerSlow "; + if (flags & ESM::Light::Pulse) properties += "Pulse "; + if (flags & ESM::Light::PulseSlow) properties += "PulseSlow "; + if (flags & ESM::Light::Negative) properties += "Negative "; + if (flags & ESM::Light::OffDefault) properties += "OffDefault "; + int unused = (0xFFFFFFFF ^ + (ESM::Light::Dynamic| + ESM::Light::Fire| + ESM::Light::Carry| + ESM::Light::Flicker| + ESM::Light::FlickerSlow| + ESM::Light::Pulse| + ESM::Light::PulseSlow| + ESM::Light::Negative| + ESM::Light::OffDefault)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string magicEffectFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + // Enchanting & SpellMaking occur on the same list of effects. + // "EXTRA SPELL" appears in the construction set under both the + // spell making and enchanting tabs as an allowed effect. Since + // most of the effects without this flags are defective in various + // ways, it's still very unclear what these flag bits are. + if (flags & ESM::MagicEffect::SpellMaking) properties += "SpellMaking "; + if (flags & ESM::MagicEffect::Enchanting) properties += "Enchanting "; + if (flags & 0x00000040) properties += "RangeNoSelf "; + if (flags & 0x00000080) properties += "RangeTouch "; + if (flags & 0x00000100) properties += "RangeTarget "; + if (flags & 0x00001000) properties += "Unknown2 "; + if (flags & 0x00000001) properties += "AffectSkill "; + if (flags & 0x00000002) properties += "AffectAttribute "; + if (flags & ESM::MagicEffect::NoDuration) properties += "NoDuration "; + if (flags & 0x00000008) properties += "NoMagnitude "; + if (flags & 0x00000010) properties += "Negative "; + if (flags & 0x00000020) properties += "Unknown1 "; + // ESM componet says 0x800 is negative, but none of the magic + // effects have this flags set. + if (flags & ESM::MagicEffect::Negative) properties += "Unused "; + // Since only Chameleon has this flag it could be anything + // that uniquely distinguishes Chameleon. + if (flags & 0x00002000) properties += "Chameleon "; + if (flags & 0x00004000) properties += "Bound "; + if (flags & 0x00008000) properties += "Summon "; + // Calm, Demoralize, Frenzy, Lock, Open, Rally, Soultrap, Turn Unded + if (flags & 0x00010000) properties += "Unknown3 "; + if (flags & 0x00020000) properties += "Absorb "; + if (flags & 0xFFFC0000) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string npcFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + // Mythicmods and the ESM component differ. Mythicmods says + // 0x8=None and 0x10=AutoCalc, while our code defines 0x8 as + // AutoCalc. The former seems to be correct. All Bethesda + // records have bit 0x8 set. A suspiciously large portion of + // females have autocalc turned off. + if (flags & ESM::NPC::Autocalc) properties += "Unknown "; + if (flags & 0x00000010) properties += "Autocalc "; + if (flags & ESM::NPC::Female) properties += "Female "; + if (flags & ESM::NPC::Respawn) properties += "Respawn "; + if (flags & ESM::NPC::Essential) properties += "Essential "; + // These two flags do not appear on any NPCs and may have been + // confused with the flags for creatures. + if (flags & ESM::NPC::Skeleton) properties += "Skeleton "; + if (flags & ESM::NPC::Metal) properties += "Metal "; + // Whether corpses persist is a bit that is unaccounted for, + // however the only unknown bit occurs on ALL records, and + // relatively few NPCs have this bit set. + int unused = (0xFFFFFFFF ^ + (ESM::NPC::Autocalc| + 0x00000010| + ESM::NPC::Female| + ESM::NPC::Respawn| + ESM::NPC::Essential| + ESM::NPC::Skeleton| + ESM::NPC::Metal)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string raceFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + // All races have the playable flag set in Bethesda files. + if (flags & ESM::Race::Playable) properties += "Playable "; + if (flags & ESM::Race::Beast) properties += "Beast "; + int unused = (0xFFFFFFFF ^ + (ESM::Race::Playable| + ESM::Race::Beast)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string spellFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + if (flags & ESM::Spell::F_Autocalc) properties += "Autocalc "; + if (flags & ESM::Spell::F_PCStart) properties += "PCStart "; + if (flags & ESM::Spell::F_Always) properties += "Always "; + int unused = (0xFFFFFFFF ^ + (ESM::Spell::F_Autocalc| + ESM::Spell::F_PCStart| + ESM::Spell::F_Always)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string weaponFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + // The interpretation of the flags are still unclear to me. + // Apparently you can't be Silver without being Magical? Many of + // the "Magical" weapons don't have enchantments of any sort. + if (flags & ESM::Weapon::Magical) properties += "Magical "; + if (flags & ESM::Weapon::Silver) properties += "Silver "; + int unused = (0xFFFFFFFF ^ + (ESM::Weapon::Magical| + ESM::Weapon::Silver)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} diff --git a/apps/esmtool/labels.hpp b/apps/esmtool/labels.hpp new file mode 100644 index 000000000..7f1ff7986 --- /dev/null +++ b/apps/esmtool/labels.hpp @@ -0,0 +1,64 @@ +#ifndef OPENMW_ESMTOOL_LABELS_H +#define OPENMW_ESMTOOL_LABELS_H + +#include + +std::string bodyPartLabel(char idx); +std::string meshPartLabel(char idx); +std::string meshTypeLabel(char idx); +std::string clothingTypeLabel(int idx); +std::string armorTypeLabel(int idx); +std::string dialogTypeLabel(int idx); +std::string questStatusLabel(int idx); +std::string creatureTypeLabel(int idx); +std::string soundTypeLabel(int idx); +std::string weaponTypeLabel(int idx); + +// This function's a bit different because the types are record types, +// not consecutive values. +std::string aiTypeLabel(int type); + +// This one's also a bit different, because it enumerates dialog +// select rule functions, not types. Structurally, it still converts +// indexes to strings for display. +std::string ruleFunction(int idx); + +// The labels below here can all be loaded from GMSTs, but are not +// currently because among other things, that requires loading the +// GMSTs before dumping any of the records. + +// If the data format supported ordered lists of GMSTs (post 1.0), the +// lists could define the valid values, their localization strings, +// and the indexes for referencing the types in other records in the +// database. Then a single label function could work for all types. + +std::string magicEffectLabel(int idx); +std::string attributeLabel(int idx); +std::string spellTypeLabel(int idx); +std::string specializationLabel(int idx); +std::string skillLabel(int idx); +std::string apparatusTypeLabel(int idx); +std::string rangeTypeLabel(int idx); +std::string schoolLabel(int idx); +std::string enchantTypeLabel(int idx); + +// The are the flag functions that convert a bitmask into a list of +// human readble strings representing the set bits. + +std::string bodyPartFlags(int flags); +std::string cellFlags(int flags); +std::string containerFlags(int flags); +std::string creatureFlags(int flags); +std::string landFlags(int flags); +std::string leveledListFlags(int flags); +std::string lightFlags(int flags); +std::string magicEffectFlags(int flags); +std::string npcFlags(int flags); +std::string raceFlags(int flags); +std::string spellFlags(int flags); +std::string weaponFlags(int flags); + +// Missing flags functions: +// aiServicesFlags, possibly more + +#endif diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index c679a1c4d..856700f5e 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -1,54 +1,126 @@ #include "record.hpp" +#include "labels.hpp" #include #include void printAIPackage(ESM::AIPackage p) { - if (p.mType == ESM::AI_Wander) - { - std::cout << " AIType Wander:" << std::endl; - std::cout << " Distance: " << p.mWander.mDistance << std::endl; - std::cout << " Duration: " << p.mWander.mDuration << std::endl; - std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl; - if (p.mWander.mUnk != 1) - std::cout << " Unknown: " << (int)p.mWander.mUnk << std::endl; + std::cout << " AI Type: " << aiTypeLabel(p.mType) + << " (" << boost::format("0x%08X") % p.mType << ")" << std::endl; + if (p.mType == ESM::AI_Wander) + { + std::cout << " Distance: " << p.mWander.mDistance << std::endl; + std::cout << " Duration: " << p.mWander.mDuration << std::endl; + std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl; + if (p.mWander.mUnk != 1) + std::cout << " Unknown: " << (int)p.mWander.mUnk << std::endl; + + std::cout << " Idle: "; + for (int i = 0; i != 8; i++) + std::cout << (int)p.mWander.mIdle[i] << " "; + std::cout << std::endl; + } + else if (p.mType == ESM::AI_Travel) + { + std::cout << " Travel Coordinates: (" << p.mTravel.mX << "," + << p.mTravel.mY << "," << p.mTravel.mZ << ")" << std::endl; + std::cout << " Travel Unknown: " << (int)p.mTravel.mUnk << std::endl; + } + else if (p.mType == ESM::AI_Follow || p.mType == ESM::AI_Escort) + { + std::cout << " Follow Coordinates: (" << p.mTarget.mX << "," + << p.mTarget.mY << "," << p.mTarget.mZ << ")" << std::endl; + std::cout << " Duration: " << p.mTarget.mDuration << std::endl; + std::cout << " Target ID: " << p.mTarget.mId.toString() << std::endl; + std::cout << " Unknown: " << (int)p.mTarget.mUnk << std::endl; + } + else if (p.mType == ESM::AI_Activate) + { + std::cout << " Name: " << p.mActivate.mName.toString() << std::endl; + std::cout << " Activate Unknown: " << (int)p.mActivate.mUnk << std::endl; + } + else { + std::cout << " BadPackage: " << boost::format("0x%08x") % p.mType << std::endl; + } + + if (p.mCellName != "") + std::cout << " Cell Name: " << p.mCellName << std::endl; +} - std::cout << " Idle: "; - for (int i = 0; i != 8; i++) - std::cout << (int)p.mWander.mIdle[i] << " "; - std::cout << std::endl; - } - else if (p.mType == ESM::AI_Travel) - { - std::cout << " AIType Travel:" << std::endl; - std::cout << " Travel Coordinates: (" << p.mTravel.mX << "," - << p.mTravel.mY << "," << p.mTravel.mZ << ")" << std::endl; - std::cout << " Travel Unknown: " << (int)p.mTravel.mUnk << std::endl; - } - else if (p.mType == ESM::AI_Follow || p.mType == ESM::AI_Escort) - { - if (p.mType == ESM::AI_Follow) std::cout << " AIType Follow:" << std::endl; - else std::cout << " AIType Escort:" << std::endl; +std::string ruleString(ESM::DialInfo::SelectStruct ss) +{ + std::string rule = ss.mSelectRule; + + if (rule.length() < 5) + return "INVALID"; + + char type = rule[1]; + char indicator = rule[2]; + + std::string type_str = "INVALID"; + std::string func_str = str(boost::format("INVALID=%s") % rule.substr(1,3)); + int func; + std::istringstream iss(rule.substr(2,2)); + iss >> func; - std::cout << " Follow Coordinates: (" << p.mTarget.mX << "," - << p.mTarget.mY << "," << p.mTarget.mZ << ")" << std::endl; - std::cout << " Duration: " << p.mTarget.mDuration << std::endl; - std::cout << " Target ID: " << p.mTarget.mId.toString() << std::endl; - std::cout << " Unknown: " << (int)p.mTarget.mUnk << std::endl; - } - else if (p.mType == ESM::AI_Activate) - { - std::cout << " AIType Activate:" << std::endl; - std::cout << " Name: " << p.mActivate.mName.toString() << std::endl; - std::cout << " Activate Unknown: " << (int)p.mActivate.mUnk << std::endl; - } - else { - std::cout << " BadPackage: " << boost::format("0x%08x") % p.mType << std::endl; - } + switch(type) + { + case '1': + type_str = "Function"; + func_str = ruleFunction(func); + break; + case '2': + if (indicator == 's') type_str = "Global short"; + else if (indicator == 'l') type_str = "Global long"; + else if (indicator == 'f') type_str = "Global float"; + break; + case '3': + if (indicator == 's') type_str = "Local short"; + else if (indicator == 'l') type_str = "Local long"; + else if (indicator == 'f') type_str = "Local float"; + break; + case '4': if (indicator == 'J') type_str = "Journal"; break; + case '5': if (indicator == 'I') type_str = "Item type"; break; + case '6': if (indicator == 'D') type_str = "NPC Dead"; break; + case '7': if (indicator == 'X') type_str = "Not ID"; break; + case '8': if (indicator == 'F') type_str = "Not Faction"; break; + case '9': if (indicator == 'C') type_str = "Not Class"; break; + case 'A': if (indicator == 'R') type_str = "Not Race"; break; + case 'B': if (indicator == 'L') type_str = "Not Cell"; break; + case 'C': if (indicator == 's') type_str = "Not Local"; break; + } + + // Append the variable name to the function string if any. + if (type != '1') func_str = rule.substr(5); + + // In the previous switch, we assumed that the second char was X + // for all types not qual to one. If this wasn't true, go back to + // the error message. + if (type != '1' && rule[3] != 'X') + func_str = str(boost::format("INVALID=%s") % rule.substr(1,3)); - if (p.mCellName != "") - std::cout << " Cell Name: " << p.mCellName << std::endl; + char oper = rule[4]; + std::string oper_str = "??"; + switch (oper) + { + case '0': oper_str = "=="; break; + case '1': oper_str = "!="; break; + case '2': oper_str = "< "; break; + case '3': oper_str = "<="; break; + case '4': oper_str = "> "; break; + case '5': oper_str = ">="; break; + } + + std::string value_str = "??"; + if (ss.mType == ESM::VT_Int) + value_str = str(boost::format("%d") % ss.mI); + else if (ss.mType == ESM::VT_Float) + value_str = str(boost::format("%f") % ss.mF); + + std::string result = str(boost::format("%-12s %-32s %2s %s") + % type_str % func_str % oper_str % value_str); + return result; } void printEffectList(ESM::EffectList effects) @@ -57,12 +129,16 @@ void printEffectList(ESM::EffectList effects) std::vector::iterator eit; for (eit = effects.mList.begin(); eit != effects.mList.end(); eit++) { - std::cout << " Effect[" << i << "]: " << eit->mEffectID << std::endl; + std::cout << " Effect[" << i << "]: " << magicEffectLabel(eit->mEffectID) + << " (" << eit->mEffectID << ")" << std::endl; if (eit->mSkill != -1) - std::cout << " Skill: " << (int)eit->mSkill << std::endl; + std::cout << " Skill: " << skillLabel(eit->mSkill) + << " (" << (int)eit->mSkill << ")" << std::endl; if (eit->mAttribute != -1) - std::cout << " Attribute: " << (int)eit->mAttribute << std::endl; - std::cout << " Range: " << eit->mRange << std::endl; + std::cout << " Attribute: " << attributeLabel(eit->mAttribute) + << " (" << (int)eit->mAttribute << ")" << std::endl; + std::cout << " Range: " << rangeTypeLabel(eit->mRange) + << " (" << eit->mRange << ")" << std::endl; // Area is always zero if range type is "Self" if (eit->mRange != ESM::RT_Self) std::cout << " Area: " << eit->mArea << std::endl; @@ -331,7 +407,8 @@ void Record::print() std::cout << " Script: " << mData.mScript << std::endl; if (mData.mEnchant != "") std::cout << " Enchantment: " << mData.mEnchant << std::endl; - std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Type: " << armorTypeLabel(mData.mData.mType) + << " (" << mData.mData.mType << ")" << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Health: " << mData.mData.mHealth << std::endl; @@ -340,7 +417,8 @@ void Record::print() std::vector::iterator pit; for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); pit++) { - std::cout << " Body Part: " << (int)(pit->mPart) << std::endl; + std::cout << " Body Part: " << bodyPartLabel(pit->mPart) + << " (" << (int)(pit->mPart) << ")" << std::endl; std::cout << " Male Name: " << pit->mMale << std::endl; if (pit->mFemale != "") std::cout << " Female Name: " << pit->mFemale << std::endl; @@ -354,7 +432,8 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Type: " << apparatusTypeLabel(mData.mData.mType) + << " (" << (int)mData.mData.mType << ")" << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Quality: " << mData.mData.mQuality << std::endl; @@ -365,9 +444,11 @@ void Record::print() { std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Type: " << (int)mData.mData.mType << std::endl; - std::cout << " Flags: " << (int)mData.mData.mFlags << std::endl; - std::cout << " Part: " << (int)mData.mData.mPart << std::endl; + std::cout << " Type: " << meshTypeLabel(mData.mData.mType) + << " (" << (int)mData.mData.mType << ")" << std::endl; + std::cout << " Flags: " << bodyPartFlags(mData.mData.mFlags) << std::endl; + std::cout << " Part: " << meshPartLabel(mData.mData.mPart) + << " (" << (int)mData.mData.mPart << ")" << std::endl; std::cout << " Vampire: " << (int)mData.mData.mVampire << std::endl; } @@ -413,7 +494,7 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; if (mData.mRegion != "") std::cout << " Region: " << mData.mRegion << std::endl; - std::cout << " Flags: " << (int)mData.mData.mFlags << std::endl; + std::cout << " Flags: " << cellFlags(mData.mData.mFlags) << std::endl; std::cout << " Coordinates: " << " (" << mData.getGridX() << "," << mData.getGridY() << ")" << std::endl; @@ -441,13 +522,18 @@ void Record::print() std::cout << " Description: " << mData.mDescription << std::endl; std::cout << " Playable: " << mData.mData.mIsPlayable << std::endl; std::cout << " AutoCalc: " << mData.mData.mCalc << std::endl; - std::cout << " Attribute1: " << mData.mData.mAttribute[0] << std::endl; - std::cout << " Attribute2: " << mData.mData.mAttribute[1] << std::endl; - std::cout << " Specialization: " << mData.mData.mSpecialization << std::endl; + std::cout << " Attribute1: " << attributeLabel(mData.mData.mAttribute[0]) + << " (" << mData.mData.mAttribute[0] << ")" << std::endl; + std::cout << " Attribute2: " << attributeLabel(mData.mData.mAttribute[1]) + << " (" << mData.mData.mAttribute[1] << ")" << std::endl; + std::cout << " Specialization: " << specializationLabel(mData.mData.mSpecialization) + << " (" << mData.mData.mSpecialization << ")" << std::endl; for (int i = 0; i != 5; i++) - std::cout << " Major Skill: " << mData.mData.mSkills[i][0] << std::endl; + std::cout << " Major Skill: " << skillLabel(mData.mData.mSkills[i][0]) + << " (" << mData.mData.mSkills[i][0] << ")" << std::endl; for (int i = 0; i != 5; i++) - std::cout << " Minor Skill: " << mData.mData.mSkills[i][1] << std::endl; + std::cout << " Minor Skill: " << skillLabel(mData.mData.mSkills[i][1]) + << " (" << mData.mData.mSkills[i][1] << ")" << std::endl; } template<> @@ -460,10 +546,20 @@ void Record::print() std::cout << " Script: " << mData.mScript << std::endl; if (mData.mEnchant != "") std::cout << " Enchantment: " << mData.mEnchant << std::endl; - std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Type: " << clothingTypeLabel(mData.mData.mType) + << " (" << mData.mData.mType << ")" << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; - // mEnchant also in CTDTstruct? + std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; + std::vector::iterator pit; + for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); pit++) + { + std::cout << " Body Part: " << bodyPartLabel(pit->mPart) + << " (" << (int)(pit->mPart) << ")" << std::endl; + std::cout << " Male Name: " << pit->mMale << std::endl; + if (pit->mFemale != "") + std::cout << " Female Name: " << pit->mFemale << std::endl; + } } template<> @@ -473,7 +569,7 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; if (mData.mScript != "") std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Flags: " << containerFlags(mData.mFlags) << std::endl; std::cout << " Weight: " << mData.mWeight << std::endl; std::vector::iterator cit; for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++) @@ -487,11 +583,12 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Flags: " << creatureFlags(mData.mFlags) << std::endl; std::cout << " Original: " << mData.mOriginal << std::endl; std::cout << " Scale: " << mData.mScale << std::endl; - std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Type: " << creatureTypeLabel(mData.mData.mType) + << " (" << mData.mData.mType << ")" << std::endl; std::cout << " Level: " << mData.mData.mLevel << std::endl; std::cout << " Attributes:" << std::endl; @@ -547,7 +644,8 @@ void Record::print() template<> void Record::print() { - std::cout << " Type: " << (int)mData.mType << std::endl; + std::cout << " Type: " << dialogTypeLabel(mData.mType) + << " (" << (int)mData.mType << ")" << std::endl; // Sadly, there are no DialInfos, because the loader dumps as it // loads, rather than loading and then dumping. :-( Anyone mind if // I change this? @@ -569,7 +667,8 @@ void Record::print() template<> void Record::print() { - std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Type: " << enchantTypeLabel(mData.mData.mType) + << " (" << mData.mData.mType << ")" << std::endl; std::cout << " Cost: " << mData.mData.mCost << std::endl; std::cout << " Charge: " << mData.mData.mCharge << std::endl; std::cout << " AutoCalc: " << mData.mData.mAutocalc << std::endl; @@ -583,11 +682,14 @@ void Record::print() std::cout << " Hidden: " << mData.mData.mIsHidden << std::endl; if (mData.mData.mUnknown != -1) std::cout << " Unknown: " << mData.mData.mUnknown << std::endl; - std::cout << " Attribute1: " << mData.mData.mAttribute1 << std::endl; - std::cout << " Attribute2: " << mData.mData.mAttribute2 << std::endl; + std::cout << " Attribute1: " << attributeLabel(mData.mData.mAttribute1) + << " (" << mData.mData.mAttribute1 << ")" << std::endl; + std::cout << " Attribute2: " << attributeLabel(mData.mData.mAttribute2) + << " (" << mData.mData.mAttribute2 << ")" << std::endl; for (int i = 0; i != 6; i++) if (mData.mData.mSkillID[i] != -1) - std::cout << " Skill: " << mData.mData.mSkillID[i] << std::endl; + std::cout << " Skill: " << skillLabel(mData.mData.mSkillID[i]) + << " (" << mData.mData.mSkillID[i] << ")" << std::endl; for (int i = 0; i != 10; i++) if (mData.mRanks[i] != "") { @@ -683,13 +785,14 @@ void Record::print() // std::cout << "-------------------------------------------" << std::endl; } - std::cout << " Quest Status: " << mData.mQuestStatus << std::endl; + std::cout << " Quest Status: " << questStatusLabel(mData.mQuestStatus) + << " (" << mData.mQuestStatus << ")" << std::endl; std::cout << " Unknown1: " << mData.mData.mUnknown1 << std::endl; std::cout << " Unknown2: " << (int)mData.mData.mUnknown2 << std::endl; std::vector::iterator sit; for (sit = mData.mSelects.begin(); sit != mData.mSelects.end(); sit++) - std::cout << " Select Rule: " << sit->mType << " " << sit->mSelectRule << std::endl; + std::cout << " Select Rule: " << ruleString(*sit) << std::endl; } template<> @@ -706,9 +809,12 @@ void Record::print() { // A value of -1 means no effect if (mData.mData.mEffectID[i] == -1) continue; - std::cout << " Effect: " << mData.mData.mEffectID[i] << std::endl; - std::cout << " Skill: " << mData.mData.mSkills[i] << std::endl; - std::cout << " Attribute: " << mData.mData.mAttributes[i] << std::endl; + std::cout << " Effect: " << magicEffectLabel(mData.mData.mEffectID[i]) + << " (" << mData.mData.mEffectID[i] << ")" << std::endl; + std::cout << " Skill: " << skillLabel(mData.mData.mSkills[i]) + << " (" << mData.mData.mSkills[i] << ")" << std::endl; + std::cout << " Attribute: " << attributeLabel(mData.mData.mAttributes[i]) + << " (" << mData.mData.mAttributes[i] << ")" << std::endl; } } @@ -716,7 +822,7 @@ template<> void Record::print() { std::cout << " Coordinates: (" << mData.mX << "," << mData.mY << ")" << std::endl; - std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Flags: " << landFlags(mData.mFlags) << std::endl; std::cout << " HasData: " << mData.mHasData << std::endl; std::cout << " DataTypes: " << mData.mDataTypes << std::endl; @@ -739,7 +845,7 @@ template<> void Record::print() { std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; - std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Flags: " << leveledListFlags(mData.mFlags) << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl; std::vector::iterator iit; for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) @@ -751,7 +857,7 @@ template<> void Record::print() { std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; - std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Flags: " << leveledListFlags(mData.mFlags) << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl; std::vector::iterator iit; for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) @@ -770,7 +876,7 @@ void Record::print() std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Flags: " << lightFlags(mData.mData.mFlags) << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Sound: " << mData.mSound << std::endl; @@ -802,6 +908,7 @@ void Record::print() std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") std::cout << " Script: " << mData.mScript << std::endl; + // BUG? No Type Label? std::cout << " Type: " << mData.mType << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -835,10 +942,11 @@ void Record::print() template<> void Record::print() { - std::cout << " Index: " << mData.mIndex << std::endl; + std::cout << " Index: " << magicEffectLabel(mData.mIndex) + << " (" << mData.mIndex << ")" << std::endl; std::cout << " Description: " << mData.mDescription << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; - std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Flags: " << magicEffectFlags(mData.mData.mFlags) << std::endl; std::cout << " Particle Texture: " << mData.mParticle << std::endl; if (mData.mCasting != "") std::cout << " Casting Static: " << mData.mCasting << std::endl; @@ -856,7 +964,8 @@ void Record::print() std::cout << " Area Static: " << mData.mArea << std::endl; if (mData.mAreaSound != "") std::cout << " Area Sound: " << mData.mAreaSound << std::endl; - std::cout << " School: " << mData.mData.mSchool << std::endl; + std::cout << " School: " << schoolLabel(mData.mData.mSchool) + << " (" << mData.mData.mSchool << ")" << std::endl; std::cout << " Base Cost: " << mData.mData.mBaseCost << std::endl; std::cout << " Speed: " << mData.mData.mSpeed << std::endl; std::cout << " Size: " << mData.mData.mSize << std::endl; @@ -893,7 +1002,7 @@ void Record::print() std::cout << " Script: " << mData.mScript << std::endl; if (mData.mFaction != "") std::cout << " Faction: " << mData.mFaction << std::endl; - std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Flags: " << npcFlags(mData.mFlags) << std::endl; // Seriously? if (mData.mNpdt52.mGold == -10) @@ -929,7 +1038,7 @@ void Record::print() std::cout << " Skills:" << std::endl; for (int i = 0; i != 27; i++) - std::cout << " " << i << " = " + std::cout << " " << skillLabel(i) << ": " << (int)((unsigned char)mData.mNpdt52.mSkills[i]) << std::endl; std::cout << " Health: " << mData.mNpdt52.mHealth << std::endl; @@ -1018,7 +1127,7 @@ void Record::print() { std::cout << " Name: " << mData.mName << std::endl; std::cout << " Description: " << mData.mDescription << std::endl; - std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Flags: " << raceFlags(mData.mData.mFlags) << std::endl; std::cout << " Male:" << std::endl; std::cout << " Strength: " @@ -1067,8 +1176,10 @@ void Record::print() for (int i = 0; i != 7; i++) // Not all races have 7 skills. if (mData.mData.mBonus[i].mSkill != -1) - std::cout << " Skill: " << mData.mData.mBonus[i].mSkill - << " = " << mData.mData.mBonus[i].mBonus << std::endl; + std::cout << " Skill: " + << skillLabel(mData.mData.mBonus[i].mSkill) + << " (" << mData.mData.mBonus[i].mSkill << ") = " + << mData.mData.mBonus[i].mBonus << std::endl; std::vector::iterator sit; for (sit = mData.mPowers.mList.begin(); sit != mData.mPowers.mList.end(); sit++) @@ -1130,18 +1241,15 @@ void Record::print() template<> void Record::print() { - std::cout << " ID: " << mData.mIndex << std::endl; - - const char *spec = 0; - int specId = mData.mData.mSpecialization; - if (specId == 0) { - spec = "Combat"; - } else if (specId == 1) { - spec = "Magic"; - } else { - spec = "Stealth"; - } - std::cout << " Type: " << spec << std::endl; + std::cout << " ID: " << skillLabel(mData.mIndex) + << " (" << mData.mIndex << ")" << std::endl; + std::cout << " Description: " << mData.mDescription << std::endl; + std::cout << " Governing Attribute: " << attributeLabel(mData.mData.mAttribute) + << " (" << mData.mData.mAttribute << ")" << std::endl; + std::cout << " Specialization: " << specializationLabel(mData.mData.mSpecialization) + << " (" << mData.mData.mSpecialization << ")" << std::endl; + for (int i = 0; i != 4; i++) + std::cout << " UseValue[" << i << "]:" << mData.mData.mUseValue[i] << std::endl; } template<> @@ -1149,7 +1257,8 @@ void Record::print() { std::cout << " Creature: " << mData.mCreature << std::endl; std::cout << " Sound: " << mData.mSound << std::endl; - std::cout << " Type: " << mData.mType << std::endl; + std::cout << " Type: " << soundTypeLabel(mData.mType) + << " (" << mData.mType << ")" << std::endl; } template<> @@ -1166,8 +1275,9 @@ template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Type: " << mData.mData.mType << std::endl; - std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Type: " << spellTypeLabel(mData.mData.mType) + << " (" << mData.mData.mType << ")" << std::endl; + std::cout << " Flags: " << spellFlags(mData.mData.mFlags) << std::endl; std::cout << " Cost: " << mData.mData.mCost << std::endl; printEffectList(mData.mEffects); } @@ -1199,8 +1309,9 @@ void Record::print() std::cout << " Script: " << mData.mScript << std::endl; if (mData.mEnchant != "") std::cout << " Enchantment: " << mData.mEnchant << std::endl; - std::cout << " Type: " << mData.mData.mType << std::endl; - std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Type: " << weaponTypeLabel(mData.mData.mType) + << " (" << mData.mData.mType << ")" << std::endl; + std::cout << " Flags: " << weaponFlags(mData.mData.mFlags) << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Health: " << mData.mData.mHealth << std::endl; From e4a61486c8420606aac580973f088ec141d956fc Mon Sep 17 00:00:00 2001 From: cfcohen Date: Wed, 10 Oct 2012 22:15:19 -0400 Subject: [PATCH 20/45] Removed minor comments left in by accident. --- apps/esmtool/labels.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/esmtool/labels.cpp b/apps/esmtool/labels.cpp index 1ebed1d55..9fb233237 100644 --- a/apps/esmtool/labels.cpp +++ b/apps/esmtool/labels.cpp @@ -48,7 +48,6 @@ std::string bodyPartLabel(char idx) "Tail" }; - // BUG? idx should probably be unsigned char instead if ((int)idx >= 0 && (int)(idx) <= 26) return bodyPartLabels[(int)(idx)]; else @@ -576,7 +575,6 @@ std::string ruleFunction(int idx) "Player Skill Mercantile", "Player Skill Speechcraft", "Player Skill Hand to Hand", -// Unknown1=0->Male, Unknown1=1->Female "Player Gender", "Player Expelled from Faction", "Player Diseased (Common)", @@ -646,7 +644,7 @@ std::string cellFlags(int flags) if (flags & ESM::Cell::Interior) properties += "Interior "; if (flags & ESM::Cell::NoSleep) properties += "NoSleep "; if (flags & ESM::Cell::QuasiEx) properties += "QuasiEx "; - // CHANGE? This used value is not in the ESM component. + // This used value is not in the ESM component. if (flags & 0x00000040) properties += "Unknown "; int unused = (0xFFFFFFFF ^ (ESM::Cell::HasWater| @@ -725,9 +723,8 @@ std::string leveledListFlags(int flags) std::string properties = ""; if (flags == 0) properties += "[None] "; if (flags & ESM::LeveledListBase::AllLevels) properties += "AllLevels "; - // BUG? This flag apparently not present on creature lists... + // This flag apparently not present on creature lists... if (flags & ESM::LeveledListBase::Each) properties += "Each "; - // BUG! The unsused bits should be defined in LeveledListBase. int unused = (0xFFFFFFFF ^ (ESM::LeveledListBase::AllLevels| ESM::LeveledListBase::Each)); From 17dc67be0a0f5a651b9693f053aba49305c044d5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 11 Oct 2012 09:08:51 +0200 Subject: [PATCH 21/45] updated credits.txt --- credits.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/credits.txt b/credits.txt index 2968e3487..45611a2d6 100644 --- a/credits.txt +++ b/credits.txt @@ -16,6 +16,7 @@ Alexander Olofsson (Ace) Artem Kotsynyak (greye) athile BrotherBrick +Cory F. Cohen (cfcohen) Cris Mihalache (Mirceam) Douglas Diniz (Dgdiniz) Eli2 From c9afe222bec803da4035e9e106b73acc55c5af77 Mon Sep 17 00:00:00 2001 From: gugus Date: Tue, 16 Oct 2012 19:34:29 +0200 Subject: [PATCH 22/45] traveling now takes time --- apps/openmw/mwgui/travelwindow.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index c2eb33c6c..7dbfdf315 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -4,10 +4,13 @@ #include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/player.hpp" #include "../mwworld/manualref.hpp" @@ -76,7 +79,6 @@ namespace MWGui toAdd->setCaptionWithReplacing(travelId+" - "+boost::lexical_cast(price)+"#{sgp}"); toAdd->setSize(toAdd->getTextSize().width,sLineHeight); toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel); - //toAdd->setUserString("ToolTipType", "Spell"); toAdd->setUserString("Destination", travelId); toAdd->setUserData(pos); toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onTravelButtonClick); @@ -141,6 +143,7 @@ namespace MWGui if (mWindowManager.getInventoryWindow()->getPlayerGold()>=price) { + //MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); ESM::Position pos = *_sender->getUserData(); std::string cellname = _sender->getUserString("Destination"); @@ -149,10 +152,23 @@ namespace MWGui MWBase::Environment::get().getWorld()->positionToIndex(pos.pos[0],pos.pos[1],x,y); MWWorld::CellStore* cell; if(interior) cell = MWBase::Environment::get().getWorld()->getInterior(cellname); - else cell = MWBase::Environment::get().getWorld()->getExterior(x,y); + else + { + cell = MWBase::Environment::get().getWorld()->getExterior(x,y); + 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) ); + int time = int(d /MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fTravelTimeMult")->getFloat()); + std::cout << time; + for(int i = 0;i < time;i++) + { + MWBase::Environment::get().getMechanicsManager ()->restoreDynamicStats (); + } + MWBase::Environment::get().getWorld()->advanceTime(time); + } MWBase::Environment::get().getWorld()->moveObject(player,*cell,pos.pos[0],pos.pos[1],pos.pos[2]); mWindowManager.removeGuiMode(GM_Travel); mWindowManager.removeGuiMode(GM_Dialogue); + //MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(0.5); } } From 9583a1b8e94df2721a3b5256215ab0ba9ca18da5 Mon Sep 17 00:00:00 2001 From: gugus Date: Tue, 16 Oct 2012 19:59:53 +0200 Subject: [PATCH 23/45] FadeOut/In, that's for you scrawl! --- apps/openmw/mwgui/travelwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 7dbfdf315..fcdd80081 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -143,7 +143,7 @@ namespace MWGui if (mWindowManager.getInventoryWindow()->getPlayerGold()>=price) { - //MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1); + MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); ESM::Position pos = *_sender->getUserData(); std::string cellname = _sender->getUserString("Destination"); @@ -168,7 +168,7 @@ namespace MWGui MWBase::Environment::get().getWorld()->moveObject(player,*cell,pos.pos[0],pos.pos[1],pos.pos[2]); mWindowManager.removeGuiMode(GM_Travel); mWindowManager.removeGuiMode(GM_Dialogue); - //MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(0.5); + MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(1); } } From 7d1e659960c2eaffeb9b61adf479bfa390cfd87b Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 16 Oct 2012 20:25:50 +0200 Subject: [PATCH 24/45] fading, greying out destinations you cant afford, warning fix --- apps/openmw/mwgui/loadingscreen.cpp | 5 +++ apps/openmw/mwgui/travelwindow.cpp | 70 +++++++++++++++-------------- extern/shiny | 2 +- 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 170fc3bc5..9ffb39221 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -6,10 +6,12 @@ #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/inputmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" @@ -106,6 +108,7 @@ namespace MWGui if (mTimer.getMilliseconds () > mLastRenderTime + (1.f/loadingScreenFps) * 1000.f) { + float dt = mTimer.getMilliseconds () - mLastRenderTime; mLastRenderTime = mTimer.getMilliseconds (); if (mFirstLoad && mTimer.getMilliseconds () > mLastWallpaperChangeTime + 3000*1) @@ -151,6 +154,8 @@ namespace MWGui } } + MWBase::Environment::get().getWorld ()->getFader ()->update (dt); + mWindow->update(); if (!hasCompositor) diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index fcdd80081..da138a42e 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -52,26 +52,28 @@ namespace MWGui void TravelWindow::addDestination(const std::string& travelId,ESM::Position pos,bool interior) { - //std::cout << "travel to" << travelId; - /*const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); - int price = spell->data.cost*MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fSpellValueMult")->getFloat();*/ int price = 0; - MyGUI::Button* toAdd = mDestinationsView->createWidget((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SpellText", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); - mCurrentY += sLineHeight; - /// \todo price adjustment depending on merchantile skill + if(interior) { - toAdd->setUserString("interior","y"); price = MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fMagesGuildTravel")->getFloat(); } else { - toAdd->setUserString("interior","n"); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); ESM::Position PlayerPos = player.getRefData().getPosition(); float d = sqrt( pow(pos.pos[0] - PlayerPos.pos[0],2) + pow(pos.pos[1] - PlayerPos.pos[1],2) + pow(pos.pos[2] - PlayerPos.pos[2],2) ); price = d/MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fTravelMult")->getFloat(); } + + MyGUI::Button* toAdd = mDestinationsView->createWidget((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SpellText", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); + mCurrentY += sLineHeight; + /// \todo price adjustment depending on merchantile skill + if(interior) + toAdd->setUserString("interior","y"); + else + toAdd->setUserString("interior","n"); + std::ostringstream oss; oss << price; toAdd->setUserString("price",oss.str()); @@ -118,7 +120,7 @@ namespace MWGui addDestination (*iter); }*/ - for(int i = 0;i()->base->mTransport.size();i++) + for(unsigned int i = 0;i()->base->mTransport.size();i++) { std::string cellname = mPtr.get()->base->mTransport[i].mCellName; bool interior = true; @@ -141,35 +143,35 @@ namespace MWGui int price; iss >> price; - if (mWindowManager.getInventoryWindow()->getPlayerGold()>=price) + assert (mWindowManager.getInventoryWindow()->getPlayerGold()>=price); + + MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + ESM::Position pos = *_sender->getUserData(); + std::string cellname = _sender->getUserString("Destination"); + int x,y; + bool interior = _sender->getUserString("interior") == "y"; + MWBase::Environment::get().getWorld()->positionToIndex(pos.pos[0],pos.pos[1],x,y); + MWWorld::CellStore* cell; + if(interior) cell = MWBase::Environment::get().getWorld()->getInterior(cellname); + else { - MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - ESM::Position pos = *_sender->getUserData(); - std::string cellname = _sender->getUserString("Destination"); - int x,y; - bool interior = _sender->getUserString("interior") == "y"; - MWBase::Environment::get().getWorld()->positionToIndex(pos.pos[0],pos.pos[1],x,y); - MWWorld::CellStore* cell; - if(interior) cell = MWBase::Environment::get().getWorld()->getInterior(cellname); - else + cell = MWBase::Environment::get().getWorld()->getExterior(x,y); + 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) ); + int time = int(d /MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fTravelTimeMult")->getFloat()); + std::cout << time; + for(int i = 0;i < time;i++) { - cell = MWBase::Environment::get().getWorld()->getExterior(x,y); - 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) ); - int time = int(d /MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fTravelTimeMult")->getFloat()); - std::cout << time; - for(int i = 0;i < time;i++) - { - MWBase::Environment::get().getMechanicsManager ()->restoreDynamicStats (); - } - MWBase::Environment::get().getWorld()->advanceTime(time); + MWBase::Environment::get().getMechanicsManager ()->restoreDynamicStats (); } - MWBase::Environment::get().getWorld()->moveObject(player,*cell,pos.pos[0],pos.pos[1],pos.pos[2]); - mWindowManager.removeGuiMode(GM_Travel); - mWindowManager.removeGuiMode(GM_Dialogue); - MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(1); + MWBase::Environment::get().getWorld()->advanceTime(time); } + MWBase::Environment::get().getWorld()->moveObject(player,*cell,pos.pos[0],pos.pos[1],pos.pos[2]); + mWindowManager.removeGuiMode(GM_Travel); + mWindowManager.removeGuiMode(GM_Dialogue); + MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0); + MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(1); } void TravelWindow::onCancelButtonClicked(MyGUI::Widget* _sender) diff --git a/extern/shiny b/extern/shiny index 4750676ac..f17c4ebab 160000 --- a/extern/shiny +++ b/extern/shiny @@ -1 +1 @@ -Subproject commit 4750676ac46a7aaa86bca53dc68c5a1ba11f3bc1 +Subproject commit f17c4ebab0e7a1f3bbb25fd9b3dbef2bd742536a From 5e9153e2b8766ff42b9aadcba6aaba2e5bb50688 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Tue, 16 Oct 2012 23:16:14 +0300 Subject: [PATCH 25/45] Issue #423: Wrong usage of "Version" Remove "Version" line from openmw.desktop file (according to http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s05.html it's not required). Fixes #423 Signed-off-by: Lukasz Gromanowski --- files/openmw.desktop | 1 - 1 file changed, 1 deletion(-) diff --git a/files/openmw.desktop b/files/openmw.desktop index 234f660c6..118cd3bbe 100644 --- a/files/openmw.desktop +++ b/files/openmw.desktop @@ -1,5 +1,4 @@ [Desktop Entry] -Version=${OPENMW_VERSION} Type=Application Name=OpenMW Launcher GenericName=Role Playing Game From 6acbea822b70b8b7e5f5c6f6222ac892da4a5e26 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 16 Oct 2012 23:59:03 +0200 Subject: [PATCH 26/45] splash screen directory listing --- apps/openmw/mwgui/loadingscreen.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 170fc3bc5..bb3aade61 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -6,6 +6,8 @@ #include #include +#include + #include "../mwbase/environment.hpp" @@ -207,20 +209,16 @@ namespace MWGui void LoadingScreen::changeWallpaper () { - /// \todo use a directory listing here std::vector splash; - splash.push_back ("Splash_Bonelord.tga"); - splash.push_back ("Splash_ClannDaddy.tga"); - splash.push_back ("Splash_Clannfear.tga"); - splash.push_back ("Splash_Daedroth.tga"); - splash.push_back ("Splash_Hunger.tga"); - splash.push_back ("Splash_KwamaWarrior.tga"); - splash.push_back ("Splash_Netch.tga"); - splash.push_back ("Splash_NixHound.tga"); - splash.push_back ("Splash_Siltstriker.tga"); - splash.push_back ("Splash_Skeleton.tga"); - splash.push_back ("Splash_SphereCenturion.tga"); + Ogre::StringVectorPtr resources = Ogre::ResourceGroupManager::getSingleton ().listResourceNames ("General", false); + for (Ogre::StringVector::const_iterator it = resources->begin(); it != resources->end(); ++it) + { + std::string start = it->substr(0, 6); + boost::to_lower(start); + if (start == "splash") + splash.push_back (*it); + } mBackgroundImage->setImageTexture (splash[rand() % splash.size()]); } } From 84a4fd56c32de6aa954c6e92490191926c4106a7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 17 Oct 2012 12:39:45 +0200 Subject: [PATCH 27/45] consider all files in Splash directory --- apps/openmw/engine.cpp | 5 ++--- apps/openmw/mwgui/loadingscreen.cpp | 6 +++++- components/bsa/bsa_archive.cpp | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index adbfca129..9b1a55025 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -163,9 +163,8 @@ void OMW::Engine::loadBSA() std::cout << "Data dir " << dataDirectory << std::endl; Bsa::addDir(dataDirectory, mFSStrict); - // Workaround: Mygui does not find textures in non-BSA subfolders, _unless_ they are explicitely added like this - // For splash screens, this is OK to do, but eventually we will need an investigation why this is necessary - Bsa::addDir(dataDirectory + "/Splash", mFSStrict); + // Workaround until resource listing capabilities are added to DirArchive, we need those to list available splash screens + addResourcesDirectory (dataDirectory); } } diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index bb3aade61..cfe54c91a 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -216,9 +216,13 @@ namespace MWGui { std::string start = it->substr(0, 6); boost::to_lower(start); + if (start == "splash") splash.push_back (*it); } - mBackgroundImage->setImageTexture (splash[rand() % splash.size()]); + std::string randomSplash = splash[rand() % splash.size()]; + + Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton ().load (randomSplash, "General"); + mBackgroundImage->setImageTexture (randomSplash); } } diff --git a/components/bsa/bsa_archive.cpp b/components/bsa/bsa_archive.cpp index 081207b0c..8380b0838 100644 --- a/components/bsa/bsa_archive.cpp +++ b/components/bsa/bsa_archive.cpp @@ -375,7 +375,7 @@ void addBSA(const std::string& name, const std::string& group) { insertBSAFactory(); ResourceGroupManager::getSingleton(). - addResourceLocation(name, "BSA", group); + addResourceLocation(name, "BSA", group, true); } void addDir(const std::string& name, const bool& fs, const std::string& group) @@ -384,7 +384,7 @@ void addDir(const std::string& name, const bool& fs, const std::string& group) insertDirFactory(); ResourceGroupManager::getSingleton(). - addResourceLocation(name, "Dir", group); + addResourceLocation(name, "Dir", group, true); } } From 6be092e26819baa5142b1a059079e105b4921690 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 17 Oct 2012 12:41:24 +0200 Subject: [PATCH 28/45] substr check --- apps/openmw/mwgui/loadingscreen.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index cfe54c91a..2eccc8f2a 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -214,6 +214,8 @@ namespace MWGui Ogre::StringVectorPtr resources = Ogre::ResourceGroupManager::getSingleton ().listResourceNames ("General", false); for (Ogre::StringVector::const_iterator it = resources->begin(); it != resources->end(); ++it) { + if (it->size() < 6) + continue; std::string start = it->substr(0, 6); boost::to_lower(start); From 1a2034b4dddfacafd52a2fbd2eeec72e008d4b57 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 17 Oct 2012 18:03:02 +0200 Subject: [PATCH 29/45] training window --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwbase/windowmanager.hpp | 1 + apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 3 + apps/openmw/mwgui/dialogue.cpp | 8 + apps/openmw/mwgui/dialogue.hpp | 3 +- apps/openmw/mwgui/mode.hpp | 1 + apps/openmw/mwgui/trainingwindow.cpp | 152 ++++++++++++++++++ apps/openmw/mwgui/trainingwindow.hpp | 36 +++++ apps/openmw/mwgui/windowmanagerimp.cpp | 16 ++ apps/openmw/mwgui/windowmanagerimp.hpp | 3 + apps/openmw/mwsound/ffmpeg_decoder.hpp | 2 +- components/esm/aipackage.hpp | 2 - files/mygui/CMakeLists.txt | 1 + files/mygui/openmw_trainingwindow.layout | 31 ++++ 14 files changed, 256 insertions(+), 5 deletions(-) create mode 100644 apps/openmw/mwgui/trainingwindow.cpp create mode 100644 apps/openmw/mwgui/trainingwindow.hpp create mode 100644 files/mygui/openmw_trainingwindow.layout diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index bc4e10501..d3698b53e 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -30,7 +30,7 @@ add_openmw_dir (mwgui formatting inventorywindow container hud countdialog tradewindow settingswindow confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog - enchantingdialog + enchantingdialog trainingwindow ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 462aef014..f4c78f5fb 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -230,6 +230,7 @@ namespace MWBase virtual void startSpellMaking(MWWorld::Ptr actor) = 0; virtual void startEnchanting(MWWorld::Ptr actor) = 0; + virtual void startTraining(MWWorld::Ptr actor) = 0; }; } diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 3a51ed2b6..063794eba 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -801,6 +801,9 @@ namespace MWDialogue if (services & ESM::NPC::Spellmaking) windowServices |= MWGui::DialogueWindow::Service_CreateSpells; + if (services & ESM::NPC::Training) + windowServices |= MWGui::DialogueWindow::Service_Training; + if (services & ESM::NPC::Enchanting) windowServices |= MWGui::DialogueWindow::Service_Enchant; diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index d03724628..d5b4ca672 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -147,6 +147,11 @@ void DialogueWindow::onSelectTopic(std::string topic) mWindowManager.pushGuiMode(GM_Enchanting); mWindowManager.startEnchanting (mPtr); } + else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sServiceTrainingTitle")->getString()) + { + mWindowManager.pushGuiMode(GM_Training); + mWindowManager.startTraining (mPtr); + } else MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic)); } @@ -181,6 +186,9 @@ void DialogueWindow::setKeywords(std::list keyWords) if (mServices & Service_Enchant) mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sEnchanting")->getString()); + if (mServices & Service_Training) + mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sServiceTrainingTitle")->getString()); + if (anyService) mTopicsList->addSeparator(); diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index acbe75eed..1592e49ee 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -57,7 +57,8 @@ namespace MWGui Service_Trade = 0x01, Service_BuySpells = 0x02, Service_CreateSpells = 0x04, - Service_Enchant = 0x08 + Service_Enchant = 0x08, + Service_Training = 0x10 }; protected: diff --git a/apps/openmw/mwgui/mode.hpp b/apps/openmw/mwgui/mode.hpp index 7fd033f5e..e594a5d0b 100644 --- a/apps/openmw/mwgui/mode.hpp +++ b/apps/openmw/mwgui/mode.hpp @@ -24,6 +24,7 @@ namespace MWGui GM_SpellBuying, GM_SpellCreation, GM_Enchanting, + GM_Training, GM_Levelup, diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp new file mode 100644 index 000000000..536b3a3a6 --- /dev/null +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -0,0 +1,152 @@ +#include "trainingwindow.hpp" + +#include + +#include + +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/player.hpp" + +#include "../mwmechanics/npcstats.hpp" + +#include "inventorywindow.hpp" +#include "tradewindow.hpp" +#include "tooltips.hpp" + +namespace MWGui +{ + + TrainingWindow::TrainingWindow(MWBase::WindowManager &parWindowManager) + : WindowBase("openmw_trainingwindow.layout", parWindowManager) + , mFadeTimeRemaining(0) + { + getWidget(mTrainingOptions, "TrainingOptions"); + getWidget(mCancelButton, "CancelButton"); + getWidget(mPlayerGold, "PlayerGold"); + + mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onCancelButtonClicked); + } + + void TrainingWindow::open() + { + center(); + } + + void TrainingWindow::startTraining (MWWorld::Ptr actor) + { + mPtr = actor; + + mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast(mWindowManager.getInventoryWindow()->getPlayerGold())); + + MWMechanics::NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats (actor); + + // NPC can train you in his best 3 skills + std::vector< std::pair > bestSkills; + bestSkills.push_back (std::make_pair(-1, -1)); + bestSkills.push_back (std::make_pair(-1, -1)); + bestSkills.push_back (std::make_pair(-1, -1)); + + for (int i=0; i bestSkills[j].second) + { + if (j<2) + { + bestSkills[j+1] = bestSkills[j]; + } + bestSkills[j] = std::make_pair(i, value); + break; + } + } + } + + MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator (); + MyGUI::Gui::getInstance ().destroyWidgets (widgets); + + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer (); + MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); + + for (int i=0; i<3; ++i) + { + /// \todo mercantile skill + int price = pcStats.getSkill (bestSkills[i].first).getBase() * MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find("iTrainingMod")->getInt (); + + std::string skin = (price > mWindowManager.getInventoryWindow ()->getPlayerGold ()) ? "SandTextGreyedOut" : "SandTextButton"; + + MyGUI::Button* button = mTrainingOptions->createWidget(skin, + MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default); + + button->setUserData(bestSkills[i].first); + button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected); + + button->setCaptionWithReplacing("#{" + ESM::Skill::sSkillNameIds[bestSkills[i].first] + "} - " + boost::lexical_cast(price)); + + button->setSize(button->getTextSize ().width+12, button->getSize().height); + + ToolTips::createSkillToolTip (button, bestSkills[i].first); + } + + center(); + } + + void TrainingWindow::onReferenceUnavailable () + { + mWindowManager.removeGuiMode(GM_Training); + } + + void TrainingWindow::onCancelButtonClicked (MyGUI::Widget *sender) + { + mWindowManager.removeGuiMode (GM_Training); + } + + void TrainingWindow::onTrainingSelected (MyGUI::Widget *sender) + { + int skillId = *sender->getUserData(); + + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer (); + MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); + + /// \todo mercantile skill + int price = pcStats.getSkill (skillId).getBase() * MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find("iTrainingMod")->getInt (); + + if (mWindowManager.getInventoryWindow()->getPlayerGold() *playerRef = player.get(); + const ESM::Class *class_ = MWBase::Environment::get().getWorld()->getStore().classes.find ( + playerRef->base->mClass); + pcStats.increaseSkill (skillId, *class_, true); + + // remove gold + mWindowManager.getTradeWindow()->addOrRemoveGold(-price); + + // go back to game mode + mWindowManager.removeGuiMode (GM_Training); + mWindowManager.removeGuiMode (GM_Dialogue); + + // advance time + MWBase::Environment::get().getWorld ()->advanceTime (2); + + MWBase::Environment::get().getWorld ()->getFader()->fadeOut(0.25); + mFadeTimeRemaining = 0.5; + } + + void TrainingWindow::onFrame(float dt) + { + if (mFadeTimeRemaining <= 0) + return; + + mFadeTimeRemaining -= dt; + + if (mFadeTimeRemaining <= 0) + MWBase::Environment::get().getWorld ()->getFader()->fadeIn(0.25); + } +} diff --git a/apps/openmw/mwgui/trainingwindow.hpp b/apps/openmw/mwgui/trainingwindow.hpp new file mode 100644 index 000000000..f2ef1714e --- /dev/null +++ b/apps/openmw/mwgui/trainingwindow.hpp @@ -0,0 +1,36 @@ +#ifndef MWGUI_TRAININGWINDOW_H +#define MWGUI_TRAININGWINDOW_H + +#include "window_base.hpp" +#include "referenceinterface.hpp" + +namespace MWGui +{ + + class TrainingWindow : public WindowBase, public ReferenceInterface + { + public: + TrainingWindow(MWBase::WindowManager& parWindowManager); + + virtual void open(); + + void startTraining(MWWorld::Ptr actor); + + void onFrame(float dt); + + protected: + virtual void onReferenceUnavailable (); + + void onCancelButtonClicked (MyGUI::Widget* sender); + void onTrainingSelected(MyGUI::Widget* sender); + + MyGUI::Widget* mTrainingOptions; + MyGUI::Button* mCancelButton; + MyGUI::TextBox* mPlayerGold; + + float mFadeTimeRemaining; + }; + +} + +#endif diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 906bb2ca7..ea5c5b6cb 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -48,6 +48,7 @@ #include "waitdialog.hpp" #include "spellcreationdialog.hpp" #include "enchantingdialog.hpp" +#include "trainingwindow.hpp" using namespace MWGui; @@ -79,6 +80,7 @@ WindowManager::WindowManager( , mWaitDialog(NULL) , mSpellCreationDialog(NULL) , mEnchantingDialog(NULL) + , mTrainingWindow(NULL) , mPlayerClass() , mPlayerName() , mPlayerRaceId() @@ -161,6 +163,7 @@ WindowManager::WindowManager( mWaitDialog = new WaitDialog(*this); mSpellCreationDialog = new SpellCreationDialog(*this); mEnchantingDialog = new EnchantingDialog(*this); + mTrainingWindow = new TrainingWindow(*this); mLoadingScreen = new LoadingScreen(mOgre->getScene (), mOgre->getWindow (), *this); mLoadingScreen->onResChange (w,h); @@ -218,6 +221,7 @@ WindowManager::~WindowManager() delete mWaitDialog; delete mSpellCreationDialog; delete mEnchantingDialog; + delete mTrainingWindow; cleanupGarbage(); @@ -269,6 +273,7 @@ void WindowManager::updateVisible() mWaitDialog->setVisible(false); mSpellCreationDialog->setVisible(false); mEnchantingDialog->setVisible(false); + mTrainingWindow->setVisible(false); mHud->setVisible(true); @@ -375,6 +380,9 @@ void WindowManager::updateVisible() case GM_Enchanting: mEnchantingDialog->setVisible(true); break; + case GM_Training: + mTrainingWindow->setVisible(true); + break; case GM_InterMessageBox: break; case GM_Journal: @@ -574,6 +582,9 @@ void WindowManager::onFrame (float frameDuration) mHud->onFrame(frameDuration); + mTrainingWindow->onFrame (frameDuration); + + mTrainingWindow->checkReferenceAvailable(); mDialogueWindow->checkReferenceAvailable(); mTradeWindow->checkReferenceAvailable(); mSpellBuyingWindow->checkReferenceAvailable(); @@ -993,3 +1004,8 @@ void WindowManager::startEnchanting (MWWorld::Ptr actor) { mEnchantingDialog->startEnchanting (actor); } + +void WindowManager::startTraining(MWWorld::Ptr actor) +{ + mTrainingWindow->startTraining(actor); +} diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index d3890f635..8b0e744db 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -66,6 +66,7 @@ namespace MWGui class WaitDialog; class SpellCreationDialog; class EnchantingDialog; + class TrainingWindow; class WindowManager : public MWBase::WindowManager { @@ -215,6 +216,7 @@ namespace MWGui virtual void startSpellMaking(MWWorld::Ptr actor); virtual void startEnchanting(MWWorld::Ptr actor); + virtual void startTraining(MWWorld::Ptr actor); private: OEngine::GUI::MyGUIManager *mGuiManager; @@ -245,6 +247,7 @@ namespace MWGui WaitDialog* mWaitDialog; SpellCreationDialog* mSpellCreationDialog; EnchantingDialog* mEnchantingDialog; + TrainingWindow* mTrainingWindow; CharacterCreation* mCharGen; diff --git a/apps/openmw/mwsound/ffmpeg_decoder.hpp b/apps/openmw/mwsound/ffmpeg_decoder.hpp index 4344397c7..7b028e1d0 100644 --- a/apps/openmw/mwsound/ffmpeg_decoder.hpp +++ b/apps/openmw/mwsound/ffmpeg_decoder.hpp @@ -54,6 +54,6 @@ namespace MWSound #ifndef DEFAULT_DECODER #define DEFAULT_DECODER (::MWSound::FFmpeg_Decoder) #endif -}; +} #endif diff --git a/components/esm/aipackage.hpp b/components/esm/aipackage.hpp index 8e55b6889..3128fe0c6 100644 --- a/components/esm/aipackage.hpp +++ b/components/esm/aipackage.hpp @@ -18,8 +18,6 @@ namespace ESM { // These are probabilities char mHello, mU1, mFight, mFlee, mAlarm, mU2, mU3, mU4; - // The last u's might be the skills that this NPC can train you - // in? int mServices; // See the Services enum }; // 12 bytes diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index a33d59ef6..1354271d5 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -78,6 +78,7 @@ set(MYGUI_FILES openmw_spellcreation_dialog.layout openmw_edit_effect.layout openmw_enchanting_dialog.layout + openmw_trainingwindow.layout smallbars.png VeraMono.ttf markers.png diff --git a/files/mygui/openmw_trainingwindow.layout b/files/mygui/openmw_trainingwindow.layout new file mode 100644 index 000000000..e9855a33b --- /dev/null +++ b/files/mygui/openmw_trainingwindow.layout @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 125315ebe7115bbe3aad2da6a215c7a1a6539f90 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 17 Oct 2012 18:21:24 +0200 Subject: [PATCH 30/45] remove a cout --- apps/openmw/mwgui/dialogue.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index f0d15aed5..23d2197b7 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -140,10 +140,8 @@ void DialogueWindow::onSelectTopic(std::string topic) } else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sTravel")->getString()) { - std::cout << "travel!"; mWindowManager.pushGuiMode(GM_Travel); mWindowManager.getTravelWindow()->startTravel(mPtr); - //mWindowManager.getSpellBuyingWindow()->startSpellBuying(mPtr); } else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sSpellMakingMenuTitle")->getString()) { From e80394c0b57652b95d6899de361a96ef2aaef646 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 17 Oct 2012 18:48:29 +0200 Subject: [PATCH 31/45] fix training limit --- apps/openmw/mwgui/trainingwindow.cpp | 7 +++++++ files/mygui/openmw_trainingwindow.layout | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 536b3a3a6..af61b3487 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -119,6 +119,13 @@ namespace MWGui if (mWindowManager.getInventoryWindow()->getPlayerGold()()); + return; + } + // increase skill MWWorld::LiveCellRef *playerRef = player.get(); const ESM::Class *class_ = MWBase::Environment::get().getWorld()->getStore().classes.find ( diff --git a/files/mygui/openmw_trainingwindow.layout b/files/mygui/openmw_trainingwindow.layout index e9855a33b..aa39d0a5c 100644 --- a/files/mygui/openmw_trainingwindow.layout +++ b/files/mygui/openmw_trainingwindow.layout @@ -21,7 +21,7 @@ - + From 0a19b5603103bfb6a4f81a9112b4122a59e31fe8 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 17 Oct 2012 18:49:49 +0200 Subject: [PATCH 32/45] fix gold label --- files/mygui/openmw_trainingwindow.layout | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/files/mygui/openmw_trainingwindow.layout b/files/mygui/openmw_trainingwindow.layout index aa39d0a5c..c58bd0ab3 100644 --- a/files/mygui/openmw_trainingwindow.layout +++ b/files/mygui/openmw_trainingwindow.layout @@ -17,9 +17,8 @@ - + - From 5fbca239dd4da63fecd0634674d7e80e43e4e0b6 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 18 Oct 2012 14:02:06 +0200 Subject: [PATCH 33/45] Issue #61: potion creation (1st part; still missing some implementations) --- apps/openmw/mwmechanics/alchemy.cpp | 308 +++++++++++++++++++++++++++- apps/openmw/mwmechanics/alchemy.hpp | 62 +++++- components/esm/loadmgef.hpp | 2 + 3 files changed, 369 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index 6d3deed3c..c8a3cf162 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -1,15 +1,259 @@ #include "alchemy.hpp" +#include + #include #include +#include +#include +#include +#include + +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" + #include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/cellstore.hpp" + +#include "magiceffects.hpp" +#include "creaturestats.hpp" +#include "npcstats.hpp" + +std::set MWMechanics::Alchemy::listEffects() const +{ + std::set effects; + + for (TIngredientsIterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter) + { + if (!iter->isEmpty()) + { + const MWWorld::LiveCellRef *ingredient = iter->get(); + + for (int i=0; i<4; ++i) + if (ingredient->base->mData.mEffectID[i]!=-1) + effects.insert (EffectKey ( + ingredient->base->mData.mEffectID[i], ingredient->base->mData.mSkills[i]!=-1 ? + ingredient->base->mData.mSkills[i] : ingredient->base->mData.mAttributes[i])); + } + } + + return effects; +} + +void MWMechanics::Alchemy::filterEffects (std::set& effects) const +{ + std::set::iterator iter = effects.begin(); + + while (iter!=effects.end()) + { + bool remove = false; + + const EffectKey& key = *iter; + + { // dodge pointless g++ warning + for (TIngredientsIterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter) + { + bool found = false; + + const MWWorld::LiveCellRef *ingredient = iter->get(); + + for (int i=0; i<4; ++i) + if (key.mId==ingredient->base->mData.mEffectID[i] && + (key.mArg==ingredient->base->mData.mSkills[i] || + key.mArg==ingredient->base->mData.mAttributes[i])) + { + found = true; + break; + } + + if (!found) + { + remove = true; + break; + } + } + } + + if (remove) + effects.erase (iter++); + else + ++iter; + } +} + +void MWMechanics::Alchemy::applyTools (int flags, float& value) const +{ + bool magnitude = !(flags & ESM::MagicEffect::NoMagnitude); + bool duration = !(flags & ESM::MagicEffect::NoDuration); + bool negative = flags & (ESM::MagicEffect::Negative | ESM::MagicEffect::Negative2); + + int tool = negative ? ESM::Apparatus::Retort : ESM::Apparatus::Albemic; + + int setup = 0; + + if (!mTools[tool].isEmpty() && !mTools[ESM::Apparatus::Calcinator].isEmpty()) + setup = 1; + else if (!mTools[tool].isEmpty()) + setup = 2; + else if (!mTools[ESM::Apparatus::Calcinator].isEmpty()) + setup = 3; + else + return; + + float toolQuality = setup==1 || setup==2 ? mTools[tool].get()->base->mData.mQuality : 0; + float calcinatorQuality = setup==1 || setup==3 ? + mTools[ESM::Apparatus::Calcinator].get()->base->mData.mQuality : 0; + + float quality = 1; + + switch (setup) + { + case 1: + + quality = negative ? 2 * toolQuality + 3 * calcinatorQuality : + (magnitude && duration ? + 2 * toolQuality + calcinatorQuality : 2/3.0 * (toolQuality + calcinatorQuality) + 0.5); + break; + + case 2: + + quality = negative ? 1+toolQuality : (magnitude && duration ? toolQuality : toolQuality + 0.5); + break; + + case 3: + + quality = magnitude && duration ? calcinatorQuality : calcinatorQuality + 0.5; + break; + } + + if (setup==3 || !negative) + { + value += quality; + } + else + { + if (quality==0) + throw std::runtime_error ("invalid derived alchemy apparatus quality"); + + value /= quality; + } +} + +void MWMechanics::Alchemy::updateEffects() +{ + mEffects.clear(); + + int ingredients = 0; + + for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) + if (!iter->isEmpty()) + ++ingredients; + + if (ingredients<2 || mAlchemist.isEmpty() || mTools[ESM::Apparatus::MortarPestle].isEmpty()) + return; + + // find effects + std::set effects (listEffects()); + filterEffects (effects); + + // general alchemy factor + float x = getChance(); + + x *= mTools[ESM::Apparatus::MortarPestle].get()->base->mData.mQuality; + x *= MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fPotionStrengthMult")->getFloat(); + + // build quantified effect list + for (std::set::const_iterator iter (effects.begin()); iter!=effects.end(); ++iter) + { + const ESM::MagicEffect *magicEffect = + MWBase::Environment::get().getWorld()->getStore().magicEffects.find (iter->mId); + + if (magicEffect->mData.mBaseCost<=0) + throw std::runtime_error ("invalid base cost for magic effect " + iter->mId); + + float fPotionT1MagMul = + MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fPotionT1MagMul")->getFloat(); + + if (fPotionT1MagMul<=0) + throw std::runtime_error ("invalid gmst: fPotionT1MagMul"); + + float fPotionT1DurMult = + MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fPotionT1DurMult")->getFloat(); + + if (fPotionT1DurMult<=0) + throw std::runtime_error ("invalid gmst: fPotionT1DurMult"); + + float magnitude = magicEffect->mData.mFlags && ESM::MagicEffect::NoMagnitude ? + 1 : (x / fPotionT1MagMul) / magicEffect->mData.mBaseCost; + float duration = magicEffect->mData.mFlags && ESM::MagicEffect::NoDuration ? + 1 : (x / fPotionT1DurMult) / magicEffect->mData.mBaseCost; + + if (!(magicEffect->mData.mFlags && ESM::MagicEffect::NoMagnitude)) + applyTools (magicEffect->mData.mFlags, magnitude); + + if (!(magicEffect->mData.mFlags && ESM::MagicEffect::NoDuration)) + applyTools (magicEffect->mData.mFlags, duration); + + duration = static_cast (duration+0.5); + magnitude = static_cast (magnitude+0.5); + + if (magnitude>0 && duration>0) + { + ESM::ENAMstruct effect; + effect.mEffectID = iter->mId; + + effect.mSkill = effect.mAttribute = iter->mArg; // somewhat hack-ish, but should work + + effect.mRange = 0; + effect.mArea = 0; + + effect.mDuration = duration; + effect.mMagnMin = effect.mMagnMax = magnitude; + + mEffects.push_back (effect); + } + } +} + +const ESM::Potion *MWMechanics::Alchemy::getRecord() const +{ + +} + +void MWMechanics::Alchemy::removeIngredients() +{ + +} + +void MWMechanics::Alchemy::addPotion (const std::string& name) +{ + +} + +void MWMechanics::Alchemy::increaseSkill() +{ + +} + +float MWMechanics::Alchemy::getChance() const +{ + const CreatureStats& creatureStats = MWWorld::Class::get (mAlchemist).getCreatureStats (mAlchemist); + const NpcStats& npcStats = MWWorld::Class::get (mAlchemist).getNpcStats (mAlchemist); + + return + (npcStats.getSkill (ESM::Skill::Alchemy).getModified() + + 0.1 * creatureStats.getAttribute (1).getModified() + + 0.1 * creatureStats.getAttribute (7).getModified()); +} void MWMechanics::Alchemy::setAlchemist (const MWWorld::Ptr& npc) { - mNpc = npc; + mAlchemist = npc; mIngredients.resize (4); @@ -19,6 +263,8 @@ void MWMechanics::Alchemy::setAlchemist (const MWWorld::Ptr& npc) std::fill (mTools.begin(), mTools.end(), MWWorld::Ptr()); + mEffects.clear(); + MWWorld::ContainerStore& store = MWWorld::Class::get (npc).getContainerStore (npc); for (MWWorld::ContainerStoreIterator iter (store.begin (MWWorld::ContainerStore::Type_Apparatus)); @@ -61,9 +307,10 @@ MWMechanics::Alchemy::TIngredientsIterator MWMechanics::Alchemy::endIngredients( void MWMechanics::Alchemy::clear() { - mNpc = MWWorld::Ptr(); + mAlchemist = MWWorld::Ptr(); mTools.clear(); mIngredients.clear(); + mEffects.clear(); } int MWMechanics::Alchemy::addIngredient (const MWWorld::Ptr& ingredient) @@ -86,6 +333,8 @@ int MWMechanics::Alchemy::addIngredient (const MWWorld::Ptr& ingredient) return -1; mIngredients[slot] = ingredient; + + updateEffects(); return slot; } @@ -93,6 +342,61 @@ int MWMechanics::Alchemy::addIngredient (const MWWorld::Ptr& ingredient) void MWMechanics::Alchemy::removeIngredient (int index) { if (index>=0 && index (mIngredients.size())) + { mIngredients[index] = MWWorld::Ptr(); + updateEffects(); + } } +MWMechanics::Alchemy::TEffectsIterator MWMechanics::Alchemy::beginEffects() const +{ + return mEffects.begin(); +} + +MWMechanics::Alchemy::TEffectsIterator MWMechanics::Alchemy::endEffects() const +{ + return mEffects.end(); +} + +std::string MWMechanics::Alchemy::getPotionName() const +{ + if (const ESM::Potion *potion = getRecord()) + return potion->mName; + + return ""; +} + +MWMechanics::Alchemy::Result MWMechanics::Alchemy::create (const std::string& name) +{ + if (mTools[ESM::Apparatus::MortarPestle].isEmpty()) + return Result_NoMortarAndPestle; + + int ingredients = 0; + + for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) + if (!iter->isEmpty()) + ++ingredients; + + if (ingredients<2) + return Result_LessThanTwoIngredients; + + if (name.empty() && getPotionName().empty()) + return Result_NoName; + + if (beginEffects()==endEffects()) + return Result_NoEffects; + + if (getChance() (RAND_MAX)*100) + { + removeIngredients(); + return Result_RandomFailure; + } + + addPotion (name); + + removeIngredients(); + + increaseSkill(); + + return Result_Success; +} diff --git a/apps/openmw/mwmechanics/alchemy.hpp b/apps/openmw/mwmechanics/alchemy.hpp index 7c3cf9e68..73fa7eb18 100644 --- a/apps/openmw/mwmechanics/alchemy.hpp +++ b/apps/openmw/mwmechanics/alchemy.hpp @@ -2,11 +2,16 @@ #define GAME_MWMECHANICS_ALCHEMY_H #include +#include + +#include #include "../mwworld/ptr.hpp" namespace MWMechanics { + struct EffectKey; + /// \brief Potion creation via alchemy skill class Alchemy { @@ -17,13 +22,54 @@ namespace MWMechanics typedef std::vector TIngredientsContainer; typedef TIngredientsContainer::const_iterator TIngredientsIterator; + + typedef std::vector TEffectsContainer; + typedef TEffectsContainer::const_iterator TEffectsIterator; + + enum Result + { + Result_Success, + + Result_NoMortarAndPestle, + Result_LessThanTwoIngredients, + Result_NoName, + Result_NoEffects, + Result_RandomFailure + }; private: - MWWorld::Ptr mNpc; + MWWorld::Ptr mAlchemist; TToolsContainer mTools; TIngredientsContainer mIngredients; + TEffectsContainer mEffects; + std::set listEffects() const; + ///< List all effects of all used ingredients. + + void filterEffects (std::set& effects) const; + ///< Filter out effects not shared by all ingredients. + + void applyTools (int flags, float& value) const; + + void updateEffects(); + + const ESM::Potion *getRecord() const; + ///< Return existing recrod for created potion (may return 0) + + void removeIngredients(); + ///< Remove selected ingredients from alchemist's inventory, cleanup selected ingredients and + /// update effect list accordingly. + + void addPotion (const std::string& name); + ///< Add a potion to the alchemist's inventory. + + void increaseSkill(); + ///< Increase alchemist's skill. + + float getChance() const; + ///< Return chance of success. + public: void setAlchemist (const MWWorld::Ptr& npc); @@ -49,6 +95,20 @@ namespace MWMechanics void removeIngredient (int index); ///< Remove ingredient from slot (calling this function on an empty slot is a no-op). + + TEffectsIterator beginEffects() const; + + TEffectsIterator endEffects() const; + + std::string getPotionName() const; + ///< Return the name of the potion that would be created when calling create (if a record for such + /// a potion already exists) or return an empty string. + + Result create (const std::string& name); + ///< Try to create a potion from the ingredients, place it in the inventory of the alchemist and + /// adjust the skills of the alchemist accordingly. + /// \param name must not be an empty string, unless there is already a potion record ( + /// getPotionName() does not return an empty string). }; } diff --git a/components/esm/loadmgef.hpp b/components/esm/loadmgef.hpp index 861f66be0..a763576c3 100644 --- a/components/esm/loadmgef.hpp +++ b/components/esm/loadmgef.hpp @@ -14,6 +14,8 @@ struct MagicEffect enum Flags { NoDuration = 0x4, + NoMagnitude = 0x8, + Negative2 = 0x10, SpellMaking = 0x0200, Enchanting = 0x0400, Negative = 0x0800 // A harmful effect. Will determine whether From 3fe0a73cf24349a8a8abff9c27724dda9812e330 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 18 Oct 2012 14:38:38 +0200 Subject: [PATCH 34/45] Issue #61: increase alchemy skill on successful potion creation --- apps/openmw/mwmechanics/alchemy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index bf39afefb..3a5efbaaf 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -237,7 +237,7 @@ void MWMechanics::Alchemy::addPotion (const std::string& name) void MWMechanics::Alchemy::increaseSkill() { - + MWWorld::Class::get (mAlchemist).skillUsageSucceeded (mAlchemist, ESM::Skill::Alchemy, 0); } float MWMechanics::Alchemy::getChance() const From 3c71378fade9b52cd011034425aa7c585f818444 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 18 Oct 2012 14:41:57 +0200 Subject: [PATCH 35/45] Issue 61: improved ingredients handling in alchemy and documenation --- apps/openmw/mwmechanics/alchemy.cpp | 29 ++++++++++++++--------------- apps/openmw/mwmechanics/alchemy.hpp | 4 ++++ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index 3a5efbaaf..d59d71306 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -148,13 +148,7 @@ void MWMechanics::Alchemy::updateEffects() { mEffects.clear(); - int ingredients = 0; - - for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) - if (!iter->isEmpty()) - ++ingredients; - - if (ingredients<2 || mAlchemist.isEmpty() || mTools[ESM::Apparatus::MortarPestle].isEmpty()) + if (countIngredients()<2 || mAlchemist.isEmpty() || mTools[ESM::Apparatus::MortarPestle].isEmpty()) return; // find effects @@ -251,6 +245,17 @@ float MWMechanics::Alchemy::getChance() const + 0.1 * creatureStats.getAttribute (7).getModified()); } +int MWMechanics::Alchemy::countIngredients() const +{ + int ingredients = 0; + + for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) + if (!iter->isEmpty()) + ++ingredients; + + return ingredients; +} + void MWMechanics::Alchemy::setAlchemist (const MWWorld::Ptr& npc) { mAlchemist = npc; @@ -370,14 +375,8 @@ MWMechanics::Alchemy::Result MWMechanics::Alchemy::create (const std::string& na { if (mTools[ESM::Apparatus::MortarPestle].isEmpty()) return Result_NoMortarAndPestle; - - int ingredients = 0; - - for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) - if (!iter->isEmpty()) - ++ingredients; - - if (ingredients<2) + + if (countIngredients()<2) return Result_LessThanTwoIngredients; if (name.empty() && getPotionName().empty()) diff --git a/apps/openmw/mwmechanics/alchemy.hpp b/apps/openmw/mwmechanics/alchemy.hpp index 73fa7eb18..52af29912 100644 --- a/apps/openmw/mwmechanics/alchemy.hpp +++ b/apps/openmw/mwmechanics/alchemy.hpp @@ -70,6 +70,8 @@ namespace MWMechanics float getChance() const; ///< Return chance of success. + int countIngredients() const; + public: void setAlchemist (const MWWorld::Ptr& npc); @@ -77,10 +79,12 @@ namespace MWMechanics /// there is no alchemist (alchemy session has ended). TToolsIterator beginTools() const; + ///< \attention Iterates over tool slots, not over tools. Some of the slots may be empty. TToolsIterator endTools() const; TIngredientsIterator beginIngredients() const; + ///< \attention Iterates over ingredient slots, not over ingredients. Some of the slots may be empty. TIngredientsIterator endIngredients() const; From f5caf227b23e602dba92da031648c78eeee84450 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 18 Oct 2012 14:47:23 +0200 Subject: [PATCH 36/45] Issue #61: remove ingredients on potion creation --- apps/openmw/mwmechanics/alchemy.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index d59d71306..f59d87ae7 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -221,7 +221,21 @@ const ESM::Potion *MWMechanics::Alchemy::getRecord() const void MWMechanics::Alchemy::removeIngredients() { - + bool needsUpdate = false; + + for (TIngredientsContainer::iterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter) + if (!iter->isEmpty()) + { + iter->getRefData().setCount (iter->getRefData().getCount()-1); + if (iter->getRefData().getCount()<1) + { + needsUpdate = true; + *iter = MWWorld::Ptr(); + } + } + + if (needsUpdate) + updateEffects(); } void MWMechanics::Alchemy::addPotion (const std::string& name) From 1864dbe0311da194b720c92da4fb9f4b91f91743 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 18 Oct 2012 15:33:27 +0200 Subject: [PATCH 37/45] Issue #61: potion creation --- apps/openmw/mwmechanics/alchemy.cpp | 72 +++++++++++++++++++++++++++++ apps/openmw/mwmechanics/alchemy.hpp | 1 + 2 files changed, 73 insertions(+) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index f59d87ae7..e37a30210 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -1,6 +1,7 @@ #include "alchemy.hpp" +#include #include #include @@ -19,6 +20,7 @@ #include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/manualref.hpp" #include "magiceffects.hpp" #include "creaturestats.hpp" @@ -147,6 +149,7 @@ void MWMechanics::Alchemy::applyTools (int flags, float& value) const void MWMechanics::Alchemy::updateEffects() { mEffects.clear(); + mValue = 0; if (countIngredients()<2 || mAlchemist.isEmpty() || mTools[ESM::Apparatus::MortarPestle].isEmpty()) return; @@ -161,6 +164,10 @@ void MWMechanics::Alchemy::updateEffects() x *= mTools[ESM::Apparatus::MortarPestle].get()->base->mData.mQuality; x *= MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fPotionStrengthMult")->getFloat(); + // value + mValue = static_cast ( + x * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("iAlchemyMod")->getFloat()); + // build quantified effect list for (std::set::const_iterator iter (effects.begin()); iter!=effects.end(); ++iter) { @@ -216,7 +223,39 @@ void MWMechanics::Alchemy::updateEffects() const ESM::Potion *MWMechanics::Alchemy::getRecord() const { + for (ESMS::RecListWithIDT::MapType::const_iterator iter ( + MWBase::Environment::get().getWorld()->getStore().potions.list.begin()); + iter!=MWBase::Environment::get().getWorld()->getStore().potions.list.end(); ++iter) + { + if (iter->second.mEffects.mList.size()!=mEffects.size()) + continue; + + bool mismatch = false; + for (int i=0; i (iter->second.mEffects.mList.size()); ++iter) + { + const ESM::ENAMstruct& first = iter->second.mEffects.mList[i]; + const ESM::ENAMstruct& second = mEffects[i]; + + if (first.mEffectID!=second.mEffectID || + first.mArea!=second.mArea || + first.mRange!=second.mRange || + first.mSkill!=second.mSkill || + first.mAttribute!=second.mAttribute || + first.mMagnMin!=second.mMagnMin || + first.mMagnMax!=second.mMagnMax || + first.mDuration!=second.mDuration) + { + mismatch = true; + break; + } + } + + if (!mismatch) + return &iter->second; + } + + return 0; } void MWMechanics::Alchemy::removeIngredients() @@ -240,7 +279,40 @@ void MWMechanics::Alchemy::removeIngredients() void MWMechanics::Alchemy::addPotion (const std::string& name) { + const ESM::Potion *record = getRecord(); + + if (!record) + { + ESM::Potion newRecord; + + newRecord.mData.mWeight = 0; + + for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) + if (!iter->isEmpty()) + newRecord.mData.mWeight += iter->get()->base->mData.mWeight; + + newRecord.mData.mWeight /= countIngredients(); + + newRecord.mData.mValue = mValue; + newRecord.mData.mAutoCalc = 0; + + newRecord.mName = name; + int index = static_cast (std::rand()/static_cast (RAND_MAX)*6); + assert (index>=0 && index<6); + + static const char *name[] = { "standard", "bargain", "cheap", "fresh", "exclusive", "quality" }; + + newRecord.mModel = "m\\misc_potion_" + std::string (name[index]) + "_01.nif"; + newRecord.mIcon = "m\\tx_potion_" + std::string (name[index]) + "_01.dds"; + + newRecord.mEffects.mList = mEffects; + + record = MWBase::Environment::get().getWorld()->createRecord (newRecord).second; + } + + MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), record->mId); + MWWorld::Class::get (mAlchemist).getContainerStore (mAlchemist).add (ref.getPtr()); } void MWMechanics::Alchemy::increaseSkill() diff --git a/apps/openmw/mwmechanics/alchemy.hpp b/apps/openmw/mwmechanics/alchemy.hpp index 52af29912..7f3e2c0ea 100644 --- a/apps/openmw/mwmechanics/alchemy.hpp +++ b/apps/openmw/mwmechanics/alchemy.hpp @@ -43,6 +43,7 @@ namespace MWMechanics TToolsContainer mTools; TIngredientsContainer mIngredients; TEffectsContainer mEffects; + int mValue; std::set listEffects() const; ///< List all effects of all used ingredients. From 28cc480ce1d4175d54c1971d2449c0066c27d23a Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 18 Oct 2012 22:21:39 +0200 Subject: [PATCH 38/45] fix some alchemy issues and make the gui use the new implementation --- apps/openmw/engine.cpp | 15 +- apps/openmw/mwgui/alchemywindow.cpp | 204 +++++----------------------- apps/openmw/mwgui/alchemywindow.hpp | 12 +- apps/openmw/mwgui/tooltips.cpp | 10 +- apps/openmw/mwmechanics/alchemy.cpp | 15 +- apps/openmw/mwworld/worldimp.cpp | 18 +-- 6 files changed, 58 insertions(+), 216 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index adbfca129..3867cb76a 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -424,21 +424,10 @@ void OMW::Engine::activate() if (handle.empty()) return; - // the faced handle is not updated immediately, so on a cell change it might - // point to an object that doesn't exist anymore - // therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case - MWWorld::Ptr ptr; - try - { - ptr = MWBase::Environment::get().getWorld()->getPtrViaHandle (handle); + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPtrViaHandle (handle); - if (ptr.isEmpty()) - return; - } - catch (std::runtime_error&) - { + if (ptr.isEmpty()) return; - } MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr); diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index cef5d6e2e..192bbd090 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -70,142 +70,44 @@ namespace MWGui void AlchemyWindow::onCreateButtonClicked(MyGUI::Widget* _sender) { + std::string name = mNameEdit->getCaption(); + boost::algorithm::trim(name); + + MWMechanics::Alchemy::Result result = mAlchemy.create (mNameEdit->getCaption ()); + + if (result == MWMechanics::Alchemy::Result_NoName) + { + mWindowManager.messageBox("#{sNotifyMessage37}", std::vector()); + return; + } + // check if mortar & pestle is available (always needed) - /// \todo check albemic, calcinator, retort (sometimes needed) - if (!mApparatus[0]->isUserString("ToolTipType")) + if (result == MWMechanics::Alchemy::Result_NoMortarAndPestle) { mWindowManager.messageBox("#{sNotifyMessage45}", std::vector()); return; } // make sure 2 or more ingredients were selected - int numIngreds = 0; - for (int i=0; i<4; ++i) - if (mIngredients[i]->isUserString("ToolTipType")) - ++numIngreds; - - if (numIngreds < 2) + if (result == MWMechanics::Alchemy::Result_LessThanTwoIngredients) { mWindowManager.messageBox("#{sNotifyMessage6a}", std::vector()); return; } - // make sure a name was entered - std::string name = mNameEdit->getCaption(); - boost::algorithm::trim(name); - if (name == "") - { - mWindowManager.messageBox("#{sNotifyMessage37}", std::vector()); - return; - } - - // if there are no created effects, the potion will always fail (but the ingredients won't be destroyed) - if (mEffects.empty()) + if (result == MWMechanics::Alchemy::Result_NoEffects) { mWindowManager.messageBox("#{sNotifyMessage8}", std::vector()); MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f); return; } - if (rand() % 2 == 0) /// \todo + if (result == MWMechanics::Alchemy::Result_Success) { - ESM::Potion newPotion; - newPotion.mName = mNameEdit->getCaption(); - ESM::EffectList effects; - for (unsigned int i=0; i<4; ++i) - { - if (mEffects.size() >= i+1) - { - ESM::ENAMstruct effect; - effect.mEffectID = mEffects[i].mEffectID; - effect.mArea = 0; - effect.mRange = ESM::RT_Self; - effect.mSkill = mEffects[i].mSkill; - effect.mAttribute = mEffects[i].mAttribute; - effect.mMagnMin = 1; /// \todo - effect.mMagnMax = 10; /// \todo - effect.mDuration = 60; /// \todo - effects.mList.push_back(effect); - } - } - - // UESP Wiki / Morrowind:Alchemy - // "The weight of a potion is an average of the weight of the ingredients, rounded down." - // note by scrawl: not rounding down here, I can't imagine a created potion to - // have 0 weight when using ingredients with 0.1 weight respectively - float weight = 0; - for (int i=0; i<4; ++i) - if (mIngredients[i]->isUserString("ToolTipType")) - weight += mIngredients[i]->getUserData()->get()->base->mData.mWeight; - newPotion.mData.mWeight = weight / float(numIngreds); - - newPotion.mData.mValue = 100; /// \todo - newPotion.mEffects = effects; - // pick a random mesh and icon - std::vector names; - /// \todo is the mesh/icon dependent on alchemy skill? - names.push_back("standard"); - names.push_back("bargain"); - names.push_back("cheap"); - names.push_back("fresh"); - names.push_back("exclusive"); - names.push_back("quality"); - int random = rand() % names.size(); - newPotion.mModel = "m\\misc_potion_" + names[random ] + "_01.nif"; - newPotion.mIcon = "m\\tx_potion_" + names[random ] + "_01.dds"; - - // check if a similiar potion record exists already - bool found = false; - std::string objectId; - typedef std::map PotionMap; - PotionMap potions = MWBase::Environment::get().getWorld()->getStore().potions.list; - for (PotionMap::const_iterator it = potions.begin(); it != potions.end(); ++it) - { - if (found) break; - - if (it->second.mData.mValue == newPotion.mData.mValue - && it->second.mData.mWeight == newPotion.mData.mWeight - && it->second.mName == newPotion.mName - && it->second.mEffects.mList.size() == newPotion.mEffects.mList.size()) - { - // check effects - for (unsigned int i=0; i < it->second.mEffects.mList.size(); ++i) - { - const ESM::ENAMstruct& a = it->second.mEffects.mList[i]; - const ESM::ENAMstruct& b = newPotion.mEffects.mList[i]; - if (a.mEffectID == b.mEffectID - && a.mArea == b.mArea - && a.mRange == b.mRange - && a.mSkill == b.mSkill - && a.mAttribute == b.mAttribute - && a.mMagnMin == b.mMagnMin - && a.mMagnMax == b.mMagnMax - && a.mDuration == b.mDuration) - { - found = true; - objectId = it->first; - break; - } - } - } - } - - if (!found) - { - std::pair result = MWBase::Environment::get().getWorld()->createRecord(newPotion); - objectId = result.first; - } - - // create a reference and add it to player inventory - MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), objectId); - MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr); - ref.getPtr().getRefData().setCount(1); - store.add(ref.getPtr()); - mWindowManager.messageBox("#{sPotionSuccess}", std::vector()); MWBase::Environment::get().getSoundManager()->playSound("potion success", 1.f, 1.f); } - else + else if (result == MWMechanics::Alchemy::Result_RandomFailure) { // potion failed mWindowManager.messageBox("#{sNotifyMessage8}", std::vector()); @@ -229,7 +131,7 @@ namespace MWGui { openContainer (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); // this sets mPtr setFilter (ContainerBase::Filter_Ingredients); - + mAlchemy.setAlchemist (mPtr); int index = 0; @@ -277,6 +179,9 @@ namespace MWGui if (!mIngredients[i]->isUserString("ToolTipType")) { add = mIngredients[i]; + + mAlchemy.addIngredient(item); + break; } @@ -306,8 +211,6 @@ namespace MWGui void AlchemyWindow::update() { - Widgets::SpellEffectList effects; - for (int i=0; i<4; ++i) { MyGUI::ImageBox* ingredient = mIngredients[i]; @@ -315,19 +218,6 @@ namespace MWGui if (!ingredient->isUserString("ToolTipType")) continue; - // add the effects of this ingredient to list of effects - MWWorld::LiveCellRef* ref = ingredient->getUserData()->get(); - for (int i=0; i<4; ++i) - { - if (ref->base->mData.mEffectID[i] < 0) - continue; - MWGui::Widgets::SpellEffectParams params; - params.mEffectID = ref->base->mData.mEffectID[i]; - params.mAttribute = ref->base->mData.mAttributes[i]; - params.mSkill = ref->base->mData.mSkills[i]; - effects.push_back(params); - } - // update ingredient count labels if (ingredient->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); @@ -340,50 +230,14 @@ namespace MWGui text->setCaption(getCountString(ingredient->getUserData()->getRefData().getCount())); } - // now remove effects that are only present once - Widgets::SpellEffectList::iterator it = effects.begin(); - while (it != effects.end()) + std::vector effects; + ESM::EffectList list; + list.mList = effects; + for (MWMechanics::Alchemy::TEffectsIterator it = mAlchemy.beginEffects (); it != mAlchemy.endEffects (); ++it) { - Widgets::SpellEffectList::iterator next = it; - ++next; - bool found = false; - for (; next != effects.end(); ++next) - { - if (*next == *it) - found = true; - } - - if (!found) - it = effects.erase(it); - else - ++it; + list.mList.push_back(*it); } - // now remove duplicates, and don't allow more than 4 effects - Widgets::SpellEffectList old = effects; - effects.clear(); - int i=0; - for (Widgets::SpellEffectList::iterator it = old.begin(); - it != old.end(); ++it) - { - bool found = false; - for (Widgets::SpellEffectList::iterator it2 = effects.begin(); - it2 != effects.end(); ++it2) - { - // MW considers all "foritfy attribute" effects as the same effect. See the - // "Can't create multi-state boost potions" discussion on http://www.uesp.net/wiki/Morrowind_talk:Alchemy - // thus, we are only checking effectID here and not attribute or skill - if (it2->mEffectID == it->mEffectID) - found = true; - } - if (!found && i<4) - { - ++i; - effects.push_back(*it); - } - } - mEffects = effects; - while (mEffectsBox->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(mEffectsBox->getChildAt(0)); @@ -391,7 +245,9 @@ namespace MWGui Widgets::MWEffectListPtr effectsWidget = mEffectsBox->createWidget ("MW_StatName", coord, MyGUI::Align::Left | MyGUI::Align::Top); effectsWidget->setWindowManager(&mWindowManager); - effectsWidget->setEffectList(effects); + + Widgets::SpellEffectList _list = Widgets::MWEffectList::effectListFromESM(&list); + effectsWidget->setEffectList(_list); std::vector effectItems; effectsWidget->createEffectWidgets(effectItems, mEffectsBox, coord, false, 0); @@ -404,5 +260,9 @@ namespace MWGui static_cast(ingredient)->setImageTexture(""); if (ingredient->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); + + for (int i=0; i<4; ++i) + if (mIngredients[i] == ingredient) + mAlchemy.removeIngredient (i); } } diff --git a/apps/openmw/mwgui/alchemywindow.hpp b/apps/openmw/mwgui/alchemywindow.hpp index 179cdd174..5f84e73e9 100644 --- a/apps/openmw/mwgui/alchemywindow.hpp +++ b/apps/openmw/mwgui/alchemywindow.hpp @@ -26,8 +26,6 @@ namespace MWGui MyGUI::EditBox* mNameEdit; - Widgets::SpellEffectList mEffects; // effects of created potion - void onCancelButtonClicked(MyGUI::Widget* _sender); void onCreateButtonClicked(MyGUI::Widget* _sender); void onIngredientSelected(MyGUI::Widget* _sender); @@ -41,12 +39,12 @@ namespace MWGui void update(); - private: - - MWMechanics::Alchemy mAlchemy; + private: - std::vector mApparatus; - std::vector mIngredients; + MWMechanics::Alchemy mAlchemy; + + std::vector mApparatus; + std::vector mIngredients; }; } diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 39afba749..5256028eb 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -79,14 +79,10 @@ void ToolTips::onFrame(float frameDuration) || (mWindowManager->getMode() == GM_Inventory))) { std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); - try - { - mFocusObject = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle); - } - catch (std::exception /* & e */) - { + + mFocusObject = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle); + if (mFocusObject.isEmpty ()) return; - } MyGUI::IntSize tooltipSize = getToolTipViaPtr(true); diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index e37a30210..583a3c18e 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -62,6 +62,9 @@ void MWMechanics::Alchemy::filterEffects (std::set& effects) const { bool found = false; + if (iter->isEmpty()) + continue; + const MWWorld::LiveCellRef *ingredient = iter->get(); for (int i=0; i<4; ++i) @@ -178,7 +181,7 @@ void MWMechanics::Alchemy::updateEffects() throw std::runtime_error ("invalid base cost for magic effect " + iter->mId); float fPotionT1MagMul = - MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fPotionT1MagMul")->getFloat(); + MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fPotionT1MagMult")->getFloat(); if (fPotionT1MagMul<=0) throw std::runtime_error ("invalid gmst: fPotionT1MagMul"); @@ -189,15 +192,15 @@ void MWMechanics::Alchemy::updateEffects() if (fPotionT1DurMult<=0) throw std::runtime_error ("invalid gmst: fPotionT1DurMult"); - float magnitude = magicEffect->mData.mFlags && ESM::MagicEffect::NoMagnitude ? + float magnitude = magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude ? 1 : (x / fPotionT1MagMul) / magicEffect->mData.mBaseCost; - float duration = magicEffect->mData.mFlags && ESM::MagicEffect::NoDuration ? + float duration = magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration ? 1 : (x / fPotionT1DurMult) / magicEffect->mData.mBaseCost; - if (!(magicEffect->mData.mFlags && ESM::MagicEffect::NoMagnitude)) + if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) applyTools (magicEffect->mData.mFlags, magnitude); - if (!(magicEffect->mData.mFlags && ESM::MagicEffect::NoDuration)) + if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)) applyTools (magicEffect->mData.mFlags, duration); duration = static_cast (duration+0.5); @@ -471,7 +474,7 @@ MWMechanics::Alchemy::Result MWMechanics::Alchemy::create (const std::string& na if (beginEffects()==endEffects()) return Result_NoEffects; - if (getChance() (RAND_MAX)*100) + if (getChance() (RAND_MAX)) { removeIngredients(); return Result_RandomFailure; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 6fc228f0b..8d8542bb5 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -339,7 +339,7 @@ namespace MWWorld return ptr; } - throw std::runtime_error ("unknown Ogre handle: " + handle); + return MWWorld::Ptr(); } void World::enable (const Ptr& reference) @@ -850,12 +850,13 @@ namespace MWWorld mWeatherManager->update (duration); // inform the GUI about focused object - try - { - MWWorld::Ptr object = getPtrViaHandle(mFacedHandle); - MWBase::Environment::get().getWindowManager()->setFocusObject(object); + MWWorld::Ptr object = getPtrViaHandle(mFacedHandle); - // retrieve object dimensions so we know where to place the floating label + MWBase::Environment::get().getWindowManager()->setFocusObject(object); + + // retrieve object dimensions so we know where to place the floating label + if (!object.isEmpty ()) + { Ogre::SceneNode* node = object.getRefData().getBaseNode(); Ogre::AxisAlignedBox bounds; int i; @@ -871,11 +872,6 @@ namespace MWWorld screenCoords[0], screenCoords[1], screenCoords[2], screenCoords[3]); } } - catch (std::runtime_error&) - { - MWWorld::Ptr null; - MWBase::Environment::get().getWindowManager()->setFocusObject(null); - } if (!mRendering->occlusionQuerySupported()) { From 3f833af46a442e2aa08bdfbab71f39b510848505 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 19 Oct 2012 10:07:27 +0200 Subject: [PATCH 39/45] Issue #407: Fortyfy attribute effects were ignored for the last 3 attributes --- apps/openmw/mwmechanics/actors.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 87a058394..ab332eb96 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -118,18 +118,14 @@ namespace MWMechanics + fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified ()); } } - - - } - void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr) { CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); // attributes - for (int i=0; i<5; ++i) + for (int i=0; i<8; ++i) { int modifier = creatureStats.getMagicEffects().get (EffectKey (79, i)).mMagnitude; From d76522e7a48ed83c659e782d81bfdbe44ca761a1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 19 Oct 2012 19:48:02 +0200 Subject: [PATCH 40/45] searchPtrViaHandle --- apps/openmw/engine.cpp | 2 +- apps/openmw/mwbase/world.hpp | 3 +++ apps/openmw/mwgui/hud.cpp | 10 +--------- apps/openmw/mwgui/tooltips.cpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 10 +++++++++- apps/openmw/mwworld/worldimp.hpp | 3 +++ 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 3867cb76a..2ce890363 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -424,7 +424,7 @@ void OMW::Engine::activate() if (handle.empty()) return; - MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPtrViaHandle (handle); + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->searchPtrViaHandle (handle); if (ptr.isEmpty()) return; diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 521bbb988..9dcdc312f 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -142,6 +142,9 @@ namespace MWBase virtual MWWorld::Ptr getPtrViaHandle (const std::string& handle) = 0; ///< Return a pointer to a liveCellRef with the given Ogre handle. + virtual MWWorld::Ptr searchPtrViaHandle (const std::string& handle) = 0; + ///< Return a pointer to a liveCellRef with the given Ogre handle or Ptr() if not found + /// \todo enable reference in the OGRE scene virtual void enable (const MWWorld::Ptr& ptr) = 0; diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index ed0e59226..66cc6b21a 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -245,15 +245,7 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender) return; std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); - MWWorld::Ptr object; - try - { - object = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle); - } - catch (std::exception& /* e */) - { - return; - } + MWWorld::Ptr object = MWBase::Environment::get().getWorld()->searchPtrViaHandle(handle); if (mode == GM_Console) MWBase::Environment::get().getWindowManager()->getConsole()->setSelectedObject(object); diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 5256028eb..35224613c 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -80,7 +80,7 @@ void ToolTips::onFrame(float frameDuration) { std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); - mFocusObject = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle); + mFocusObject = MWBase::Environment::get().getWorld()->searchPtrViaHandle(handle); if (mFocusObject.isEmpty ()) return; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 8d8542bb5..2e3d80aa4 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -326,6 +326,14 @@ namespace MWWorld } Ptr World::getPtrViaHandle (const std::string& handle) + { + Ptr res = searchPtrViaHandle (handle); + if (res.isEmpty ()) + throw std::runtime_error ("unknown Ogre handle: " + handle); + return res; + } + + Ptr World::searchPtrViaHandle (const std::string& handle) { if (mPlayer->getPlayer().getRefData().getHandle()==handle) return mPlayer->getPlayer(); @@ -850,7 +858,7 @@ namespace MWWorld mWeatherManager->update (duration); // inform the GUI about focused object - MWWorld::Ptr object = getPtrViaHandle(mFacedHandle); + MWWorld::Ptr object = searchPtrViaHandle(mFacedHandle); MWBase::Environment::get().getWindowManager()->setFocusObject(object); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 90cd2151b..f94882c10 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -163,6 +163,9 @@ namespace MWWorld virtual Ptr getPtrViaHandle (const std::string& handle); ///< Return a pointer to a liveCellRef with the given Ogre handle. + virtual Ptr searchPtrViaHandle (const std::string& handle); + ///< Return a pointer to a liveCellRef with the given Ogre handle or Ptr() if not found + virtual void enable (const Ptr& ptr); virtual void disable (const Ptr& ptr); From 8d7514e341f4cd2c554507ea8c6c64772fec9714 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 19 Oct 2012 19:48:54 +0200 Subject: [PATCH 41/45] corrected chance --- apps/openmw/mwmechanics/alchemy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index 583a3c18e..df7c786b1 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -474,7 +474,7 @@ MWMechanics::Alchemy::Result MWMechanics::Alchemy::create (const std::string& na if (beginEffects()==endEffects()) return Result_NoEffects; - if (getChance() (RAND_MAX)) + if (getChance() (RAND_MAX)*100) { removeIngredients(); return Result_RandomFailure; From fbe3538f3263ee711f70aac8233009235e8c9f7e Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 19 Oct 2012 20:13:37 +0200 Subject: [PATCH 42/45] bug #412: sort birth signs --- apps/openmw/mwgui/birth.cpp | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index c8ef35be3..284653aee 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -14,6 +14,16 @@ using namespace MWGui; using namespace Widgets; +namespace +{ + +bool sortBirthSigns(const std::pair& left, const std::pair& right) +{ + return left.second->mName.compare (right.second->mName) < 0; +} + +} + BirthDialog::BirthDialog(MWBase::WindowManager& parWindowManager) : WindowBase("openmw_chargen_birth.layout", parWindowManager) { @@ -115,11 +125,21 @@ void BirthDialog::updateBirths() ESMS::RecListT::MapType::const_iterator it = store.birthSigns.list.begin(); ESMS::RecListT::MapType::const_iterator end = store.birthSigns.list.end(); int index = 0; - for (; it != end; ++it) + + // sort by name + std::vector < std::pair > birthSigns; + for (; it!=end; ++it) { - const ESM::BirthSign &birth = it->second; - mBirthList->addItem(birth.mName, it->first); - if (boost::iequals(it->first, mCurrentBirthId)) + std::string id = it->first; + const ESM::BirthSign* sign = &it->second; + birthSigns.push_back(std::make_pair(id, sign)); + } + std::sort(birthSigns.begin(), birthSigns.end(), sortBirthSigns); + + for (std::vector < std::pair >::const_iterator it2 = birthSigns.begin(); it2 != birthSigns.end(); ++it2) + { + mBirthList->addItem(it2->second->mName, it2->first); + if (boost::iequals(it2->first, mCurrentBirthId)) mBirthList->setIndexSelected(index); ++index; } From b2b92547187d46fc71ca5249ae1e4a69a16d8d76 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 19 Oct 2012 20:44:53 +0200 Subject: [PATCH 43/45] improved the ingredient GUI code (this didnt fix anything, though) --- apps/openmw/mwgui/alchemywindow.cpp | 60 +++++++++-------------------- 1 file changed, 19 insertions(+), 41 deletions(-) diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index 192bbd090..bda76490b 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -151,46 +151,15 @@ namespace MWGui void AlchemyWindow::onIngredientSelected(MyGUI::Widget* _sender) { removeIngredient(_sender); - drawItems(); update(); } void AlchemyWindow::onSelectedItemImpl(MWWorld::Ptr item) { - MyGUI::ImageBox* add = NULL; + int res = mAlchemy.addIngredient(item); - // don't allow to add an ingredient that is already added - // (which could happen if two similiar ingredients don't stack because of script / owner) - bool alreadyAdded = false; - std::string name = MWWorld::Class::get(item).getName(item); - for (int i=0; i<4; ++i) - if (mIngredients[i]->isUserString("ToolTipType")) - { - MWWorld::Ptr item2 = *mIngredients[i]->getUserData(); - std::string name2 = MWWorld::Class::get(item2).getName(item2); - if (name == name2) - alreadyAdded = true; - } - - if (alreadyAdded) - return; - - for (int i=0; i<4; ++i) - if (!mIngredients[i]->isUserString("ToolTipType")) - { - add = mIngredients[i]; - - mAlchemy.addIngredient(item); - - break; - } - - if (add != NULL) + if (res != -1) { - add->setUserString("ToolTipType", "ItemPtr"); - add->setUserData(item); - add->setImageTexture(getIconPath(item)); - drawItems(); update(); std::string sound = MWWorld::Class::get(item).getUpSoundId(item); @@ -211,17 +180,27 @@ namespace MWGui void AlchemyWindow::update() { + MWMechanics::Alchemy::TIngredientsIterator it = mAlchemy.beginIngredients (); for (int i=0; i<4; ++i) { MyGUI::ImageBox* ingredient = mIngredients[i]; - if (!ingredient->isUserString("ToolTipType")) - continue; + MWWorld::Ptr item = *it; + ++it; - // update ingredient count labels if (ingredient->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); + ingredient->setImageTexture(""); + ingredient->clearUserStrings (); + + if (item.isEmpty ()) + continue; + + ingredient->setUserString("ToolTipType", "ItemPtr"); + ingredient->setUserData(item); + ingredient->setImageTexture(getIconPath(item)); + MyGUI::TextBox* text = ingredient->createWidget("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label")); text->setTextAlign(MyGUI::Align::Right); text->setNeedMouseFocus(false); @@ -230,6 +209,8 @@ namespace MWGui text->setCaption(getCountString(ingredient->getUserData()->getRefData().getCount())); } + drawItems(); + std::vector effects; ESM::EffectList list; list.mList = effects; @@ -256,13 +237,10 @@ namespace MWGui void AlchemyWindow::removeIngredient(MyGUI::Widget* ingredient) { - ingredient->clearUserStrings(); - static_cast(ingredient)->setImageTexture(""); - if (ingredient->getChildCount()) - MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); - for (int i=0; i<4; ++i) if (mIngredients[i] == ingredient) mAlchemy.removeIngredient (i); + + update(); } } From 59560e84eb18b8376f383d0b7411b885108de3fe Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 19 Oct 2012 20:48:15 +0200 Subject: [PATCH 44/45] small addition --- apps/openmw/mwgui/alchemywindow.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index bda76490b..56db47a0f 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -146,6 +146,8 @@ namespace MWGui mApparatus.at (index)->setImageTexture (getIconPath (*iter)); } } + + update(); } void AlchemyWindow::onIngredientSelected(MyGUI::Widget* _sender) @@ -185,8 +187,12 @@ namespace MWGui { MyGUI::ImageBox* ingredient = mIngredients[i]; - MWWorld::Ptr item = *it; - ++it; + MWWorld::Ptr item; + if (it != mAlchemy.endIngredients ()) + { + item = *it; + ++it; + } if (ingredient->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); From 9f821e5df20370da3eb3c39f24a69e05c96cdc3b Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 22 Oct 2012 16:56:43 +0200 Subject: [PATCH 45/45] fix shaders --- files/materials/objects.shader | 15 ++++++++++++--- files/materials/terrain.shader | 12 ++++++++---- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/files/materials/objects.shader b/files/materials/objects.shader index 525e4ab63..5ea076342 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -157,10 +157,15 @@ shUniform(float4, shadowFar_fadeStart) @shSharedParameter(shadowFar_fadeStart) #endif -#if UNDERWATER +#if (UNDERWATER) || (FOG) shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix) - shUniform(float, waterLevel) @shSharedParameter(waterLevel) shUniform(float4, cameraPos) @shAutoConstant(cameraPos, camera_position) +#endif + +#if UNDERWATER + + shUniform(float, waterLevel) @shSharedParameter(waterLevel) + shUniform(float4, lightDirectionWS0) @shAutoConstant(lightDirectionWS0, light_position, 0) shSampler2D(causticMap) @@ -211,8 +216,12 @@ float3 caustics = float3(1,1,1); -#if UNDERWATER + +#if (UNDERWATER) || (FOG) float3 worldPos = shMatrixMult(worldMatrix, float4(objSpacePositionPassthrough,1)).xyz; +#endif + +#if UNDERWATER float3 waterEyePos = float3(1,1,1); // NOTE: this calculation would be wrong for non-uniform scaling float4 worldNormal = shMatrixMult(worldMatrix, float4(normal.xyz, 0)); diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index 35ce40330..dee733263 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -187,11 +187,13 @@ shUniform(float4, shadowFar_fadeStart) @shSharedParameter(shadowFar_fadeStart) #endif +#if (UNDERWATER) || (FOG) + shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix) + shUniform(float4, cameraPos) @shAutoConstant(cameraPos, camera_position) +#endif #if UNDERWATER - shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix) shUniform(float, waterLevel) @shSharedParameter(waterLevel) - shUniform(float4, cameraPos) @shAutoConstant(cameraPos, camera_position) shUniform(float4, lightDirectionWS0) @shAutoConstant(lightDirectionWS0, light_position, 0) shSampler2D(causticMap) @@ -222,9 +224,12 @@ float3 caustics = float3(1,1,1); +#if (UNDERWATER) || (FOG) + float3 worldPos = shMatrixMult(worldMatrix, float4(objSpacePosition,1)).xyz; +#endif + #if UNDERWATER - float3 worldPos = shMatrixMult(worldMatrix, float4(objSpacePosition,1)).xyz; float3 waterEyePos = float3(1,1,1); // NOTE: this calculation would be wrong for non-uniform scaling float4 worldNormal = shMatrixMult(worldMatrix, float4(normal.xyz, 0)); @@ -373,7 +378,6 @@ shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz); - #if MRT shOutputColour(1) = float4(depth / far,1,1,1); #endif