diff --git a/CMakeLists.txt b/CMakeLists.txt index b4ef872eb6..57ebeefcfd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,7 @@ message(STATUS "Configuring OpenMW...") set(OPENMW_VERSION_MAJOR 0) set(OPENMW_VERSION_MINOR 50) set(OPENMW_VERSION_RELEASE 0) -set(OPENMW_LUA_API_REVISION 86) +set(OPENMW_LUA_API_REVISION 87) set(OPENMW_POSTPROCESSING_API_REVISION 3) set(OPENMW_VERSION_COMMITHASH "") diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 0ea8451774..2a66878a04 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -5,7 +5,8 @@ #include #include -#include +#include +#include #include #include @@ -28,7 +29,6 @@ #include -#include #include #include diff --git a/apps/openmw/mwbase/luamanager.hpp b/apps/openmw/mwbase/luamanager.hpp index 61574de3ac..5772c555a3 100644 --- a/apps/openmw/mwbase/luamanager.hpp +++ b/apps/openmw/mwbase/luamanager.hpp @@ -75,6 +75,7 @@ namespace MWBase const MWRender::AnimPriority& priority, int blendMask, bool autodisable, float speedmult, std::string_view start, std::string_view stop, float startpoint, uint32_t loops, bool loopfallback) = 0; + virtual void jailTimeServed(const MWWorld::Ptr& actor, int days) = 0; virtual void skillLevelUp(const MWWorld::Ptr& actor, ESM::RefId skillId, std::string_view source) = 0; virtual void skillUse(const MWWorld::Ptr& actor, ESM::RefId skillId, int useType, float scale) = 0; virtual void onHit(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& weapon, diff --git a/apps/openmw/mwgui/jailscreen.cpp b/apps/openmw/mwgui/jailscreen.cpp index 2fbaa8d8ac..9244e9dd2f 100644 --- a/apps/openmw/mwgui/jailscreen.cpp +++ b/apps/openmw/mwgui/jailscreen.cpp @@ -4,6 +4,7 @@ #include #include "../mwbase/environment.hpp" +#include "../mwbase/luamanager.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" @@ -86,46 +87,6 @@ namespace MWGui // We should not worsen corprus when in prison player.getClass().getCreatureStats(player).getActiveSpells().skipWorsenings(mDays * 24); - - const auto& skillStore = MWBase::Environment::get().getESMStore()->get(); - std::set skills; - for (int day = 0; day < mDays; ++day) - { - auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - const ESM::Skill* skill = skillStore.searchRandom({}, prng); - skills.insert(skill); - - MWMechanics::SkillValue& value = player.getClass().getNpcStats(player).getSkill(skill->mId); - if (skill->mId == ESM::Skill::Security || skill->mId == ESM::Skill::Sneak) - value.setBase(std::min(100.f, value.getBase() + 1)); - else - value.setBase(std::max(0.f, value.getBase() - 1)); - } - - const MWWorld::Store& gmst - = MWBase::Environment::get().getESMStore()->get(); - - std::string message; - if (mDays == 1) - message = gmst.find("sNotifyMessage42")->mValue.getString(); - else - message = gmst.find("sNotifyMessage43")->mValue.getString(); - - message = Misc::StringUtils::format(message, mDays); - - for (const ESM::Skill* skill : skills) - { - int skillValue = player.getClass().getNpcStats(player).getSkill(skill->mId).getBase(); - std::string skillMsg = gmst.find("sNotifyMessage44")->mValue.getString(); - if (skill->mId == ESM::Skill::Sneak || skill->mId == ESM::Skill::Security) - skillMsg = gmst.find("sNotifyMessage39")->mValue.getString(); - - skillMsg = Misc::StringUtils::format(skillMsg, skill->mName, skillValue); - message += "\n" + skillMsg; - } - - std::vector buttons; - buttons.emplace_back("#{Interface:OK}"); - MWBase::Environment::get().getWindowManager()->interactiveMessageBox(message, buttons); + MWBase::Environment::get().getLuaManager()->jailTimeServed(player, mDays); } } diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index 59d21886dc..51a765442a 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -774,12 +774,10 @@ namespace MWGui , mGlobalMapRender(std::make_unique(localMapRender->getRoot(), workQueue)) , mEditNoteDialog() { - static bool registered = false; - if (!registered) - { + [[maybe_unused]] static const bool registered = [] { MyGUI::FactoryManager::getInstance().registerFactory("Widget"); - registered = true; - } + return true; + }(); mEditNoteDialog.setVisible(false); mEditNoteDialog.eventOkClicked += MyGUI::newDelegate(this, &MapWindow::onNoteEditOk); diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index d8302df87c..6bd9ef3ac8 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -352,6 +352,7 @@ namespace MWGui getWidget(mAvailableEffectsList, "AvailableEffects"); getWidget(mUsedEffectsView, "UsedEffects"); getWidget(mPriceLabel, "PriceLabel"); + getWidget(mPlayerGold, "PlayerGold"); getWidget(mBuyButton, "BuyButton"); getWidget(mCancelButton, "CancelButton"); @@ -370,6 +371,10 @@ namespace MWGui mPtr = actor; mNameEdit->setCaption({}); + MWWorld::Ptr player = MWMechanics::getPlayer(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); + mPlayerGold->setCaptionWithReplacing(MyGUI::utility::toString(playerGold)); + startEditing(); } diff --git a/apps/openmw/mwgui/spellcreationdialog.hpp b/apps/openmw/mwgui/spellcreationdialog.hpp index 6dfe61fc57..0887dd8c94 100644 --- a/apps/openmw/mwgui/spellcreationdialog.hpp +++ b/apps/openmw/mwgui/spellcreationdialog.hpp @@ -175,6 +175,7 @@ namespace MWGui MyGUI::Button* mBuyButton; MyGUI::Button* mCancelButton; MyGUI::TextBox* mPriceLabel; + MyGUI::TextBox* mPlayerGold; ESM::Spell mSpell; }; diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 4bde77a552..3fc8412d4c 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -29,7 +29,7 @@ namespace MWGui : WindowBase("openmw_trainingwindow.layout") { getWidget(mTrainingOptions, "TrainingOptions"); - getWidget(mCancelButton, "CancelButton"); + getWidget(mCancelButton, "OkButton"); getWidget(mPlayerGold, "PlayerGold"); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onCancelButtonClicked); @@ -115,14 +115,14 @@ namespace MWGui MyGUI::Button* button = mTrainingOptions->createWidget(price <= playerGold ? "SandTextButton" : "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip - MyGUI::IntCoord(5, 5 + i * lineHeight, mTrainingOptions->getWidth() - 10, lineHeight), + MyGUI::IntCoord(4, 3 + i * lineHeight, mTrainingOptions->getWidth() - 10, lineHeight), MyGUI::Align::Default); button->setUserData(skills[i].first); button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected); button->setCaptionWithReplacing( - MyGUI::TextIterator::toTagsString(skill->mName) + " - " + MyGUI::utility::toString(price)); + MyGUI::TextIterator::toTagsString(skill->mName) + " - " + MyGUI::utility::toString(price) + "#{sgp}"); button->setSize(button->getTextSize().width + 12, button->getSize().height); diff --git a/apps/openmw/mwlua/animationbindings.cpp b/apps/openmw/mwlua/animationbindings.cpp index 1af7acea36..5ecd3bd1fa 100644 --- a/apps/openmw/mwlua/animationbindings.cpp +++ b/apps/openmw/mwlua/animationbindings.cpp @@ -1,13 +1,7 @@ #include "animationbindings.hpp" -#include -#include -#include #include -#include #include -#include -#include #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" @@ -15,11 +9,8 @@ #include "../mwmechanics/character.hpp" -#include "../mwworld/esmstore.hpp" - #include "context.hpp" #include "luamanagerimp.hpp" -#include "objectvariant.hpp" namespace MWLua { diff --git a/apps/openmw/mwlua/birthsignbindings.cpp b/apps/openmw/mwlua/birthsignbindings.cpp index 218d05b804..130144ab9b 100644 --- a/apps/openmw/mwlua/birthsignbindings.cpp +++ b/apps/openmw/mwlua/birthsignbindings.cpp @@ -8,7 +8,7 @@ #include "../mwbase/environment.hpp" #include "idcollectionbindings.hpp" -#include "types/types.hpp" +#include "recordstore.hpp" namespace sol { diff --git a/apps/openmw/mwlua/birthsignbindings.hpp b/apps/openmw/mwlua/birthsignbindings.hpp index bf41707d47..e57d56c971 100644 --- a/apps/openmw/mwlua/birthsignbindings.hpp +++ b/apps/openmw/mwlua/birthsignbindings.hpp @@ -3,10 +3,10 @@ #include -#include "context.hpp" - namespace MWLua { + struct Context; + sol::table initBirthSignRecordBindings(const Context& context); } diff --git a/apps/openmw/mwlua/cellbindings.cpp b/apps/openmw/mwlua/cellbindings.cpp index ec64a3cddd..4e4542d89f 100644 --- a/apps/openmw/mwlua/cellbindings.cpp +++ b/apps/openmw/mwlua/cellbindings.cpp @@ -1,7 +1,5 @@ #include "cellbindings.hpp" -#include - #include #include #include @@ -27,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -38,7 +35,6 @@ #include #include #include -#include #include #include #include diff --git a/apps/openmw/mwlua/cellbindings.hpp b/apps/openmw/mwlua/cellbindings.hpp index 0d8e90e989..70255d8d7f 100644 --- a/apps/openmw/mwlua/cellbindings.hpp +++ b/apps/openmw/mwlua/cellbindings.hpp @@ -1,12 +1,12 @@ #ifndef MWLUA_CELLBINDINGS_H #define MWLUA_CELLBINDINGS_H -#include "context.hpp" - namespace MWLua { - void initCellBindingsForLocalScripts(const Context&); - void initCellBindingsForGlobalScripts(const Context&); + struct Context; + + void initCellBindingsForLocalScripts(const Context& context); + void initCellBindingsForGlobalScripts(const Context& context); } #endif // MWLUA_CELLBINDINGS_H diff --git a/apps/openmw/mwlua/classbindings.cpp b/apps/openmw/mwlua/classbindings.cpp index c94631fb3c..338698bfee 100644 --- a/apps/openmw/mwlua/classbindings.cpp +++ b/apps/openmw/mwlua/classbindings.cpp @@ -4,7 +4,7 @@ #include #include "idcollectionbindings.hpp" -#include "types/types.hpp" +#include "recordstore.hpp" namespace sol { diff --git a/apps/openmw/mwlua/classbindings.hpp b/apps/openmw/mwlua/classbindings.hpp index 1acb0a9ad3..cc67f2df02 100644 --- a/apps/openmw/mwlua/classbindings.hpp +++ b/apps/openmw/mwlua/classbindings.hpp @@ -3,10 +3,10 @@ #include -#include "context.hpp" - namespace MWLua { + struct Context; + sol::table initClassRecordBindings(const Context& context); } diff --git a/apps/openmw/mwlua/corebindings.cpp b/apps/openmw/mwlua/corebindings.cpp index bdf71710af..282a9f970b 100644 --- a/apps/openmw/mwlua/corebindings.cpp +++ b/apps/openmw/mwlua/corebindings.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -20,6 +19,7 @@ #include "../mwworld/datetimemanager.hpp" #include "../mwworld/esmstore.hpp" +#include "context.hpp" #include "coremwscriptbindings.hpp" #include "dialoguebindings.hpp" #include "factionbindings.hpp" diff --git a/apps/openmw/mwlua/corebindings.hpp b/apps/openmw/mwlua/corebindings.hpp index ef385ca993..6d27dd0412 100644 --- a/apps/openmw/mwlua/corebindings.hpp +++ b/apps/openmw/mwlua/corebindings.hpp @@ -3,13 +3,13 @@ #include -#include "context.hpp" - namespace MWLua { + struct Context; + void addCoreTimeBindings(sol::table& api, const Context& context); - sol::table initCorePackage(const Context&); + sol::table initCorePackage(const Context& context); } #endif // MWLUA_COREBINDINGS_H diff --git a/apps/openmw/mwlua/debugbindings.hpp b/apps/openmw/mwlua/debugbindings.hpp index c508b54496..d7902cb618 100644 --- a/apps/openmw/mwlua/debugbindings.hpp +++ b/apps/openmw/mwlua/debugbindings.hpp @@ -1,7 +1,7 @@ #ifndef OPENMW_MWLUA_DEBUGBINDINGS_H #define OPENMW_MWLUA_DEBUGBINDINGS_H -#include +#include namespace MWLua { diff --git a/apps/openmw/mwlua/engineevents.cpp b/apps/openmw/mwlua/engineevents.cpp index 6c652bccba..be7d249bfc 100644 --- a/apps/openmw/mwlua/engineevents.cpp +++ b/apps/openmw/mwlua/engineevents.cpp @@ -113,6 +113,15 @@ namespace MWLua scripts->onSkillLevelUp(event.mSkill, event.mSource); } + void operator()(const OnJailTimeServed& event) const + { + MWWorld::Ptr actor = getPtr(event.mActor); + if (actor.isEmpty()) + return; + if (auto* scripts = getLocalScripts(actor)) + scripts->onJailTimeServed(event.mDays); + } + private: MWWorld::Ptr getPtr(ESM::RefNum id) const { diff --git a/apps/openmw/mwlua/engineevents.hpp b/apps/openmw/mwlua/engineevents.hpp index fb9183eb7c..407739d60e 100644 --- a/apps/openmw/mwlua/engineevents.hpp +++ b/apps/openmw/mwlua/engineevents.hpp @@ -70,8 +70,13 @@ namespace MWLua std::string mSkill; std::string mSource; }; + struct OnJailTimeServed + { + ESM::RefNum mActor; + int mDays; + }; using Event = std::variant; + OnAnimationTextKey, OnSkillUse, OnSkillLevelUp, OnJailTimeServed>; void clear() { mQueue.clear(); } void addToQueue(Event e) { mQueue.push_back(std::move(e)); } diff --git a/apps/openmw/mwlua/factionbindings.hpp b/apps/openmw/mwlua/factionbindings.hpp index 0dc06ceaf2..280c7d4791 100644 --- a/apps/openmw/mwlua/factionbindings.hpp +++ b/apps/openmw/mwlua/factionbindings.hpp @@ -3,10 +3,10 @@ #include -#include "context.hpp" - namespace MWLua { + struct Context; + sol::table initCoreFactionBindings(const Context& context); } diff --git a/apps/openmw/mwlua/inputbindings.cpp b/apps/openmw/mwlua/inputbindings.cpp index c3b47c5061..9a781106a6 100644 --- a/apps/openmw/mwlua/inputbindings.cpp +++ b/apps/openmw/mwlua/inputbindings.cpp @@ -13,6 +13,7 @@ #include "../mwbase/windowmanager.hpp" #include "../mwinput/actions.hpp" +#include "context.hpp" #include "luamanagerimp.hpp" namespace sol diff --git a/apps/openmw/mwlua/inputbindings.hpp b/apps/openmw/mwlua/inputbindings.hpp index 195f69f5f9..e9a19ed34d 100644 --- a/apps/openmw/mwlua/inputbindings.hpp +++ b/apps/openmw/mwlua/inputbindings.hpp @@ -3,11 +3,11 @@ #include -#include "context.hpp" - namespace MWLua { - sol::table initInputPackage(const Context&); + struct Context; + + sol::table initInputPackage(const Context& context); } #endif // MWLUA_INPUTBINDINGS_H diff --git a/apps/openmw/mwlua/landbindings.cpp b/apps/openmw/mwlua/landbindings.cpp index 3f85e2b066..2b053802db 100644 --- a/apps/openmw/mwlua/landbindings.cpp +++ b/apps/openmw/mwlua/landbindings.cpp @@ -1,14 +1,24 @@ #include "landbindings.hpp" +#include +#include + +#include +#include +#include + #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/worldmodel.hpp" + +#include "context.hpp" #include "object.hpp" namespace diff --git a/apps/openmw/mwlua/landbindings.hpp b/apps/openmw/mwlua/landbindings.hpp index 8cdf30046b..f38d260759 100644 --- a/apps/openmw/mwlua/landbindings.hpp +++ b/apps/openmw/mwlua/landbindings.hpp @@ -1,10 +1,12 @@ #ifndef MWLUA_LANDBINDINGS_H #define MWLUA_LANDBINDINGS_H -#include "context.hpp" +#include namespace MWLua { + struct Context; + sol::table initCoreLandBindings(const Context& context); } diff --git a/apps/openmw/mwlua/localscripts.cpp b/apps/openmw/mwlua/localscripts.cpp index d784328035..99c994304b 100644 --- a/apps/openmw/mwlua/localscripts.cpp +++ b/apps/openmw/mwlua/localscripts.cpp @@ -1,9 +1,5 @@ #include "localscripts.hpp" -#include -#include -#include - #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwmechanics/aicombat.hpp" @@ -232,7 +228,7 @@ namespace MWLua [&](LuaUtil::LuaView& view) { addPackage("openmw.self", sol::make_object(view.sol(), &mData)); }); registerEngineHandlers({ &mOnActiveHandlers, &mOnInactiveHandlers, &mOnConsumeHandlers, &mOnActivatedHandlers, &mOnTeleportedHandlers, &mOnAnimationTextKeyHandlers, &mOnPlayAnimationHandlers, &mOnSkillUse, - &mOnSkillLevelUp }); + &mOnSkillLevelUp, &mOnJailTimeServed }); } void LocalScripts::setActive(bool active, bool callHandlers) diff --git a/apps/openmw/mwlua/localscripts.hpp b/apps/openmw/mwlua/localscripts.hpp index b3ec647d0e..c51d2d8c19 100644 --- a/apps/openmw/mwlua/localscripts.hpp +++ b/apps/openmw/mwlua/localscripts.hpp @@ -1,9 +1,7 @@ #ifndef MWLUA_LOCALSCRIPTS_H #define MWLUA_LOCALSCRIPTS_H -#include -#include -#include +#include #include #include @@ -89,6 +87,7 @@ namespace MWLua { callEngineHandlers(mOnSkillLevelUp, skillId, source); } + void onJailTimeServed(int days) { callEngineHandlers(mOnJailTimeServed, days); } void applyStatsCache(); @@ -118,6 +117,7 @@ namespace MWLua EngineHandlerList mOnPlayAnimationHandlers{ "_onPlayAnimation" }; EngineHandlerList mOnSkillUse{ "_onSkillUse" }; EngineHandlerList mOnSkillLevelUp{ "_onSkillLevelUp" }; + EngineHandlerList mOnJailTimeServed{ "_onJailTimeServed" }; }; } diff --git a/apps/openmw/mwlua/luabindings.hpp b/apps/openmw/mwlua/luabindings.hpp index 749987e5b2..e7b73dbca1 100644 --- a/apps/openmw/mwlua/luabindings.hpp +++ b/apps/openmw/mwlua/luabindings.hpp @@ -1,29 +1,30 @@ #ifndef MWLUA_LUABINDINGS_H #define MWLUA_LUABINDINGS_H -#include #include -#include -#include "context.hpp" +#include +#include namespace MWLua { + struct Context; + // Initialize Lua packages that are available for all scripts. - std::map initCommonPackages(const Context&); + std::map initCommonPackages(const Context& context); // Initialize Lua packages that are available for global scripts (additionally to common packages). - std::map initGlobalPackages(const Context&); + std::map initGlobalPackages(const Context& context); // Initialize Lua packages that are available for local scripts (additionally to common packages). - std::map initLocalPackages(const Context&); + std::map initLocalPackages(const Context& context); // Initialize Lua packages that are available only for local scripts on the player (additionally to common and local // packages). - std::map initPlayerPackages(const Context&); + std::map initPlayerPackages(const Context& context); // Initialize Lua packages that are available only for menu scripts (additionally to common packages). - std::map initMenuPackages(const Context&); + std::map initMenuPackages(const Context& context); } #endif // MWLUA_LUABINDINGS_H diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index df9c9cd50f..66ecfb1c55 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -5,6 +5,10 @@ #include #include +#include +#include +#include + #include #include @@ -15,7 +19,6 @@ #include -#include #include #include @@ -490,6 +493,11 @@ namespace MWLua EngineEvents::OnSkillLevelUp{ getId(actor), skillId.serializeText(), std::string(source) }); } + void LuaManager::jailTimeServed(const MWWorld::Ptr& actor, int days) + { + mEngineEvents.addToQueue(EngineEvents::OnJailTimeServed{ getId(actor), days }); + } + void LuaManager::onHit(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo, int attackType, float attackStrength, float damage, bool isHealth, const osg::Vec3f& hitPos, bool successful, MWMechanics::DamageSourceType sourceType) diff --git a/apps/openmw/mwlua/luamanagerimp.hpp b/apps/openmw/mwlua/luamanagerimp.hpp index f47b6f96cf..42b18d236f 100644 --- a/apps/openmw/mwlua/luamanagerimp.hpp +++ b/apps/openmw/mwlua/luamanagerimp.hpp @@ -3,9 +3,10 @@ #include #include -#include #include +#include + #include #include #include @@ -92,6 +93,7 @@ namespace MWLua bool loopfallback) override; void skillUse(const MWWorld::Ptr& actor, ESM::RefId skillId, int useType, float scale) override; void skillLevelUp(const MWWorld::Ptr& actor, ESM::RefId skillId, std::string_view source) override; + void jailTimeServed(const MWWorld::Ptr& actor, int days) override; void onHit(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo, int attackType, float attackStrength, float damage, bool isHealth, const osg::Vec3f& hitPos, bool successful, MWMechanics::DamageSourceType sourceType) override; diff --git a/apps/openmw/mwlua/magicbindings.hpp b/apps/openmw/mwlua/magicbindings.hpp index 047bd2e3d9..d9c5182d76 100644 --- a/apps/openmw/mwlua/magicbindings.hpp +++ b/apps/openmw/mwlua/magicbindings.hpp @@ -3,10 +3,10 @@ #include -#include "context.hpp" - namespace MWLua { + struct Context; + sol::table initCoreMagicBindings(const Context& context); void addActorMagicBindings(sol::table& actor, const Context& context); } diff --git a/apps/openmw/mwlua/markupbindings.hpp b/apps/openmw/mwlua/markupbindings.hpp index 9105ab5edf..ec4b6dbbb2 100644 --- a/apps/openmw/mwlua/markupbindings.hpp +++ b/apps/openmw/mwlua/markupbindings.hpp @@ -3,11 +3,11 @@ #include -#include "context.hpp" - namespace MWLua { - sol::table initMarkupPackage(const Context&); + struct Context; + + sol::table initMarkupPackage(const Context& context); } #endif // MWLUA_MARKUPBINDINGS_H diff --git a/apps/openmw/mwlua/menuscripts.cpp b/apps/openmw/mwlua/menuscripts.cpp index 32520c0822..a7ff80e63e 100644 --- a/apps/openmw/mwlua/menuscripts.cpp +++ b/apps/openmw/mwlua/menuscripts.cpp @@ -7,6 +7,8 @@ #include "../mwbase/statemanager.hpp" #include "../mwstate/character.hpp" +#include "context.hpp" + namespace MWLua { static const MWState::Character* findCharacter(std::string_view characterDir) diff --git a/apps/openmw/mwlua/menuscripts.hpp b/apps/openmw/mwlua/menuscripts.hpp index 8721224413..11c6cc1912 100644 --- a/apps/openmw/mwlua/menuscripts.hpp +++ b/apps/openmw/mwlua/menuscripts.hpp @@ -9,11 +9,11 @@ #include "../mwbase/luamanager.hpp" -#include "context.hpp" #include "inputprocessor.hpp" namespace MWLua { + struct Context; sol::table initMenuPackage(const Context& context); diff --git a/apps/openmw/mwlua/mwscriptbindings.cpp b/apps/openmw/mwlua/mwscriptbindings.cpp index 90d24b39fe..179b35aa5c 100644 --- a/apps/openmw/mwlua/mwscriptbindings.cpp +++ b/apps/openmw/mwlua/mwscriptbindings.cpp @@ -12,6 +12,7 @@ #include "../mwworld/esmstore.hpp" #include "../mwworld/worldimp.hpp" +#include "context.hpp" #include "object.hpp" #include diff --git a/apps/openmw/mwlua/mwscriptbindings.hpp b/apps/openmw/mwlua/mwscriptbindings.hpp index 9598f051ae..c0c88ec28c 100644 --- a/apps/openmw/mwlua/mwscriptbindings.hpp +++ b/apps/openmw/mwlua/mwscriptbindings.hpp @@ -3,13 +3,11 @@ #include -#include "context.hpp" - namespace MWLua { + struct Context; - sol::table initMWScriptBindings(const Context&); - + sol::table initMWScriptBindings(const Context& context); } #endif // MWLUA_MWSCRIPTBINDINGS_H diff --git a/apps/openmw/mwlua/nearbybindings.cpp b/apps/openmw/mwlua/nearbybindings.cpp index 6c244a0fd4..b31a934a54 100644 --- a/apps/openmw/mwlua/nearbybindings.cpp +++ b/apps/openmw/mwlua/nearbybindings.cpp @@ -13,9 +13,12 @@ #include "../mwworld/cellstore.hpp" #include "../mwworld/scene.hpp" +#include "context.hpp" #include "luamanagerimp.hpp" #include "objectlists.hpp" +#include + namespace { template diff --git a/apps/openmw/mwlua/nearbybindings.hpp b/apps/openmw/mwlua/nearbybindings.hpp index ee0022898e..2d8140195e 100644 --- a/apps/openmw/mwlua/nearbybindings.hpp +++ b/apps/openmw/mwlua/nearbybindings.hpp @@ -3,11 +3,11 @@ #include -#include "context.hpp" - namespace MWLua { - sol::table initNearbyPackage(const Context&); + struct Context; + + sol::table initNearbyPackage(const Context& context); } #endif // MWLUA_NEARBYBINDINGS_H diff --git a/apps/openmw/mwlua/object.hpp b/apps/openmw/mwlua/object.hpp index d032515314..4a50dee8b6 100644 --- a/apps/openmw/mwlua/object.hpp +++ b/apps/openmw/mwlua/object.hpp @@ -1,9 +1,7 @@ #ifndef MWLUA_OBJECT_H #define MWLUA_OBJECT_H -#include #include -#include #include diff --git a/apps/openmw/mwlua/objectbindings.hpp b/apps/openmw/mwlua/objectbindings.hpp index 5f69c54da3..3861211357 100644 --- a/apps/openmw/mwlua/objectbindings.hpp +++ b/apps/openmw/mwlua/objectbindings.hpp @@ -1,12 +1,12 @@ #ifndef MWLUA_OBJECTBINDINGS_H #define MWLUA_OBJECTBINDINGS_H -#include "context.hpp" - namespace MWLua { - void initObjectBindingsForLocalScripts(const Context&); - void initObjectBindingsForGlobalScripts(const Context&); + struct Context; + + void initObjectBindingsForLocalScripts(const Context& context); + void initObjectBindingsForGlobalScripts(const Context& context); } #endif // MWLUA_OBJECTBINDINGS_H diff --git a/apps/openmw/mwlua/objectlists.cpp b/apps/openmw/mwlua/objectlists.cpp index d0bda5a644..b0169dd651 100644 --- a/apps/openmw/mwlua/objectlists.cpp +++ b/apps/openmw/mwlua/objectlists.cpp @@ -1,9 +1,5 @@ #include "objectlists.hpp" -#include -#include -#include - #include #include "../mwbase/environment.hpp" diff --git a/apps/openmw/mwlua/postprocessingbindings.cpp b/apps/openmw/mwlua/postprocessingbindings.cpp index f12bda8650..6d0c33848a 100644 --- a/apps/openmw/mwlua/postprocessingbindings.cpp +++ b/apps/openmw/mwlua/postprocessingbindings.cpp @@ -8,6 +8,7 @@ #include "../mwbase/world.hpp" #include "../mwrender/postprocessor.hpp" +#include "context.hpp" #include "luamanagerimp.hpp" namespace diff --git a/apps/openmw/mwlua/postprocessingbindings.hpp b/apps/openmw/mwlua/postprocessingbindings.hpp index 50cd84fa24..55b46d2524 100644 --- a/apps/openmw/mwlua/postprocessingbindings.hpp +++ b/apps/openmw/mwlua/postprocessingbindings.hpp @@ -3,11 +3,11 @@ #include -#include "context.hpp" - namespace MWLua { - sol::table initPostprocessingPackage(const Context&); + struct Context; + + sol::table initPostprocessingPackage(const Context& context); } #endif // MWLUA_POSTPROCESSINGBINDINGS_H diff --git a/apps/openmw/mwlua/racebindings.cpp b/apps/openmw/mwlua/racebindings.cpp index b5c4d6093f..590d16b4c9 100644 --- a/apps/openmw/mwlua/racebindings.cpp +++ b/apps/openmw/mwlua/racebindings.cpp @@ -8,7 +8,7 @@ #include "../mwworld/esmstore.hpp" #include "idcollectionbindings.hpp" -#include "types/types.hpp" +#include "recordstore.hpp" namespace { diff --git a/apps/openmw/mwlua/racebindings.hpp b/apps/openmw/mwlua/racebindings.hpp index 43ba9237c5..405a158899 100644 --- a/apps/openmw/mwlua/racebindings.hpp +++ b/apps/openmw/mwlua/racebindings.hpp @@ -3,10 +3,10 @@ #include -#include "context.hpp" - namespace MWLua { + struct Context; + sol::table initRaceRecordBindings(const Context& context); } diff --git a/apps/openmw/mwlua/recordstore.hpp b/apps/openmw/mwlua/recordstore.hpp index aed84a1271..f2fb4ed453 100644 --- a/apps/openmw/mwlua/recordstore.hpp +++ b/apps/openmw/mwlua/recordstore.hpp @@ -1,10 +1,16 @@ #ifndef MWLUA_RECORDSTORE_H #define MWLUA_RECORDSTORE_H -#include +#include + +#include +#include +#include +#include +#include +#include +#include -#include -#include #include #include "apps/openmw/mwbase/environment.hpp" diff --git a/apps/openmw/mwlua/soundbindings.hpp b/apps/openmw/mwlua/soundbindings.hpp index 333ed898c4..d7af17cb69 100644 --- a/apps/openmw/mwlua/soundbindings.hpp +++ b/apps/openmw/mwlua/soundbindings.hpp @@ -3,11 +3,11 @@ #include -#include "context.hpp" - namespace MWLua { - sol::table initCoreSoundBindings(const Context&); + struct Context; + + sol::table initCoreSoundBindings(const Context& context); sol::table initAmbientPackage(const Context& context); } diff --git a/apps/openmw/mwlua/stats.cpp b/apps/openmw/mwlua/stats.cpp index 637ae0b002..8b103d5943 100644 --- a/apps/openmw/mwlua/stats.cpp +++ b/apps/openmw/mwlua/stats.cpp @@ -1,9 +1,11 @@ #include "stats.hpp" #include -#include #include +#include #include +#include +#include #include #include diff --git a/apps/openmw/mwlua/uibindings.cpp b/apps/openmw/mwlua/uibindings.cpp index 826338ca7d..8d9892005c 100644 --- a/apps/openmw/mwlua/uibindings.cpp +++ b/apps/openmw/mwlua/uibindings.cpp @@ -108,6 +108,10 @@ namespace MWLua } luaManager->addUIMessage(message, mode); }; + + api["_showInteractiveMessage"] = [windowManager](std::string_view message, sol::optional) { + windowManager->interactiveMessageBox(message, { "#{Interface:OK}" }); + }; api["CONSOLE_COLOR"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs(lua, { { "Default", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Default.substr(1)) }, diff --git a/apps/openmw/mwlua/uibindings.hpp b/apps/openmw/mwlua/uibindings.hpp index 930ba7f3d8..32fb54e590 100644 --- a/apps/openmw/mwlua/uibindings.hpp +++ b/apps/openmw/mwlua/uibindings.hpp @@ -3,11 +3,11 @@ #include -#include "context.hpp" - namespace MWLua { - sol::table initUserInterfacePackage(const Context&); + struct Context; + + sol::table initUserInterfacePackage(const Context& context); } #endif // MWLUA_UIBINDINGS_H diff --git a/apps/openmw/mwlua/userdataserializer.hpp b/apps/openmw/mwlua/userdataserializer.hpp index f52bb22723..35e4c4729b 100644 --- a/apps/openmw/mwlua/userdataserializer.hpp +++ b/apps/openmw/mwlua/userdataserializer.hpp @@ -1,7 +1,8 @@ #ifndef MWLUA_USERDATASERIALIZER_H #define MWLUA_USERDATASERIALIZER_H -#include "object.hpp" +#include +#include namespace LuaUtil { diff --git a/apps/openmw/mwlua/vfsbindings.hpp b/apps/openmw/mwlua/vfsbindings.hpp index b251db6fd4..ab3ad3662c 100644 --- a/apps/openmw/mwlua/vfsbindings.hpp +++ b/apps/openmw/mwlua/vfsbindings.hpp @@ -3,11 +3,11 @@ #include -#include "context.hpp" - namespace MWLua { - sol::table initVFSPackage(const Context&); + struct Context; + + sol::table initVFSPackage(const Context& context); } #endif // MWLUA_VFSBINDINGS_H diff --git a/apps/openmw/mwlua/worldbindings.cpp b/apps/openmw/mwlua/worldbindings.cpp index 228e70b464..5539d8d77c 100644 --- a/apps/openmw/mwlua/worldbindings.cpp +++ b/apps/openmw/mwlua/worldbindings.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -28,6 +27,7 @@ #include "luamanagerimp.hpp" #include "animationbindings.hpp" +#include "context.hpp" #include "corebindings.hpp" #include "mwscriptbindings.hpp" diff --git a/apps/openmw/mwlua/worldbindings.hpp b/apps/openmw/mwlua/worldbindings.hpp index 4bd2318b68..368344429b 100644 --- a/apps/openmw/mwlua/worldbindings.hpp +++ b/apps/openmw/mwlua/worldbindings.hpp @@ -3,11 +3,11 @@ #include -#include "context.hpp" - namespace MWLua { - sol::table initWorldPackage(const Context&); + struct Context; + + sol::table initWorldPackage(const Context& context); } #endif // MWLUA_WORLDBINDINGS_H diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index c14eee27e4..4aface83d6 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -401,14 +401,12 @@ namespace MWRender { if (mViewMode == VM_FirstPerson) { - static bool prototypeAdded = false; - if (!prototypeAdded) - { + [[maybe_unused]] static const bool prototypeAdded = [&] { osg::ref_ptr depthClearBin(new osgUtil::RenderBin); depthClearBin->setDrawCallback(new DepthClearCallback()); osgUtil::RenderBin::addRenderBinPrototype("DepthClear", depthClearBin); - prototypeAdded = true; - } + return true; + }(); mObjectRoot->getOrCreateStateSet()->setRenderBinDetails( RenderBin_FirstPerson, "DepthClear", osg::StateSet::OVERRIDE_RENDERBIN_DETAILS); } diff --git a/apps/openmw/mwrender/ripples.cpp b/apps/openmw/mwrender/ripples.cpp index ab982d0c55..b19863d695 100644 --- a/apps/openmw/mwrender/ripples.cpp +++ b/apps/openmw/mwrender/ripples.cpp @@ -88,14 +88,13 @@ namespace MWRender if (mProgramBlobber != nullptr) { - static bool pipelineLogged = [&] { + [[maybe_unused]] static const bool pipelineLogged = [&] { if (mUseCompute) Log(Debug::Info) << "Initialized compute shader pipeline for water ripples"; else Log(Debug::Info) << "Initialized fallback fragment shader pipeline for water ripples"; return true; }(); - (void)pipelineLogged; } setCullCallback(new osg::NodeCallback); diff --git a/apps/openmw/mwsound/ffmpegdecoder.cpp b/apps/openmw/mwsound/ffmpegdecoder.cpp index 5a0f336a93..f8b40ddabb 100644 --- a/apps/openmw/mwsound/ffmpegdecoder.cpp +++ b/apps/openmw/mwsound/ffmpegdecoder.cpp @@ -522,16 +522,14 @@ namespace MWSound /* We need to make sure ffmpeg is initialized. Optionally silence warning * output from the lib */ - static bool done_init = false; - if (!done_init) - { + [[maybe_unused]] static const bool doneInit = [] { // This is not needed anymore above FFMpeg version 4.0 #if LIBAVCODEC_VERSION_INT < 3805796 av_register_all(); #endif av_log_set_level(AV_LOG_ERROR); - done_init = true; - } + return true; + }(); } FFmpegDecoder::~FFmpegDecoder() diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 0c9a13bc47..1a68142c15 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -1273,13 +1273,12 @@ namespace MWWorld const std::size_t leftCapacity = mPreloader->getMaxCacheSize() - mPreloader->getCacheSize(); if (cells.size() > leftCapacity) { - static bool logged = [&] { + [[maybe_unused]] static const bool logged = [&] { Log(Debug::Warning) << "Not enough cell preloader cache capacity to preload exterior cells, consider " "increasing \"preload cell cache max\" up to " << (mPreloader->getCacheSize() + cells.size()); return true; }(); - (void)logged; cells.resize(leftCapacity); } diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 8a3325ea71..6b7fe32d40 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -407,6 +407,7 @@ add_component_dir(detournavigator areatype asyncnavmeshupdater bounds + cellgridbounds changetype collisionshapetype commulativeaabb diff --git a/components/detournavigator/dbrefgeometryobject.hpp b/components/detournavigator/dbrefgeometryobject.hpp index dbbafe7e18..71e035d9e6 100644 --- a/components/detournavigator/dbrefgeometryobject.hpp +++ b/components/detournavigator/dbrefgeometryobject.hpp @@ -8,7 +8,6 @@ #include #include -#include #include #include #include diff --git a/components/detournavigator/generatenavmeshtile.cpp b/components/detournavigator/generatenavmeshtile.cpp index 118114181e..115ca75d40 100644 --- a/components/detournavigator/generatenavmeshtile.cpp +++ b/components/detournavigator/generatenavmeshtile.cpp @@ -10,10 +10,8 @@ #include -#include #include #include -#include #include namespace DetourNavigator @@ -79,7 +77,7 @@ namespace DetourNavigator return; } - const auto data + const std::unique_ptr data = prepareNavMeshTileData(*recastMesh, mWorldspace, mTilePosition, mAgentBounds, mSettings.mRecast); if (data == nullptr) diff --git a/components/detournavigator/makenavmesh.cpp b/components/detournavigator/makenavmesh.cpp index fe63d27a1e..06bb693aad 100644 --- a/components/detournavigator/makenavmesh.cpp +++ b/components/detournavigator/makenavmesh.cpp @@ -3,8 +3,6 @@ #include "exceptions.hpp" #include "flags.hpp" #include "navmeshdata.hpp" -#include "navmeshdb.hpp" -#include "navmeshtilescache.hpp" #include "offmeshconnection.hpp" #include "preparednavmeshdata.hpp" #include "recastcontext.hpp" @@ -22,8 +20,6 @@ #include #include -#include -#include namespace DetourNavigator { diff --git a/components/detournavigator/navmeshtileview.cpp b/components/detournavigator/navmeshtileview.cpp index d22efcbfff..e77962bb3c 100644 --- a/components/detournavigator/navmeshtileview.cpp +++ b/components/detournavigator/navmeshtileview.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include diff --git a/components/detournavigator/offmeshconnection.hpp b/components/detournavigator/offmeshconnection.hpp index fb8b166498..01bae02732 100644 --- a/components/detournavigator/offmeshconnection.hpp +++ b/components/detournavigator/offmeshconnection.hpp @@ -6,7 +6,6 @@ #include #include -#include namespace DetourNavigator { diff --git a/components/detournavigator/preparednavmeshdata.cpp b/components/detournavigator/preparednavmeshdata.cpp index a737ae19a5..32e559b8d0 100644 --- a/components/detournavigator/preparednavmeshdata.cpp +++ b/components/detournavigator/preparednavmeshdata.cpp @@ -4,8 +4,6 @@ #include -#include - namespace { void initPolyMeshDetail(rcPolyMeshDetail& value) noexcept diff --git a/components/detournavigator/raycast.hpp b/components/detournavigator/raycast.hpp index 855c5562fc..374b09320c 100644 --- a/components/detournavigator/raycast.hpp +++ b/components/detournavigator/raycast.hpp @@ -3,9 +3,10 @@ #include "flags.hpp" -#include #include +#include + class dtNavMeshQuery; namespace DetourNavigator diff --git a/components/detournavigator/recastmesh.hpp b/components/detournavigator/recastmesh.hpp index 6d06db0799..1a67bb5495 100644 --- a/components/detournavigator/recastmesh.hpp +++ b/components/detournavigator/recastmesh.hpp @@ -11,9 +11,7 @@ #include #include -#include #include -#include #include #include diff --git a/components/files/configurationmanager.cpp b/components/files/configurationmanager.cpp index 49fdd996a7..bef98b73f0 100644 --- a/components/files/configurationmanager.cpp +++ b/components/files/configurationmanager.cpp @@ -1,6 +1,7 @@ #include "configurationmanager.hpp" #include +#include #include #include diff --git a/components/files/configurationmanager.hpp b/components/files/configurationmanager.hpp index 184c6ebb82..da4397146b 100644 --- a/components/files/configurationmanager.hpp +++ b/components/files/configurationmanager.hpp @@ -1,7 +1,6 @@ #ifndef COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP #define COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP -#include #include #include #include diff --git a/components/sceneutil/depth.hpp b/components/sceneutil/depth.hpp index a9f99b145f..b9004c457f 100644 --- a/components/sceneutil/depth.hpp +++ b/components/sceneutil/depth.hpp @@ -95,13 +95,10 @@ namespace SceneUtil static void setReversed(bool reverseZ) { - static bool init = false; - - if (!init) - { + [[maybe_unused]] static const bool init = [&] { AutoDepth::sReversed = reverseZ; - init = true; - } + return true; + }(); } static bool isReversed() diff --git a/components/sceneutil/mwshadowtechnique.cpp b/components/sceneutil/mwshadowtechnique.cpp index 9fa01385d5..d456795781 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -27,7 +27,6 @@ #include #include -#include #include #include "glextensions.hpp" diff --git a/docs/source/reference/lua-scripting/events.rst b/docs/source/reference/lua-scripting/events.rst index 590ff14d88..810739caeb 100644 --- a/docs/source/reference/lua-scripting/events.rst +++ b/docs/source/reference/lua-scripting/events.rst @@ -107,8 +107,8 @@ Example: local attack = { attacker = self, weapon = Actor.getEquipment(self, Actor.EQUIPMENT_SLOT.CarriedRight), - sourceType = I.Combat.ATTACK_SOURCE_TYPE.Melee, - strenght = 1, + sourceType = I.Combat.ATTACK_SOURCE_TYPES.Melee, + strength = 1, type = self.ATTACK_TYPE.Chop, damage = { health = 20, diff --git a/docs/source/reference/lua-scripting/index_interfaces.rst b/docs/source/reference/lua-scripting/index_interfaces.rst index 37a2df63c4..0b113c7744 100644 --- a/docs/source/reference/lua-scripting/index_interfaces.rst +++ b/docs/source/reference/lua-scripting/index_interfaces.rst @@ -11,6 +11,7 @@ Interfaces AI AnimationController Camera + Combat Controls Crimes GamepadControls diff --git a/files/data/mygui/openmw_spellcreation_dialog.layout b/files/data/mygui/openmw_spellcreation_dialog.layout index c284927a37..d616e00dcb 100644 --- a/files/data/mygui/openmw_spellcreation_dialog.layout +++ b/files/data/mygui/openmw_spellcreation_dialog.layout @@ -68,6 +68,12 @@ + + + + + + diff --git a/files/data/mygui/openmw_trainingwindow.layout b/files/data/mygui/openmw_trainingwindow.layout index 80526068ce..f3cadcaf46 100644 --- a/files/data/mygui/openmw_trainingwindow.layout +++ b/files/data/mygui/openmw_trainingwindow.layout @@ -1,28 +1,28 @@ - + - + - + - + - + - + - + diff --git a/files/data/scripts/omw/mechanics/playercontroller.lua b/files/data/scripts/omw/mechanics/playercontroller.lua index 6de31afdea..a0d1b11362 100644 --- a/files/data/scripts/omw/mechanics/playercontroller.lua +++ b/files/data/scripts/omw/mechanics/playercontroller.lua @@ -39,7 +39,8 @@ end local function skillLevelUpHandler(skillid, source, params) local skillStat = NPC.stats.skills[skillid](self) - if skillStat.base >= 100 then + if (skillStat.base >= 100 and params.skillIncreaseValue > 0) or + (skillStat.base <= 0 and params.skillIncreaseValue < 0) then return false end @@ -62,25 +63,67 @@ local function skillLevelUpHandler(skillid, source, params) = levelStat.skillIncreasesForSpecialization[params.levelUpSpecialization] + params.levelUpSpecializationIncreaseValue; end - local skillRecord = Skill.record(skillid) - local npcRecord = NPC.record(self) - local class = NPC.classes.record(npcRecord.class) + if source ~= 'jail' then + local skillRecord = Skill.record(skillid) + local npcRecord = NPC.record(self) + local class = NPC.classes.record(npcRecord.class) - ambient.playSound("skillraise") + ambient.playSound("skillraise") - local message = string.format(core.getGMST('sNotifyMessage39'),skillRecord.name,skillStat.base) + local message = string.format(core.getGMST('sNotifyMessage39'),skillRecord.name,skillStat.base) - if source == I.SkillProgression.SKILL_INCREASE_SOURCES.Book then - message = '#{sBookSkillMessage}\n'..message + if source == I.SkillProgression.SKILL_INCREASE_SOURCES.Book then + message = '#{sBookSkillMessage}\n'..message + end + + ui.showMessage(message, { showInDialogue = false }) + + if levelStat.progress >= core.getGMST('iLevelUpTotal') then + ui.showMessage('#{sLevelUpMsg}', { showInDialogue = false }) + end + + if not source or source == I.SkillProgression.SKILL_INCREASE_SOURCES.Usage then skillStat.progress = 0 end end +end - ui.showMessage(message, { showInDialogue = false }) +local function jailTimeServed(days) + if not days or days <= 0 then + return + end - if levelStat.progress >= core.getGMST('iLevelUpTotal') then - ui.showMessage('#{sLevelUpMsg}', { showInDialogue = false }) + local oldSkillLevels = {} + local skillByNumber = {} + for skillid, skillStat in pairs(NPC.stats.skills) do + oldSkillLevels[skillid] = skillStat(self).base + skillByNumber[#skillByNumber+1] = skillid + end + + math.randomseed(core.getSimulationTime()) + for day=1,days do + local skillid = skillByNumber[math.random(#skillByNumber)] + -- skillLevelUp() handles skill-based increase/decrease + I.SkillProgression.skillLevelUp(skillid, I.SkillProgression.SKILL_INCREASE_SOURCES.Jail) end - if not source or source == I.SkillProgression.SKILL_INCREASE_SOURCES.Usage then skillStat.progress = 0 end + local message = '' + if days == 1 then + message = string.format(core.getGMST('sNotifyMessage42'), days) + else + message = string.format(core.getGMST('sNotifyMessage43'), days) + end + for skillid, skillStat in pairs(NPC.stats.skills) do + local diff = skillStat(self).base - oldSkillLevels[skillid] + if diff ~= 0 then + local skillMsg = core.getGMST('sNotifyMessage39') + if diff < 0 then + skillMsg = core.getGMST('sNotifyMessage44') + end + local skillRecord = Skill.record(skillid) + message = message..'\n'..string.format(skillMsg, skillRecord.name, skillStat(self).base) + end + end + + I.UI.showInteractiveMessage(message) end local function skillUsedHandler(skillid, params) @@ -114,6 +157,7 @@ I.SkillProgression.addSkillLevelUpHandler(skillLevelUpHandler) return { engineHandlers = { onUpdate = onUpdate, + _onJailTimeServed = jailTimeServed, }, eventHandlers = { diff --git a/files/data/scripts/omw/skillhandlers.lua b/files/data/scripts/omw/skillhandlers.lua index d3a224dc46..9b58d81174 100644 --- a/files/data/scripts/omw/skillhandlers.lua +++ b/files/data/scripts/omw/skillhandlers.lua @@ -38,6 +38,7 @@ local Skill = core.stats.Skill -- Table of all existing sources for skill increases. Any sources not listed below will be treated as equal to Trainer. -- @type SkillLevelUpSource -- @field #string Book book +-- @field #string Jail jail -- @field #string Trainer trainer -- @field #string Usage usage @@ -131,15 +132,17 @@ local function skillLevelUp(skillid, source) levelUpAttributeIncreaseValue = core.getGMST('iLevelUpMajorMultAttribute') end - local options = - { - skillIncreaseValue = 1, - levelUpProgress = levelUpProgress, - levelUpAttribute = skillRecord.attribute, - levelUpAttributeIncreaseValue = levelUpAttributeIncreaseValue, - levelUpSpecialization = skillRecord.specialization, - levelUpSpecializationIncreaseValue = core.getGMST('iLevelupSpecialization'), - } + local options = {} + if source == 'jail' and not (skillid == 'security' or skillid == 'sneak') then + options.skillIncreaseValue = -1 + else + options.skillIncreaseValue = 1 + options.levelUpProgress = levelUpProgress + options.levelUpAttribute = skillRecord.attribute + options.levelUpAttributeIncreaseValue = levelUpAttributeIncreaseValue + options.levelUpSpecialization = skillRecord.specialization + options.levelUpSpecializationIncreaseValue = core.getGMST('iLevelupSpecialization') + end for i = #skillLevelUpHandlers, 1, -1 do if skillLevelUpHandlers[i](skillid, source, options) == false then @@ -156,8 +159,15 @@ return { -- @context local -- @usage local I = require('openmw.interfaces') -- + -- -- Make jail time hurt sneak skill instead of benefitting it + -- I.SkillProgression.addSkillLevelUpHandler(function(skillid, source, options) + -- if skillid == 'sneak' and source == 'jail' and options.skillIncreaseValue > 0 then + -- options.skillIncreaseValue = -options.skillIncreaseValue + -- end + -- end) + -- -- -- Forbid increasing destruction skill past 50 - -- I.SkillProgression.addSkillLevelUpHandler(function(skillid, options) + -- I.SkillProgression.addSkillLevelUpHandler(function(skillid, source, options) -- if skillid == 'destruction' and types.NPC.stats.skills.destruction(self).base >= 50 then -- return false -- end @@ -187,7 +197,7 @@ return { -- a modifiable table of skill level up values, and can be modified to change the behavior of later handlers. -- These values are calculated based on vanilla mechanics. Setting any value to nil will cause that mechanic to be skipped. By default contains these values: -- - -- * `skillIncreaseValue` - The numeric amount of skill levels gained. + -- * `skillIncreaseValue` - The numeric amount of skill levels gained. By default this is 1, except when the source is jail in which case it will instead be -1 for all skills except sneak and security. -- * `levelUpProgress` - The numeric amount of level up progress gained. -- * `levelUpAttribute` - The string identifying the attribute that should receive points from this skill level up. -- * `levelUpAttributeIncreaseValue` - The numeric amount of attribute increase points received. This contributes to the amount of each attribute the character receives during a vanilla level up. @@ -263,7 +273,7 @@ return { --- Trigger a skill level up, activating relevant handlers -- @function [parent=#SkillProgression] skillLevelUp -- @param #string skillid The id of the skill to level up. - -- @param #SkillLevelUpSource source The source of the skill increase. + -- @param #SkillLevelUpSource source The source of the skill increase. Note that passing a value of @{#SkillLevelUpSource.Jail} will cause a skill decrease for all skills except sneak and security. skillLevelUp = skillLevelUp, --- @{#SkillLevelUpSource} @@ -272,6 +282,7 @@ return { Book = 'book', Usage = 'usage', Trainer = 'trainer', + Jail = 'jail', }, --- Compute the total skill gain required to level up a skill based on its current level, and other modifying factors such as major skills and specialization. diff --git a/files/data/scripts/omw/ui.lua b/files/data/scripts/omw/ui.lua index 31502fd6ee..c63c085fab 100644 --- a/files/data/scripts/omw/ui.lua +++ b/files/data/scripts/omw/ui.lua @@ -171,7 +171,7 @@ return { interface = { --- Interface version -- @field [parent=#UI] #number version - version = 2, + version = 3, --- All available UI modes. -- Use `view(I.UI.MODE)` in `luap` console mode to see the list. @@ -254,6 +254,13 @@ return { -- @return #boolean isWindowVisible = isWindowVisible, + --- + -- Shows a message as an interactive message box pausing the game, with a single button with the localized text OK. + -- @function [parent=#UI] showInteractiveMessage + -- @param #string message Message to display + -- @param #table options Options (none yet) + showInteractiveMessage = ui._showInteractiveMessage + -- TODO -- registerHudElement = function(name, showFn, hideFn) end, -- showHudElement = function(name, bool) end, diff --git a/files/lua_api/openmw/ambient.lua b/files/lua_api/openmw/ambient.lua index 436f10de1a..a9e8c08d4a 100644 --- a/files/lua_api/openmw/ambient.lua +++ b/files/lua_api/openmw/ambient.lua @@ -18,7 +18,7 @@ -- * `scale` - a boolean, to set if the sound's pitch should be scaled by simulation time scaling (default: true); -- * `loop` - a boolean, to set if the sound should be repeated when it ends (default: false); -- @usage local params = { --- timeOffset=0.1 +-- timeOffset=0.1, -- volume=0.3, -- scale=false, -- pitch=1.0, @@ -38,7 +38,7 @@ -- * `scale` - a boolean, to set if the sound's pitch should be scaled by simulation time scaling (default: true); -- * `loop` - a boolean, to set if the sound should be repeated when it ends (default: false); -- @usage local params = { --- timeOffset=0.1 +-- timeOffset=0.1, -- volume=0.3, -- scale=false, -- pitch=1.0, diff --git a/files/lua_api/openmw/animation.lua b/files/lua_api/openmw/animation.lua index 929a784ba9..9fcbe8ea21 100644 --- a/files/lua_api/openmw/animation.lua +++ b/files/lua_api/openmw/animation.lua @@ -188,7 +188,7 @@ -- -- * `loops` - a number >= 0, the number of times the animation should loop after the first play (default: 0). -- * `priority` - Either a single #Priority value that will be assigned to all bone groups. Or a table mapping bone groups to its priority (default: PRIORITY.Default). --- * `blendMask` - A mask of which bone groups to include in the animation (Default: BLEND_MASK.All. +-- * `blendMask` - A mask of which bone groups to include in the animation (Default: BLEND_MASK.All). -- * `autoDisable` - If true, the animation will be immediately removed upon finishing, which means information will not be possible to query once completed. (Default: true) -- * `speed` - a floating point number >= 0, the speed at which the animation should play (default: 1) -- * `startKey` - the animation key at which the animation should start (default: "start") @@ -242,7 +242,7 @@ -- model = types.Static.record(mgef.hitStatic).model, -- options = { -- vfxId = mgef.id, --- particuleTextureOverride = mgef.particle, +-- particleTextureOverride = mgef.particle, -- loop = false, -- } -- }) @@ -254,7 +254,7 @@ -- Can only be used on self. -- @function [parent=#animation] removeVfx -- @param openmw.core#GameObject actor --- @param #number vfxId an integer ID that uniquely identifies the VFX to remove +-- @param #string vfxId a string ID that uniquely identifies the VFX to remove --- -- Removes all vfx from the actor. diff --git a/files/lua_api/openmw/camera.lua b/files/lua_api/openmw/camera.lua index b6b605fc10..67b3ec2a8e 100644 --- a/files/lua_api/openmw/camera.lua +++ b/files/lua_api/openmw/camera.lua @@ -109,7 +109,6 @@ --- -- Additional summand for the yaw angle; useful for camera shaking effects. --- Setting extra pitch doesn't block player input. -- Full yaw is `getYaw()+getExtraYaw()`. -- @function [parent=#camera] setExtraYaw -- @param #number value @@ -122,7 +121,7 @@ --- -- Additional summand for the roll angle; useful for camera shaking effects. --- Full yaw is `getRoll()+getExtraRoll()`. +-- Full roll is `getRoll()+getExtraRoll()`. -- @function [parent=#camera] setExtraRoll -- @param #number value @@ -150,7 +149,7 @@ --- -- Set preferred offset between tracked position (see `getTrackedPosition`) and the camera focal point (the center of the screen) in third person mode. -- The offset is a 2d vector (X, Y) where X is horizontal (to the right from the character) and Y component is vertical (upward). --- The real offset can differ from the preferred one during smooth transition of if blocked by an obstacle. +-- The real offset can differ from the preferred one during smooth transition or if blocked by an obstacle. -- Smooth transition happens by default every time when the preferred offset was changed. Use `instantTransition()` to skip the current transition. -- @function [parent=#camera] setFocalPreferredOffset -- @param openmw.util#Vector2 offset diff --git a/files/lua_api/openmw/core.lua b/files/lua_api/openmw/core.lua index 054e96674b..c1b888bd43 100644 --- a/files/lua_api/openmw/core.lua +++ b/files/lua_api/openmw/core.lua @@ -801,7 +801,7 @@ -- * `pitch` - a floating point number >= 0, to set a sound pitch (default: 1); -- * `loop` - a boolean, to set if sound should be repeated when it ends (default: false); -- @usage local params = { --- timeOffset=0.1 +-- timeOffset=0.1, -- volume=0.3, -- loop=false, -- pitch=1.0 @@ -822,7 +822,7 @@ -- * `pitch` - a floating point number >= 0, to set a sound pitch (default: 1); -- * `loop` - a boolean, to set if sound should be repeated when it ends (default: false); -- @usage local params = { --- timeOffset=0.1 +-- timeOffset=0.1, -- volume=0.3, -- loop=false, -- pitch=1.0 diff --git a/files/lua_api/openmw/types.lua b/files/lua_api/openmw/types.lua index 5c21de8f56..e85da3f0f6 100644 --- a/files/lua_api/openmw/types.lua +++ b/files/lua_api/openmw/types.lua @@ -1011,7 +1011,7 @@ -- @param openmw.core#GameObject actor NPC object -- @param #string faction Faction ID -- @usage local NPC = require('openmw.types').NPC; --- NPC.clearExpell(player, "mages guild"); +-- NPC.clearExpelled(player, "mages guild"); --- -- Check if NPC is expelled from given faction.