Merge branch openmw:master into master

This commit is contained in:
Igilq 2025-08-01 06:03:07 +00:00
commit 26b508b11f
12 changed files with 101 additions and 36 deletions

View File

@ -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 86)
set(OPENMW_POSTPROCESSING_API_REVISION 3) set(OPENMW_POSTPROCESSING_API_REVISION 3)
set(OPENMW_VERSION_COMMITHASH "") set(OPENMW_VERSION_COMMITHASH "")

View File

@ -507,8 +507,10 @@ namespace CSMPrefs
Settings::SettingValue<std::string> mOrbitRollRight{ mIndex, sName, "orbit-roll-right", "E" }; Settings::SettingValue<std::string> mOrbitRollRight{ mIndex, sName, "orbit-roll-right", "E" };
Settings::SettingValue<std::string> mOrbitSpeedMode{ mIndex, sName, "orbit-speed-mode", "" }; Settings::SettingValue<std::string> mOrbitSpeedMode{ mIndex, sName, "orbit-speed-mode", "" };
Settings::SettingValue<std::string> mOrbitCenterSelection{ mIndex, sName, "orbit-center-selection", "C" }; Settings::SettingValue<std::string> mOrbitCenterSelection{ mIndex, sName, "orbit-center-selection", "C" };
Settings::SettingValue<std::string> mScriptEditorComment{ mIndex, sName, "script-editor-comment", "" }; Settings::SettingValue<std::string> mScriptEditorComment{ mIndex, sName, "script-editor-comment",
Settings::SettingValue<std::string> mScriptEditorUncomment{ mIndex, sName, "script-editor-uncomment", "" }; "Ctrl+Slash" };
Settings::SettingValue<std::string> mScriptEditorUncomment{ mIndex, sName, "script-editor-uncomment",
"Ctrl+Shift+Question" };
}; };
struct ModelsCategory : Settings::WithIndex struct ModelsCategory : Settings::WithIndex

View File

@ -21,6 +21,24 @@
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
#include "../../model/world/universalid.hpp" #include "../../model/world/universalid.hpp"
namespace
{
void prependToEachLine(QTextCursor begin, const QString& text)
{
QTextCursor end = begin;
begin.setPosition(begin.selectionStart());
begin.movePosition(QTextCursor::StartOfLine);
end.setPosition(end.selectionEnd());
end.movePosition(QTextCursor::EndOfLine);
begin.beginEditBlock();
for (; begin < end; begin.movePosition(QTextCursor::EndOfLine), begin.movePosition(QTextCursor::Right))
{
begin.insertText(text);
}
begin.endEditBlock();
}
}
CSVWorld::ScriptEdit::ChangeLock::ChangeLock(ScriptEdit& edit) CSVWorld::ScriptEdit::ChangeLock::ChangeLock(ScriptEdit& edit)
: mEdit(edit) : mEdit(edit)
{ {
@ -46,6 +64,55 @@ bool CSVWorld::ScriptEdit::event(QEvent* event)
return QPlainTextEdit::event(event); return QPlainTextEdit::event(event);
} }
void CSVWorld::ScriptEdit::keyPressEvent(QKeyEvent* event)
{
if (event->key() == Qt::Key_Backtab)
{
QTextCursor cursor = textCursor();
QTextCursor end = cursor;
cursor.setPosition(cursor.selectionStart());
cursor.movePosition(QTextCursor::StartOfLine);
end.setPosition(end.selectionEnd());
end.movePosition(QTextCursor::EndOfLine);
cursor.beginEditBlock();
for (; cursor < end; cursor.movePosition(QTextCursor::EndOfLine), cursor.movePosition(QTextCursor::Right))
{
cursor.select(QTextCursor::LineUnderCursor);
QString line = cursor.selectedText();
if (line.isEmpty())
continue;
qsizetype index = 0;
if (line[0] == '\t')
index = 1;
else
{
// Remove up to a tab worth of spaces instead
while (line[index].isSpace() && index < mTabCharCount && line[index] != '\t')
index++;
}
if (index != 0)
{
line.remove(0, index);
cursor.insertText(line);
}
}
cursor.endEditBlock();
return;
}
else if (event->key() == Qt::Key_Tab)
{
QTextCursor cursor = textCursor();
if (cursor.hasSelection())
{
prependToEachLine(cursor, "\t");
return;
}
}
QPlainTextEdit::keyPressEvent(event);
}
CSVWorld::ScriptEdit::ScriptEdit(const CSMDoc::Document& document, ScriptHighlighter::Mode mode, QWidget* parent) CSVWorld::ScriptEdit::ScriptEdit(const CSMDoc::Document& document, ScriptHighlighter::Mode mode, QWidget* parent)
: QPlainTextEdit(parent) : QPlainTextEdit(parent)
, mChangeLocked(0) , mChangeLocked(0)
@ -316,22 +383,7 @@ void CSVWorld::ScriptEdit::markOccurrences()
void CSVWorld::ScriptEdit::commentSelection() void CSVWorld::ScriptEdit::commentSelection()
{ {
QTextCursor begin = textCursor(); prependToEachLine(textCursor(), ";");
QTextCursor end = begin;
begin.setPosition(begin.selectionStart());
begin.movePosition(QTextCursor::StartOfLine);
end.setPosition(end.selectionEnd());
end.movePosition(QTextCursor::EndOfLine);
begin.beginEditBlock();
for (; begin < end; begin.movePosition(QTextCursor::EndOfLine), begin.movePosition(QTextCursor::Right))
{
begin.insertText(";");
}
begin.endEditBlock();
} }
void CSVWorld::ScriptEdit::uncommentSelection() void CSVWorld::ScriptEdit::uncommentSelection()
@ -345,17 +397,16 @@ void CSVWorld::ScriptEdit::uncommentSelection()
end.movePosition(QTextCursor::EndOfLine); end.movePosition(QTextCursor::EndOfLine);
begin.beginEditBlock(); begin.beginEditBlock();
for (; begin < end; begin.movePosition(QTextCursor::EndOfLine), begin.movePosition(QTextCursor::Right)) for (; begin < end; begin.movePosition(QTextCursor::EndOfLine), begin.movePosition(QTextCursor::Right))
{ {
begin.select(QTextCursor::LineUnderCursor); begin.select(QTextCursor::LineUnderCursor);
QString line = begin.selectedText(); QString line = begin.selectedText();
if (line.size() == 0) if (line.isEmpty())
continue; continue;
// get first nonspace character in line // get first nonspace character in line
int index; qsizetype index;
for (index = 0; index != line.size(); ++index) for (index = 0; index != line.size(); ++index)
{ {
if (!line[index].isSpace()) if (!line[index].isSpace())

View File

@ -74,6 +74,7 @@ namespace CSVWorld
protected: protected:
bool event(QEvent* event) override; bool event(QEvent* event) override;
void keyPressEvent(QKeyEvent* e) override;
public: public:
ScriptEdit(const CSMDoc::Document& document, ScriptHighlighter::Mode mode, QWidget* parent); ScriptEdit(const CSMDoc::Document& document, ScriptHighlighter::Mode mode, QWidget* parent);

View File

@ -212,13 +212,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); });
} }

View File

@ -28,7 +28,7 @@ Engine handler is a function defined by a script, that can be called by the engi
| `assigned to a script in openmw-cs (not yet implemented).` | `assigned to a script in openmw-cs (not yet implemented).`
| ``onInterfaceOverride`` can be called before ``onInit``. | ``onInterfaceOverride`` can be called before ``onInit``.
* - onUpdate(dt) * - onUpdate(dt)
- | Called every frame if the game is not paused. `dt` is - | Called every frame in the Lua thread (even if the game is paused). `dt` is
| the simulation time from the last update in seconds. | the simulation time from the last update in seconds.
* - onSave() -> savedData * - onSave() -> savedData
- | Called when the game is saving. May be called in inactive state, - | Called when the game is saving. May be called in inactive state,

View File

@ -182,6 +182,10 @@ local function updateCrosshair()
end end
local function onUpdate(dt) local function onUpdate(dt)
if dt <= 0 then
return
end
camera.setExtraPitch(0) camera.setExtraPitch(0)
camera.setExtraYaw(0) camera.setExtraYaw(0)
camera.setExtraRoll(0) camera.setExtraRoll(0)

View File

@ -41,6 +41,10 @@ end
local initialized = false local initialized = false
local function onUpdate(dt) local function onUpdate(dt)
if dt <= 0 then
return
end
-- The script is loaded before the actor's CharacterController object is initialized, therefore -- The script is loaded before the actor's CharacterController object is initialized, therefore
-- we have to delay this initialization step or the call won't have any effect. -- we have to delay this initialization step or the call won't have any effect.
if not initialized then if not initialized then

View File

@ -96,7 +96,11 @@ local function skillUsedHandler(skillid, params)
end end
end end
local function onUpdate() local function onUpdate(dt)
if dt <= 0 then
return
end
if self.cell ~= cell then if self.cell ~= cell then
cell = self.cell cell = self.cell
onCellChange() onCellChange()

View File

@ -11,7 +11,7 @@ local function emitTargetsChanged()
end end
end end
local function onUpdate() local function onUpdate(dt)
if types.Actor.isDeathFinished(self) or not types.Actor.isInActorsProcessingRange(self) then if types.Actor.isDeathFinished(self) or not types.Actor.isInActorsProcessingRange(self) then
if next(targets) ~= nil then if next(targets) ~= nil then
targets = {} targets = {}
@ -21,10 +21,10 @@ local function onUpdate()
return return
end end
-- Early-out for actors without targets and without combat state -- Early-out for actors without targets and without combat state when the game is not paused
-- TODO: use events or engine handlers to detect when targets change -- TODO: use events or engine handlers to detect when targets change
local isStanceNothing = types.Actor.getStance(self) == types.Actor.STANCE.Nothing local isStanceNothing = types.Actor.getStance(self) == types.Actor.STANCE.Nothing
if isStanceNothing and next(targets) == nil and not AI.isFleeing() then if isStanceNothing and next(targets) == nil and not AI.isFleeing() and dt > 0 then
return return
end end

View File

@ -42,7 +42,7 @@
-- @return #number -- @return #number
--- ---
-- Whether the world is paused (onUpdate doesn't work when the world is paused). -- Whether the world is paused.
-- @function [parent=#core] isWorldPaused -- @function [parent=#core] isWorldPaused
-- @return #boolean -- @return #boolean

View File

@ -119,7 +119,7 @@
-- @param #number ratio -- @param #number ratio
--- ---
-- Whether the world is paused (onUpdate doesn't work when the world is paused). -- Whether the world is paused.
-- @function [parent=#world] isWorldPaused -- @function [parent=#world] isWorldPaused
-- @return #boolean -- @return #boolean