mirror of
https://github.com/OpenMW/openmw.git
synced 2025-10-15 21:46:37 +00:00
Merge branch 'master' of https://gitlab.com/OpenMW/openmw
This commit is contained in:
commit
8e76a0ab06
146 changed files with 928 additions and 499 deletions
|
@ -108,8 +108,8 @@ Coverity:
|
||||||
- ccache/
|
- ccache/
|
||||||
variables:
|
variables:
|
||||||
CCACHE_SIZE: 2G
|
CCACHE_SIZE: 2G
|
||||||
CC: clang-12
|
CC: clang
|
||||||
CXX: clang++-12
|
CXX: clang++
|
||||||
CMAKE_BUILD_TYPE: Debug
|
CMAKE_BUILD_TYPE: Debug
|
||||||
CMAKE_CXX_FLAGS_DEBUG: -O0
|
CMAKE_CXX_FLAGS_DEBUG: -O0
|
||||||
before_script:
|
before_script:
|
||||||
|
@ -125,18 +125,34 @@ Coverity:
|
||||||
- ccache -z -M "${CCACHE_SIZE}"
|
- ccache -z -M "${CCACHE_SIZE}"
|
||||||
- CI/before_script.linux.sh
|
- CI/before_script.linux.sh
|
||||||
- cov-analysis-linux64-*/bin/cov-configure --template --comptype prefix --compiler ccache
|
- cov-analysis-linux64-*/bin/cov-configure --template --comptype prefix --compiler ccache
|
||||||
# Remove the specific targets and build everything once we can do it under 3h
|
|
||||||
- cov-analysis-linux64-*/bin/cov-build --dir cov-int cmake --build build -- -j $(nproc)
|
- cov-analysis-linux64-*/bin/cov-build --dir cov-int cmake --build build -- -j $(nproc)
|
||||||
- ccache -svv
|
- ccache -svv
|
||||||
after_script:
|
|
||||||
- tar cfz cov-int.tar.gz cov-int
|
- tar cfz cov-int.tar.gz cov-int
|
||||||
- curl https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME
|
- echo "OPENMW_JOB_ID=$CI_JOB_ID" >> build.env
|
||||||
--form token=$COVERITY_SCAN_TOKEN --form email=$GITLAB_USER_EMAIL
|
|
||||||
--form file=@cov-int.tar.gz --form version="$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA"
|
|
||||||
--form description="CI_COMMIT_SHORT_SHA / $CI_COMMIT_TITLE / $CI_COMMIT_REF_NAME:$CI_PIPELINE_ID"
|
|
||||||
artifacts:
|
artifacts:
|
||||||
|
expire_in: 1 day
|
||||||
paths:
|
paths:
|
||||||
- /builds/OpenMW/openmw/cov-int/build-log.txt
|
- /builds/OpenMW/openmw/cov-int/build-log.txt
|
||||||
|
- /builds/OpenMW/openmw/cov-int.tar.gz
|
||||||
|
reports:
|
||||||
|
dotenv: build.env
|
||||||
|
|
||||||
|
Coverity_Upload:
|
||||||
|
image: ubuntu:24.04
|
||||||
|
stage: build
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||||
|
before_script:
|
||||||
|
- CI/install_debian_deps.sh coverity_upload
|
||||||
|
script:
|
||||||
|
- echo "$CI_API_V4_URL/projects/$CI_PROJECT_ID/jobs/$OPENMW_JOB_ID/artifacts/cov-int.tar.gz"
|
||||||
|
- curl https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME
|
||||||
|
--form token=$COVERITY_SCAN_TOKEN --form email=$GITLAB_USER_EMAIL
|
||||||
|
--form version="$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA"
|
||||||
|
--form description="CI_COMMIT_SHORT_SHA / $CI_COMMIT_TITLE / $CI_COMMIT_REF_NAME:$CI_PIPELINE_ID"
|
||||||
|
--form url="$CI_API_V4_URL/projects/$CI_PROJECT_ID/jobs/$OPENMW_JOB_ID/artifacts/cov-int.tar.gz"
|
||||||
|
needs:
|
||||||
|
- Coverity
|
||||||
|
|
||||||
Ubuntu_GCC:
|
Ubuntu_GCC:
|
||||||
extends: .Ubuntu
|
extends: .Ubuntu
|
||||||
|
|
|
@ -11,7 +11,8 @@ print_help() {
|
||||||
declare -rA GROUPED_DEPS=(
|
declare -rA GROUPED_DEPS=(
|
||||||
[gcc]="binutils gcc build-essential cmake ccache curl unzip git pkg-config mold"
|
[gcc]="binutils gcc build-essential cmake ccache curl unzip git pkg-config mold"
|
||||||
[clang]="binutils clang make cmake ccache curl unzip git pkg-config mold"
|
[clang]="binutils clang make cmake ccache curl unzip git pkg-config mold"
|
||||||
[coverity]="binutils clang-12 make cmake ccache curl unzip git pkg-config"
|
[coverity]="binutils clang make cmake ccache curl unzip git pkg-config file"
|
||||||
|
[coverity_upload]="curl"
|
||||||
[gcc_preprocess]="
|
[gcc_preprocess]="
|
||||||
binutils
|
binutils
|
||||||
build-essential
|
build-essential
|
||||||
|
|
|
@ -82,7 +82,7 @@ message(STATUS "Configuring OpenMW...")
|
||||||
set(OPENMW_VERSION_MAJOR 0)
|
set(OPENMW_VERSION_MAJOR 0)
|
||||||
set(OPENMW_VERSION_MINOR 50)
|
set(OPENMW_VERSION_MINOR 50)
|
||||||
set(OPENMW_VERSION_RELEASE 0)
|
set(OPENMW_VERSION_RELEASE 0)
|
||||||
set(OPENMW_LUA_API_REVISION 85)
|
set(OPENMW_LUA_API_REVISION 87)
|
||||||
set(OPENMW_POSTPROCESSING_API_REVISION 3)
|
set(OPENMW_POSTPROCESSING_API_REVISION 3)
|
||||||
|
|
||||||
set(OPENMW_VERSION_COMMITHASH "")
|
set(OPENMW_VERSION_COMMITHASH "")
|
||||||
|
|
|
@ -638,8 +638,9 @@ CUSTOM: customdata.lua
|
||||||
sol::object deserialized = LuaUtil::deserialize(lua.sol(), data2.mScripts[0].mData, &serializer1);
|
sol::object deserialized = LuaUtil::deserialize(lua.sol(), data2.mScripts[0].mData, &serializer1);
|
||||||
EXPECT_TRUE(deserialized.is<sol::table>());
|
EXPECT_TRUE(deserialized.is<sol::table>());
|
||||||
sol::table table = deserialized;
|
sol::table table = deserialized;
|
||||||
for (const auto& [key, value] : table)
|
if (!table.empty())
|
||||||
{
|
{
|
||||||
|
const auto [key, value] = *table.cbegin();
|
||||||
EXPECT_TRUE(key.is<ESM::RefNum>());
|
EXPECT_TRUE(key.is<ESM::RefNum>());
|
||||||
EXPECT_TRUE(value.is<ESM::RefNum>());
|
EXPECT_TRUE(value.is<ESM::RefNum>());
|
||||||
EXPECT_EQ(key.as<ESM::RefNum>(), (ESM::RefNum{ 42, 34 }));
|
EXPECT_EQ(key.as<ESM::RefNum>(), (ESM::RefNum{ 42, 34 }));
|
||||||
|
|
|
@ -215,8 +215,6 @@ int main(int argc, char** argv)
|
||||||
std::cerr << "ERROR: " << e.what() << std::endl;
|
std::cerr << "ERROR: " << e.what() << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
|
|
@ -291,6 +291,7 @@ bool Launcher::SettingsPage::loadSettings()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loadSettingBool(Settings::sound().mCameraListener, *cameraListenerCheckBox);
|
loadSettingBool(Settings::sound().mCameraListener, *cameraListenerCheckBox);
|
||||||
|
dopplerSpinBox->setValue(Settings::sound().mDopplerFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface Changes
|
// Interface Changes
|
||||||
|
@ -485,6 +486,8 @@ void Launcher::SettingsPage::saveSettings()
|
||||||
|
|
||||||
const bool cCameraListener = cameraListenerCheckBox->checkState() != Qt::Unchecked;
|
const bool cCameraListener = cameraListenerCheckBox->checkState() != Qt::Unchecked;
|
||||||
Settings::sound().mCameraListener.set(cCameraListener);
|
Settings::sound().mCameraListener.set(cCameraListener);
|
||||||
|
|
||||||
|
Settings::sound().mDopplerFactor.set(dopplerSpinBox->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface Changes
|
// Interface Changes
|
||||||
|
|
|
@ -1224,6 +1224,51 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="dopplerLabel">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Controls the strength of the Doppler effect. Zero means it is completely disabled.</p><p>The Doppler effect increases or decreases the pitch of sounds relative to the velocity of the sound source and the listener.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Doppler Factor</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDoubleSpinBox" name="dopplerSpinBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>283</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.010000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.250000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer>
|
<spacer>
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|
|
@ -59,14 +59,13 @@ namespace CSMWorld
|
||||||
|
|
||||||
const Record<ESM::LandTexture>* IdCollection<ESM::LandTexture>::searchRecord(std::uint16_t index, int plugin) const
|
const Record<ESM::LandTexture>* IdCollection<ESM::LandTexture>::searchRecord(std::uint16_t index, int plugin) const
|
||||||
{
|
{
|
||||||
auto found = mIndices.find({ plugin, index });
|
const auto it = mIndices.find({ plugin, index });
|
||||||
if (found != mIndices.end())
|
if (it == mIndices.end())
|
||||||
{
|
return nullptr;
|
||||||
int index = searchId(found->second);
|
const int recordIndex = searchId(it->second);
|
||||||
if (index != -1)
|
if (recordIndex == -1)
|
||||||
return &getRecord(index);
|
return nullptr;
|
||||||
}
|
return &getRecord(recordIndex);
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string* IdCollection<ESM::LandTexture>::getLandTexture(std::uint16_t index, int plugin) const
|
const std::string* IdCollection<ESM::LandTexture>::getLandTexture(std::uint16_t index, int plugin) const
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
|
|
||||||
#include <osgDB/WriteFile>
|
#include <osgDB/ReaderWriter>
|
||||||
|
#include <osgDB/Registry>
|
||||||
#include <osgViewer/ViewerEventHandlers>
|
#include <osgViewer/ViewerEventHandlers>
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
@ -28,7 +29,6 @@
|
||||||
|
|
||||||
#include <components/compiler/extensions0.hpp>
|
#include <components/compiler/extensions0.hpp>
|
||||||
|
|
||||||
#include <components/stereo/multiview.hpp>
|
|
||||||
#include <components/stereo/stereomanager.hpp>
|
#include <components/stereo/stereomanager.hpp>
|
||||||
|
|
||||||
#include <components/sceneutil/glextensions.hpp>
|
#include <components/sceneutil/glextensions.hpp>
|
||||||
|
|
|
@ -75,6 +75,7 @@ namespace MWBase
|
||||||
const MWRender::AnimPriority& priority, int blendMask, bool autodisable, float speedmult,
|
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)
|
std::string_view start, std::string_view stop, float startpoint, uint32_t loops, bool loopfallback)
|
||||||
= 0;
|
= 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 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 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,
|
virtual void onHit(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& weapon,
|
||||||
|
|
|
@ -234,6 +234,8 @@ namespace MWBase
|
||||||
const osg::Vec3f& pos, const osg::Vec3f& dir, const osg::Vec3f& up, bool underwater)
|
const osg::Vec3f& pos, const osg::Vec3f& dir, const osg::Vec3f& up, bool underwater)
|
||||||
= 0;
|
= 0;
|
||||||
|
|
||||||
|
virtual void setListenerVel(const osg::Vec3f& vel) = 0;
|
||||||
|
|
||||||
virtual void updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) = 0;
|
virtual void updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) = 0;
|
||||||
|
|
||||||
void setSimulationTimeScale(float scale) { mSimulationTimeScale = scale; }
|
void setSimulationTimeScale(float scale) { mSimulationTimeScale = scale; }
|
||||||
|
|
|
@ -496,6 +496,8 @@ namespace MWBase
|
||||||
virtual float getSunVisibility() const = 0;
|
virtual float getSunVisibility() const = 0;
|
||||||
virtual float getSunPercentage() const = 0;
|
virtual float getSunPercentage() const = 0;
|
||||||
|
|
||||||
|
virtual float getPhysicsFrameRateDt() const = 0;
|
||||||
|
|
||||||
virtual bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) = 0;
|
virtual bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) = 0;
|
||||||
|
|
||||||
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <components/misc/strings/format.hpp>
|
#include <components/misc/strings/format.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/luamanager.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
@ -86,46 +87,6 @@ namespace MWGui
|
||||||
|
|
||||||
// We should not worsen corprus when in prison
|
// We should not worsen corprus when in prison
|
||||||
player.getClass().getCreatureStats(player).getActiveSpells().skipWorsenings(mDays * 24);
|
player.getClass().getCreatureStats(player).getActiveSpells().skipWorsenings(mDays * 24);
|
||||||
|
MWBase::Environment::get().getLuaManager()->jailTimeServed(player, mDays);
|
||||||
const auto& skillStore = MWBase::Environment::get().getESMStore()->get<ESM::Skill>();
|
|
||||||
std::set<const ESM::Skill*> 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<ESM::GameSetting>& gmst
|
|
||||||
= MWBase::Environment::get().getESMStore()->get<ESM::GameSetting>();
|
|
||||||
|
|
||||||
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<std::string> buttons;
|
|
||||||
buttons.emplace_back("#{Interface:OK}");
|
|
||||||
MWBase::Environment::get().getWindowManager()->interactiveMessageBox(message, buttons);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -775,12 +775,10 @@ namespace MWGui
|
||||||
, mGlobalMapRender(std::make_unique<MWRender::GlobalMap>(localMapRender->getRoot(), workQueue))
|
, mGlobalMapRender(std::make_unique<MWRender::GlobalMap>(localMapRender->getRoot(), workQueue))
|
||||||
, mEditNoteDialog()
|
, mEditNoteDialog()
|
||||||
{
|
{
|
||||||
static bool registered = false;
|
[[maybe_unused]] static const bool registered = [] {
|
||||||
if (!registered)
|
|
||||||
{
|
|
||||||
MyGUI::FactoryManager::getInstance().registerFactory<MarkerWidget>("Widget");
|
MyGUI::FactoryManager::getInstance().registerFactory<MarkerWidget>("Widget");
|
||||||
registered = true;
|
return true;
|
||||||
}
|
}();
|
||||||
|
|
||||||
mEditNoteDialog.setVisible(false);
|
mEditNoteDialog.setVisible(false);
|
||||||
mEditNoteDialog.eventOkClicked += MyGUI::newDelegate(this, &MapWindow::onNoteEditOk);
|
mEditNoteDialog.eventOkClicked += MyGUI::newDelegate(this, &MapWindow::onNoteEditOk);
|
||||||
|
|
|
@ -587,6 +587,7 @@ namespace MWGui
|
||||||
getWidget(mAvailableEffectsList, "AvailableEffects");
|
getWidget(mAvailableEffectsList, "AvailableEffects");
|
||||||
getWidget(mUsedEffectsView, "UsedEffects");
|
getWidget(mUsedEffectsView, "UsedEffects");
|
||||||
getWidget(mPriceLabel, "PriceLabel");
|
getWidget(mPriceLabel, "PriceLabel");
|
||||||
|
getWidget(mPlayerGold, "PlayerGold");
|
||||||
getWidget(mBuyButton, "BuyButton");
|
getWidget(mBuyButton, "BuyButton");
|
||||||
getWidget(mCancelButton, "CancelButton");
|
getWidget(mCancelButton, "CancelButton");
|
||||||
|
|
||||||
|
@ -613,6 +614,10 @@ namespace MWGui
|
||||||
mPtr = actor;
|
mPtr = actor;
|
||||||
mNameEdit->setCaption({});
|
mNameEdit->setCaption({});
|
||||||
|
|
||||||
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||||
|
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
|
||||||
|
mPlayerGold->setCaptionWithReplacing(MyGUI::utility::toString(playerGold));
|
||||||
|
|
||||||
startEditing();
|
startEditing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -190,6 +190,7 @@ namespace MWGui
|
||||||
MyGUI::Button* mBuyButton;
|
MyGUI::Button* mBuyButton;
|
||||||
MyGUI::Button* mCancelButton;
|
MyGUI::Button* mCancelButton;
|
||||||
MyGUI::TextBox* mPriceLabel;
|
MyGUI::TextBox* mPriceLabel;
|
||||||
|
MyGUI::TextBox* mPlayerGold;
|
||||||
|
|
||||||
ESM::Spell mSpell;
|
ESM::Spell mSpell;
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace MWGui
|
||||||
: WindowBase("openmw_trainingwindow.layout")
|
: WindowBase("openmw_trainingwindow.layout")
|
||||||
{
|
{
|
||||||
getWidget(mTrainingOptions, "TrainingOptions");
|
getWidget(mTrainingOptions, "TrainingOptions");
|
||||||
getWidget(mCancelButton, "CancelButton");
|
getWidget(mCancelButton, "OkButton");
|
||||||
getWidget(mPlayerGold, "PlayerGold");
|
getWidget(mPlayerGold, "PlayerGold");
|
||||||
|
|
||||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onCancelButtonClicked);
|
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onCancelButtonClicked);
|
||||||
|
@ -123,14 +123,14 @@ namespace MWGui
|
||||||
MyGUI::Button* button = mTrainingOptions->createWidget<MyGUI::Button>(price <= playerGold
|
MyGUI::Button* button = mTrainingOptions->createWidget<MyGUI::Button>(price <= playerGold
|
||||||
? "SandTextButton"
|
? "SandTextButton"
|
||||||
: "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip
|
: "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);
|
MyGUI::Align::Default);
|
||||||
|
|
||||||
button->setUserData(skills[i].first);
|
button->setUserData(skills[i].first);
|
||||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected);
|
button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected);
|
||||||
|
|
||||||
button->setCaptionWithReplacing(
|
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);
|
button->setSize(button->getTextSize().width + 12, button->getSize().height);
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
#include "animationbindings.hpp"
|
#include "animationbindings.hpp"
|
||||||
|
|
||||||
#include <components/esm3/loadmgef.hpp>
|
|
||||||
#include <components/esm3/loadstat.hpp>
|
|
||||||
#include <components/lua/asyncpackage.hpp>
|
|
||||||
#include <components/lua/luastate.hpp>
|
#include <components/lua/luastate.hpp>
|
||||||
#include <components/lua/utilpackage.hpp>
|
|
||||||
#include <components/misc/finitenumbers.hpp>
|
#include <components/misc/finitenumbers.hpp>
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
|
||||||
#include <components/settings/values.hpp>
|
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
@ -15,11 +9,8 @@
|
||||||
|
|
||||||
#include "../mwmechanics/character.hpp"
|
#include "../mwmechanics/character.hpp"
|
||||||
|
|
||||||
#include "../mwworld/esmstore.hpp"
|
|
||||||
|
|
||||||
#include "context.hpp"
|
#include "context.hpp"
|
||||||
#include "luamanagerimp.hpp"
|
#include "luamanagerimp.hpp"
|
||||||
#include "objectvariant.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
||||||
#include "idcollectionbindings.hpp"
|
#include "idcollectionbindings.hpp"
|
||||||
#include "types/types.hpp"
|
#include "recordstore.hpp"
|
||||||
|
|
||||||
namespace sol
|
namespace sol
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
|
struct Context;
|
||||||
|
|
||||||
sol::table initBirthSignRecordBindings(const Context& context);
|
sol::table initBirthSignRecordBindings(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include "cellbindings.hpp"
|
#include "cellbindings.hpp"
|
||||||
|
|
||||||
#include <components/esm/esmbridge.hpp>
|
|
||||||
|
|
||||||
#include <components/esm3/loadacti.hpp>
|
#include <components/esm3/loadacti.hpp>
|
||||||
#include <components/esm3/loadalch.hpp>
|
#include <components/esm3/loadalch.hpp>
|
||||||
#include <components/esm3/loadappa.hpp>
|
#include <components/esm3/loadappa.hpp>
|
||||||
|
@ -27,7 +25,6 @@
|
||||||
#include <components/esm4/loadammo.hpp>
|
#include <components/esm4/loadammo.hpp>
|
||||||
#include <components/esm4/loadarmo.hpp>
|
#include <components/esm4/loadarmo.hpp>
|
||||||
#include <components/esm4/loadbook.hpp>
|
#include <components/esm4/loadbook.hpp>
|
||||||
#include <components/esm4/loadcell.hpp>
|
|
||||||
#include <components/esm4/loadclot.hpp>
|
#include <components/esm4/loadclot.hpp>
|
||||||
#include <components/esm4/loadcont.hpp>
|
#include <components/esm4/loadcont.hpp>
|
||||||
#include <components/esm4/loaddoor.hpp>
|
#include <components/esm4/loaddoor.hpp>
|
||||||
|
@ -38,7 +35,6 @@
|
||||||
#include <components/esm4/loadligh.hpp>
|
#include <components/esm4/loadligh.hpp>
|
||||||
#include <components/esm4/loadmisc.hpp>
|
#include <components/esm4/loadmisc.hpp>
|
||||||
#include <components/esm4/loadmstt.hpp>
|
#include <components/esm4/loadmstt.hpp>
|
||||||
#include <components/esm4/loadrefr.hpp>
|
|
||||||
#include <components/esm4/loadscol.hpp>
|
#include <components/esm4/loadscol.hpp>
|
||||||
#include <components/esm4/loadstat.hpp>
|
#include <components/esm4/loadstat.hpp>
|
||||||
#include <components/esm4/loadtree.hpp>
|
#include <components/esm4/loadtree.hpp>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#ifndef MWLUA_CELLBINDINGS_H
|
#ifndef MWLUA_CELLBINDINGS_H
|
||||||
#define MWLUA_CELLBINDINGS_H
|
#define MWLUA_CELLBINDINGS_H
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
void initCellBindingsForLocalScripts(const Context&);
|
struct Context;
|
||||||
void initCellBindingsForGlobalScripts(const Context&);
|
|
||||||
|
void initCellBindingsForLocalScripts(const Context& context);
|
||||||
|
void initCellBindingsForGlobalScripts(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MWLUA_CELLBINDINGS_H
|
#endif // MWLUA_CELLBINDINGS_H
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <components/lua/luastate.hpp>
|
#include <components/lua/luastate.hpp>
|
||||||
|
|
||||||
#include "idcollectionbindings.hpp"
|
#include "idcollectionbindings.hpp"
|
||||||
#include "types/types.hpp"
|
#include "recordstore.hpp"
|
||||||
|
|
||||||
namespace sol
|
namespace sol
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
|
struct Context;
|
||||||
|
|
||||||
sol::table initClassRecordBindings(const Context& context);
|
sol::table initClassRecordBindings(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
#include <components/esm3/loadfact.hpp>
|
|
||||||
#include <components/lua/l10n.hpp>
|
#include <components/lua/l10n.hpp>
|
||||||
#include <components/lua/luastate.hpp>
|
#include <components/lua/luastate.hpp>
|
||||||
#include <components/lua/serialization.hpp>
|
#include <components/lua/serialization.hpp>
|
||||||
|
@ -20,6 +19,7 @@
|
||||||
#include "../mwworld/datetimemanager.hpp"
|
#include "../mwworld/datetimemanager.hpp"
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
|
||||||
|
#include "context.hpp"
|
||||||
#include "coremwscriptbindings.hpp"
|
#include "coremwscriptbindings.hpp"
|
||||||
#include "dialoguebindings.hpp"
|
#include "dialoguebindings.hpp"
|
||||||
#include "factionbindings.hpp"
|
#include "factionbindings.hpp"
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
|
struct Context;
|
||||||
|
|
||||||
void addCoreTimeBindings(sol::table& api, const Context& context);
|
void addCoreTimeBindings(sol::table& api, const Context& context);
|
||||||
|
|
||||||
sol::table initCorePackage(const Context&);
|
sol::table initCorePackage(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MWLUA_COREBINDINGS_H
|
#endif // MWLUA_COREBINDINGS_H
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef OPENMW_MWLUA_DEBUGBINDINGS_H
|
#ifndef OPENMW_MWLUA_DEBUGBINDINGS_H
|
||||||
#define OPENMW_MWLUA_DEBUGBINDINGS_H
|
#define OPENMW_MWLUA_DEBUGBINDINGS_H
|
||||||
|
|
||||||
#include <sol/sol.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
|
|
|
@ -113,6 +113,15 @@ namespace MWLua
|
||||||
scripts->onSkillLevelUp(event.mSkill, event.mSource);
|
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:
|
private:
|
||||||
MWWorld::Ptr getPtr(ESM::RefNum id) const
|
MWWorld::Ptr getPtr(ESM::RefNum id) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -70,8 +70,13 @@ namespace MWLua
|
||||||
std::string mSkill;
|
std::string mSkill;
|
||||||
std::string mSource;
|
std::string mSource;
|
||||||
};
|
};
|
||||||
|
struct OnJailTimeServed
|
||||||
|
{
|
||||||
|
ESM::RefNum mActor;
|
||||||
|
int mDays;
|
||||||
|
};
|
||||||
using Event = std::variant<OnActive, OnInactive, OnConsume, OnActivate, OnUseItem, OnNewExterior, OnTeleported,
|
using Event = std::variant<OnActive, OnInactive, OnConsume, OnActivate, OnUseItem, OnNewExterior, OnTeleported,
|
||||||
OnAnimationTextKey, OnSkillUse, OnSkillLevelUp>;
|
OnAnimationTextKey, OnSkillUse, OnSkillLevelUp, OnJailTimeServed>;
|
||||||
|
|
||||||
void clear() { mQueue.clear(); }
|
void clear() { mQueue.clear(); }
|
||||||
void addToQueue(Event e) { mQueue.push_back(std::move(e)); }
|
void addToQueue(Event e) { mQueue.push_back(std::move(e)); }
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
|
struct Context;
|
||||||
|
|
||||||
sol::table initCoreFactionBindings(const Context& context);
|
sol::table initCoreFactionBindings(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwinput/actions.hpp"
|
#include "../mwinput/actions.hpp"
|
||||||
|
|
||||||
|
#include "context.hpp"
|
||||||
#include "luamanagerimp.hpp"
|
#include "luamanagerimp.hpp"
|
||||||
|
|
||||||
namespace sol
|
namespace sol
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initInputPackage(const Context&);
|
struct Context;
|
||||||
|
|
||||||
|
sol::table initInputPackage(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MWLUA_INPUTBINDINGS_H
|
#endif // MWLUA_INPUTBINDINGS_H
|
||||||
|
|
|
@ -1,14 +1,24 @@
|
||||||
#include "landbindings.hpp"
|
#include "landbindings.hpp"
|
||||||
|
|
||||||
|
#include <span>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <sol/object.hpp>
|
||||||
|
#include <sol/table.hpp>
|
||||||
|
#include <sol/variadic_results.hpp>
|
||||||
|
|
||||||
#include <components/esm/refid.hpp>
|
#include <components/esm/refid.hpp>
|
||||||
#include <components/esm/util.hpp>
|
#include <components/esm/util.hpp>
|
||||||
#include <components/esmterrain/storage.hpp>
|
#include <components/esmterrain/storage.hpp>
|
||||||
|
#include <components/lua/luastate.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
#include "../mwworld/worldmodel.hpp"
|
#include "../mwworld/worldmodel.hpp"
|
||||||
|
|
||||||
|
#include "context.hpp"
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
#ifndef MWLUA_LANDBINDINGS_H
|
#ifndef MWLUA_LANDBINDINGS_H
|
||||||
#define MWLUA_LANDBINDINGS_H
|
#define MWLUA_LANDBINDINGS_H
|
||||||
|
|
||||||
#include "context.hpp"
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
|
struct Context;
|
||||||
|
|
||||||
sol::table initCoreLandBindings(const Context& context);
|
sol::table initCoreLandBindings(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
#include "localscripts.hpp"
|
#include "localscripts.hpp"
|
||||||
|
|
||||||
#include <components/esm3/loadcell.hpp>
|
|
||||||
#include <components/esm3/loadweap.hpp>
|
|
||||||
#include <components/misc/strings/lower.hpp>
|
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
#include "../mwmechanics/aicombat.hpp"
|
#include "../mwmechanics/aicombat.hpp"
|
||||||
|
@ -232,7 +228,7 @@ namespace MWLua
|
||||||
[&](LuaUtil::LuaView& view) { addPackage("openmw.self", sol::make_object(view.sol(), &mData)); });
|
[&](LuaUtil::LuaView& view) { addPackage("openmw.self", sol::make_object(view.sol(), &mData)); });
|
||||||
registerEngineHandlers({ &mOnActiveHandlers, &mOnInactiveHandlers, &mOnConsumeHandlers, &mOnActivatedHandlers,
|
registerEngineHandlers({ &mOnActiveHandlers, &mOnInactiveHandlers, &mOnConsumeHandlers, &mOnActivatedHandlers,
|
||||||
&mOnTeleportedHandlers, &mOnAnimationTextKeyHandlers, &mOnPlayAnimationHandlers, &mOnSkillUse,
|
&mOnTeleportedHandlers, &mOnAnimationTextKeyHandlers, &mOnPlayAnimationHandlers, &mOnSkillUse,
|
||||||
&mOnSkillLevelUp });
|
&mOnSkillLevelUp, &mOnJailTimeServed });
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalScripts::setActive(bool active, bool callHandlers)
|
void LocalScripts::setActive(bool active, bool callHandlers)
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
#ifndef MWLUA_LOCALSCRIPTS_H
|
#ifndef MWLUA_LOCALSCRIPTS_H
|
||||||
#define MWLUA_LOCALSCRIPTS_H
|
#define MWLUA_LOCALSCRIPTS_H
|
||||||
|
|
||||||
#include <memory>
|
#include <string_view>
|
||||||
#include <set>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <components/lua/luastate.hpp>
|
#include <components/lua/luastate.hpp>
|
||||||
|
@ -89,6 +87,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
callEngineHandlers(mOnSkillLevelUp, skillId, source);
|
callEngineHandlers(mOnSkillLevelUp, skillId, source);
|
||||||
}
|
}
|
||||||
|
void onJailTimeServed(int days) { callEngineHandlers(mOnJailTimeServed, days); }
|
||||||
|
|
||||||
void applyStatsCache();
|
void applyStatsCache();
|
||||||
|
|
||||||
|
@ -118,6 +117,7 @@ namespace MWLua
|
||||||
EngineHandlerList mOnPlayAnimationHandlers{ "_onPlayAnimation" };
|
EngineHandlerList mOnPlayAnimationHandlers{ "_onPlayAnimation" };
|
||||||
EngineHandlerList mOnSkillUse{ "_onSkillUse" };
|
EngineHandlerList mOnSkillUse{ "_onSkillUse" };
|
||||||
EngineHandlerList mOnSkillLevelUp{ "_onSkillLevelUp" };
|
EngineHandlerList mOnSkillLevelUp{ "_onSkillLevelUp" };
|
||||||
|
EngineHandlerList mOnJailTimeServed{ "_onJailTimeServed" };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,30 @@
|
||||||
#ifndef MWLUA_LUABINDINGS_H
|
#ifndef MWLUA_LUABINDINGS_H
|
||||||
#define MWLUA_LUABINDINGS_H
|
#define MWLUA_LUABINDINGS_H
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "context.hpp"
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
|
struct Context;
|
||||||
|
|
||||||
// Initialize Lua packages that are available for all scripts.
|
// Initialize Lua packages that are available for all scripts.
|
||||||
std::map<std::string, sol::object> initCommonPackages(const Context&);
|
std::map<std::string, sol::object> initCommonPackages(const Context& context);
|
||||||
|
|
||||||
// Initialize Lua packages that are available for global scripts (additionally to common packages).
|
// Initialize Lua packages that are available for global scripts (additionally to common packages).
|
||||||
std::map<std::string, sol::object> initGlobalPackages(const Context&);
|
std::map<std::string, sol::object> initGlobalPackages(const Context& context);
|
||||||
|
|
||||||
// Initialize Lua packages that are available for local scripts (additionally to common packages).
|
// Initialize Lua packages that are available for local scripts (additionally to common packages).
|
||||||
std::map<std::string, sol::object> initLocalPackages(const Context&);
|
std::map<std::string, sol::object> initLocalPackages(const Context& context);
|
||||||
|
|
||||||
// Initialize Lua packages that are available only for local scripts on the player (additionally to common and local
|
// Initialize Lua packages that are available only for local scripts on the player (additionally to common and local
|
||||||
// packages).
|
// packages).
|
||||||
std::map<std::string, sol::object> initPlayerPackages(const Context&);
|
std::map<std::string, sol::object> initPlayerPackages(const Context& context);
|
||||||
|
|
||||||
// Initialize Lua packages that are available only for menu scripts (additionally to common packages).
|
// Initialize Lua packages that are available only for menu scripts (additionally to common packages).
|
||||||
std::map<std::string, sol::object> initMenuPackages(const Context&);
|
std::map<std::string, sol::object> initMenuPackages(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MWLUA_LUABINDINGS_H
|
#endif // MWLUA_LUABINDINGS_H
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
#include <MyGUI_InputManager.h>
|
#include <MyGUI_InputManager.h>
|
||||||
#include <osg/Stats>
|
#include <osg/Stats>
|
||||||
|
|
||||||
|
#include <sol/object.hpp>
|
||||||
|
#include <sol/table.hpp>
|
||||||
|
#include <sol/types.hpp>
|
||||||
|
|
||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
|
|
||||||
#include <components/esm/luascripts.hpp>
|
#include <components/esm/luascripts.hpp>
|
||||||
|
@ -15,7 +19,6 @@
|
||||||
|
|
||||||
#include <components/l10n/manager.hpp>
|
#include <components/l10n/manager.hpp>
|
||||||
|
|
||||||
#include <components/lua_ui/content.hpp>
|
|
||||||
#include <components/lua_ui/registerscriptsettings.hpp>
|
#include <components/lua_ui/registerscriptsettings.hpp>
|
||||||
#include <components/lua_ui/util.hpp>
|
#include <components/lua_ui/util.hpp>
|
||||||
|
|
||||||
|
@ -212,13 +215,12 @@ namespace MWLua
|
||||||
|
|
||||||
// Run engine handlers
|
// Run engine handlers
|
||||||
mEngineEvents.callEngineHandlers();
|
mEngineEvents.callEngineHandlers();
|
||||||
if (!timeManager.isPaused())
|
bool isPaused = timeManager.isPaused();
|
||||||
{
|
|
||||||
float frameDuration = MWBase::Environment::get().getFrameDuration();
|
float frameDuration = MWBase::Environment::get().getFrameDuration();
|
||||||
for (LocalScripts* scripts : mActiveLocalScripts)
|
for (LocalScripts* scripts : mActiveLocalScripts)
|
||||||
scripts->update(frameDuration);
|
scripts->update(isPaused ? 0 : frameDuration);
|
||||||
mGlobalScripts.update(frameDuration);
|
mGlobalScripts.update(isPaused ? 0 : frameDuration);
|
||||||
}
|
|
||||||
|
|
||||||
mLua.protectedCall([&](LuaUtil::LuaView& lua) { mScriptTracker.unloadInactiveScripts(lua); });
|
mLua.protectedCall([&](LuaUtil::LuaView& lua) { mScriptTracker.unloadInactiveScripts(lua); });
|
||||||
}
|
}
|
||||||
|
@ -491,6 +493,11 @@ namespace MWLua
|
||||||
EngineEvents::OnSkillLevelUp{ getId(actor), skillId.serializeText(), std::string(source) });
|
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,
|
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 MWWorld::Ptr& ammo, int attackType, float attackStrength, float damage, bool isHealth,
|
||||||
const osg::Vec3f& hitPos, bool successful, MWMechanics::DamageSourceType sourceType)
|
const osg::Vec3f& hitPos, bool successful, MWMechanics::DamageSourceType sourceType)
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <osg/Stats>
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#include <osg/Stats>
|
||||||
|
|
||||||
#include <components/lua/inputactions.hpp>
|
#include <components/lua/inputactions.hpp>
|
||||||
#include <components/lua/luastate.hpp>
|
#include <components/lua/luastate.hpp>
|
||||||
#include <components/lua/scripttracker.hpp>
|
#include <components/lua/scripttracker.hpp>
|
||||||
|
@ -92,6 +93,7 @@ namespace MWLua
|
||||||
bool loopfallback) override;
|
bool loopfallback) override;
|
||||||
void skillUse(const MWWorld::Ptr& actor, ESM::RefId skillId, int useType, float scale) 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 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,
|
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 MWWorld::Ptr& ammo, int attackType, float attackStrength, float damage, bool isHealth,
|
||||||
const osg::Vec3f& hitPos, bool successful, MWMechanics::DamageSourceType sourceType) override;
|
const osg::Vec3f& hitPos, bool successful, MWMechanics::DamageSourceType sourceType) override;
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
|
struct Context;
|
||||||
|
|
||||||
sol::table initCoreMagicBindings(const Context& context);
|
sol::table initCoreMagicBindings(const Context& context);
|
||||||
void addActorMagicBindings(sol::table& actor, const Context& context);
|
void addActorMagicBindings(sol::table& actor, const Context& context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initMarkupPackage(const Context&);
|
struct Context;
|
||||||
|
|
||||||
|
sol::table initMarkupPackage(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MWLUA_MARKUPBINDINGS_H
|
#endif // MWLUA_MARKUPBINDINGS_H
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include "../mwbase/statemanager.hpp"
|
#include "../mwbase/statemanager.hpp"
|
||||||
#include "../mwstate/character.hpp"
|
#include "../mwstate/character.hpp"
|
||||||
|
|
||||||
|
#include "context.hpp"
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
static const MWState::Character* findCharacter(std::string_view characterDir)
|
static const MWState::Character* findCharacter(std::string_view characterDir)
|
||||||
|
|
|
@ -9,11 +9,11 @@
|
||||||
|
|
||||||
#include "../mwbase/luamanager.hpp"
|
#include "../mwbase/luamanager.hpp"
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
#include "inputprocessor.hpp"
|
#include "inputprocessor.hpp"
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
|
struct Context;
|
||||||
|
|
||||||
sol::table initMenuPackage(const Context& context);
|
sol::table initMenuPackage(const Context& context);
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
#include "../mwworld/worldimp.hpp"
|
#include "../mwworld/worldimp.hpp"
|
||||||
|
|
||||||
|
#include "context.hpp"
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
|
@ -3,13 +3,11 @@
|
||||||
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
|
struct Context;
|
||||||
|
|
||||||
sol::table initMWScriptBindings(const Context&);
|
sol::table initMWScriptBindings(const Context& context);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MWLUA_MWSCRIPTBINDINGS_H
|
#endif // MWLUA_MWSCRIPTBINDINGS_H
|
||||||
|
|
|
@ -13,9 +13,12 @@
|
||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
#include "../mwworld/scene.hpp"
|
#include "../mwworld/scene.hpp"
|
||||||
|
|
||||||
|
#include "context.hpp"
|
||||||
#include "luamanagerimp.hpp"
|
#include "luamanagerimp.hpp"
|
||||||
#include "objectlists.hpp"
|
#include "objectlists.hpp"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
template <class T = MWWorld::Ptr>
|
template <class T = MWWorld::Ptr>
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initNearbyPackage(const Context&);
|
struct Context;
|
||||||
|
|
||||||
|
sol::table initNearbyPackage(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MWLUA_NEARBYBINDINGS_H
|
#endif // MWLUA_NEARBYBINDINGS_H
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
#ifndef MWLUA_OBJECT_H
|
#ifndef MWLUA_OBJECT_H
|
||||||
#define MWLUA_OBJECT_H
|
#define MWLUA_OBJECT_H
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <typeindex>
|
|
||||||
|
|
||||||
#include <sol/sol.hpp>
|
#include <sol/sol.hpp>
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#ifndef MWLUA_OBJECTBINDINGS_H
|
#ifndef MWLUA_OBJECTBINDINGS_H
|
||||||
#define MWLUA_OBJECTBINDINGS_H
|
#define MWLUA_OBJECTBINDINGS_H
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
void initObjectBindingsForLocalScripts(const Context&);
|
struct Context;
|
||||||
void initObjectBindingsForGlobalScripts(const Context&);
|
|
||||||
|
void initObjectBindingsForLocalScripts(const Context& context);
|
||||||
|
void initObjectBindingsForGlobalScripts(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MWLUA_OBJECTBINDINGS_H
|
#endif // MWLUA_OBJECTBINDINGS_H
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
#include "objectlists.hpp"
|
#include "objectlists.hpp"
|
||||||
|
|
||||||
#include <components/esm3/esmreader.hpp>
|
|
||||||
#include <components/esm3/esmwriter.hpp>
|
|
||||||
#include <components/esm3/loadcell.hpp>
|
|
||||||
|
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwrender/postprocessor.hpp"
|
#include "../mwrender/postprocessor.hpp"
|
||||||
|
|
||||||
|
#include "context.hpp"
|
||||||
#include "luamanagerimp.hpp"
|
#include "luamanagerimp.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initPostprocessingPackage(const Context&);
|
struct Context;
|
||||||
|
|
||||||
|
sol::table initPostprocessingPackage(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MWLUA_POSTPROCESSINGBINDINGS_H
|
#endif // MWLUA_POSTPROCESSINGBINDINGS_H
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
|
||||||
#include "idcollectionbindings.hpp"
|
#include "idcollectionbindings.hpp"
|
||||||
#include "types/types.hpp"
|
#include "recordstore.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
|
struct Context;
|
||||||
|
|
||||||
sol::table initRaceRecordBindings(const Context& context);
|
sol::table initRaceRecordBindings(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
#ifndef MWLUA_RECORDSTORE_H
|
#ifndef MWLUA_RECORDSTORE_H
|
||||||
#define MWLUA_RECORDSTORE_H
|
#define MWLUA_RECORDSTORE_H
|
||||||
|
|
||||||
#include <sol/sol.hpp>
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <sol/forward.hpp>
|
||||||
|
#include <sol/overload.hpp>
|
||||||
|
#include <sol/state_view.hpp>
|
||||||
|
#include <sol/table.hpp>
|
||||||
|
#include <sol/types.hpp>
|
||||||
|
#include <sol/unsafe_function.hpp>
|
||||||
|
#include <sol/usertype.hpp>
|
||||||
|
|
||||||
#include <components/esm/defs.hpp>
|
|
||||||
#include <components/lua/luastate.hpp>
|
|
||||||
#include <components/lua/util.hpp>
|
#include <components/lua/util.hpp>
|
||||||
|
|
||||||
#include "apps/openmw/mwbase/environment.hpp"
|
#include "apps/openmw/mwbase/environment.hpp"
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initCoreSoundBindings(const Context&);
|
struct Context;
|
||||||
|
|
||||||
|
sol::table initCoreSoundBindings(const Context& context);
|
||||||
|
|
||||||
sol::table initAmbientPackage(const Context& context);
|
sol::table initAmbientPackage(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#include "stats.hpp"
|
#include "stats.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#include <components/esm3/loadclas.hpp>
|
#include <components/esm3/loadclas.hpp>
|
||||||
|
|
|
@ -108,6 +108,10 @@ namespace MWLua
|
||||||
}
|
}
|
||||||
luaManager->addUIMessage(message, mode);
|
luaManager->addUIMessage(message, mode);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
api["_showInteractiveMessage"] = [windowManager](std::string_view message, sol::optional<sol::table>) {
|
||||||
|
windowManager->interactiveMessageBox(message, { "#{Interface:OK}" });
|
||||||
|
};
|
||||||
api["CONSOLE_COLOR"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string, Misc::Color>(lua,
|
api["CONSOLE_COLOR"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string, Misc::Color>(lua,
|
||||||
{
|
{
|
||||||
{ "Default", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Default.substr(1)) },
|
{ "Default", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Default.substr(1)) },
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initUserInterfacePackage(const Context&);
|
struct Context;
|
||||||
|
|
||||||
|
sol::table initUserInterfacePackage(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MWLUA_UIBINDINGS_H
|
#endif // MWLUA_UIBINDINGS_H
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#ifndef MWLUA_USERDATASERIALIZER_H
|
#ifndef MWLUA_USERDATASERIALIZER_H
|
||||||
#define MWLUA_USERDATASERIALIZER_H
|
#define MWLUA_USERDATASERIALIZER_H
|
||||||
|
|
||||||
#include "object.hpp"
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace LuaUtil
|
namespace LuaUtil
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initVFSPackage(const Context&);
|
struct Context;
|
||||||
|
|
||||||
|
sol::table initVFSPackage(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MWLUA_VFSBINDINGS_H
|
#endif // MWLUA_VFSBINDINGS_H
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include <components/esm3/loadclot.hpp>
|
#include <components/esm3/loadclot.hpp>
|
||||||
#include <components/esm3/loadligh.hpp>
|
#include <components/esm3/loadligh.hpp>
|
||||||
#include <components/esm3/loadmisc.hpp>
|
#include <components/esm3/loadmisc.hpp>
|
||||||
#include <components/esm3/loadskil.hpp>
|
|
||||||
#include <components/esm3/loadweap.hpp>
|
#include <components/esm3/loadweap.hpp>
|
||||||
#include <components/lua/luastate.hpp>
|
#include <components/lua/luastate.hpp>
|
||||||
#include <components/misc/finitenumbers.hpp>
|
#include <components/misc/finitenumbers.hpp>
|
||||||
|
@ -27,6 +26,7 @@
|
||||||
#include "luamanagerimp.hpp"
|
#include "luamanagerimp.hpp"
|
||||||
|
|
||||||
#include "animationbindings.hpp"
|
#include "animationbindings.hpp"
|
||||||
|
#include "context.hpp"
|
||||||
#include "corebindings.hpp"
|
#include "corebindings.hpp"
|
||||||
#include "mwscriptbindings.hpp"
|
#include "mwscriptbindings.hpp"
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
#include <sol/forward.hpp>
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initWorldPackage(const Context&);
|
struct Context;
|
||||||
|
|
||||||
|
sol::table initWorldPackage(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MWLUA_WORLDBINDINGS_H
|
#endif // MWLUA_WORLDBINDINGS_H
|
||||||
|
|
|
@ -93,9 +93,10 @@ namespace
|
||||||
namespace MWPhysics
|
namespace MWPhysics
|
||||||
{
|
{
|
||||||
PhysicsSystem::PhysicsSystem(Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Group> parentNode)
|
PhysicsSystem::PhysicsSystem(Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Group> parentNode)
|
||||||
: mShapeManager(
|
: mPhysicsDt(1.f / 60.f)
|
||||||
std::make_unique<Resource::BulletShapeManager>(resourceSystem->getVFS(), resourceSystem->getSceneManager(),
|
, mShapeManager(std::make_unique<Resource::BulletShapeManager>(resourceSystem->getVFS(),
|
||||||
resourceSystem->getNifFileManager(), Settings::cells().mCacheExpiryDelay))
|
resourceSystem->getSceneManager(), resourceSystem->getNifFileManager(),
|
||||||
|
Settings::cells().mCacheExpiryDelay))
|
||||||
, mResourceSystem(resourceSystem)
|
, mResourceSystem(resourceSystem)
|
||||||
, mDebugDrawEnabled(false)
|
, mDebugDrawEnabled(false)
|
||||||
, mTimeAccum(0.0f)
|
, mTimeAccum(0.0f)
|
||||||
|
@ -103,7 +104,6 @@ namespace MWPhysics
|
||||||
, mWaterHeight(0)
|
, mWaterHeight(0)
|
||||||
, mWaterEnabled(false)
|
, mWaterEnabled(false)
|
||||||
, mParentNode(std::move(parentNode))
|
, mParentNode(std::move(parentNode))
|
||||||
, mPhysicsDt(1.f / 60.f)
|
|
||||||
{
|
{
|
||||||
mResourceSystem->addResourceManager(mShapeManager.get());
|
mResourceSystem->addResourceManager(mShapeManager.get());
|
||||||
|
|
||||||
|
|
|
@ -287,6 +287,8 @@ namespace MWPhysics
|
||||||
void reportStats(unsigned int frameNumber, osg::Stats& stats) const;
|
void reportStats(unsigned int frameNumber, osg::Stats& stats) const;
|
||||||
void reportCollision(const btVector3& position, const btVector3& normal);
|
void reportCollision(const btVector3& position, const btVector3& normal);
|
||||||
|
|
||||||
|
float mPhysicsDt;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateWater();
|
void updateWater();
|
||||||
|
|
||||||
|
@ -330,8 +332,6 @@ namespace MWPhysics
|
||||||
|
|
||||||
osg::ref_ptr<osg::Group> mParentNode;
|
osg::ref_ptr<osg::Group> mParentNode;
|
||||||
|
|
||||||
float mPhysicsDt;
|
|
||||||
|
|
||||||
std::size_t mSimulationsCounter = 0;
|
std::size_t mSimulationsCounter = 0;
|
||||||
std::array<std::vector<Simulation>, 2> mSimulations;
|
std::array<std::vector<Simulation>, 2> mSimulations;
|
||||||
std::vector<std::pair<MWWorld::Ptr, osg::Vec3f>> mActorsPositions;
|
std::vector<std::pair<MWWorld::Ptr, osg::Vec3f>> mActorsPositions;
|
||||||
|
|
|
@ -1117,8 +1117,8 @@ namespace MWRender
|
||||||
|
|
||||||
return keyframeController->getAsCallback();
|
return keyframeController->getAsCallback();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
return asCallback;
|
return asCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animation::resetActiveGroups()
|
void Animation::resetActiveGroups()
|
||||||
|
|
|
@ -401,14 +401,12 @@ namespace MWRender
|
||||||
{
|
{
|
||||||
if (mViewMode == VM_FirstPerson)
|
if (mViewMode == VM_FirstPerson)
|
||||||
{
|
{
|
||||||
static bool prototypeAdded = false;
|
[[maybe_unused]] static const bool prototypeAdded = [&] {
|
||||||
if (!prototypeAdded)
|
|
||||||
{
|
|
||||||
osg::ref_ptr<osgUtil::RenderBin> depthClearBin(new osgUtil::RenderBin);
|
osg::ref_ptr<osgUtil::RenderBin> depthClearBin(new osgUtil::RenderBin);
|
||||||
depthClearBin->setDrawCallback(new DepthClearCallback());
|
depthClearBin->setDrawCallback(new DepthClearCallback());
|
||||||
osgUtil::RenderBin::addRenderBinPrototype("DepthClear", depthClearBin);
|
osgUtil::RenderBin::addRenderBinPrototype("DepthClear", depthClearBin);
|
||||||
prototypeAdded = true;
|
return true;
|
||||||
}
|
}();
|
||||||
mObjectRoot->getOrCreateStateSet()->setRenderBinDetails(
|
mObjectRoot->getOrCreateStateSet()->setRenderBinDetails(
|
||||||
RenderBin_FirstPerson, "DepthClear", osg::StateSet::OVERRIDE_RENDERBIN_DETAILS);
|
RenderBin_FirstPerson, "DepthClear", osg::StateSet::OVERRIDE_RENDERBIN_DETAILS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,14 +88,13 @@ namespace MWRender
|
||||||
|
|
||||||
if (mProgramBlobber != nullptr)
|
if (mProgramBlobber != nullptr)
|
||||||
{
|
{
|
||||||
static bool pipelineLogged = [&] {
|
[[maybe_unused]] static const bool pipelineLogged = [&] {
|
||||||
if (mUseCompute)
|
if (mUseCompute)
|
||||||
Log(Debug::Info) << "Initialized compute shader pipeline for water ripples";
|
Log(Debug::Info) << "Initialized compute shader pipeline for water ripples";
|
||||||
else
|
else
|
||||||
Log(Debug::Info) << "Initialized fallback fragment shader pipeline for water ripples";
|
Log(Debug::Info) << "Initialized fallback fragment shader pipeline for water ripples";
|
||||||
return true;
|
return true;
|
||||||
}();
|
}();
|
||||||
(void)pipelineLogged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setCullCallback(new osg::NodeCallback);
|
setCullCallback(new osg::NodeCallback);
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "terrainstorage.hpp"
|
#include "terrainstorage.hpp"
|
||||||
|
|
||||||
#include <components/esm3/loadland.hpp>
|
#include <components/esm3/loadland.hpp>
|
||||||
|
#include <components/esm4/loadltex.hpp>
|
||||||
|
#include <components/esm4/loadtxst.hpp>
|
||||||
#include <components/esm4/loadwrld.hpp>
|
#include <components/esm4/loadwrld.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
@ -111,4 +113,15 @@ namespace MWRender
|
||||||
return esmStore.get<ESM::LandTexture>().search(index, plugin);
|
return esmStore.get<ESM::LandTexture>().search(index, plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ESM4::LandTexture* TerrainStorage::getEsm4LandTexture(ESM::RefId ltexId) const
|
||||||
|
{
|
||||||
|
const MWWorld::ESMStore& esmStore = *MWBase::Environment::get().getESMStore();
|
||||||
|
return esmStore.get<ESM4::LandTexture>().search(ltexId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ESM4::TextureSet* TerrainStorage::getEsm4TextureSet(ESM::RefId txstId) const
|
||||||
|
{
|
||||||
|
const MWWorld::ESMStore& esmStore = *MWBase::Environment::get().getESMStore();
|
||||||
|
return esmStore.get<ESM4::TextureSet>().search(txstId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,9 @@ namespace MWRender
|
||||||
osg::ref_ptr<const ESMTerrain::LandObject> getLand(ESM::ExteriorCellLocation cellLocation) override;
|
osg::ref_ptr<const ESMTerrain::LandObject> getLand(ESM::ExteriorCellLocation cellLocation) override;
|
||||||
const std::string* getLandTexture(std::uint16_t index, int plugin) override;
|
const std::string* getLandTexture(std::uint16_t index, int plugin) override;
|
||||||
|
|
||||||
|
const ESM4::LandTexture* getEsm4LandTexture(ESM::RefId ltexId) const override;
|
||||||
|
const ESM4::TextureSet* getEsm4TextureSet(ESM::RefId txstId) const override;
|
||||||
|
|
||||||
bool hasData(ESM::ExteriorCellLocation cellLocation) override;
|
bool hasData(ESM::ExteriorCellLocation cellLocation) override;
|
||||||
|
|
||||||
/// Get bounds of the whole terrain in cell units
|
/// Get bounds of the whole terrain in cell units
|
||||||
|
|
|
@ -604,7 +604,7 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = R()(runtime);
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
|
||||||
std::string_view effect = runtime.getStringLiteral(runtime[0].mInteger);
|
const std::string_view effectName = runtime.getStringLiteral(runtime[0].mInteger);
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
if (!ptr.getClass().isActor())
|
if (!ptr.getClass().isActor())
|
||||||
|
@ -615,11 +615,11 @@ namespace MWScript
|
||||||
|
|
||||||
long key;
|
long key;
|
||||||
|
|
||||||
if (const auto k = ::Misc::StringUtils::toNumeric<long>(effect.data());
|
if (const auto k = ::Misc::StringUtils::toNumeric<long>(effectName);
|
||||||
k.has_value() && *k >= 0 && *k <= 32767)
|
k.has_value() && *k >= 0 && *k <= 32767)
|
||||||
key = *k;
|
key = *k;
|
||||||
else
|
else
|
||||||
key = ESM::MagicEffect::effectGmstIdToIndex(effect);
|
key = ESM::MagicEffect::effectGmstIdToIndex(effectName);
|
||||||
|
|
||||||
const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
||||||
for (const auto& spell : stats.getActiveSpells())
|
for (const auto& spell : stats.getActiveSpells())
|
||||||
|
|
|
@ -522,16 +522,14 @@ namespace MWSound
|
||||||
|
|
||||||
/* We need to make sure ffmpeg is initialized. Optionally silence warning
|
/* We need to make sure ffmpeg is initialized. Optionally silence warning
|
||||||
* output from the lib */
|
* output from the lib */
|
||||||
static bool done_init = false;
|
[[maybe_unused]] static const bool doneInit = [] {
|
||||||
if (!done_init)
|
|
||||||
{
|
|
||||||
// This is not needed anymore above FFMpeg version 4.0
|
// This is not needed anymore above FFMpeg version 4.0
|
||||||
#if LIBAVCODEC_VERSION_INT < 3805796
|
#if LIBAVCODEC_VERSION_INT < 3805796
|
||||||
av_register_all();
|
av_register_all();
|
||||||
#endif
|
#endif
|
||||||
av_log_set_level(AV_LOG_ERROR);
|
av_log_set_level(AV_LOG_ERROR);
|
||||||
done_init = true;
|
return true;
|
||||||
}
|
}();
|
||||||
}
|
}
|
||||||
|
|
||||||
FFmpegDecoder::~FFmpegDecoder()
|
FFmpegDecoder::~FFmpegDecoder()
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <components/misc/constants.hpp>
|
#include <components/misc/constants.hpp>
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
#include <components/misc/thread.hpp>
|
#include <components/misc/thread.hpp>
|
||||||
|
#include <components/settings/values.hpp>
|
||||||
#include <components/vfs/manager.hpp>
|
#include <components/vfs/manager.hpp>
|
||||||
|
|
||||||
#include "efxpresets.h"
|
#include "efxpresets.h"
|
||||||
|
@ -963,6 +964,7 @@ namespace MWSound
|
||||||
// Speed of sound is in units per second. Take the sound speed in air (assumed
|
// Speed of sound is in units per second. Take the sound speed in air (assumed
|
||||||
// meters per second), multiply by the units per meter to get the speed in u/s.
|
// meters per second), multiply by the units per meter to get the speed in u/s.
|
||||||
alSpeedOfSound(Constants::SoundSpeedInAir * Constants::UnitsPerMeter);
|
alSpeedOfSound(Constants::SoundSpeedInAir * Constants::UnitsPerMeter);
|
||||||
|
alDopplerFactor(Settings::sound().mDopplerFactor);
|
||||||
alGetError();
|
alGetError();
|
||||||
|
|
||||||
mInitialized = true;
|
mInitialized = true;
|
||||||
|
@ -1142,8 +1144,8 @@ namespace MWSound
|
||||||
alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenALOutput::initCommon3D(ALuint source, const osg::Vec3f& pos, ALfloat mindist, ALfloat maxdist,
|
void OpenALOutput::initCommon3D(ALuint source, const osg::Vec3f& pos, const osg::Vec3f& vel, ALfloat mindist,
|
||||||
ALfloat gain, ALfloat pitch, bool loop, bool useenv)
|
ALfloat maxdist, ALfloat gain, ALfloat pitch, bool loop, bool useenv)
|
||||||
{
|
{
|
||||||
alSourcef(source, AL_REFERENCE_DISTANCE, mindist);
|
alSourcef(source, AL_REFERENCE_DISTANCE, mindist);
|
||||||
alSourcef(source, AL_MAX_DISTANCE, maxdist);
|
alSourcef(source, AL_MAX_DISTANCE, maxdist);
|
||||||
|
@ -1179,11 +1181,11 @@ namespace MWSound
|
||||||
alSourcef(source, AL_PITCH, pitch);
|
alSourcef(source, AL_PITCH, pitch);
|
||||||
alSourcefv(source, AL_POSITION, pos.ptr());
|
alSourcefv(source, AL_POSITION, pos.ptr());
|
||||||
alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
||||||
alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
alSourcefv(source, AL_VELOCITY, vel.ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenALOutput::updateCommon(
|
void OpenALOutput::updateCommon(ALuint source, const osg::Vec3f& pos, const osg::Vec3f& vel, ALfloat maxdist,
|
||||||
ALuint source, const osg::Vec3f& pos, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool useenv)
|
ALfloat gain, ALfloat pitch, bool useenv)
|
||||||
{
|
{
|
||||||
if (useenv && mListenerEnv == Env_Underwater && !mWaterFilter)
|
if (useenv && mListenerEnv == Env_Underwater && !mWaterFilter)
|
||||||
{
|
{
|
||||||
|
@ -1195,7 +1197,7 @@ namespace MWSound
|
||||||
alSourcef(source, AL_PITCH, pitch);
|
alSourcef(source, AL_PITCH, pitch);
|
||||||
alSourcefv(source, AL_POSITION, pos.ptr());
|
alSourcefv(source, AL_POSITION, pos.ptr());
|
||||||
alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
||||||
alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
alSourcefv(source, AL_VELOCITY, vel.ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenALOutput::playSound(Sound* sound, Sound_Handle data, float offset)
|
bool OpenALOutput::playSound(Sound* sound, Sound_Handle data, float offset)
|
||||||
|
@ -1248,8 +1250,9 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
source = mFreeSources.front();
|
source = mFreeSources.front();
|
||||||
|
|
||||||
initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(),
|
initCommon3D(source, sound->getPosition(), sound->getVelocity(), sound->getMinDistance(),
|
||||||
sound->getRealVolume(), getTimeScaledPitch(sound), sound->getIsLooping(), sound->getUseEnv());
|
sound->getMaxDistance(), sound->getRealVolume(), getTimeScaledPitch(sound), sound->getIsLooping(),
|
||||||
|
sound->getUseEnv());
|
||||||
alSourcei(source, AL_BUFFER, GET_PTRID(data));
|
alSourcei(source, AL_BUFFER, GET_PTRID(data));
|
||||||
alSourcef(source, AL_SEC_OFFSET, offset);
|
alSourcef(source, AL_SEC_OFFSET, offset);
|
||||||
if (getALError() != AL_NO_ERROR)
|
if (getALError() != AL_NO_ERROR)
|
||||||
|
@ -1312,8 +1315,8 @@ namespace MWSound
|
||||||
return;
|
return;
|
||||||
ALuint source = GET_PTRID(sound->mHandle);
|
ALuint source = GET_PTRID(sound->mHandle);
|
||||||
|
|
||||||
updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(),
|
updateCommon(source, sound->getPosition(), sound->getVelocity(), sound->getMaxDistance(),
|
||||||
getTimeScaledPitch(sound), sound->getUseEnv());
|
sound->getRealVolume(), getTimeScaledPitch(sound), sound->getUseEnv());
|
||||||
getALError();
|
getALError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1360,8 +1363,8 @@ namespace MWSound
|
||||||
if (sound->getIsLooping())
|
if (sound->getIsLooping())
|
||||||
Log(Debug::Warning) << "Warning: cannot loop stream \"" << decoder->getName() << "\"";
|
Log(Debug::Warning) << "Warning: cannot loop stream \"" << decoder->getName() << "\"";
|
||||||
|
|
||||||
initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(),
|
initCommon3D(source, sound->getPosition(), sound->getVelocity(), sound->getMinDistance(),
|
||||||
sound->getRealVolume(), getTimeScaledPitch(sound), false, sound->getUseEnv());
|
sound->getMaxDistance(), sound->getRealVolume(), getTimeScaledPitch(sound), false, sound->getUseEnv());
|
||||||
if (getALError() != AL_NO_ERROR)
|
if (getALError() != AL_NO_ERROR)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1443,8 +1446,8 @@ namespace MWSound
|
||||||
OpenAL_SoundStream* stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle);
|
OpenAL_SoundStream* stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle);
|
||||||
ALuint source = stream->mSource;
|
ALuint source = stream->mSource;
|
||||||
|
|
||||||
updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(),
|
updateCommon(source, sound->getPosition(), sound->getVelocity(), sound->getMaxDistance(),
|
||||||
getTimeScaledPitch(sound), sound->getUseEnv());
|
sound->getRealVolume(), getTimeScaledPitch(sound), sound->getUseEnv());
|
||||||
getALError();
|
getALError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1459,12 +1462,13 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenALOutput::updateListener(
|
void OpenALOutput::updateListener(
|
||||||
const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, Environment env)
|
const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, const osg::Vec3f& vel, Environment env)
|
||||||
{
|
{
|
||||||
if (mContext)
|
if (mContext)
|
||||||
{
|
{
|
||||||
ALfloat orient[6] = { atdir.x(), atdir.y(), atdir.z(), updir.x(), updir.y(), updir.z() };
|
ALfloat orient[6] = { atdir.x(), atdir.y(), atdir.z(), updir.x(), updir.y(), updir.z() };
|
||||||
alListenerfv(AL_POSITION, pos.ptr());
|
alListenerfv(AL_POSITION, pos.ptr());
|
||||||
|
alListenerfv(AL_VELOCITY, vel.ptr());
|
||||||
alListenerfv(AL_ORIENTATION, orient);
|
alListenerfv(AL_ORIENTATION, orient);
|
||||||
|
|
||||||
if (env != mListenerEnv)
|
if (env != mListenerEnv)
|
||||||
|
@ -1497,6 +1501,7 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
|
|
||||||
mListenerPos = pos;
|
mListenerPos = pos;
|
||||||
|
mListenerVel = vel;
|
||||||
mListenerEnv = env;
|
mListenerEnv = env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1582,7 +1587,6 @@ namespace MWSound
|
||||||
: SoundOutput(mgr)
|
: SoundOutput(mgr)
|
||||||
, mDevice(nullptr)
|
, mDevice(nullptr)
|
||||||
, mContext(nullptr)
|
, mContext(nullptr)
|
||||||
, mListenerPos(0.0f, 0.0f, 0.0f)
|
|
||||||
, mListenerEnv(Env_Normal)
|
, mListenerEnv(Env_Normal)
|
||||||
, mWaterFilter(0)
|
, mWaterFilter(0)
|
||||||
, mWaterEffect(0)
|
, mWaterEffect(0)
|
||||||
|
|
|
@ -46,6 +46,7 @@ namespace MWSound
|
||||||
StreamVec mActiveStreams;
|
StreamVec mActiveStreams;
|
||||||
|
|
||||||
osg::Vec3f mListenerPos;
|
osg::Vec3f mListenerPos;
|
||||||
|
osg::Vec3f mListenerVel;
|
||||||
Environment mListenerEnv;
|
Environment mListenerEnv;
|
||||||
|
|
||||||
ALuint mWaterFilter;
|
ALuint mWaterFilter;
|
||||||
|
@ -64,11 +65,11 @@ namespace MWSound
|
||||||
std::unique_ptr<DefaultDeviceThread> mDefaultDeviceThread;
|
std::unique_ptr<DefaultDeviceThread> mDefaultDeviceThread;
|
||||||
|
|
||||||
void initCommon2D(ALuint source, const osg::Vec3f& pos, ALfloat gain, ALfloat pitch, bool loop, bool useenv);
|
void initCommon2D(ALuint source, const osg::Vec3f& pos, ALfloat gain, ALfloat pitch, bool loop, bool useenv);
|
||||||
void initCommon3D(ALuint source, const osg::Vec3f& pos, ALfloat mindist, ALfloat maxdist, ALfloat gain,
|
void initCommon3D(ALuint source, const osg::Vec3f& pos, const osg::Vec3f& vel, ALfloat mindist, ALfloat maxdist,
|
||||||
ALfloat pitch, bool loop, bool useenv);
|
ALfloat gain, ALfloat pitch, bool loop, bool useenv);
|
||||||
|
|
||||||
void updateCommon(
|
void updateCommon(ALuint source, const osg::Vec3f& pos, const osg::Vec3f& vel, ALfloat maxdist, ALfloat gain,
|
||||||
ALuint source, const osg::Vec3f& pos, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool useenv);
|
ALfloat pitch, bool useenv);
|
||||||
|
|
||||||
float getTimeScaledPitch(SoundBase* sound);
|
float getTimeScaledPitch(SoundBase* sound);
|
||||||
|
|
||||||
|
@ -108,8 +109,8 @@ namespace MWSound
|
||||||
void startUpdate() override;
|
void startUpdate() override;
|
||||||
void finishUpdate() override;
|
void finishUpdate() override;
|
||||||
|
|
||||||
void updateListener(
|
void updateListener(const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir,
|
||||||
const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, Environment env) override;
|
const osg::Vec3f& vel, Environment env) override;
|
||||||
|
|
||||||
void pauseSounds(int types) override;
|
void pauseSounds(int types) override;
|
||||||
void resumeSounds(int types) override;
|
void resumeSounds(int types) override;
|
||||||
|
|
|
@ -31,6 +31,8 @@ namespace MWSound
|
||||||
struct SoundParams
|
struct SoundParams
|
||||||
{
|
{
|
||||||
osg::Vec3f mPos;
|
osg::Vec3f mPos;
|
||||||
|
osg::Vec3f mLastPos;
|
||||||
|
osg::Vec3f mVel;
|
||||||
float mVolume = 1.0f;
|
float mVolume = 1.0f;
|
||||||
float mBaseVolume = 1.0f;
|
float mBaseVolume = 1.0f;
|
||||||
float mPitch = 1.0f;
|
float mPitch = 1.0f;
|
||||||
|
@ -57,6 +59,8 @@ namespace MWSound
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setPosition(const osg::Vec3f& pos) { mParams.mPos = pos; }
|
void setPosition(const osg::Vec3f& pos) { mParams.mPos = pos; }
|
||||||
|
void setLastPosition(const osg::Vec3f& lastpos) { mParams.mLastPos = lastpos; }
|
||||||
|
void setVelocity(const osg::Vec3f& vel) { mParams.mVel = vel; }
|
||||||
void setVolume(float volume) { mParams.mVolume = volume; }
|
void setVolume(float volume) { mParams.mVolume = volume; }
|
||||||
void setBaseVolume(float volume) { mParams.mBaseVolume = volume; }
|
void setBaseVolume(float volume) { mParams.mBaseVolume = volume; }
|
||||||
void setFadeout(float duration) { setFade(duration, 0.0, Play_StopAtFadeEnd); }
|
void setFadeout(float duration) { setFade(duration, 0.0, Play_StopAtFadeEnd); }
|
||||||
|
@ -150,6 +154,8 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
|
|
||||||
const osg::Vec3f& getPosition() const { return mParams.mPos; }
|
const osg::Vec3f& getPosition() const { return mParams.mPos; }
|
||||||
|
const osg::Vec3f& getLastPosition() const { return mParams.mLastPos; }
|
||||||
|
const osg::Vec3f& getVelocity() const { return mParams.mVel; }
|
||||||
float getRealVolume() const { return mParams.mVolume * mParams.mBaseVolume * mParams.mFadeVolume; }
|
float getRealVolume() const { return mParams.mVolume * mParams.mBaseVolume * mParams.mFadeVolume; }
|
||||||
float getPitch() const { return mParams.mPitch; }
|
float getPitch() const { return mParams.mPitch; }
|
||||||
float getMinDistance() const { return mParams.mMinDistance; }
|
float getMinDistance() const { return mParams.mMinDistance; }
|
||||||
|
|
|
@ -119,6 +119,7 @@ namespace MWSound
|
||||||
, mListenerPos(0, 0, 0)
|
, mListenerPos(0, 0, 0)
|
||||||
, mListenerDir(1, 0, 0)
|
, mListenerDir(1, 0, 0)
|
||||||
, mListenerUp(0, 0, 1)
|
, mListenerUp(0, 0, 1)
|
||||||
|
, mListenerVel(0, 0, 0)
|
||||||
, mUnderwaterSound(nullptr)
|
, mUnderwaterSound(nullptr)
|
||||||
, mNearWaterSound(nullptr)
|
, mNearWaterSound(nullptr)
|
||||||
, mPlaybackPaused(false)
|
, mPlaybackPaused(false)
|
||||||
|
@ -960,7 +961,7 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
|
|
||||||
mOutput->startUpdate();
|
mOutput->startUpdate();
|
||||||
mOutput->updateListener(mListenerPos, mListenerDir, mListenerUp, env);
|
mOutput->updateListener(mListenerPos, mListenerDir, mListenerUp, mListenerVel, env);
|
||||||
|
|
||||||
updateMusic(duration);
|
updateMusic(duration);
|
||||||
|
|
||||||
|
@ -977,7 +978,13 @@ namespace MWSound
|
||||||
if (sound->getIs3D())
|
if (sound->getIs3D())
|
||||||
{
|
{
|
||||||
if (!ptr.isEmpty())
|
if (!ptr.isEmpty())
|
||||||
|
{
|
||||||
|
sound->setLastPosition(sound->getPosition());
|
||||||
sound->setPosition(ptr.getRefData().getPosition().asVec3());
|
sound->setPosition(ptr.getRefData().getPosition().asVec3());
|
||||||
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
|
sound->setVelocity(
|
||||||
|
(sound->getPosition() - sound->getLastPosition()) / world->getPhysicsFrameRateDt());
|
||||||
|
}
|
||||||
|
|
||||||
cull3DSound(sound);
|
cull3DSound(sound);
|
||||||
}
|
}
|
||||||
|
@ -1013,8 +1020,11 @@ namespace MWSound
|
||||||
{
|
{
|
||||||
if (!ptr.isEmpty())
|
if (!ptr.isEmpty())
|
||||||
{
|
{
|
||||||
|
sound->setLastPosition(sound->getPosition());
|
||||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
sound->setPosition(world->getActorHeadTransform(ptr).getTrans());
|
sound->setPosition(world->getActorHeadTransform(ptr).getTrans());
|
||||||
|
sound->setVelocity(
|
||||||
|
(sound->getPosition() - sound->getLastPosition()) / world->getPhysicsFrameRateDt());
|
||||||
}
|
}
|
||||||
|
|
||||||
cull3DSound(sound);
|
cull3DSound(sound);
|
||||||
|
@ -1153,6 +1163,11 @@ namespace MWSound
|
||||||
mWaterSoundUpdater.setUnderwater(underwater);
|
mWaterSoundUpdater.setUnderwater(underwater);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoundManager::setListenerVel(const osg::Vec3f& vel)
|
||||||
|
{
|
||||||
|
mListenerVel = vel;
|
||||||
|
}
|
||||||
|
|
||||||
void SoundManager::updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated)
|
void SoundManager::updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated)
|
||||||
{
|
{
|
||||||
SoundMap::iterator snditer = mActiveSounds.find(old.mRef);
|
SoundMap::iterator snditer = mActiveSounds.find(old.mRef);
|
||||||
|
|
|
@ -92,6 +92,7 @@ namespace MWSound
|
||||||
osg::Vec3f mListenerPos;
|
osg::Vec3f mListenerPos;
|
||||||
osg::Vec3f mListenerDir;
|
osg::Vec3f mListenerDir;
|
||||||
osg::Vec3f mListenerUp;
|
osg::Vec3f mListenerUp;
|
||||||
|
osg::Vec3f mListenerVel;
|
||||||
|
|
||||||
int mPausedSoundTypes[BlockerType::MaxCount] = {};
|
int mPausedSoundTypes[BlockerType::MaxCount] = {};
|
||||||
|
|
||||||
|
@ -283,6 +284,8 @@ namespace MWSound
|
||||||
void setListenerPosDir(
|
void setListenerPosDir(
|
||||||
const osg::Vec3f& pos, const osg::Vec3f& dir, const osg::Vec3f& up, bool underwater) override;
|
const osg::Vec3f& pos, const osg::Vec3f& dir, const osg::Vec3f& up, bool underwater) override;
|
||||||
|
|
||||||
|
void setListenerVel(const osg::Vec3f& vel) override;
|
||||||
|
|
||||||
void updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) override;
|
void updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) override;
|
||||||
|
|
||||||
void clear() override;
|
void clear() override;
|
||||||
|
|
|
@ -61,8 +61,8 @@ namespace MWSound
|
||||||
virtual void startUpdate() = 0;
|
virtual void startUpdate() = 0;
|
||||||
virtual void finishUpdate() = 0;
|
virtual void finishUpdate() = 0;
|
||||||
|
|
||||||
virtual void updateListener(
|
virtual void updateListener(const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir,
|
||||||
const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, Environment env)
|
const osg::Vec3f& vel, Environment env)
|
||||||
= 0;
|
= 0;
|
||||||
|
|
||||||
virtual void pauseSounds(int types) = 0;
|
virtual void pauseSounds(int types) = 0;
|
||||||
|
|
|
@ -110,6 +110,7 @@ namespace ESM4
|
||||||
struct Static;
|
struct Static;
|
||||||
struct StaticCollection;
|
struct StaticCollection;
|
||||||
struct Terminal;
|
struct Terminal;
|
||||||
|
struct TextureSet;
|
||||||
struct Tree;
|
struct Tree;
|
||||||
struct Weapon;
|
struct Weapon;
|
||||||
struct World;
|
struct World;
|
||||||
|
@ -149,7 +150,7 @@ namespace MWWorld
|
||||||
Store<ESM4::LevelledNpc>, Store<ESM4::Light>, Store<ESM4::MiscItem>, Store<ESM4::MovableStatic>,
|
Store<ESM4::LevelledNpc>, Store<ESM4::Light>, Store<ESM4::MiscItem>, Store<ESM4::MovableStatic>,
|
||||||
Store<ESM4::Npc>, Store<ESM4::Outfit>, Store<ESM4::Potion>, Store<ESM4::Race>, Store<ESM4::Reference>,
|
Store<ESM4::Npc>, Store<ESM4::Outfit>, Store<ESM4::Potion>, Store<ESM4::Race>, Store<ESM4::Reference>,
|
||||||
Store<ESM4::Sound>, Store<ESM4::SoundReference>, Store<ESM4::Static>, Store<ESM4::StaticCollection>,
|
Store<ESM4::Sound>, Store<ESM4::SoundReference>, Store<ESM4::Static>, Store<ESM4::StaticCollection>,
|
||||||
Store<ESM4::Terminal>, Store<ESM4::Tree>, Store<ESM4::Weapon>, Store<ESM4::World>>;
|
Store<ESM4::Terminal>, Store<ESM4::TextureSet>, Store<ESM4::Tree>, Store<ESM4::Weapon>, Store<ESM4::World>>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -461,6 +461,11 @@ namespace MWWorld
|
||||||
|
|
||||||
update(magicBoltState, duration);
|
update(magicBoltState, duration);
|
||||||
|
|
||||||
|
for (const auto& sound : magicBoltState.mSounds)
|
||||||
|
{
|
||||||
|
sound->setVelocity(direction * speed);
|
||||||
|
}
|
||||||
|
|
||||||
// For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit
|
// For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit
|
||||||
// result.
|
// result.
|
||||||
std::vector<MWWorld::Ptr> targetActors;
|
std::vector<MWWorld::Ptr> targetActors;
|
||||||
|
|
|
@ -1273,13 +1273,12 @@ namespace MWWorld
|
||||||
const std::size_t leftCapacity = mPreloader->getMaxCacheSize() - mPreloader->getCacheSize();
|
const std::size_t leftCapacity = mPreloader->getMaxCacheSize() - mPreloader->getCacheSize();
|
||||||
if (cells.size() > leftCapacity)
|
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 "
|
Log(Debug::Warning) << "Not enough cell preloader cache capacity to preload exterior cells, consider "
|
||||||
"increasing \"preload cell cache max\" up to "
|
"increasing \"preload cell cache max\" up to "
|
||||||
<< (mPreloader->getCacheSize() + cells.size());
|
<< (mPreloader->getCacheSize() + cells.size());
|
||||||
return true;
|
return true;
|
||||||
}();
|
}();
|
||||||
(void)logged;
|
|
||||||
cells.resize(leftCapacity);
|
cells.resize(leftCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1354,6 +1354,7 @@ template class MWWorld::TypedDynamicStore<ESM4::SoundReference>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Static>;
|
template class MWWorld::TypedDynamicStore<ESM4::Static>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::StaticCollection>;
|
template class MWWorld::TypedDynamicStore<ESM4::StaticCollection>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Terminal>;
|
template class MWWorld::TypedDynamicStore<ESM4::Terminal>;
|
||||||
|
template class MWWorld::TypedDynamicStore<ESM4::TextureSet>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Tree>;
|
template class MWWorld::TypedDynamicStore<ESM4::Tree>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Weapon>;
|
template class MWWorld::TypedDynamicStore<ESM4::Weapon>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::World>;
|
template class MWWorld::TypedDynamicStore<ESM4::World>;
|
||||||
|
|
|
@ -1460,6 +1460,8 @@ namespace MWWorld
|
||||||
void World::queueMovement(const Ptr& ptr, const osg::Vec3f& velocity)
|
void World::queueMovement(const Ptr& ptr, const osg::Vec3f& velocity)
|
||||||
{
|
{
|
||||||
mPhysics->queueObjectMovement(ptr, velocity);
|
mPhysics->queueObjectMovement(ptr, velocity);
|
||||||
|
if (ptr == MWMechanics::getPlayer())
|
||||||
|
MWBase::Environment::get().getSoundManager()->setListenerVel(velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::updateAnimatedCollisionShape(const Ptr& ptr)
|
void World::updateAnimatedCollisionShape(const Ptr& ptr)
|
||||||
|
@ -3182,6 +3184,11 @@ namespace MWWorld
|
||||||
return mWeatherManager->getSunPercentage(getTimeStamp().getHour());
|
return mWeatherManager->getSunPercentage(getTimeStamp().getHour());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float World::getPhysicsFrameRateDt() const
|
||||||
|
{
|
||||||
|
return mPhysics->mPhysicsDt;
|
||||||
|
}
|
||||||
|
|
||||||
bool World::findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result)
|
bool World::findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result)
|
||||||
{
|
{
|
||||||
if (cell->isExterior())
|
if (cell->isExterior())
|
||||||
|
|
|
@ -584,6 +584,8 @@ namespace MWWorld
|
||||||
float getSunVisibility() const override;
|
float getSunVisibility() const override;
|
||||||
float getSunPercentage() const override;
|
float getSunPercentage() const override;
|
||||||
|
|
||||||
|
float getPhysicsFrameRateDt() const override;
|
||||||
|
|
||||||
bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) override;
|
bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) override;
|
||||||
|
|
||||||
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
||||||
|
|
|
@ -407,6 +407,7 @@ add_component_dir(detournavigator
|
||||||
areatype
|
areatype
|
||||||
asyncnavmeshupdater
|
asyncnavmeshupdater
|
||||||
bounds
|
bounds
|
||||||
|
cellgridbounds
|
||||||
changetype
|
changetype
|
||||||
collisionshapetype
|
collisionshapetype
|
||||||
commulativeaabb
|
commulativeaabb
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <optional>
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
|
@ -10,10 +10,8 @@
|
||||||
|
|
||||||
#include <osg/io_utils>
|
#include <osg/io_utils>
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <stdexcept>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
|
@ -79,7 +77,7 @@ namespace DetourNavigator
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto data
|
const std::unique_ptr<PreparedNavMeshData> data
|
||||||
= prepareNavMeshTileData(*recastMesh, mWorldspace, mTilePosition, mAgentBounds, mSettings.mRecast);
|
= prepareNavMeshTileData(*recastMesh, mWorldspace, mTilePosition, mAgentBounds, mSettings.mRecast);
|
||||||
|
|
||||||
if (data == nullptr)
|
if (data == nullptr)
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
#include "exceptions.hpp"
|
#include "exceptions.hpp"
|
||||||
#include "flags.hpp"
|
#include "flags.hpp"
|
||||||
#include "navmeshdata.hpp"
|
#include "navmeshdata.hpp"
|
||||||
#include "navmeshdb.hpp"
|
|
||||||
#include "navmeshtilescache.hpp"
|
|
||||||
#include "offmeshconnection.hpp"
|
#include "offmeshconnection.hpp"
|
||||||
#include "preparednavmeshdata.hpp"
|
#include "preparednavmeshdata.hpp"
|
||||||
#include "recastcontext.hpp"
|
#include "recastcontext.hpp"
|
||||||
|
@ -22,8 +20,6 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <iomanip>
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include <DetourCommon.h>
|
#include <DetourCommon.h>
|
||||||
#include <DetourNavMesh.h>
|
#include <DetourNavMesh.h>
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <osg/Vec3f>
|
#include <osg/Vec3f>
|
||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
|
|
||||||
#include <Recast.h>
|
#include <Recast.h>
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
void initPolyMeshDetail(rcPolyMeshDetail& value) noexcept
|
void initPolyMeshDetail(rcPolyMeshDetail& value) noexcept
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
|
|
||||||
#include "flags.hpp"
|
#include "flags.hpp"
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
#include <osg/Vec3f>
|
#include <osg/Vec3f>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
class dtNavMeshQuery;
|
class dtNavMeshQuery;
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
|
|
|
@ -11,9 +11,7 @@
|
||||||
#include <osg/Vec3f>
|
#include <osg/Vec3f>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <string>
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace ESM
|
||||||
VER_134 = 0x3fab851f, // FONV, GunRunnersArsenal, LonesomeRoad, OldWorldBlues
|
VER_134 = 0x3fab851f, // FONV, GunRunnersArsenal, LonesomeRoad, OldWorldBlues
|
||||||
VER_094 = 0x3f70a3d7, // TES5/FO3
|
VER_094 = 0x3f70a3d7, // TES5/FO3
|
||||||
VER_170 = 0x3fd9999a, // TES5
|
VER_170 = 0x3fd9999a, // TES5
|
||||||
|
VER_171 = 0x3fdae148, // TES5
|
||||||
VER_095 = 0x3f733333, // FO4
|
VER_095 = 0x3f733333, // FO4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ ESM::LandData::LandData(const ESM::Land& land, int loadFlags)
|
||||||
, mNormals(mData->mNormals)
|
, mNormals(mData->mNormals)
|
||||||
, mColors(mData->mColours)
|
, mColors(mData->mColours)
|
||||||
, mTextures(mData->mTextures)
|
, mTextures(mData->mTextures)
|
||||||
|
, mIsEsm4(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,9 +44,11 @@ ESM::LandData::LandData(const ESM4::Land& land, int /*loadFlags*/)
|
||||||
, mMaxHeight(std::numeric_limits<float>::lowest())
|
, mMaxHeight(std::numeric_limits<float>::lowest())
|
||||||
, mSize(Constants::ESM4CellSizeInUnits)
|
, mSize(Constants::ESM4CellSizeInUnits)
|
||||||
, mLandSize(ESM4::Land::sVertsPerSide)
|
, mLandSize(ESM4::Land::sVertsPerSide)
|
||||||
|
, mPlugin(land.mId.mContentFile)
|
||||||
, mNormals(land.mVertNorm)
|
, mNormals(land.mVertNorm)
|
||||||
, mColors(land.mVertColr)
|
, mColors(land.mVertColr)
|
||||||
, mTextures(textures)
|
, mTextures(textures)
|
||||||
|
, mIsEsm4(true)
|
||||||
{
|
{
|
||||||
float rowOffset = land.mHeightMap.heightOffset;
|
float rowOffset = land.mHeightMap.heightOffset;
|
||||||
for (int y = 0; y < mLandSize; y++)
|
for (int y = 0; y < mLandSize; y++)
|
||||||
|
@ -69,6 +72,9 @@ ESM::LandData::LandData(const ESM4::Land& land, int /*loadFlags*/)
|
||||||
}
|
}
|
||||||
|
|
||||||
mHeights = mHeightsData;
|
mHeights = mHeightsData;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; ++i)
|
||||||
|
mEsm4Textures[i] = land.mTextures[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
#ifndef COMPONENTS_ESM_ESMTERRAIN
|
#ifndef COMPONENTS_ESM_ESMTERRAIN
|
||||||
#define COMPONENTS_ESM_ESMTERRAIN
|
#define COMPONENTS_ESM_ESMTERRAIN
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace ESM4
|
#include <components/esm4/loadland.hpp>
|
||||||
{
|
|
||||||
struct Land;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
|
@ -28,7 +26,6 @@ namespace ESM
|
||||||
std::span<const float> getHeights() const { return mHeights; }
|
std::span<const float> getHeights() const { return mHeights; }
|
||||||
std::span<const std::int8_t> getNormals() const { return mNormals; }
|
std::span<const std::int8_t> getNormals() const { return mNormals; }
|
||||||
std::span<const std::uint8_t> getColors() const { return mColors; }
|
std::span<const std::uint8_t> getColors() const { return mColors; }
|
||||||
std::span<const std::uint16_t> getTextures() const { return mTextures; }
|
|
||||||
float getSize() const { return mSize; }
|
float getSize() const { return mSize; }
|
||||||
float getMinHeight() const { return mMinHeight; }
|
float getMinHeight() const { return mMinHeight; }
|
||||||
float getMaxHeight() const { return mMaxHeight; }
|
float getMaxHeight() const { return mMaxHeight; }
|
||||||
|
@ -36,6 +33,22 @@ namespace ESM
|
||||||
int getLoadFlags() const { return mLoadFlags; }
|
int getLoadFlags() const { return mLoadFlags; }
|
||||||
int getPlugin() const { return mPlugin; }
|
int getPlugin() const { return mPlugin; }
|
||||||
|
|
||||||
|
bool isEsm4() const { return mIsEsm4; }
|
||||||
|
|
||||||
|
std::span<const std::uint16_t> getTextures() const
|
||||||
|
{
|
||||||
|
if (mIsEsm4)
|
||||||
|
throw std::logic_error("ESM3 textures requested from ESM4 LandData");
|
||||||
|
return mTextures;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ESM4::Land::Texture& getEsm4Texture(std::size_t quad) const
|
||||||
|
{
|
||||||
|
if (!mIsEsm4)
|
||||||
|
throw std::logic_error("ESM4 texture requested from ESM3 LandData");
|
||||||
|
return mEsm4Textures[quad];
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<const ESM::LandRecordData> mData;
|
std::unique_ptr<const ESM::LandRecordData> mData;
|
||||||
int mLoadFlags = 0;
|
int mLoadFlags = 0;
|
||||||
|
@ -49,6 +62,8 @@ namespace ESM
|
||||||
std::span<const std::int8_t> mNormals;
|
std::span<const std::int8_t> mNormals;
|
||||||
std::span<const std::uint8_t> mColors;
|
std::span<const std::uint8_t> mColors;
|
||||||
std::span<const std::uint16_t> mTextures;
|
std::span<const std::uint16_t> mTextures;
|
||||||
|
std::array<ESM4::Land::Texture, 4> mEsm4Textures;
|
||||||
|
bool mIsEsm4;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,10 +51,10 @@ namespace std
|
||||||
{
|
{
|
||||||
size_t operator()(const ESM::FormId& formId) const
|
size_t operator()(const ESM::FormId& formId) const
|
||||||
{
|
{
|
||||||
static_assert(sizeof(ESM::FormId) == sizeof(size_t));
|
static_assert(sizeof(ESM::FormId) == sizeof(uint64_t));
|
||||||
size_t s;
|
uint64_t s;
|
||||||
memcpy(&s, &formId, sizeof(size_t));
|
memcpy(&s, &formId, sizeof(ESM::FormId));
|
||||||
return hash<size_t>()(s);
|
return hash<uint64_t>()(s);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@
|
||||||
#include <components/esm4/loadstat.hpp>
|
#include <components/esm4/loadstat.hpp>
|
||||||
#include <components/esm4/loadterm.hpp>
|
#include <components/esm4/loadterm.hpp>
|
||||||
#include <components/esm4/loadtree.hpp>
|
#include <components/esm4/loadtree.hpp>
|
||||||
|
#include <components/esm4/loadtxst.hpp>
|
||||||
#include <components/esm4/loadweap.hpp>
|
#include <components/esm4/loadweap.hpp>
|
||||||
#include <components/esm4/loadwrld.hpp>
|
#include <components/esm4/loadwrld.hpp>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2015-2016, 2018, 2020-2021 cc9cii
|
Copyright (C) 2015 - 2024 cc9cii
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
misrepresented as being the original software.
|
misrepresented as being the original software.
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
cc9cii cc9c@iinet.net.au
|
cc9cii cc9cii@hotmail.com
|
||||||
|
|
||||||
Much of the information on the data structures are based on the information
|
Much of the information on the data structures are based on the information
|
||||||
from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
|
from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
|
||||||
|
@ -26,13 +26,51 @@
|
||||||
*/
|
*/
|
||||||
#include "loadland.hpp"
|
#include "loadland.hpp"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
|
|
||||||
#include "reader.hpp"
|
#include "reader.hpp"
|
||||||
// #include "writer.hpp"
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void assignDefaultTextures(ESM4::Land& land, ESM4::Reader& reader)
|
||||||
|
{
|
||||||
|
std::uint32_t esmVer = reader.esmVersion();
|
||||||
|
|
||||||
|
// Note: in games after TES4 it can be configured in ini file (sDefaultLandDiffuseTexture)
|
||||||
|
if (!reader.hasFormVersion() && (esmVer == ESM::VER_080 || esmVer == ESM::VER_100)) // TES4
|
||||||
|
{
|
||||||
|
land.mDefaultDiffuseMap = VFS::Path::NormalizedView("textures/landscape/terrainhddirt01.dds");
|
||||||
|
land.mDefaultNormalMap = VFS::Path::NormalizedView("textures/landscape/terrainhddirt01_n.dds");
|
||||||
|
}
|
||||||
|
else if (reader.hasFormVersion() && reader.formVersion() >= 16
|
||||||
|
&& (esmVer == ESM::VER_094 || esmVer == ESM::VER_170 || esmVer == ESM::VER_171)) // TES5
|
||||||
|
{
|
||||||
|
land.mDefaultDiffuseMap = VFS::Path::NormalizedView("textures/landscape/dirt02.dds");
|
||||||
|
land.mDefaultNormalMap = VFS::Path::NormalizedView("textures/landscape/dirt02_n.dds");
|
||||||
|
}
|
||||||
|
else if (esmVer == ESM::VER_095 || esmVer == ESM::VER_100) // FO4
|
||||||
|
{
|
||||||
|
land.mDefaultDiffuseMap
|
||||||
|
= VFS::Path::NormalizedView("textures/landscape/ground/commonwealthdefault01_d.dds");
|
||||||
|
land.mDefaultNormalMap = VFS::Path::NormalizedView("textures/landscape/ground/commonwealthdefault01_n.dds");
|
||||||
|
}
|
||||||
|
else if (esmVer == ESM::VER_094 || esmVer == ESM::VER_132 || esmVer == ESM::VER_133 || esmVer == ESM::VER_134)
|
||||||
|
{ // FO3, FONV
|
||||||
|
land.mDefaultDiffuseMap = VFS::Path::NormalizedView("textures/landscape/dirtwasteland01.dds");
|
||||||
|
land.mDefaultNormalMap = VFS::Path::NormalizedView("textures/landscape/dirtwasteland01_n.dds");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Nothing especially bad happens if default texture is not set (except of the missing texture of course),
|
||||||
|
// but we throw an error because this case is unexpected and detection logic needs to be updated.
|
||||||
|
throw std::runtime_error("ESM4::Land unknown ESM version");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// overlap north
|
// overlap north
|
||||||
//
|
//
|
||||||
|
@ -53,12 +91,16 @@ void ESM4::Land::load(ESM4::Reader& reader)
|
||||||
{
|
{
|
||||||
mId = reader.getFormIdFromHeader();
|
mId = reader.getFormIdFromHeader();
|
||||||
mFlags = reader.hdr().record.flags;
|
mFlags = reader.hdr().record.flags;
|
||||||
|
|
||||||
mDataTypes = 0;
|
mDataTypes = 0;
|
||||||
mCell = reader.currCell();
|
mCell = reader.currCell();
|
||||||
TxtLayer layer;
|
TxtLayer layer;
|
||||||
std::int8_t currentAddQuad = -1; // for VTXT following ATXT
|
std::int8_t currentAddQuad = -1; // for VTXT following ATXT
|
||||||
|
assignDefaultTextures(*this, reader);
|
||||||
|
|
||||||
// std::map<FormId, int> uniqueTextures; // FIXME: for temp testing only
|
layer.texture.formId = 0;
|
||||||
|
for (int i = 0; i < 4; ++i)
|
||||||
|
mTextures[i].base.formId = 0;
|
||||||
|
|
||||||
while (reader.getSubRecordHeader())
|
while (reader.getSubRecordHeader())
|
||||||
{
|
{
|
||||||
|
@ -78,12 +120,6 @@ void ESM4::Land::load(ESM4::Reader& reader)
|
||||||
}
|
}
|
||||||
case ESM::fourCC("VHGT"): // vertex height gradient, 4+33x33+3 = 4+1089+3 = 1096
|
case ESM::fourCC("VHGT"): // vertex height gradient, 4+33x33+3 = 4+1089+3 = 1096
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
reader.get(mHeightMap.heightOffset);
|
|
||||||
reader.get(mHeightMap.gradientData);
|
|
||||||
reader.get(mHeightMap.unknown1);
|
|
||||||
reader.get(mHeightMap.unknown2);
|
|
||||||
#endif
|
|
||||||
reader.get(mHeightMap);
|
reader.get(mHeightMap);
|
||||||
mDataTypes |= LAND_VHGT;
|
mDataTypes |= LAND_VHGT;
|
||||||
break;
|
break;
|
||||||
|
@ -102,13 +138,9 @@ void ESM4::Land::load(ESM4::Reader& reader)
|
||||||
if (base.quadrant >= 4)
|
if (base.quadrant >= 4)
|
||||||
throw std::runtime_error("base texture quadrant index error");
|
throw std::runtime_error("base texture quadrant index error");
|
||||||
|
|
||||||
reader.adjustFormId(base.formId);
|
if (base.formId != 0)
|
||||||
mTextures[base.quadrant].base = std::move(base);
|
reader.adjustFormId(base.formId);
|
||||||
#if 0
|
mTextures[base.quadrant].base = base;
|
||||||
std::cout << "Base Texture formid: 0x"
|
|
||||||
<< std::hex << mTextures[base.quadrant].base.formId
|
|
||||||
<< ", quad " << std::dec << (int)base.quadrant << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -116,31 +148,23 @@ void ESM4::Land::load(ESM4::Reader& reader)
|
||||||
{
|
{
|
||||||
if (currentAddQuad != -1)
|
if (currentAddQuad != -1)
|
||||||
{
|
{
|
||||||
// FIXME: sometimes there are no VTXT following an ATXT? Just add a dummy one for now
|
// NOTE: sometimes there are no VTXT following an ATXT
|
||||||
Log(Debug::Verbose) << "ESM4::Land VTXT empty layer " << layer.texture.layerIndex;
|
layer.data.resize(1); // just one spot
|
||||||
|
layer.data.back().position = 0; // this corner
|
||||||
|
layer.data.back().opacity = 0.f; // transparent
|
||||||
|
|
||||||
|
if (layer.texture.layerIndex != mTextures[currentAddQuad].layers.size())
|
||||||
|
throw std::runtime_error("ESM4::LAND additional texture skipping layer");
|
||||||
|
|
||||||
mTextures[currentAddQuad].layers.push_back(layer);
|
mTextures[currentAddQuad].layers.push_back(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.get(layer.texture);
|
reader.get(layer.texture);
|
||||||
reader.adjustFormId(layer.texture.formId);
|
if (layer.texture.formId != 0)
|
||||||
|
reader.adjustFormId(layer.texture.formId);
|
||||||
if (layer.texture.quadrant >= 4)
|
if (layer.texture.quadrant >= 4)
|
||||||
throw std::runtime_error("additional texture quadrant index error");
|
throw std::runtime_error("ESM4::LAND additional texture quadrant index error");
|
||||||
#if 0
|
|
||||||
FormId txt = layer.texture.formId;
|
|
||||||
std::map<FormId, int>::iterator lb = uniqueTextures.lower_bound(txt);
|
|
||||||
if (lb != uniqueTextures.end() && !(uniqueTextures.key_comp()(txt, lb->first)))
|
|
||||||
{
|
|
||||||
lb->second += 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
uniqueTextures.insert(lb, std::make_pair(txt, 1));
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
std::cout << "Additional Texture formId: 0x"
|
|
||||||
<< std::hex << layer.texture.formId
|
|
||||||
<< ", quad " << std::dec << (int)layer.texture.quadrant << std::endl;
|
|
||||||
std::cout << "Additional Texture layer: "
|
|
||||||
<< std::dec << (int)layer.texture.layerIndex << std::endl;
|
|
||||||
#endif
|
|
||||||
currentAddQuad = layer.texture.quadrant;
|
currentAddQuad = layer.texture.quadrant;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -156,25 +180,17 @@ void ESM4::Land::load(ESM4::Reader& reader)
|
||||||
if (count)
|
if (count)
|
||||||
{
|
{
|
||||||
layer.data.resize(count);
|
layer.data.resize(count);
|
||||||
std::vector<ESM4::Land::VTXT>::iterator it = layer.data.begin();
|
for (ESM4::Land::VTXT& vtxt : layer.data)
|
||||||
for (; it != layer.data.end(); ++it)
|
reader.get(vtxt);
|
||||||
{
|
|
||||||
reader.get(*it);
|
|
||||||
// FIXME: debug only
|
|
||||||
// std::cout << "pos: " << std::dec << (int)(*it).position << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mTextures[currentAddQuad].layers.push_back(layer);
|
|
||||||
|
|
||||||
// Assumed that the layers are added in the correct sequence
|
if (layer.texture.layerIndex != mTextures[currentAddQuad].layers.size())
|
||||||
// FIXME: Knights.esp doesn't seem to observe this - investigate more
|
throw std::runtime_error("ESM4::LAND additional texture skipping layer");
|
||||||
// assert(layer.texture.layerIndex == mTextures[currentAddQuad].layers.size()-1
|
|
||||||
//&& "additional texture layer index error");
|
mTextures[currentAddQuad].layers.push_back(layer);
|
||||||
|
|
||||||
currentAddQuad = -1;
|
currentAddQuad = -1;
|
||||||
layer.data.clear();
|
layer.data.clear();
|
||||||
// FIXME: debug only
|
|
||||||
// std::cout << "VTXT: count " << std::dec << count << std::endl;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ESM::fourCC("VTEX"): // only in Oblivion?
|
case ESM::fourCC("VTEX"): // only in Oblivion?
|
||||||
|
@ -195,44 +211,14 @@ void ESM4::Land::load(ESM4::Reader& reader)
|
||||||
reader.skipSubRecordData();
|
reader.skipSubRecordData();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("ESM4::LAND::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
|
throw std::runtime_error("ESM4::LAND - Unknown subrecord " + ESM::printName(subHdr.typeId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentAddQuad != -1)
|
if (currentAddQuad != -1)
|
||||||
{
|
{
|
||||||
// FIXME: not sure if it happens here as well
|
// not sure if it happens here as well, if so just ignore
|
||||||
Log(Debug::Verbose) << "ESM4::Land VTXT empty layer " << layer.texture.layerIndex << " quad "
|
Log(Debug::Verbose) << "ESM4::Land VTXT empty layer " << layer.texture.layerIndex << " quad "
|
||||||
<< static_cast<unsigned>(layer.texture.quadrant);
|
<< static_cast<unsigned>(layer.texture.quadrant);
|
||||||
mTextures[currentAddQuad].layers.push_back(layer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool missing = false;
|
|
||||||
for (int i = 0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
if (mTextures[i].base.formId == 0)
|
|
||||||
{
|
|
||||||
// std::cout << "ESM4::LAND " << ESM4::formIdToString(mFormId) << " missing base, quad " << i << std::endl;
|
|
||||||
// std::cout << "layers " << mTextures[i].layers.size() << std::endl;
|
|
||||||
// NOTE: can't set the default here since FO3/FONV may have different defaults
|
|
||||||
// mTextures[i].base.formId = 0x000008C0; // TerrainHDDirt01.dds
|
|
||||||
missing = true;
|
|
||||||
}
|
|
||||||
// else
|
|
||||||
//{
|
|
||||||
// std::cout << "ESM4::LAND " << ESM4::formIdToString(mFormId) << " base, quad " << i << std::endl;
|
|
||||||
// std::cout << "layers " << mTextures[i].layers.size() << std::endl;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
// at least one of the quadrants do not have a base texture, return without setting the flag
|
|
||||||
if (!missing)
|
|
||||||
mDataTypes |= LAND_VTEX;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// void ESM4::Land::save(ESM4::Writer& writer) const
|
|
||||||
//{
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void ESM4::Land::blank()
|
|
||||||
//{
|
|
||||||
// }
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
#include <components/esm/defs.hpp>
|
#include <components/esm/defs.hpp>
|
||||||
#include <components/esm/formid.hpp>
|
#include <components/esm/formid.hpp>
|
||||||
|
#include <components/vfs/pathutil.hpp>
|
||||||
|
|
||||||
namespace ESM4
|
namespace ESM4
|
||||||
{
|
{
|
||||||
|
@ -124,6 +125,8 @@ namespace ESM4
|
||||||
Texture mTextures[4]; // 0 = bottom left, 1 = bottom right, 2 = top left, 3 = top right
|
Texture mTextures[4]; // 0 = bottom left, 1 = bottom right, 2 = top left, 3 = top right
|
||||||
std::vector<ESM::FormId> mIds; // land texture (LTEX) formids
|
std::vector<ESM::FormId> mIds; // land texture (LTEX) formids
|
||||||
ESM::FormId mCell;
|
ESM::FormId mCell;
|
||||||
|
VFS::Path::NormalizedView mDefaultDiffuseMap;
|
||||||
|
VFS::Path::NormalizedView mDefaultNormalMap;
|
||||||
|
|
||||||
void load(Reader& reader);
|
void load(Reader& reader);
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue