1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-08-16 07:14:07 +00:00

Compare commits

..

1223 commits

Author SHA1 Message Date
Alexei Kotov
9610be7c8a Merge branch 'coveritymovesme' into 'master'
Address more simple Coverity defects

See merge request OpenMW/openmw!4851
2025-08-15 16:14:31 +03:00
Alexei Kotov
2b403b38be Merge branch 'changelog' into 'master'
Sync changelog

See merge request OpenMW/openmw!4852
2025-08-15 16:13:58 +03:00
psi29a
ac2627a7b7 Merge branch 'regions_lua' into 'master'
Add regions record store in lua

Closes #7879

See merge request OpenMW/openmw!4743
2025-08-15 07:12:17 +00:00
psi29a
8622dacaea Merge branch '8551-orang-kk' into 'master'
Fix loss of quick key bindings for temporary or missing items

See merge request OpenMW/openmw!4780
2025-08-15 06:49:51 +00:00
Alexei Kotov
8c18c8460f Sync changelog for 0.50.0 2025-08-14 21:42:01 +03:00
psi29a
72bf7673f4 Merge branch 'formattool' into 'master'
Use std::format in esmtool

See merge request OpenMW/openmw!4841
2025-08-14 16:25:09 +00:00
Alexei Kotov
488f73c5da Merge branch 'bmdhacks-skill-controller-crash' into 'master'
fix a crash in skill selection dialog due to uninitialized controller data

See merge request OpenMW/openmw!4843
2025-08-14 16:37:57 +03:00
Alexei Kotov
a049f3c3a8 Merge branch 'bmdhacks-lua-doublepress' into 'master'
Controller Input: Fix Lua dialogs from causing a double-press

See merge request OpenMW/openmw!4844
2025-08-14 15:45:43 +03:00
Evil Eye
8073c59898 Add integration tests 2025-08-14 14:19:20 +02:00
Evil Eye
450f907166 Adjust documentation and bump API revision 2025-08-14 14:01:15 +02:00
Kuyondo
bc2f948abe add warning if id of quickkey is non-existent 2025-08-14 19:47:21 +08:00
SkyHasACat
111d6620a6 Remove index weather 2025-08-14 13:42:52 +02:00
SkyHasACat
50ebf304c7 Formatting 2025-08-14 13:42:52 +02:00
SkyHasACat
1b5450557e Don't hardcode weather ids 2025-08-14 13:42:52 +02:00
SkyHasACat
fe48e2c9ae Fixed properly 2025-08-14 13:42:52 +02:00
SkyHasACat
a418e05869 foward declare? 2025-08-14 13:42:52 +02:00
SkyHasACat
3a9a83b107 Fix sound desc, remove removed field 2025-08-14 13:42:51 +02:00
SkyHasACat
9f2ad18549 Fix formatting 2025-08-14 13:42:51 +02:00
SkyHasACat
475e5522ed Make read only 2025-08-14 13:42:51 +02:00
SkyHasACat
943966d59a Fix more things 2025-08-14 13:42:51 +02:00
SkyHasACat
3d954ed720 Fix review issues 2025-08-14 13:42:51 +02:00
SkyHasACat
046c0a64f2 Revert ID change 2025-08-14 13:42:51 +02:00
SkyHasACat
548fb5fecb Add region sound binding 2025-08-14 13:42:51 +02:00
SkyHasACat
40f26a9495 Use luautil id 2025-08-14 13:42:51 +02:00
SkyHasACat
944985e1ce Fix color 2025-08-14 13:42:51 +02:00
SkyHasACat
0acde006a0 Remove unneeded includes? 2025-08-14 13:42:51 +02:00
SkyHasACat
5e30e45700 formatting 2025-08-14 13:42:51 +02:00
SkyHasACat
d58545ca39 Add region bindings 2025-08-14 13:42:49 +02:00
Evil Eye
cae36d6eec Add remaining default initialisations flagged by Coverity 2025-08-14 13:33:20 +02:00
Kuyondo
e226963d0d clear temporary items 2025-08-14 19:28:03 +08:00
Alexei Kotov
32e463945e Merge branch 'settingscrash' into 'master'
Fix some dangling window pointer use on exit

See merge request OpenMW/openmw!4846
2025-08-14 13:52:56 +03:00
Alexei Kotov
37c4277b92 Also don't process controller menu axis navigation events for hidden menus 2025-08-14 13:47:18 +03:00
Alexei Kotov
30bd014bd7 Some controller focus initialization cleanup 2025-08-14 13:43:46 +03:00
Evil Eye
9db9df95e2 Address more simple Coverity defects 2025-08-14 11:19:13 +02:00
Kuyondo
4749ddf586 save lifetime of temporary quickkey items 2025-08-14 15:32:36 +08:00
Alexei Kotov
cb0316e6be Merge branch 'journal-lua-api' into 'master'
Add Lua API for the player journal text data

Closes #7966

See merge request OpenMW/openmw!4203
2025-08-13 14:58:48 +03:00
Evil Eye
1ffcd3f213 Replace usage of std::distance and std::advance 2025-08-13 11:43:51 +02:00
trav5
cffb045767 Lua journal read access post-review formatting corrected 2025-08-13 11:09:10 +02:00
trav5
6d0f05e97b Lua journal read access post-review class debug names aligned 2025-08-13 11:09:10 +02:00
trav5
87819b3e0d Lua journal read access post-review documentation fixes 2025-08-13 11:09:10 +02:00
trav5
596ee3e8fa Lua journal read access post-review std::distance 2025-08-13 11:09:10 +02:00
trav5
7f3bc4884e Add Lua API for the player journal text data
This implements #7966 - adds the Lua API read-only access to the player's stored journal text entries (quest & topics data). See the issue ticket for some details on the proposal.
2025-08-13 11:08:10 +02:00
Evil Eye
d4bc9696e9 Combine format strings 2025-08-13 09:50:13 +02:00
Evil Eye
ace1f7f3d0 Merge branch 'fixkaramunsing' into 'master'
Ensure draganddrop finishes when item is used from it

Closes #8659

See merge request OpenMW/openmw!4847
2025-08-12 21:52:41 +00:00
Evil Eye
33ea16655b Add missing paren and remove unnecessary flushes 2025-08-12 23:38:47 +02:00
Kuyondo
8ea5448112 use find() 2025-08-12 21:24:09 +08:00
Kuyondo
9426a36f5a maintain missing item info in quickkey menu 2025-08-12 21:24:09 +08:00
psi29a
f5d866894e Merge branch 'coverityspam' into 'master'
Resolve a number of Coverity defects

See merge request OpenMW/openmw!4835
2025-08-12 07:59:19 +00:00
psi29a
a1d9cbd47c Merge branch 'sounds-page-engoodening' into 'master'
Clean up launcher audio tab formatting

See merge request OpenMW/openmw!4833
2025-08-12 07:50:06 +00:00
psi29a
8f8723e2fc Merge branch 'topurgeornottopurge' into 'master'
Improve parity around spell store based effects

Closes #8309

See merge request OpenMW/openmw!4827
2025-08-12 07:48:41 +00:00
bmdhacks
80a29ab57b bulk initialize controller focus to zero 2025-08-11 17:08:17 -07:00
Kuyondo
41e2282501 fix #8659 2025-08-11 22:16:10 +08:00
Alexei Kotov
2bb1c4810d Fix some dangling window pointer use on exit 2025-08-11 13:52:51 +03:00
epochwon
363a6e0aa0 clean up audio page formatting 2025-08-11 08:13:02 +03:00
bmdhacks
d05bb877fe fix a double-press bug where controller input on Lua dialog boxes was being broadcast down into whatever the last open dialog box was. 2025-08-10 17:27:36 -07:00
bmdhacks
1b34248ef6 fix a crash in skill selection dialog due to uninitialized controller data 2025-08-10 17:05:37 -07:00
Evil Eye
a7ba54c361 Use std::format in esmtool 2025-08-10 12:03:34 +02:00
Evil Eye
a30b4ad615 Undo changes to nifkey.hpp 2025-08-07 20:57:40 +02:00
Alexei Kotov
b5f87a9d50 Merge branch 'fix_ppa_build_failure_ButtonDefinition' into 'master'
Fix PPA GCC-15 build failure with ButtonDefinition

See merge request OpenMW/openmw!4837
2025-08-07 21:13:27 +03:00
Bret Curtis
23fb414fd4 use std::string_view instead 2025-08-07 17:18:53 +02:00
Bret Curtis
7ff139e7b1 Fix PPA GCC-15 build failure with ButtonDefinition 2025-08-07 15:45:41 +02:00
psi29a
d46e68a4d5 Merge branch 'unawarenesstraining' into 'master'
Cache awareness rolls for 5 seconds to make sneaking easier

See merge request OpenMW/openmw!4434
2025-08-07 08:13:50 +00:00
psi29a
dd654e62f8 Merge branch 'scheduledinterruption' into 'master'
Don't auto cancel jobs that only run when scheduled

See merge request OpenMW/openmw!4834
2025-08-07 07:07:45 +00:00
psi29a
25adab1526 Merge branch 'fix_build' into 'master'
Fix build with msvc

See merge request OpenMW/openmw!4836
2025-08-07 07:06:29 +00:00
elsid
2b88a620f5
Fix build with msvc
openmw\apps\openmw\mwgui\controllerbuttonsoverlay.hpp(75): error C2079: 'MWGui::ControllerButtonsOverlay::mButtons' uses undefined class 'std::array<MWGui::ControllerButtonsOverlay::ButtonWidgets,15>'
2025-08-06 22:19:49 +02:00
Evil Eye
a085036a92 Resolve a number of Coverity defects 2025-08-06 19:52:09 +02:00
Evil Eye
60d5e4d30b Merge branch 'local_variable_naming' into 'master'
Fix and enforce local variable naming (#8424)

See merge request OpenMW/openmw!4832
2025-08-06 17:50:33 +00:00
Evil Eye
8c3757a324 Don't auto cancel jobs that only run when scheduled 2025-08-06 16:36:07 +02:00
Alexei Kotov
5ad9010e07 Merge branch 'dont-take-away-my-individuality' into 'master'
FIX: Track the highest local refNum during plugin loading and increment it for each cloned/created reference

Closes #8620

See merge request OpenMW/openmw!4781
2025-08-06 09:53:06 +03:00
Alexei Kotov
34d297969e Merge branch 'master' into 'master'
Gamepad GUI Mode: add (optional) native controller support to all menus [round 2]

See merge request OpenMW/openmw!4741
2025-08-06 09:34:35 +03:00
Andrew Lanzone
e4cc3adc98 Merge branch 'master' of https://gitlab.com/OpenMW/openmw 2025-08-05 17:32:50 -07:00
Andrew Lanzone
dd801a55e2 Bump OPENMW_LUA_API_REVISION version 2025-08-05 17:31:36 -07:00
Dave Corley
d68b774c10 CLEANUP: Don't handle refnums during saving at all 2025-08-05 14:16:44 -07:00
elsid
d121b606b6
Fix and enforce local variable naming 2025-08-05 21:27:48 +02:00
Alexei Kotov
a69b67a2b1 Merge branch 'nomushroomdataforyou' into 'master'
Don't init custom data when checking container resolution

Closes #8650

See merge request OpenMW/openmw!4831
2025-08-05 21:06:56 +03:00
Evil Eye
4344dc6e00 Don't init custom data when checking container resolution 2025-08-05 19:10:48 +02:00
psi29a
aca6532044 Merge branch 'createnewpeople' into 'master'
Allow creating new NPC records via lua

See merge request OpenMW/openmw!4825
2025-08-05 07:25:07 +00:00
Andrew Lanzone
c293c76bd7 Remove hardcoded row/column values in some controller menus 2025-08-04 19:10:07 -07:00
Andrew Lanzone
8e76a0ab06 Merge branch 'master' of https://gitlab.com/OpenMW/openmw 2025-08-04 16:44:12 -07:00
SkyHasACat
ef2332eb37 Update API, feature 2025-08-04 11:30:47 -07:00
SkyHasACat
493f70a661 Formatting 2025-08-04 11:10:06 -07:00
SkyHasACat
e74167c7b7 Revert bad change, do actual fix 2025-08-04 11:09:26 -07:00
SkyHasACat
1a886db951 Merge namespace, remove redundant 2025-08-04 10:41:31 -07:00
Evil Eye
4337ed7683 Use new example suite tests 2025-08-04 19:22:49 +02:00
SkyHasACat
7a5fe778bc Add validation 2025-08-04 10:04:34 -07:00
SkyHasACat
aa545467fd Remove unused 2025-08-04 09:56:58 -07:00
SkyHasACat
4c5118a24b Fix rank 2025-08-04 08:43:37 -07:00
SkyHasACat
2ab87f2d22 Use namespace for servicesoffered 2025-08-04 08:35:13 -07:00
SkyHasACat
b2746a7b4b Fix autocalc, remove thing 2025-08-04 08:27:26 -07:00
Evil Eye
0c4da49c74 Merge branch 'fix_msvc_warnings' into 'master'
Fix msvc warnings

See merge request OpenMW/openmw!4829
2025-08-04 14:56:59 +00:00
psi29a
ef3f52d6a4 Merge branch 'coverity' into 'master'
Fix coverity builds

See merge request OpenMW/openmw!4826
2025-08-04 06:55:06 +00:00
Alexei Kotov
aae81264a2 Merge branch 'skibidi-dop-doppler' into 'master'
Doppler, take two

See merge request OpenMW/openmw!4660
2025-08-04 09:24:50 +03:00
SkyHasACat
afb7f1da54 Fix formatting 2025-08-03 21:39:44 -07:00
Skyhasacat
c71448359b Merge branch '32bitfixes' into 'master'
fix 32bit builds. closes #8625

Closes #8625

See merge request OpenMW/openmw!4791
2025-08-03 21:00:52 +00:00
SkyHasACat
99ae52e94c Add fields to record 2025-08-03 13:42:04 -07:00
psi29a
cc2ec85244 Merge branch 'tex' into 'master'
ESM4 landscape texturing

See merge request OpenMW/openmw!4799
2025-08-03 19:56:34 +00:00
SkyHasACat
a0585949a9 Remove dead code, fix grammer 2025-08-03 12:50:57 -07:00
SkyHasACat
4a2f85cfde Merge remote-tracking branch 'origin/master' into createnewpeople 2025-08-03 12:14:10 -07:00
Evil Eye
c77a849e9e Merge branch 'cleanup_includes' into 'master'
Cleanup includes

See merge request OpenMW/openmw!4828
2025-08-03 19:11:55 +00:00
Evil Eye
485517cf64 Use std::hash 2025-08-03 20:52:22 +02:00
zlice
0d7efaa2e3 fix 32bit builds 2025-08-03 20:52:22 +02:00
SkyHasACat
d7a411cc72 Suggested fixes 2025-08-03 11:44:45 -07:00
unknown
3bf62235ba Restore rules 2025-08-03 20:05:36 +02:00
unknown
b6b4e4f102 Use a URL that doesn't require the pipeline to succeed 2025-08-03 18:36:30 +02:00
unknown
7569273b33 Expose cov-int.tar.gz as an artifact and upload its URL 2025-08-03 17:06:47 +02:00
elsid
555a10f50c
Fix msvc warnings
openmw\apps\opencs\model\world\idcollection.cpp(65): warning C4457: declaration of 'index' hides function parameter

openmw\apps\openmw\mwscript\miscextensions.cpp(627): warning C4456: declaration of 'effect' hides previous local declaration
2025-08-03 14:22:38 +02:00
psi29a
b9a28dab3e Merge branch 'thread_safe_static_init' into 'master'
Do thread safe local static based initialization

See merge request OpenMW/openmw!4822
2025-08-03 10:55:50 +00:00
psi29a
fa290956c8 Merge branch 'spellgc' into 'master'
Add Player Gold Counter to Spell Creation Window(Updated)

See merge request OpenMW/openmw!4737
2025-08-03 10:51:25 +00:00
Evil Eye
ccb4ca49ca Merge branch 'fix_lua_examples' into 'master'
Fix lua doc example errors and typos

See merge request OpenMW/openmw!4823
2025-08-03 08:56:50 +00:00
SkyHasACat
c276f850dc One more fix 2025-08-02 22:49:58 -07:00
SkyHasACat
286c4d9101 a word 2025-08-02 21:40:09 -07:00
SkyHasACat
2abed374f9 Fix missing link 2025-08-02 19:00:12 -07:00
SkyHasACat
7c4ed3c11d Fixing XML? 2025-08-02 15:19:49 -07:00
SkyHasACat
ae9c42e0a0 Merge remote-tracking branch 'origin/master' into spellgc 2025-08-02 15:08:25 -07:00
Andrew Lanzone
7e9d4795ba Fix range check in journal window 2025-08-02 09:11:30 -07:00
Andrew Lanzone
3147aea0ed Better dead zone handling 2025-08-02 09:00:59 -07:00
SkyHasACat
d40a78e8ac Player shennanigans 2025-08-02 06:32:46 -07:00
SkyHasACat
31abd366ff no const 2025-08-02 06:25:14 -07:00
SkyHasACat
7c665643ad Use overload 2025-08-02 06:08:29 -07:00
SkyHasACat
5203f300e2 Requested changes 2025-08-02 05:33:27 -07:00
elsid
e87b95f642
Use forward declaration for context and sol 2025-08-02 12:45:03 +02:00
elsid
eeca0b13b0
Add missing files to components/detournavigator list 2025-08-02 12:45:03 +02:00
elsid
a2bc1569e0
Remove unused includes 2025-08-02 12:45:03 +02:00
Evil Eye
5ea3cca83b Remove spell effects on RemoveSpell 2025-08-02 12:16:46 +02:00
Evil Eye
c89f88c4e6 Allow removed abilities to be detected 2025-08-02 12:01:37 +02:00
Evil Eye
550b0c985f Include file 2025-08-02 10:56:50 +02:00
Evil Eye
05f0b4cdbd Use the default clang version in Coverity 2025-08-02 10:50:43 +02:00
psi29a
cc68316f72 Merge branch 'lua-jail-skills' into 'master'
Bring jail time skill changes over to lua

Closes #8399

See merge request OpenMW/openmw!4593
2025-08-02 08:39:14 +00:00
Mads Buvik Sandvei
978d8668f4 Bring jail time skill changes over to lua 2025-08-02 08:39:13 +00:00
Evil Eye
dbd92e6844 Merge branch 'spacetraining' into 'master'
Training menu fixes (#8584)

Closes #8584

See merge request OpenMW/openmw!4758
2025-08-02 07:04:02 +00:00
Alexei Kotov
4c4d6078d8 Training menu fixes (#8584)
Rework the layout
Use "OK" instead of "Cancel" for the OK button
Add gp to the price
Use entry spacing consistent with other service menus
2025-08-02 03:47:22 +03:00
SkyHasACat
1986891e79 different empty line? 2025-08-01 16:51:10 -07:00
SkyHasACat
c139680ce3 Add line 2025-08-01 16:49:19 -07:00
SkyHasACat
f2cfaac4b8 Fix clang 2025-08-01 16:46:25 -07:00
SkyHasACat
1fbbaefb47 Remove unrelated change, doc 2025-08-01 16:45:24 -07:00
SkyHasACat
5209685783 revert some changes 2025-08-01 16:40:30 -07:00
SkyHasACat
64a45f8aeb Change world store insert 2025-08-01 16:30:16 -07:00
SkyHasACat
6464e2a11b remove N 2025-08-01 16:11:32 -07:00
SkyHasACat
abb381a163 Fix issues 2025-08-01 16:10:49 -07:00
SkyHasACat
5e64015aa9 Fix typo, remove change 2025-08-01 15:57:31 -07:00
SkyHasACat
2cd4b643d0 npc stuff 2025-08-01 15:18:55 -07:00
epochwon
05d67ef412 swedish lines 2025-08-01 14:47:54 -04:00
Petr Mikheev
0b5c8271e0 ESM4 landscape textures 2025-08-01 18:45:24 +02:00
SkyHasACat
929a65126a Fix docs 2025-08-01 08:25:02 -07:00
elsid
0801e0512d
Do thread safe local static based initialization 2025-08-01 11:48:35 +02:00
psi29a
b160cee0b7 Merge branch 'sonarview' into 'master'
Address string_view conversions flagged by SonarQube

See merge request OpenMW/openmw!4693
2025-08-01 08:06:36 +00:00
psi29a
2a8dc56619 Merge branch 'pedanticmsvc' into 'master'
Resolve unused code warnings when compiling in Debug mode using MSVC

See merge request OpenMW/openmw!4820
2025-08-01 08:06:11 +00:00
Andrew Lanzone
2e5836a748 Remove hardcoded map size 2025-07-31 23:58:00 -07:00
Andrew Lanzone
d49a6a119b Fix clang warnings 2025-07-31 22:27:31 -07:00
Andrew Lanzone
f453ce27a0 Remove uses of std::variant and std::holds_alternative because they're not supported on Ubuntu 2025-07-31 22:22:21 -07:00
Andrew Lanzone
666f154082 Fix clang warnings in Ubuntu 2025-07-31 22:13:56 -07:00
Skyhasacat
04f42f12e1 Merge branch 'onUpdate' into 'master'
Run onUpdate when the game is paused

Closes #8012

See merge request OpenMW/openmw!4487
2025-08-01 02:11:21 +00:00
Andrei Kortunov
645eb81133 Run onUpdate when the game is paused 2025-08-01 04:18:03 +03:00
Andy Lanzone
59aba3ae7e Merge branch openmw:master into master 2025-07-31 18:02:10 -07:00
Andrew Lanzone
a134f8d882 Fix clang warning 2025-07-31 18:01:08 -07:00
Andrew Lanzone
5de1ae7b24 Simplify controller button overlay even more 2025-07-31 17:52:35 -07:00
Andrew Lanzone
23e3d0b49a Initialize inventory tabs in a loop 2025-07-31 17:50:14 -07:00
epochwon
b792bc0ee2 fixes + russian line 2025-07-31 11:14:08 -04:00
psi29a
405388b89f Merge branch 'scripteditorplz' into 'master'
Improve multiline script editing

Closes #8579

See merge request OpenMW/openmw!4728
2025-07-31 07:21:06 +00:00
Skyhasacat
27e1a842a0 Merge branch 'partially-dehardcode-onhit' into 'master'
[Lua] Partially dehardcode onHit

See merge request OpenMW/openmw!4334
2025-07-30 20:21:15 +00:00
Mads Buvik Sandvei
34eb3d485d [Lua] Partially dehardcode onHit 2025-07-30 20:21:15 +00:00
Evil Eye
2efa76052f Merge branch 'master' into 'master'
Update Installation Instructions to include Fedora installation

See merge request OpenMW/openmw!4819
2025-07-30 19:22:56 +00:00
epochwon
aae21c6f53 Get physics fps delta time from physics system 2025-07-30 14:51:18 -04:00
Evil Eye
bc05628fa8 Resolve unused code warnings when compiling in Debug mode using MSVC 2025-07-30 20:44:59 +02:00
Evil Eye
75845bf863 Work around compiler versions that haven't addressed defect 3865 2025-07-30 19:41:14 +02:00
Evil Eye
ee540039a1 Address string_view conversions flagged by SonarQube 2025-07-30 19:37:37 +02:00
Claire
24c7d2f075 Edit install-openmw.rst 2025-07-30 09:54:54 -07:00
Claire
62492c7738 Edit install-openmw.rst 2025-07-30 09:11:00 -07:00
Claire
442e8796b4 Edit install-openmw.rst 2025-07-30 09:08:56 -07:00
Evil Eye
27ee192354 Set default hotkeys for (un)commenting script lines 2025-07-30 16:58:32 +02:00
Evil Eye
aefa0ec1c4 Add multiline (un)indent behaviour to the script editor 2025-07-30 16:58:32 +02:00
epochwon
57280eaf9d Update Doppler description + Russian line 2025-07-30 10:28:41 -04:00
Alexei Kotov
399ec4eccc Merge branch 'qt6' into 'master'
Drop support for Qt5

Closes #8578

See merge request OpenMW/openmw!4742
2025-07-30 13:26:46 +03:00
Andrew Lanzone
582b409f7f Fix right stick from causing mouse to appear in controller mode 2025-07-29 19:29:20 -07:00
Andrew Lanzone
5d5d14a5a6 Fix spurious button presses causing controller tooltip to wiggle 2025-07-29 17:28:52 -07:00
Alexei Kotov
b0e8544d58 Merge branch 'addthoseactivespells' into 'master'
Remove minimum duration from continuous effects and add clarification to the docs

Closes #8641

See merge request OpenMW/openmw!4817
2025-07-29 23:36:39 +03:00
Alexei Kotov
0e8ca0cf19 Merge branch 'changelog' into 'master'
Sync changelog

See merge request OpenMW/openmw!4816
2025-07-29 23:36:05 +03:00
Claire
b7fe1a6eb2 Edit install-openmw.rst 2025-07-29 11:59:42 -07:00
psi29a
b937b0271f Merge branch 'fightthechameleon' into 'master'
Prevent witnesses from ending combat because they didn't get hit

See merge request OpenMW/openmw!4814
2025-07-29 07:43:59 +00:00
Alexei Kotov
45a7040bc7 Merge branch 'fix_tests' into 'master'
Make tests more stable

See merge request OpenMW/openmw!4818
2025-07-29 08:05:58 +03:00
AnyOldName3
7c3fa3c89f Merge branch 'classheader' into 'master'
Some include cleanup

See merge request OpenMW/openmw!4815
2025-07-28 22:35:24 +00:00
Alexei Kotov
ebcacf04bc Sync changelog for 0.50.0 2025-07-28 23:12:52 +03:00
elsid
70207750f2
Make tests more stable 2025-07-28 20:23:45 +02:00
Evil Eye
395f6811c9 Remove minimum duration from continuous effects and add clarification to the docs 2025-07-28 18:59:23 +02:00
psi29a
176dab5b3d Merge branch 'nomagnitudeforyou' into 'master'
Don't multiply magnitudes for effects that don't have magnitudes

Closes #8540

See merge request OpenMW/openmw!4810
2025-07-28 15:59:13 +00:00
psi29a
e304ceb449 Merge branch 'fix_init' into 'master'
Do not copy cell store to count refs

See merge request OpenMW/openmw!4813
2025-07-28 15:58:46 +00:00
psi29a
4efc8bf99d Merge branch 'fix_clang_tidy' into 'master'
Fix clang tidy warnings

See merge request OpenMW/openmw!4811
2025-07-28 15:55:53 +00:00
Alexei Kotov
0a8373987d Merge branch 'aiwander' into 'master'
Build checkpoints based path for wandering actors (#8433)

Closes #8433

See merge request OpenMW/openmw!4652
2025-07-28 00:48:17 +03:00
Andrew Lanzone
7b9958247a Null ControllerButtons pointers are supported; they hide the button overlay 2025-07-27 14:08:13 -07:00
Andy Lanzone
31580ffb71 Merge branch openmw:master into master 2025-07-27 13:21:40 -07:00
Andrew Lanzone
dc2ff4bfa2 Rename ControllerButtonStr struct and its internal fields 2025-07-27 13:14:31 -07:00
Alexei Kotov
272e6fabf9 Turn GreetingState into enum class and cut some mechanics manager includes 2025-07-27 23:02:06 +03:00
Andrew Lanzone
9870605aab Update enum defintion for ControllerAction 2025-07-27 12:57:56 -07:00
Andrew Lanzone
2d5ec48892 Fix default return type for getControllerAxisIcon 2025-07-27 12:56:56 -07:00
Evil Eye
f6a6a33c59 Prevent witnesses from ending combat because they didn't get hit 2025-07-27 21:12:52 +02:00
Alexei Kotov
ee501d8d0d Remove some redundant class header includes 2025-07-27 22:02:02 +03:00
elsid
e77ee5c20f
Do not copy cell store to count refs 2025-07-27 18:40:39 +02:00
psi29a
2051d5cbef Merge branch 'master' into 'master'
Fixed Unit Test in `apps/openmw_tests/mwworld/testptr.cpp`

See merge request OpenMW/openmw!4807
2025-07-27 16:33:39 +00:00
Claire
af58da58fd Fixed Unit Test in apps/openmw_tests/mwworld/testptr.cpp 2025-07-27 16:33:38 +00:00
psi29a
d3309e0a8d Merge branch 'vfxdocs' into 'master'
Fix useAmbientLight references in docs

See merge request OpenMW/openmw!4803
2025-07-27 16:33:22 +00:00
psi29a
7637ca536b Merge branch 'turnedwerewolf' into 'master'
Remove completion threshold-based turning for the player (#8447)

Closes #8447

See merge request OpenMW/openmw!4628
2025-07-27 16:32:43 +00:00
psi29a
7aeff7e473 Merge branch 'combatparalysis' into 'master'
Put combat actions on hold when the actor is incapacitated (#7979)

Closes #7979

See merge request OpenMW/openmw!4597
2025-07-27 16:32:22 +00:00
psi29a
02102eeeca Merge branch 'instantmagicjustaddwater' into 'master'
Update effects upon applying them

Closes #7996

See merge request OpenMW/openmw!4124
2025-07-27 16:30:56 +00:00
psi29a
c8aa644111 Merge branch 'collisionprediction' into 'master'
Avoid recomputing collision prediction things an extra N times (#8548)

Closes #8548

See merge request OpenMW/openmw!4801
2025-07-27 16:30:11 +00:00
Evil Eye
aae954643c Don't multiply magnitudes for effects that don't have magnitudes 2025-07-27 12:47:35 +02:00
elsid
c6f381f1c4
Ignore readability-identifier-naming for boost::program_options namespace alias 2025-07-27 12:21:13 +02:00
elsid
8682ea522f
Remove unused namespace alias 2025-07-27 12:20:10 +02:00
elsid
ec0c76d2f3
Ignore false positive warning
cellSize > 1 so the result of the division cannot be undefined.

/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:18:35: error: The result of the '/' expression is undefined [clang-analyzer-core.UndefinedBinaryOperatorResult,-warnings-as-errors]
   18 |         std::size_t cell = global / (cellSize - 1);
      |                                   ^
/home/elsid/dev/openmw/components/esmterrain/storage.cpp:244:13: note: Assuming 'lodLevel' is >= 0
  244 |         if (lodLevel < 0 || 63 < lodLevel)
      |             ^~~~~~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/storage.cpp:244:13: note: Left side of '||' is false
/home/elsid/dev/openmw/components/esmterrain/storage.cpp:244:29: note: Assuming 'lodLevel' is <= 63
  244 |         if (lodLevel < 0 || 63 < lodLevel)
      |                             ^~~~~~~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/storage.cpp:244:9: note: Taking false branch
  244 |         if (lodLevel < 0 || 63 < lodLevel)
      |         ^
/home/elsid/dev/openmw/components/esmterrain/storage.cpp:247:13: note: Assuming 'size' is > 0
  247 |         if (size <= 0)
      |             ^~~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/storage.cpp:247:9: note: Taking false branch
  247 |         if (size <= 0)
      |         ^
/home/elsid/dev/openmw/components/esmterrain/storage.cpp:272:13: note: Assuming the condition is false
  272 |         if (land != nullptr)
      |             ^~~~~~~~~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/storage.cpp:272:9: note: Taking false branch
  272 |         if (land != nullptr)
      |         ^
/home/elsid/dev/openmw/components/esmterrain/storage.cpp:363:9: note: Calling 'sampleCellGrid<const (lambda at /home/elsid/dev/openmw/components/esmterrain/storage.cpp:280:35) &>'
  363 |         sampleCellGrid(cellSize, sampleSize, beginX, beginY, distance, handleSample);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:72:13: note: Assuming 'cellSize' is >= 2
   72 |         if (cellSize < 2 || !Misc::isPowerOfTwo(cellSize - 1))
      |             ^~~~~~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:72:13: note: Left side of '||' is false
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:72:9: note: Taking false branch
   72 |         if (cellSize < 2 || !Misc::isPowerOfTwo(cellSize - 1))
      |         ^
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:75:13: note: Assuming 'sampleSize' is not equal to 0
   75 |         if (sampleSize == 0 || !Misc::isPowerOfTwo(sampleSize))
      |             ^~~~~~~~~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:75:13: note: Left side of '||' is false
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:75:9: note: Taking false branch
   75 |         if (sampleSize == 0 || !Misc::isPowerOfTwo(sampleSize))
      |         ^
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:78:13: note: Assuming 'distance' is >= 2
   78 |         if (distance < 2 || !Misc::isPowerOfTwo(distance - 1))
      |             ^~~~~~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:78:13: note: Left side of '||' is false
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:78:9: note: Taking false branch
   78 |         if (distance < 2 || !Misc::isPowerOfTwo(distance - 1))
      |         ^
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:84:13: note: Assuming 'distance' is >= 'cellSize'
   84 |         if (distance < cellSize || sampleSize > cellSize - 1)
      |             ^~~~~~~~~~~~~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:84:13: note: Left side of '||' is false
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:84:36: note: Assuming the condition is true
   84 |         if (distance < cellSize || sampleSize > cellSize - 1)
      |                                    ^~~~~~~~~~~~~~~~~~~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:84:9: note: Taking true branch
   84 |         if (distance < cellSize || sampleSize > cellSize - 1)
      |         ^
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:85:20: note: Calling 'sampleCellGridSimple<const (lambda at /home/elsid/dev/openmw/components/esmterrain/storage.cpp:280:35) &>'
   85 |             return sampleCellGridSimple(cellSize, sampleSize, beginX, beginY, endX, endY, f);
      |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:56:16: note: 'cellSize' is > 1
   56 |         assert(cellSize > 1);
      |                ^
/usr/include/assert.h💯27: note: expanded from macro 'assert'
  100 |      (static_cast <bool> (expr)                                         \
      |                           ^~~~
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:56:9: note: '?' condition is true
   56 |         assert(cellSize > 1);
      |         ^
/usr/include/assert.h💯7: note: expanded from macro 'assert'
  100 |      (static_cast <bool> (expr)                                         \
      |       ^
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:57:9: note: '?' condition is true
   57 |         assert(Misc::isPowerOfTwo(cellSize - 1));
      |         ^
/usr/include/assert.h💯7: note: expanded from macro 'assert'
  100 |      (static_cast <bool> (expr)                                         \
      |       ^
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:58:16: note: 'sampleSize' is not equal to 0
   58 |         assert(sampleSize != 0);
      |                ^
/usr/include/assert.h💯27: note: expanded from macro 'assert'
  100 |      (static_cast <bool> (expr)                                         \
      |                           ^~~~
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:58:9: note: '?' condition is true
   58 |         assert(sampleSize != 0);
      |         ^
/usr/include/assert.h💯7: note: expanded from macro 'assert'
  100 |      (static_cast <bool> (expr)                                         \
      |       ^
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:60:9: note: Calling 'sampleGrid<(lambda at /home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:61:13)>'
   60 |         sampleGrid(sampleSize, beginX, beginY, endX, endY,
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   61 |             [&](std::size_t globalX, std::size_t globalY, std::size_t vertX, std::size_t vertY) {
      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   62 |                 const auto [cellX, x] = toCellAndLocal(beginX, globalX, cellSize);
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   63 |                 const auto [cellY, y] = toCellAndLocal(beginY, globalY, cellSize);
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   64 |                 f(cellX, cellY, x, y, vertX, vertY);
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   65 |             });
      |             ~~
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:33:38: note: Assuming 'y' is < 'endY'
   33 |         for (std::size_t y = beginY; y < endY; y += sampleSize)
      |                                      ^~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:33:9: note: Loop condition is true.  Entering loop body
   33 |         for (std::size_t y = beginY; y < endY; y += sampleSize)
      |         ^
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:36:42: note: Assuming 'x' is < 'endX'
   36 |             for (std::size_t x = beginX; x < endX; x += sampleSize)
      |                                          ^~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:36:13: note: Loop condition is true.  Entering loop body
   36 |             for (std::size_t x = beginX; x < endX; x += sampleSize)
      |             ^
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:36:42: note: Assuming 'x' is < 'endX'
   36 |             for (std::size_t x = beginX; x < endX; x += sampleSize)
      |                                          ^~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:36:13: note: Loop condition is true.  Entering loop body
   36 |             for (std::size_t x = beginX; x < endX; x += sampleSize)
      |             ^
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:37:17: note: Calling 'operator()'
   37 |                 f(x, y, vertX++, vertY);
      |                 ^~~~~~~~~~~~~~~~~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:62:41: note: Calling 'toCellAndLocal'
   62 |                 const auto [cellX, x] = toCellAndLocal(beginX, globalX, cellSize);
      |                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/elsid/dev/openmw/components/esmterrain/gridsampling.hpp:18:35: note: The result of the '/' expression is undefined
   18 |         std::size_t cell = global / (cellSize - 1);
      |                            ~~~~~~~^~~~~~~~~~~~~~~~
2025-07-27 12:11:24 +02:00
elsid
c5d74818eb
Disable portability-template-virtual-member-function clang tidy warning
There is no compatibility problem in practice.

/home/elsid/dev/openmw/components/settings/sanitizer.hpp:11:19: error: unspecified virtual member function instantiation; the virtual member function is not instantiated but it might be with a different compiler [portability-template-virtual-member-function,-warnings-as-errors]
   11 |         virtual T apply(const T& value) const = 0;
      |                   ^
/home/elsid/dev/openmw/components/settings/sanitizerimpl.cpp:20:28: note: template instantiated here
   20 |         struct Max final : Sanitizer<T>
      |                            ^
2025-07-27 11:30:07 +02:00
elsid
4433e3c2de
Build path over navmesh for wandering actors
Using a path over pathgrid as checkpoints.

This allows to avoid having paths going through obstacles if they are
placed over pathgrid points.
2025-07-27 11:17:17 +02:00
elsid
5dfda0090b
Remove redundant cell argument from build path functions
Actor can provide a cell.
2025-07-27 11:17:17 +02:00
elsid
3f1ac1848c
Move getClosestPoint to a separate file 2025-07-27 11:17:17 +02:00
elsid
927b2bcceb
Replace PathFinder::makeOsgVec3 by Misc::Convert::makeOsgVec3f 2025-07-27 11:17:16 +02:00
elsid
50f5bc51c6
Store allowed positions as osg::Vec3f
There is no need to store pathgrid points.
2025-07-27 11:16:47 +02:00
Evil Eye
de68310992 Ignore time travel 2025-07-27 10:47:34 +02:00
Evil Eye
7f6fe15b10 Use local gcovr 2025-07-27 10:47:34 +02:00
Evil Eye
bdb3387bff Install gcovr via pipx and disable Werror when building Benchmarks 2025-07-27 10:47:34 +02:00
Evil Eye
2bce45260c Drop support for Qt5 2025-07-27 10:47:34 +02:00
Alexei Kotov
8deb050ea2 Merge branch 'ghversion' into 'master'
Use the new Windows deps on GitHub

See merge request OpenMW/openmw!4808
2025-07-27 11:41:01 +03:00
Alexei Kotov
1896375380 Merge branch 'solarpowered' into 'master'
Update sol

Closes #8591 and #8614

See merge request OpenMW/openmw!4745
2025-07-27 11:38:16 +03:00
Andrew Lanzone
3c3f36679e Re-add ESM include 2025-07-27 00:45:54 -07:00
Andrew Lanzone
de057cc030 Update includes on controllermanager 2025-07-27 00:33:57 -07:00
Andrew Lanzone
984582b586 Cleanup includes for itemchargeview 2025-07-27 00:06:05 -07:00
Andrew Lanzone
360c801b73 Remove local wrapper of MyGUI::Scrollbar 2025-07-26 23:54:25 -07:00
Andrew Lanzone
24c7a3f1ce Remove duplicate class declarations 2025-07-26 23:53:57 -07:00
Andrew Lanzone
2a0ff5626c Remove extra include that was inadvertently added 2025-07-26 22:56:47 -07:00
Andrew Lanzone
80dd2ea6da Merge branch 'master' of https://gitlab.com/enoznal/openmw 2025-07-26 22:53:23 -07:00
Andrew Lanzone
8a2888fa00 Replace many includes with forward declarations 2025-07-26 22:53:03 -07:00
Andrew Lanzone
94b460389b Replace many includes with forward declarations 2025-07-26 22:48:35 -07:00
Alexei Kotov
d3328552e8 Avoid recomputing collision prediction things an extra N times (#8548) 2025-07-27 07:36:43 +03:00
Alexei Kotov
ed32e4405a Merge branch 'optionalglobalism' into 'master'
Remove global config on Windows

Closes #8434

See merge request OpenMW/openmw!4762
2025-07-26 23:25:55 +03:00
Andrew Lanzone
b961007345 Fix unsigned type warning/error on Windows 2025-07-26 09:41:26 -07:00
Skyhasacat
9f10269ecc Merge branch 'lua_weather_bindings' into 'master'
lua - add weatherbindings to openmw.core (#6976)

See merge request OpenMW/openmw!4526
2025-07-26 15:01:32 +00:00
Evil Eye
e692025579 Use the new Windows deps on GitHub 2025-07-26 16:36:50 +02:00
Sebastian Fieber
534d6b3ae9 typo 2025-07-26 13:39:37 +02:00
elsid
7c46635a5a
Make trimAllowedNodes a free function 2025-07-26 11:48:36 +02:00
elsid
ae909d7685
Remove isAreaOccupiedByOtherActor from obstacle.*
It uses functions only from World anyway.
2025-07-26 11:48:36 +02:00
elsid
c79b39cf0d
Remove unused arguments from isAreaOccupiedByOtherActor 2025-07-26 11:48:36 +02:00
elsid
20bd1491a7
Make sure distance and duration are not negative 2025-07-26 11:48:36 +02:00
elsid
4a3ffb2073
Use camel case for variables 2025-07-26 11:48:35 +02:00
Evil Eye
4ca9cac784 Don't use cached awareness in combat 2025-07-26 11:05:40 +02:00
Evil Eye
b3fe84a560 Cache awareness rolls for 5 seconds to make sneaking easier 2025-07-26 10:55:20 +02:00
Andrew Lanzone
ab03e01127 Remove dedicated 'Unequip' button and just us 'A' 2025-07-26 01:35:25 -07:00
Evil Eye
b4a753812e Use empty paths instead of optionals 2025-07-26 10:23:19 +02:00
Andrew Lanzone
defd1edb6f Fix clang error and unsigned bug 2025-07-26 00:59:43 -07:00
Evil Eye
c0b230b742 Remove global config on Windows 2025-07-26 09:45:35 +02:00
Andy Lanzone
c015599356 Merge branch openmw:master into master 2025-07-26 00:17:39 -07:00
Andrew Lanzone
fb19a0da91 Fix inventory menu getting messed up when resizing game window 2025-07-26 00:16:41 -07:00
Andrew Lanzone
5b5ed21f20 Split journal's onControllerButtonEvent into a few functions 2025-07-25 22:53:39 -07:00
Andrew Lanzone
b9ae89e032 Split onControllerButtonEvent into two; loop through ingredient slots 2025-07-25 21:46:00 -07:00
Sebastian Fieber
95fc66bccd adjusments to weatherbindings
- return nil for not existing effects
- also use currectTexturePath for cloud texture
- corrections for docs
2025-07-25 23:22:33 +02:00
Sebastian Fieber
855b236ee8 direction of the sun light != direction to the sun 2025-07-25 21:00:09 +02:00
Alexei Kotov
730a62effc Merge branch 'warn-baby-warn' into 'master'
Fix MSVC warnings

Closes #7882

See merge request OpenMW/openmw!4804
2025-07-25 21:45:34 +03:00
Sebastian Fieber
a560aceb2a correct sunDiscSunsetColor type 2025-07-25 20:37:05 +02:00
Sebastian Fieber
cbb96e0fc2 colors should use Misc::Color 2025-07-25 20:10:21 +02:00
psi29a
a599825bf8 Merge branch 'everyonelikeschameleons' into 'master'
Prevent hostile actors from engaging combat against actors with 75 chameleon

See merge request OpenMW/openmw!4806
2025-07-25 08:02:32 +00:00
psi29a
714c128947 Merge branch 'compositemipmaps' into 'master'
Apply filtering settings to composite maps

See merge request OpenMW/openmw!4805
2025-07-25 07:12:07 +00:00
psi29a
45e08f62a1 Merge branch 'smolpiranha' into 'master'
Take skin transform and skeleton root into account

Closes #4437

See merge request OpenMW/openmw!4471
2025-07-25 07:09:55 +00:00
Sebastian Fieber
b8fec360c3 typo 2025-07-25 02:20:26 +02:00
Sebastian Fieber
f1447207b2 more less preprocessed code lines 2025-07-25 01:13:43 +02:00
Sebastian Fieber
3f54d3e569 update lua api revision 2025-07-25 00:53:04 +02:00
Sebastian Fieber
27adbf0cde less preprocessed code lines 2025-07-25 00:53:04 +02:00
Sebastian Fieber
d20a56517b add getCurrentSunLightDirection 2025-07-25 00:52:56 +02:00
Sebastian Fieber
6be96da6a4 lua - add weatherbindings to core 2025-07-25 00:43:39 +02:00
Alexei Kotov
d595d9f3b8 Merge branch 'maccitest' into 'master'
Mac CI updates

See merge request OpenMW/openmw!4789
2025-07-24 18:58:49 +03:00
Evil Eye
f52d9ad977 Prevent hostile actors from engaging combat against actors with 75 chameleon 2025-07-24 17:02:42 +02:00
Evil Eye
e3c9e6fe2b Set a root for BS skins as well 2025-07-24 08:46:21 +02:00
Evil Eye
8d7218c118 Take skin transform and skeleton root into account 2025-07-24 08:40:20 +02:00
Alexei Kotov
ad996393f1 Apply filtering settings to composite maps 2025-07-24 08:41:43 +03:00
AnyOldName3
437f22ed72 Typo fix 2025-07-24 00:37:28 +01:00
AnyOldName3
092d9a4c62 Remove dumb comment 2025-07-24 00:35:22 +01:00
AnyOldName3
f8a96fae24 Some formatting changes I missed 2025-07-24 00:26:47 +01:00
AnyOldName3
be54521cfa Fix loads of warnings
These weren't detected due to https://gitlab.com/OpenMW/openmw/-/issues/7882, but now they are, so they can be fixed.
2025-07-24 00:20:05 +01:00
AnyOldName3
52b785f726 Use updated Windows dependencies
The main changes are changing an OSG option that was disabling most of our warnings, and MSVC2019 switching to a custom vcpkg triplet.
2025-07-23 23:18:03 +01:00
Alexei Kotov
5dddf9153d Fix useAmbientLight references in docs 2025-07-24 00:25:26 +03:00
Evil Eye
acfe9b6785 Merge branch 'karamunsing' into 'master'
Don't deselect item when usage is denied

Closes #7693

See merge request OpenMW/openmw!4788
2025-07-23 18:43:41 +00:00
Evil Eye
362c1a7ebe Update sol 2025-07-23 17:35:35 +02:00
psi29a
d1b03734b3 Merge branch 'master' into 'master'
Save user settings when closing windows

Closes #8077

See merge request OpenMW/openmw!4367
2025-07-23 09:32:04 +00:00
Jared Davenport
324bdf8f7a Save user settings when closing windows 2025-07-23 09:32:04 +00:00
psi29a
d401dd2441 Merge branch 'ContainerCapacityCheck' into 'master'
Fix precision issue with container capacity check

Closes #8606

See merge request OpenMW/openmw!4776
2025-07-23 09:31:38 +00:00
Aussiemon
044c556f0e Fix precision issue with container capacity check 2025-07-23 09:31:38 +00:00
AnyOldName3
125bbdc118 Merge branch 'long-specular' into 'master'
Elongated specular highlight for water

See merge request OpenMW/openmw!4726
2025-07-22 13:04:03 +00:00
Alexei Kotov
896d6fd01e Put combat actions on hold when the actor is incapacitated (#7979) 2025-07-22 15:38:04 +03:00
Alexei Kotov
d899454f36 Remove completion threshold-based turning for the player (#8447) 2025-07-22 15:35:57 +03:00
psi29a
b2cc549585 Merge branch 'theemperorwantedyoutohavethisinvaliditerator' into 'master'
Prevent iterator invalidation during actor traversal

Closes #4885

See merge request OpenMW/openmw!4445
2025-07-22 07:38:20 +00:00
psi29a
2b1cd1deb8 Merge branch 'getpcrunning' into 'master'
Deduplicate GetPCRunning logic

See merge request OpenMW/openmw!4800
2025-07-22 07:37:35 +00:00
Alexei Kotov
93cde36b09 Deduplicate GetPCRunning logic 2025-07-21 19:09:24 +03:00
Evil Eye
30cfb42ed1 Fix rebase fallout 2025-07-21 17:57:51 +02:00
psi29a
c30964feb2 Merge branch 'namespace_naming' into 'master'
Fix and enforce namespace naming (#8424)

See merge request OpenMW/openmw!4648
2025-07-21 10:30:47 +00:00
elsid
28851411a3
Fix and enforce namespace naming 2025-07-20 21:19:16 +02:00
AnyOldName3
9845f76583 Merge branch 'nonessentialjobs' into 'master'
Don't run some non-essential jobs on upstream branch pushes

See merge request OpenMW/openmw!4797
2025-07-20 16:59:04 +00:00
Alexei Kotov
2b4b532745 Merge branch 'charmdispofix' into 'master'
Fix permanent disposition loss on exit conversation

Closes #8557

See merge request OpenMW/openmw!4796
2025-07-20 19:05:24 +03:00
Aussiemon
01fa3cc4e6 Subtract Charm from permanent disposition clamp range 2025-07-20 19:05:24 +03:00
Dave Corley
0f0a402ead Local content file index is actually -1 2025-07-20 08:53:14 +00:00
Andy Lanzone
6114a01ad4 Merge branch openmw:master into master 2025-07-19 18:10:08 -07:00
Andrew Lanzone
ef50578a62 Move controller button overlay padding into layout file 2025-07-19 18:09:00 -07:00
Andrew Lanzone
b0bdd68e7c Update a comment 2025-07-19 17:12:33 -07:00
Andrew Lanzone
29f1c7c68f Remove some hardcoded menu sizes for inventory mode 2025-07-19 17:12:09 -07:00
Andrew Lanzone
f8d9149e4f Use enum and array for cleaner management of controller button overlay 2025-07-19 16:31:25 -07:00
Andrew Lanzone
c2ad1df030 Update Swedish translation for controller tooltips option 2025-07-19 14:03:26 -07:00
Dave Corley
dcac39aefd FIX: never serialize MVRF for refferences from the local plugin 2025-07-19 09:44:01 -07:00
Alexei Kotov
10602a0412 Don't run some non-essential jobs on upstream branch pushes 2025-07-19 12:08:48 +03:00
Evil Eye
8bf9b205b7 Merge branch 'supporteddirections' into 'master'
Cache computed supported movement directions

See merge request OpenMW/openmw!4709
2025-07-19 08:59:18 +00:00
Evil Eye
39cc893639 Unbreak swimdeath fallback 2025-07-19 09:38:44 +02:00
Evil Eye
1dfa2629f0 Remove more redundant checks 2025-07-19 09:24:24 +02:00
Evil Eye
35eed68269 Move null checks to address feedback 2025-07-19 09:24:23 +02:00
Evil Eye
d34aee6257 Allow unsetting a character controller's animation 2025-07-19 09:23:43 +02:00
Evil Eye
b2bb12cd19 Run ~CharacterController when invalidating an Actor 2025-07-19 09:22:44 +02:00
Evil Eye
c098f2ccde Prevent iterator invalidation during actor traversal 2025-07-19 09:22:44 +02:00
Kuyondo
614062d387 prevent item flickering on drag use and dont stop drag on denied lua itemusage 2025-07-19 15:02:32 +08:00
Andrew Lanzone
bf327adc93 Bump OPENMW_LUA_API_REVISION and gamepad controls versions 2025-07-18 17:53:29 -07:00
Alexei Kotov
152d87a6b3 Merge branch 'esm4paging' into 'master'
Object paging in ESM4 worldspaces

See merge request OpenMW/openmw!4770
2025-07-18 23:41:18 +03:00
Petr Mikheev
7f28b33cf1 Object paging in ESM4 worldspaces 2025-07-18 22:12:24 +02:00
psi29a
82b1d1b78e Merge branch 'corpsecollector' into 'master'
Ensure corpses of actors that have moved cells are cleaned up

See merge request OpenMW/openmw!4793
2025-07-18 19:57:58 +00:00
psi29a
412134da99 Merge branch 'bsazoomies' into 'master'
Use zlib directly for BSA file decompression (#8569)

Closes #8569

See merge request OpenMW/openmw!4795
2025-07-18 19:56:15 +00:00
Evil Eye
22232e8710 Merge branch 'sortedanimations' into 'master'
Assume NIF controller data is already sorted (#8545)

Closes #8545

See merge request OpenMW/openmw!4794
2025-07-18 19:29:24 +00:00
Alexei Kotov
f7238cd043 Merge branch 'document_object_cache' into 'master'
Add documentation for update function of Generic Object Cache

See merge request OpenMW/openmw!4164
2025-07-18 21:51:16 +03:00
Alexei Kotov
9370b41636 Merge branch 'convertthis' into 'master'
Remove int conversions from pathfinding

See merge request OpenMW/openmw!4755
2025-07-18 16:13:20 +03:00
Andy Lanzone
bef2948062 Merge branch openmw:master into master 2025-07-18 01:23:05 -07:00
Andrew Lanzone
c53b1bf2c0 Replace more C-style casts with C++ variants 2025-07-18 01:06:25 -07:00
Andrew Lanzone
a73b803592 Fix crash when spell buying window is empty 2025-07-18 01:05:48 -07:00
Andrew Lanzone
0abbf91477 Disable double-clicking on window titles in the inventory menu 2025-07-17 23:07:54 -07:00
Alexei Kotov
4a0c998f53 Avoid zero division during animation interpolation 2025-07-18 00:13:01 +03:00
Alexei Kotov
93cb69b012 Assume NIF controller data is already sorted (#8545) 2025-07-18 00:09:28 +03:00
Alexei Kotov
6796121305 Use zlib directly for BSA file decompression (#8569) 2025-07-17 22:25:18 +03:00
Dave Corley
7d5a9a2e2f CLEANUP: Only increment highest refNum for ones which are actually higher 2025-07-17 11:26:36 -07:00
Skyhasacat
c90ae89381 Merge branch 'luapaths' into 'master'
Expose path grids to Lua

See merge request OpenMW/openmw!4792
2025-07-17 16:13:09 +00:00
Andrew Lanzone
eba063ac23 Merge branch 'master' of https://gitlab.com/OpenMW/openmw 2025-07-17 08:14:28 -07:00
Evil Eye
b61d8fb585 Use Context::initializeOnce 2025-07-17 16:42:24 +02:00
psi29a
3b42874797 Merge branch 'defendingthelight' into 'master'
Only autoequip the shield in updateEquippedLight (#8404)

Closes #8404

See merge request OpenMW/openmw!4763
2025-07-17 14:23:57 +00:00
psi29a
0006cb22e2 Merge branch 'FillJournalConsoleCommand' into 'master'
Implement FillJournal script instruction

Closes #8509

See merge request OpenMW/openmw!4676
2025-07-17 14:22:53 +00:00
psi29a
eb67d1a1fb Merge branch 'activescripts' into 'master'
Mark scripts on newly scripted, active objects as active

See merge request OpenMW/openmw!4785
2025-07-17 14:21:45 +00:00
psi29a
e1847d2670 Merge branch 'master' into 'master'
Bump libsdl to 2.0.20

See merge request OpenMW/openmw!4779
2025-07-17 14:20:13 +00:00
Andy Lanzone
f45053ad25 Bump libsdl to 2.0.20 2025-07-17 14:20:13 +00:00
Evil Eye
bd6254b6df Ensure corpses of actors that have moved cells are cleaned up 2025-07-17 08:22:26 +02:00
Alexei Kotov
446a4452d3 Merge branch 'changelog' into 'master'
Sync changelog

See merge request OpenMW/openmw!4790
2025-07-16 21:53:06 +03:00
Evil Eye
183652e51d Expose path grids to Lua 2025-07-16 20:18:17 +02:00
Evil Eye
6dadf5de75 Merge branch 'quittingpeacefully' into 'master'
Move Quitting peacefully message to a more appropriate place

See merge request OpenMW/openmw!4769
2025-07-16 14:40:29 +00:00
psi29a
418879bada Merge branch 'tcbtakethree' into 'master'
Re-reimplement TCB interpolation for scalars and vectors (#2379)

See merge request OpenMW/openmw!4784
2025-07-16 14:12:48 +00:00
Alexei Kotov
f9c7dc0b20 Sync changelog for 0.50.0 2025-07-16 13:43:59 +03:00
Alexei Kotov
281dea527f Merge branch 'clangtidy' into 'master'
Don't build the engine, the editor and editor tests multiple times in Clang Tidy jobs

See merge request OpenMW/openmw!4787
2025-07-16 12:30:32 +03:00
psi29a
3899260eea Merge branch 'herbalismsound' into 'master'
Don't harvest if player activation is blocked (#8612)

Closes #8612

See merge request OpenMW/openmw!4773
2025-07-16 09:05:32 +00:00
psi29a
a7a47f3ea9 Merge branch 'silencekey' into 'master'
Don't play down sound while loading quick keys

See merge request OpenMW/openmw!4783
2025-07-16 09:04:49 +00:00
psi29a
ab8e17196f Merge branch 'mac-brew-tweaks' into 'master'
[CI] Mac - Brew cleanup/simplify

See merge request OpenMW/openmw!4759
2025-07-16 08:44:31 +00:00
Alexei Kotov
4f827b6336 Rename mac jobs, test caching 2025-07-16 11:30:21 +03:00
Andrew Lanzone
f50c275133 Ensure mouse really moved before unhiding cursor in controller menu 2025-07-16 00:25:45 -07:00
Alexei Kotov
400c5a6dba Bump mac CI image to macos-15-xcode-16 and tweak trigger rules 2025-07-16 01:09:57 +03:00
Evil Eye
931555c7ff Remove int conversions from pathfinding 2025-07-15 21:57:12 +02:00
Alexei Kotov
d602e9ff7a Don't build the engine, the editor and editor tests multiple times in Clang Tidy jobs 2025-07-15 18:05:57 +03:00
Skyhasacat
3b7b97c58c Merge branch 'coup' into 'master'
Update project leader history

See merge request OpenMW/openmw!4786
2025-07-15 14:25:01 +00:00
Alexei Kotov
8826d5cb0e Update project leader history 2025-07-15 15:04:39 +03:00
Andrew Lanzone
4adb9bd8ac Unhide the cursor if it was hidden to show a controller tooltip 2025-07-15 02:02:49 -07:00
Andrew Lanzone
cf24063226 Replace more C-style casts with C++ style 2025-07-15 01:33:52 -07:00
Andy Lanzone
a3a1b6d11f Merge branch openmw:master into master 2025-07-14 17:48:36 -07:00
Andrew Lanzone
9e2927f734 Use the localized strings from Interface l10n module where possible 2025-07-14 17:45:03 -07:00
Andrew Lanzone
af6634ee57 Remove spurious debug log line 2025-07-14 17:27:20 -07:00
Andrew Lanzone
b8381f6e62 Replace C-style cast with C++ cast. 2025-07-14 17:25:57 -07:00
Andrew Lanzone
a296fa2b40 Add more details to "controller menus" setting. 2025-07-14 17:24:28 -07:00
Evil Eye
6f9b813bd1 Mark scripts on newly scripted, active objects as active 2025-07-14 22:39:19 +02:00
Alexei Kotov
a12a0916ed Merge branch 'too-many-markers' into 'master'
FEAT(CS): Replace selection markers with a real one (#8139)

Closes #8139

See merge request OpenMW/openmw!4349
2025-07-14 23:18:46 +03:00
Dave Corley
9dd028b260 FEAT(CS): Replace selection markers with a real one (#8139) 2025-07-14 23:18:45 +03:00
Alexei Kotov
64fef724a6 Merge branch 'ccache-status-verbose' into 'master'
Use verbose status for ccache so we can see what caused hit failures

See merge request OpenMW/openmw!4756
2025-07-14 21:01:28 +03:00
AnyOldName3
4f60284a35 Merge branch 'first' into 'master'
Prepend new characters so they're first on the list

See merge request OpenMW/openmw!4778
2025-07-14 17:49:59 +00:00
Alexei Kotov
a03a2a5ff2 Re-reimplement TCB interpolation for scalars and vectors (#2379) 2025-07-14 13:09:23 +03:00
Andrew Lanzone
1b240c7dd6 Clean up controller logic to match item transfer logic 2025-07-13 15:24:16 -07:00
Andrew Lanzone
a894481fd7 Clean up controller logic to match item transfer logic 2025-07-13 15:12:33 -07:00
Andrew Lanzone
6a02e6a4bc Merge branch 'master' of https://gitlab.com/OpenMW/openmw 2025-07-13 14:55:27 -07:00
Evil Eye
682f00bcff Don't play down sound while loading quick keys 2025-07-13 18:36:30 +02:00
Aussiemon
445cf1742d ptr.getCellRef().getRefId() 2025-07-13 10:20:58 -06:00
Alexei Kotov
b53cb085c9 Merge branch 'revert-9347fe5c' into 'master'
Unimplement TCB interpolation (!4539)

Closes #8621

See merge request OpenMW/openmw!4782
2025-07-13 18:28:32 +03:00
Alexei Kotov
119a87b7f4 Revert "Merge branch 'tbcornottbcwaititstcbactually' into 'master'"
This reverts merge request !4539
2025-07-13 18:02:15 +03:00
Dave Corley
79d86bf2bd FIX: Track the highest local refNum during plugin loading and increment it for each cloned/created reference 2025-07-13 05:12:42 -07:00
Dave Corley
2cb7d6c392 CLEANUP: Remove commented code & use the builtin getNewId function when cloning 2025-07-13 05:11:38 -07:00
Dave Corley
85fdf2011a FIX: Do not attempt to bump refNums during savingStages 2025-07-13 05:10:43 -07:00
Dave Corley
42109fc811 CLEANUP: Remove dead code in cloneRecordImp 2025-07-13 05:10:14 -07:00
Alexei Kotov
4f95ca4196 Merge branch 'talk-to-me-about-something-else' into 'master'
FEAT: AddTopic in Lua, close #8334

Closes #8334

See merge request OpenMW/openmw!4529
2025-07-13 12:35:41 +03:00
Alexei Kotov
79c689784b Merge branch 'quick_item_transfer' into 'master'
Support quick item transfer (#2522)

Closes #2522

See merge request OpenMW/openmw!4659
2025-07-13 12:33:56 +03:00
Evil Eye
c80b3d26b9 Only check for spelllist/equipment changes in the update loop 2025-07-13 11:18:15 +02:00
Evil Eye
2dbe30ed5c Update effects upon applying them 2025-07-13 10:53:34 +02:00
Aussiemon
bb1214ed69 factionId instead of faction->mName 2025-07-13 02:48:37 -06:00
Aussiemon
11947286d9 Reuse factionId 2025-07-13 02:36:59 -06:00
Aussiemon
87e41425bb Unnecessary ptrClass 2025-07-13 02:36:16 -06:00
Aussiemon
cef1807536 Use RefId instead of name 2025-07-13 02:30:55 -06:00
Aussiemon
61ebb4b259 Redo debug warnings in interpreter 2025-07-13 02:07:49 -06:00
Dave Corley
1abaf706c8 CLEANUP: Bump api revision 2025-07-12 19:37:36 -07:00
Dave Corley
ced135bc87 CLEANUP: No, record ids should totally be quoted 2025-07-12 19:37:15 -07:00
Dave Corley
943cd765e7 CLEANUP: Update for MR Comments 2025-07-12 19:37:15 -07:00
Dave Corley
8ec4fcbf30 CLEANUP: Actually check the record in question is a topic when using addTopic 2025-07-12 19:37:15 -07:00
Dave Corley
05b12ac879 CLEANUP: Use more appropriate object types & functions in addTopic binding 2025-07-12 19:37:15 -07:00
Dave Corley
4150f5fad6 FEAT: AddTopic in Lua, close #8334 2025-07-12 19:37:15 -07:00
Andrew Lanzone
843a6487cc Fix clang warning 2025-07-12 19:04:14 -07:00
Andrew Lanzone
6629a186b1 Controller mode uses LB/RB in journal and spell list to scroll faster 2025-07-12 15:37:48 -07:00
Andrew Lanzone
084e4a3155 Change type of mControllerFocus to size_t when applicable 2025-07-12 15:13:33 -07:00
Andrew Lanzone
622cbd5288 Remove SDL_VERSION_ATLEAST references 2025-07-12 14:17:23 -07:00
Andy Lanzone
3600a5c716 Merge branch openmw:master into master 2025-07-12 14:13:10 -07:00
Alexei Kotov
2504550c6f Merge branch 'fasterwait' into 'master'
More closely match rest/wait progress speed to vanilla

See merge request OpenMW/openmw!4772
2025-07-12 21:55:58 +03:00
Evil Eye
6dd10f1666 Prepend new characters so they're first on the list 2025-07-12 19:32:32 +02:00
Kuyondo
def31cfb05 cleanup 2025-07-12 22:44:28 +08:00
Kuyondo
d2c78ee88c move member var to implementation 2025-07-12 22:14:47 +08:00
Alexei Kotov
403b5d19e0 Merge branch 'KwarmaQueenCombat' into 'master'
Prevent immobile creatures' combat actions, but allow combat

Closes #7871

See merge request OpenMW/openmw!4632
2025-07-12 15:29:32 +03:00
elsid
463de2d791
Instantly transfer items if alt key is pressed
Support player's inventory, container and companion windows with
dropping and picking up items from the world.

Add ItemTransfer class to handle transfers similar to DragAndDrop. When
a container window is opened the view is added to the set of targets and
removed when closed. If ALT is pressed instead of starting dragging an
item perform a transfer. If there is 1 target which is not a source move
item there. If there is no target drop item into the world using
WorldItemModel.

Special case is picking up an item. Don't start dragging, just update
the player's inventory view because the item is already there.
2025-07-12 13:34:59 +02:00
elsid
f5e66f3e24
Remove unused includes 2025-07-12 12:31:15 +02:00
elsid
eb7af832e4
Remove trailing spaces 2025-07-12 12:31:15 +02:00
elsid
a4af037293
Remove ContainerWindow::onTakeItem 2025-07-12 12:31:15 +02:00
elsid
bcfe06d85a
Use std::size_t for items count 2025-07-12 12:31:14 +02:00
Alexei Kotov
4e5e8e7889 Merge branch '1kiawayan-7649' into 'master'
Don't play vfx and sound on resisted magic

Closes #7649

See merge request OpenMW/openmw!4766
2025-07-12 12:38:51 +03:00
Alexei Kotov
e9081fec9f Merge branch 'refactorshowvars' into 'master'
Improve showVars

See merge request OpenMW/openmw!4747
2025-07-12 12:37:05 +03:00
Alexei Kotov
3e711c30db Merge branch 'maluu-apa-bosku' into 'master'
Play down sound when equip fails

Closes #7371

See merge request OpenMW/openmw!4248
2025-07-12 11:52:26 +03:00
Alexei Kotov
f4ff683905 Merge branch 'terrain_normals_fix' into 'master'
Fix terrain normal map handedness

Closes #8610

See merge request OpenMW/openmw!4775
2025-07-12 11:50:00 +03:00
Kuyondo
77c30a68c9 more similar to vanilla 2025-07-12 12:04:38 +08:00
wareya
869881d227 fix terrain normal map handedness 2025-07-11 12:23:22 -04:00
Alexei Kotov
fe7970421f Don't harvest if player activation is blocked (#8612) 2025-07-11 11:47:20 +03:00
psi29a
f5de0d1c40 Merge branch 'quickkeysmenu' into 'master'
Quick keys menu fixes (#8359)

Closes #8359

See merge request OpenMW/openmw!4546
2025-07-11 07:41:55 +00:00
Kuyondo
25d9c80067 Don't play vfx and sound on fully resisted debuffs 2025-07-11 03:10:49 +08:00
Alexei Kotov
1ce7110a9e Merge branch 'less-strict-dialogues' into 'master'
FIX: Skip only the current subrecord when reading quest status (Close #8333)

Closes #8333

See merge request OpenMW/openmw!4528
2025-07-10 20:14:53 +03:00
Andrew Lanzone
73ffe7f62b Fix clang formatting issue 2025-07-10 08:56:24 -07:00
Andrew Lanzone
b075428513 Minor fixes based on code review feedback. 2025-07-10 08:46:01 -07:00
Andrew Lanzone
e04f0a8bd6 Move logic for determining Russian index page count to a shared place 2025-07-10 08:45:51 -07:00
Andrew Lanzone
d100867bce Add ReST documentation for controller menu options 2025-07-10 08:44:58 -07:00
Alexei Kotov
6d74a4607c Restore some omitted object cache remarks that seemed useful 2025-07-10 17:25:27 +03:00
Florian Heberer
a00e5ec828 Add documentation for update function of Generic Object Cache 2025-07-10 17:18:18 +03:00
Dave Corley
7bc507eb58 FIX: Skip only the current subrecord when reading quest status 2025-07-10 17:08:47 +03:00
Alexei Kotov
b958dc7297 Merge branch 'launcher_resolutions' into 'master'
Do not allow to select a screen resolution in the Windowed Fullscreen mode in the launcher

See merge request OpenMW/openmw!4765
2025-07-10 15:44:35 +03:00
Alexei Kotov
f64f53341b Merge branch 'gen_mipmaps_after_draw' into 'master'
Generate mipmaps after we draw fullscreen geometry

See merge request OpenMW/openmw!4768
2025-07-10 10:06:07 +03:00
Andrei Kortunov
dca83c2500 Add resolution hints to launcher 2025-07-10 10:24:39 +04:00
Alexei Kotov
3789070ea2 Merge branch 'docs_less_padding' into 'master'
Tighten table padding and luadoc anchors

See merge request OpenMW/openmw!4767
2025-07-10 00:55:36 +03:00
Cody Glassman
064b8d3f9b use more explicit null check 2025-07-09 11:49:38 -07:00
Alexei Kotov
f3420bd1bd Move Quitting peacefully message to a more appropriate place 2025-07-09 10:55:17 +03:00
Andy Lanzone
d46f034e5d Merge branch openmw:master into master 2025-07-08 19:46:37 -07:00
Andrew Lanzone
9a637563cd Fix getIndexSelected typing 2025-07-08 19:46:24 -07:00
Cody Glassman
759739ecca generate mipmaps after we draw, not before 2025-07-08 15:53:18 -07:00
Cody Glassman
3ec04f4ba7 docs - improve link contrast in dark mode 2025-07-08 14:15:37 -07:00
Andrei Kortunov
a68107712c Do not allow to select a screen resolution in the Windowed Fullscreen mode in the launcher 2025-07-08 22:33:35 +04:00
Cody Glassman
8b44b95830 docs - fix table padding and luadoc scroll padding 2025-07-08 11:26:16 -07:00
Alexei Kotov
0892357230 Only autoequip the shield in updateEquippedLight (#8404) 2025-07-08 20:32:20 +03:00
psi29a
e9a9659abc Merge branch 'autoequip' into 'master'
Unify creature/NPC armor autoequip

See merge request OpenMW/openmw!4753
2025-07-08 10:35:17 +00:00
psi29a
3135e2e479 Merge branch 'smexypants' into 'master'
Make ExtraSpell undress less

See merge request OpenMW/openmw!4752
2025-07-08 10:34:32 +00:00
psi29a
c691c72cec Merge branch 'esm4sound' into 'master'
Initial support of ESM4 sounds

See merge request OpenMW/openmw!3784
2025-07-08 10:32:24 +00:00
Alexei Kotov
c0276b6890 Merge branch 'cpputil2lua' into 'master'
Move some util to lua

See merge request OpenMW/openmw!4750
2025-07-08 12:45:14 +03:00
Petr Mikheev
10dba7cda7 Initial support of ESM4 sounds; play opening sound of ESM4 doors. 2025-07-08 11:14:13 +02:00
Kuyondo
f87d6818b7 pressing enter for newline 2025-07-08 05:02:53 +08:00
Kuyondo
ede768532c cleanup 2 2025-07-08 03:48:40 +08:00
Alexei Kotov
f56d6e4c1e Merge branch 'changelog' into 'master'
Changelog sync

See merge request OpenMW/openmw!4761
2025-07-07 19:08:13 +03:00
Andrew Lanzone
c61d4783e6 Merge branch 'master' of https://gitlab.com/OpenMW/openmw 2025-07-07 08:59:58 -07:00
Andrew Lanzone
21367a6127 Merge branch 'master' of https://gitlab.com/OpenMW/openmw 2025-07-07 08:58:21 -07:00
AnyOldName3
1331318002 Add another v 2025-07-07 16:28:52 +01:00
Evil Eye
0c4af81a69 Fix tests 2025-07-07 16:48:24 +02:00
Kuyondo
36604777f2 tests 2 2025-07-07 20:14:38 +08:00
Kuyondo
3f352b2470 tests 2025-07-07 19:28:12 +08:00
Alexei Kotov
d5e3703aa8 Changelog sync for 0.50.0 2025-07-07 12:51:49 +03:00
psi29a
83a37fecea Merge branch 'l10n_format' into 'master'
Treat formatting string arguments as UTF-8 string

Closes #8385

See merge request OpenMW/openmw!4751
2025-07-07 09:28:43 +00:00
Kuyondo
e4f0723a90 cleanup 2025-07-07 17:01:18 +08:00
Kuyondo
40e9b2d707 play down sound when equip fails 2025-07-07 17:01:18 +08:00
Alexei Kotov
2ce697a366 Merge branch 'errno' into 'master'
Print a more verbose message when we failed to write savegame

See merge request OpenMW/openmw!4749
2025-07-07 10:35:12 +03:00
Andrew Lanzone
3a05ddb982 Fix issues caused by incomplete merge 2025-07-06 23:17:00 -07:00
Andrew Lanzone
b170500183 Merge branch 'master' of https://gitlab.com/OpenMW/openmw 2025-07-06 23:00:28 -07:00
Andrew Lanzone
952abf5557 Support either two- or three- column layouts for cyrillic journal indices 2025-07-06 22:51:31 -07:00
Andrew Lanzone
fdc392435f Fix controller tooltip temporarily disappearing when dealing with stacks of items 2025-07-06 22:42:08 -07:00
Andrew Lanzone
e349fa248a Tweak how scroll offsets are calculated for smoother scrolling 2025-07-06 22:42:08 -07:00
Andrew Lanzone
abe0467915 Show count dialog when dropping stacks (cleans up the logic too) 2025-07-06 22:42:08 -07:00
epochwon
db22706e8e I'm sorry clang, forgive me 2025-07-07 01:40:25 -04:00
epochwon
ba361302a1 cache physics framerate at start instead of checking every update 2025-07-07 01:40:25 -04:00
epochwon
ce666db34f don't use EFX doppler, set doppler factor globally instead of per-sound 2025-07-07 01:40:25 -04:00
epochwon
f0e9df4de2 fix launcher ui and lang mess 2025-07-07 01:40:25 -04:00
epochwon
1206688494 language files maybe? 2025-07-07 01:40:25 -04:00
epochwon
d29c01be26 appease clang + docs 2025-07-07 01:40:24 -04:00
epochwon
c541cb96cc doppler take 2 2025-07-07 01:37:18 -04:00
Aussiemon
67795543a2 Revert "Fix unneeded runtime errors"
This reverts commit d207c2251f.
2025-07-06 20:51:53 -06:00
Sarah Sunday
6a9b2d3302 [CI] Brew cleanup/simplify 2025-07-06 17:28:23 -05:00
Kindi
c4a4c435f1 refactor opshowvars 2025-07-07 04:38:25 +08:00
Alexei Kotov
abbbeefdbd Merge branch 'harvest' into 'master'
Do not recreate animation object when harvesting a plant

See merge request OpenMW/openmw!4744
2025-07-06 22:24:20 +03:00
Alexei Kotov
eb9096baf4 Merge branch 'eventful' into 'master'
[Lua] Some event handlers.

See merge request OpenMW/openmw!4738
2025-07-06 22:20:27 +03:00
Alexei Kotov
0b192c4485 Merge branch 'tidy-up-warnings' into 'master'
Apply warning flags consistently for all compilers

Closes #7882

See merge request OpenMW/openmw!4748
2025-07-06 22:18:22 +03:00
Alexei Kotov
a109052296 Merge branch 'no_water_blend' into 'master'
Fix disappearing normals with refraction disabled (#8490)

Closes #8490

See merge request OpenMW/openmw!4746
2025-07-06 22:12:59 +03:00
Aussiemon
555721141d Skip quest names (vanilla improvement) 2025-07-06 12:16:17 -06:00
Aussiemon
d207c2251f Fix unneeded runtime errors 2025-07-06 12:16:17 -06:00
Aussiemon
0e1ed078e9 Clang format 2025-07-06 12:16:17 -06:00
Aussiemon
73a3033e0f Get the dialogue manager once 2025-07-06 12:16:17 -06:00
Aussiemon
30140d9548 Get the journal only once 2025-07-06 12:16:17 -06:00
Aussiemon
565b199380 Clang format 2025-07-06 12:16:17 -06:00
Aussiemon
83903455f9 Address review comments 2025-07-06 12:16:17 -06:00
Aussiemon
4b98520266 Revert shared addJournalEntry 2025-07-06 12:16:17 -06:00
Aussiemon
34194f9c08 Add topics as known topics in addition to journal topics 2025-07-06 12:16:17 -06:00
Aussiemon
2e1f3d5d2c Clang format 2025-07-06 12:16:17 -06:00
Aussiemon
6c70c403be Implement FillJournal console command 2025-07-06 12:16:17 -06:00
Aussiemon
2db36c49b5 Move early out to better place 2025-07-06 11:51:44 -06:00
Aussiemon
09ed5bb234 Allow immobile actors to initiate combat when attacked 2025-07-06 11:51:44 -06:00
Aussiemon
3df695df4a Found better place for early return 2025-07-06 11:51:44 -06:00
Aussiemon
23dc226dff Revert autoformat changes 2025-07-06 11:51:44 -06:00
Aussiemon
a77a8904e5 Immobile creatures should enter combat, but not act 2025-07-06 11:51:44 -06:00
Aussiemon
266702e729 Remove obsolete combat block for immobile creatures and autoformat 2025-07-06 11:51:44 -06:00
AnyOldName3
89d6f59388 Use verbose status for ccache so we can see what caused hit failures 2025-07-06 15:58:12 +01:00
Mads Buvik Sandvei
45c187028f Bump 2025-07-06 14:23:39 +02:00
Alexei Kotov
df5625a1e3 Unify creature/NPC armor autoequip 2025-07-06 13:58:25 +03:00
psi29a
c232ad55b4 Merge branch 'updateinventory' into 'master'
Update inventory window when item is added or removed into container by script

Closes #8431

See merge request OpenMW/openmw!4609
2025-07-06 10:20:52 +00:00
psi29a
86d81af199 Merge branch 'hairwidthcrosshair' into 'master'
Make the crosshair smaller

See merge request OpenMW/openmw!4608
2025-07-06 10:20:16 +00:00
psi29a
3405d5017e Merge branch 'birthsigntooltip' into 'master'
Revise birthsign tooltip layout (#6792)

Closes #6792

See merge request OpenMW/openmw!4558
2025-07-06 10:18:52 +00:00
psi29a
a5e23f5fd3 Merge branch 'portedesetoiles' into 'master'
Fix path handling for files in BSAs

Closes #8598 and #8599

See merge request OpenMW/openmw!4655
2025-07-06 10:17:55 +00:00
Evil Eye
3574cd552c Make ExtraSpell undress less 2025-07-06 12:10:49 +02:00
Andrei Kortunov
d455ff5f5e Treat formatting string arguments as UTF-8 string 2025-07-06 13:35:27 +04:00
Andrei Kortunov
779840deea Print a more verbose message when we failed to write savegame 2025-07-06 11:27:03 +04:00
Alexei Kotov
9b8a383e8d Merge branch 'sinalau-bakas' into 'master'
Respawning npc respawns in origin cell

See merge request OpenMW/openmw!4695
2025-07-06 07:06:47 +03:00
AnyOldName3
c253590338 Restore previous interpretation of OPENMW_CXX_FLAGS
It used to be copied as-is into the command-line options for the compiler, whereas add_compile_options expects a list of arguments.
separate_arguments can be used to split a string how the system would split a command line.
2025-07-05 22:56:42 +01:00
Mads Buvik Sandvei
7143115e57 Doc update 2025-07-05 21:30:51 +02:00
Mads Buvik Sandvei
1b9802472d Doc updates 2025-07-05 21:30:51 +02:00
Mads Buvik Sandvei
c7e3f9b0cf Add some events from the dehardcode spellcasting MR, that do not need to be specific to that MR. 2025-07-05 21:30:51 +02:00
AnyOldName3
da32ccee50 Apply warning flags consistently for all compilers
This avoids a problem where a bunch of our targets weren't having the right warning flags set up with MSVC.
It shouldn't make any difference for other compilers, except Clang in clang-cl mode, which wants MSVC warning flags, and will now get them.

It doesn't seem to resolve https://gitlab.com/OpenMW/openmw/-/issues/7882, so you still have to disable precompiled headers to see warnings with MSVC.
2025-07-05 19:49:08 +01:00
Andrew Lanzone
b6f3b2760a Use a new string for 'Select Character' controller button label 2025-07-05 10:27:45 -07:00
AnyOldName3
bf92e551a7 Eliminate reference to vestigial MT_BUILD variable 2025-07-05 18:09:36 +01:00
Alexei Kotov
a51afbeaa8 Merge branch 'gen_mipmaps_for_rendertargets' into 'master'
Generate mipmaps for rendertargets (#8593)

See merge request OpenMW/openmw!4734
2025-07-05 19:25:37 +03:00
Alexei Kotov
0655e7988e Merge branch 'docs_openmw_cfg' into 'master'
Improve docs styling for code blocks and headers

See merge request OpenMW/openmw!4733
2025-07-05 19:22:18 +03:00
Cody Glassman
da71ec6e49 postprocessing - bump revision 2025-07-05 08:55:06 -07:00
Cody Glassman
390589795c postprocessing - set mipmaps levels for rendertargets when requested 2025-07-05 08:53:54 -07:00
Cody Glassman
30a852bb88 disable blending in second color attachment on water node 2025-07-05 08:32:21 -07:00
Andrei Kortunov
2db9b91c10 Do not recreate animation object when harvesting a plant 2025-07-05 17:11:17 +04:00
Alexei Kotov
a6503233a6 Merge branch 'windowvisiblelua' into 'master'
lua - add binding to check window visibility

Closes #8355

See merge request OpenMW/openmw!4543
2025-07-05 09:57:50 +03:00
Andrew Lanzone
dfa3b5f7ed Add Russian translation for controller menu launcher checkboxes 2025-07-04 23:09:31 -07:00
Andrew Lanzone
e577257ec4 Make topic padding a const and use it when scrolling dialog topics 2025-07-04 23:06:05 -07:00
Andrew Lanzone
0f26270f66 Sync to master tree but keep changes 2025-07-04 16:17:27 -07:00
Skyhasacat
e4a6db1b84 Merge branch 'revert-b29850f4' into 'master'
Revert !4710

See merge request OpenMW/openmw!4740
2025-07-04 22:15:37 +00:00
Alexei Kotov
38efdd2fd8 Revert "Merge branch 'master' into 'master'"
This reverts merge request !4710
2025-07-05 01:00:26 +03:00
Andy Lanzone
fdcf9f773c Merge branch 'xbox_buttons' into 'master'
Xbox buttons

See merge request enoznal/openmw!1
2025-07-04 14:38:55 -07:00
Andy Lanzone
ffec2e8d74 Automatically show Xbox, PS, or Switch button icons 2025-07-04 14:38:55 -07:00
Skyhasacat
b29850f4c6 Merge branch 'master' into 'master'
Gamepad GUI Mode: add (optional) native controller support to all menus

See merge request OpenMW/openmw!4710
2025-07-04 21:29:55 +00:00
Alexei Kotov
4bf43665c4 Revise birthsign tooltip layout (#6792)
Make all description bits distinct widgets to allow proper padding
Use spaces instead of line breaks to separate spells
Enable word-wrapping for description text
Make the tooltip wider and increase padding
2025-07-04 20:03:55 +00:00
Andrew Lanzone
28f3b4a530 Remove unused argument from lambda to fix compiler warning 2025-07-04 12:49:54 -07:00
SkyHasACat
3504e85051 More whitespace 2025-07-04 14:33:15 -05:00
SkyHasACat
424a62187a whitespace? 2025-07-04 14:26:16 -05:00
SkyHasACat
ed8b9742ae Add name 2025-07-04 14:22:01 -05:00
SkyHasACat
b3105e9382 Fix other changes 2025-07-04 14:22:01 -05:00
SkyHasACat
30e5e17e4c Remove enchanting dialog, missing empty lines 2025-07-04 14:22:01 -05:00
Garrett
fce73395e5 Update file openmw_enchanting_dialog.layout 2025-07-04 14:22:01 -05:00
Garrett
7f11579d39 Update file enchantingdialog.cpp 2025-07-04 14:22:01 -05:00
Garrett
57f8355bac Update file enchantingdialog.hpp 2025-07-04 14:22:01 -05:00
Garrett
30dae411d0 Update file spellcreationdialog.cpp 2025-07-04 14:22:01 -05:00
Garrett
57bb6f2e2f Update file spellcreationdialog.cpp 2025-07-04 14:22:01 -05:00
Garrett
284be88b95 Update file openmw_spellcreation_dialog.layout 2025-07-04 14:22:01 -05:00
Garrett
937c020e58 Update file openmw_spellcreation_dialog.layout 2025-07-04 14:22:01 -05:00
Garrett
190a1266a1 Update 2 files
- /apps/openmw/mwgui/spellcreationdialog.cpp
- /apps/openmw/mwgui/spellcreationdialog.hpp
2025-07-04 14:22:01 -05:00
Garrett
2d2df30f80 Update file spellcreationdialog.cpp 2025-07-04 14:22:01 -05:00
Garrett
bcb27fff6a Update 2 files
- /apps/openmw/mwgui/spellcreationdialog.cpp
- /apps/openmw/mwgui/spellcreationdialog.hpp
2025-07-04 14:22:01 -05:00
Garrett
f8c8b9b433 Replace spellcreationdialog.hpp to add player gold to spell creation window. 2025-07-04 14:22:01 -05:00
Garrett
15a525676c Replace spellcreationdialog.cpp to add gold counter for player 2025-07-04 14:22:01 -05:00
Garrett
0ac0c62091 Replace openmw_spellcreation_dialog.layout 2025-07-04 14:22:01 -05:00
Andrew Lanzone
04d73cf195 Revert clang formatting suggestion because it breaks the pipeline 2025-07-04 12:02:17 -07:00
Andrew Lanzone
ce0ae47478 Expose controller menus setting to Lua 2025-07-04 11:53:36 -07:00
Andrew Lanzone
64284063b3 Merge branch 'master' of https://gitlab.com/OpenMW/openmw 2025-07-04 11:52:31 -07:00
Mads Buvik Sandvei
ec3357ff3f Bump UI interface version number 2025-07-04 20:30:31 +02:00
Cody Glassman
28de55df6a docs - use default pygment style in light mode 2025-07-04 11:19:04 -07:00
Cody Glassman
bc78aa4198 docs - add semicolons before examples 2025-07-04 11:03:29 -07:00
Cody Glassman
a5b8db70a4 docs - improve styling in headers and code blocks 2025-07-04 06:59:05 -07:00
psi29a
1a08565a20 Merge branch 'destinationunknown' into 'master'
Don't add non-existent cell travel destinations (#8349)

Closes #8349

See merge request OpenMW/openmw!4540
2025-07-04 11:06:33 +00:00
psi29a
d0af16c5db Merge branch 'travelprice' into 'master'
Rescale the base travel cost by the number of followers (#8446)

Closes #8446

See merge request OpenMW/openmw!4626
2025-07-04 11:05:56 +00:00
psi29a
b2228de0b7 Merge branch 'pinnedinventory' into 'master'
Restore 0.45.0 pin button visibility conditions (#8437)

Closes #8437

See merge request OpenMW/openmw!4612
2025-07-04 11:05:40 +00:00
psi29a
3d75dec73d Merge branch 'waterwalkingtcl' into 'master'
Don't enable water collision when collision is disabled (#8414)

Closes #8414

See merge request OpenMW/openmw!4600
2025-07-04 11:04:12 +00:00
psi29a
94507567da Merge branch 'conspiracyofsilence' into 'master'
Make powers immune to silence (#8371)

Closes #8371

See merge request OpenMW/openmw!4557
2025-07-04 11:03:40 +00:00
psi29a
9013ed16f0 Merge branch 'reststates' into 'master'
Inform the player about both resting hindrances (#8408)

Closes #8408

See merge request OpenMW/openmw!4598
2025-07-04 11:03:28 +00:00
psi29a
99a6a04c70 Merge branch 'massselect' into 'master'
Support extended selection in the directory picker (#8113)

Closes #8113

See merge request OpenMW/openmw!4669
2025-07-04 11:02:55 +00:00
Andrew Lanzone
8379c31f13 Add option to show controller tooltips by default 2025-07-04 02:40:52 -07:00
Andrew Lanzone
088b2d1bbc Fix GCC warning 2025-07-03 14:47:34 -07:00
Andrew Lanzone
ee33424c20 Prevent controller from dismissing dialog window when there is a choice active 2025-07-03 14:32:13 -07:00
Andrew Lanzone
ffac1cdf3c Remove int casts by using size_t in a few places 2025-07-03 14:20:24 -07:00
Mads Buvik Sandvei
b1f32c8cee isWindowVisible must handle replaced windows' visibility 2025-07-03 22:11:21 +02:00
Mads Buvik Sandvei
9fe420e562 improve error report when windowId is invalid. 2025-07-03 22:11:21 +02:00
Mads Buvik Sandvei
593988e82b bump lua revision 2025-07-03 22:11:19 +02:00
Mads Buvik Sandvei
7f34e52a11 lua interface for window visibility 2025-07-03 22:10:56 +02:00
Andrew Lanzone
6a1f8b3f69 Merge branch openmw:master into master 2025-07-03 19:03:08 +00:00
Andrew Lanzone
5d8c349899 Fix issues with setControllerFocus 2025-07-03 12:01:24 -07:00
Andrew Lanzone
44fb923d7b Keep active quest focused in same journal session 2025-07-03 12:00:55 -07:00
Evil Eye
dbc732231f Allow non-existent techniques to exist 2025-07-03 17:21:50 +02:00
psi29a
0aca34c02b Merge branch 'magicalintegrationtests' into 'master'
Add integration tests for mwscript-magic interactions

See merge request OpenMW/openmw!4511
2025-07-03 13:04:46 +00:00
Kuyondo
32f59c16aa move some util to lua 2025-07-03 19:38:02 +08:00
Kuyondo
a6cf359820 update offer player side, next frame update view 2025-07-03 15:13:21 +08:00
psi29a
d40c4855b1 Merge branch 'showVars' into 'master'
Show global script variables in showVars

See merge request OpenMW/openmw!4614
2025-07-03 07:11:23 +00:00
psi29a
ea147d78ed Merge branch 'sortedsaves' into 'master'
Order characters by last save

Closes #8580

See merge request OpenMW/openmw!4730
2025-07-03 07:06:27 +00:00
Evil Eye
206d38f3d7 Fix path handling for files in BSAs 2025-07-03 08:46:23 +02:00
Evil Eye
66b5623bc9 Actually run the new test 2025-07-03 07:37:58 +02:00
Evil Eye
18ad2db59c Remove unused variable 2025-07-03 07:33:03 +02:00
Alexei Kotov
a0e0b3c65b Some quick key menu layout fixes 2025-07-03 08:30:50 +03:00
Alexei Kotov
733dfbb89d Don't assume any scripted item is usable 2025-07-03 08:10:59 +03:00
Alexei Kotov
982962c608 Don't center quick keys menu instructions 2025-07-03 08:10:59 +03:00
Alexei Kotov
29177bccb8 Play the item's down sound when an item quick key is assigned 2025-07-03 08:10:59 +03:00
Andrew Lanzone
7cc25d8916 Dialog window improvements: use LB/RB to move up/down by 5; if only one dialog choice, autoselect it. 2025-07-02 22:00:40 -07:00
Alexei Kotov
7cf74c570e Properly disable named exterior destination interior flag 2025-07-03 07:46:09 +03:00
Andrew Lanzone
3767b60512 Fix L1 and R1 buttons not disappearing 2025-07-02 21:35:26 -07:00
Alexei Kotov
00e6e855f1 Don't add non-existent cell travel destinations (#8349) 2025-07-03 07:25:44 +03:00
psi29a
53feb29a5b Merge branch 'landscape-data-bindings' into 'master'
Landscape height and texture bindings for Lua (Revised and Reopened)

See merge request OpenMW/openmw!4724
2025-07-02 21:53:05 +00:00
psi29a
75b4682cd7 Merge branch 'no_null_shader' into 'master'
Fix invalid deletion of shaders during iteration (#7587)

See merge request OpenMW/openmw!4731
2025-07-02 21:45:02 +00:00
psi29a
66befc67d9 Merge branch 'topiclist' into 'master'
Improve topic and magic effect list padding accuracy (#8585)

Closes #8585

See merge request OpenMW/openmw!4580
2025-07-02 21:44:00 +00:00
psi29a
b5b5aa4331 Merge branch 'winserver2025' into 'master'
Replace Windows Server 2019 with 2025

Closes #8586

See merge request OpenMW/openmw!4732
2025-07-02 21:43:06 +00:00
psi29a
2309aeec70 Merge branch 'suijutsu' into 'master'
Underwater projectile fixes (#7622, #8303)

Closes #7622 and #8303

See merge request OpenMW/openmw!4567
2025-07-02 21:42:00 +00:00
psi29a
6f48a6f1bf Merge branch 'docs_me_not_v2' into 'master'
Docs - begin restructuring docs

See merge request OpenMW/openmw!4720
2025-07-02 21:37:30 +00:00
Sebastian Fieber
f5e24804ce fix format 2025-07-02 20:45:55 +02:00
Evil Eye
7c1dbdd191 Select a fallback character if possible 2025-07-02 20:42:02 +02:00
Evil Eye
c3a5ad4328 Declare operator in MWState namespace 2025-07-02 20:29:38 +02:00
Evil Eye
d756b02d68 Order characters by last save 2025-07-02 20:29:38 +02:00
Evil Eye
acb554faac Only build on one image 2025-07-02 17:56:46 +02:00
Kuyondo
2dc0d8abca use << 2025-07-02 23:51:15 +08:00
Evil Eye
00e7439533 Replace Windows Server 2019 with 2025 2025-07-02 17:13:44 +02:00
Evil Eye
dca8c7c163 Add integration tests for mwscript-magic interactions 2025-07-02 17:03:33 +02:00
epochwon
0027a5bcab make the specular terms easier to read, turn the magic number into a const 2025-07-02 10:49:27 -04:00
Sebastian Fieber
e4439806ed land bindings afterwork
- fix include order + style
- cellOrName -> cellOrId
- bump lua api revision to 78
- cellOrId is not optional anymore for getHeightAt
2025-07-02 16:14:03 +02:00
Sebastian Fieber
eb4d3b7224 Reapply "Merge branch 'landscape-data-bindings' into 'master'"
This reverts commit 3ff7dedfd1.
2025-07-02 16:09:06 +02:00
Cody Glassman
10f86c67fe docs - fix spacing in example lua 2025-07-02 06:04:39 -07:00
psi29a
4520eb077d Merge branch 'lua_pp_order' into 'master'
lua - add ability to query the currently active shaders

Closes #8285

See merge request OpenMW/openmw!4506
2025-07-02 09:45:00 +00:00
psi29a
cb0b44e0b2 Merge branch 'bounditems' into 'master'
Interrupt bound item effect if equipment failed (#8383)

Closes #8383

See merge request OpenMW/openmw!4572
2025-07-02 09:43:21 +00:00
psi29a
5a292624a5 Merge branch 'add_scripText_to_mwscriptbindings' into 'master'
lua - add mwscript bindings to core (#8320)

Closes #8320

See merge request OpenMW/openmw!4517
2025-07-02 09:42:25 +00:00
psi29a
5c60168b16 Merge branch 'ini-importer-tidying' into 'master'
INI importer tidying

See merge request OpenMW/openmw!4519
2025-07-02 09:40:58 +00:00
Evil Eye
681a95b89f Merge branch 'fix_keyword_highlighting' into 'master'
FIX keyword substring highlighting regression

Closes #8265 and #1047

See merge request OpenMW/openmw!4685
2025-07-02 06:13:26 +00:00
Charles Horn
c948171d5f FIX keyword substring highlighting regression 2025-07-02 06:13:25 +00:00
Alexei Kotov
612411e492 Allow non-actor spell projectiles to fire underwater (#8303) 2025-07-02 08:54:30 +03:00
Alexei Kotov
be13b1d085 Handle instant projectile impact before underwater logic (#7622) 2025-07-02 08:54:30 +03:00
Sebastian Fieber
fa8ba57ab3 add mwscript bindings to core 2025-07-02 00:57:40 +02:00
Andrew Lanzone
e2e8a02a26 Merge branch 'master' of https://gitlab.com/OpenMW/openmw 2025-07-01 12:22:35 -10:00
psi29a
9228f90f46 Merge branch 'RecalcSpellBuyCost' into 'master'
Calculate spell cost when building spell-buying window

Closes #8459

See merge request OpenMW/openmw!4640
2025-07-01 21:38:01 +00:00
psi29a
aa652a20f0 Merge branch 'StackValueAffectsFightTerm' into 'master'
Make item value affect theft observer's fight willingness

Closes #8500

See merge request OpenMW/openmw!4673
2025-07-01 21:37:28 +00:00
Aussiemon
5ba0b3ab52 Make item value affect theft observer's fight willingness 2025-07-01 21:37:27 +00:00
psi29a
149587dda4 Merge branch 'scaledselection' into 'master'
Editor: Account for pixel ratio in instance mode mouse coordinates conversion (#6573)

Closes #6573

See merge request OpenMW/openmw!4587
2025-07-01 21:34:40 +00:00
psi29a
583af381a6 Merge branch 'baseresistance' into 'master'
Ignore resistances for base diseases

Closes #8485

See merge request OpenMW/openmw!4662
2025-07-01 21:32:55 +00:00
psi29a
32f13816f8 Merge branch 'equippedSpellIterationFix' into 'master'
Skip duplicate enchantments on Spell Cycle action

Closes #6039

See merge request OpenMW/openmw!4668
2025-07-01 21:32:20 +00:00
Aussiemon
0a9c3ce96f Skip duplicate enchantments on Spell Cycle action 2025-07-01 21:32:20 +00:00
psi29a
48bc9e5dd2 Merge branch 'updatespellwindowquickkey' into 'master'
Update spell window after selecting spell using quickkey #8436

See merge request OpenMW/openmw!4611
2025-07-01 21:29:30 +00:00
psi29a
47aa0b27ff Merge branch 'FixDoublePickpocketBounty' into 'master'
Prevent second bounty for "closed pickpocket window" when steal is already detected

Closes #8519

See merge request OpenMW/openmw!4694
2025-07-01 21:29:06 +00:00
psi29a
ceac11d6df Merge branch 'sillyphysics' into 'master'
Stop postponing physics for objects that _don't_ have physics

Closes #8432

See merge request OpenMW/openmw!4658
2025-07-01 21:28:48 +00:00
psi29a
aa3e991352 Merge branch 'showmap' into 'master'
Require a non-empty argument in ShowMap (#8466)

Closes #8466

See merge request OpenMW/openmw!4649
2025-07-01 21:28:02 +00:00
psi29a
f6bff53398 Merge branch 'idempotent-parallax' into 'master'
Don't forget parallax when reapplying shader visitor

Closes #8341

See merge request OpenMW/openmw!4634
2025-07-01 21:27:01 +00:00
psi29a
917b08e05d Merge branch 'MoonPhaseAndVisibilityFixes' into 'master'
Match vanilla moon phases and visibility times

Closes #8375

See merge request OpenMW/openmw!4616
2025-07-01 21:25:36 +00:00
Aussiemon
5ef947e14f Match vanilla moon phases and visibility times 2025-07-01 21:25:36 +00:00
psi29a
a29f4b3ba0 Merge branch 'enchantmentprice' into 'master'
Use the final effect cost to calculate enchantment price (#8340)

Closes #8340

See merge request OpenMW/openmw!4530
2025-07-01 21:23:58 +00:00
psi29a
59eb7b9888 Merge branch 'cattlethief' into 'master'
Fix AI issues with Command spells

Closes #5331

See merge request OpenMW/openmw!4599
2025-07-01 21:18:09 +00:00
psi29a
0a44112dcc Merge branch 'charactername' into 'master'
Revise saved game dialog save info layout (#8313)

Closes #8313

See merge request OpenMW/openmw!4545
2025-07-01 21:17:21 +00:00
psi29a
0d308eae3e Merge branch 'spell____prices' into 'master'
Spell buying window layout tweaks

See merge request OpenMW/openmw!4571
2025-07-01 21:07:03 +00:00
psi29a
48e386bf90 Merge branch 'merchantrepairrepaired' into 'master'
Merchant repair menu layout tweaks

See merge request OpenMW/openmw!4588
2025-07-01 21:06:00 +00:00
psi29a
c9f6bdb6e0 Merge branch '__travel_____' into 'master'
Fix Travel window header alignment

See merge request OpenMW/openmw!4569
2025-07-01 21:04:20 +00:00
Cody Glassman
514174ffc4 allow handles to be fetched for non-dynamic shaders 2025-07-01 14:03:41 -07:00
Cody Glassman
feeb15d1ff use table instead of vector in return type 2025-07-01 14:03:41 -07:00
Cody Glassman
179341b221 add changelog entry 2025-07-01 14:03:40 -07:00
Cody Glassman
450f587844 lua - add ability to query the currently active shaders 2025-07-01 14:02:48 -07:00
psi29a
33ca7da731 Merge branch 'balmora__________-__________-69gp' into 'master'
Remove excessive spacing between travel destination and price

See merge request OpenMW/openmw!4568
2025-07-01 21:01:26 +00:00
Cody Glassman
2619859786 fix invalid deletion for shaders 2025-07-01 13:58:28 -07:00
psi29a
50f8bc721d Merge branch 'stupidfilters' into 'master'
Bring dialogue filters in line with Morrowind.exe

Closes #8318

See merge request OpenMW/openmw!4525
2025-07-01 20:52:37 +00:00
psi29a
d31ac93c69 Merge branch 'itemwidgetbg' into 'master'
Clip HUD item widgets to not overlap the borders (#7740)

Closes #7740

See merge request OpenMW/openmw!4586
2025-07-01 20:50:24 +00:00
psi29a
9347fe5c4a Merge branch 'tbcornottbcwaititstcbactually' into 'master'
Implement TCB interpolation for vectors and scalars (#2379)

See merge request OpenMW/openmw!4539
2025-07-01 20:46:47 +00:00
psi29a
2ffc44c31f Merge branch 'filenameexceptions' into 'master'
Remove file name naming convention check exceptions (#7249)

Closes #7249

See merge request OpenMW/openmw!4551
2025-07-01 20:45:33 +00:00
psi29a
2b0e5c3cc1 Merge branch 'enchantment_exclamationmark' into 'master'
Allow GetSpellEffects to detect enchantments by id

Closes #3769

See merge request OpenMW/openmw!4521
2025-07-01 20:40:08 +00:00
AnyOldName3
5ab73f5ecb t t t t t t t typo fix 2025-07-01 21:24:45 +01:00
psi29a
ac7b3e9de9 Merge branch 'itshappening' into 'master'
Bump us up to 0.50.0

See merge request OpenMW/openmw!4502
2025-07-01 20:23:24 +00:00
epochwon
c89b2b0c60 fix indenting 2025-07-01 10:42:42 -04:00
psi29a
675146bd8b Merge branch 'sellmesweetlittlecrashes' into 'master'
Clear the window manager before destroying singletons

Closes #8576

See merge request OpenMW/openmw!4727
2025-07-01 11:41:15 +00:00
psi29a
eca9b84f39 Merge branch 'shortcutsv' into 'master'
Use string_view in CSMPrefs::ShortcutManager

See merge request OpenMW/openmw!4729
2025-07-01 11:40:21 +00:00
Evil Eye
2ff497c3e5 Use string_view in CSMPrefs::ShortcutManager 2025-06-29 12:49:22 +02:00
Evil Eye
cbb50c001b Destroy the script manager after the window manager 2025-06-28 11:25:19 +02:00
Cody Glassman
8ed5d84ff7 docs - update theme in requirements.txt 2025-06-27 07:11:45 -07:00
Cody Glassman
c4506d2d67 docs - add missing inherited fields and events to widgets 2025-06-26 18:37:46 -07:00
epochwon
13f1b76a25 tabs to spaces 2025-06-25 17:23:04 -04:00
epochwon
fdc878d766 elongate specular highlight 2025-06-25 17:04:21 -04:00
Cody Glassman
759cea3051 docs - advanced settings 2025-06-23 17:39:01 -07:00
psi29a
164563f522 Merge branch 'intel-mac-builds' into 'master'
[CI] Add intel mac build with separate build step

See merge request OpenMW/openmw!4718
2025-06-23 08:59:11 +00:00
psi29a
d49a42037a Merge branch 'fix_docs' into 'master'
Fix some errors in Lua docs

See merge request OpenMW/openmw!4725
2025-06-23 06:52:12 +00:00
Cody Glassman
937f2bd441 docs - sphinx card colors 2025-06-22 15:56:16 -07:00
Andrew Lanzone
88b43cabec Reset controller focus when reopening container and quest menus 2025-06-22 14:47:54 -07:00
Andrew Lanzone
5777a3cc3f Update controller buttons shown for companion window 2025-06-22 14:44:32 -07:00
Sarah Sunday
493827285b [CI] Fix path and big env goof 2025-06-22 13:35:23 -05:00
Cody Glassman
ce8f81a6a7 docs - less blue dark 2025-06-22 09:54:11 -07:00
Cody Glassman
8301dafad1 docs - remove ugly blue in dark mode links 2025-06-22 09:31:55 -07:00
Sarah Sunday
50e3c9d500 [CI] Ccache flow tweak, use forked commands, cd build 2025-06-22 10:35:16 -05:00
Andrei Kortunov
4bbc5710fb Fix some errors in Lua docs 2025-06-22 15:11:49 +04:00
Evil Eye
a524b3c9b0 Merge branch 'clangcast' into 'master'
Export symbols for openmw binary under Clang (#8039)

Closes #8039

See merge request OpenMW/openmw!4722
2025-06-22 06:17:25 +00:00
Andrew Lanzone
fb5fa6ce18 Fix controller tooltip disappearing because of spurious controller input 2025-06-21 22:04:35 -07:00
Andrew Lanzone
c41f034a23 Scroll the list of topics in controller mode 2025-06-21 21:34:11 -07:00
Sarah Sunday
adc4698c44 [CI] Revert ccache script forking, rename try, cleanup 2025-06-21 21:19:07 -05:00
Sarah Sunday
faa9af4428 [CI] Overhaul mac CI flow 2025-06-21 19:54:42 -05:00
Sarah Sunday
12f3596220 [CI] Specify intel brew location 2025-06-21 14:19:43 -05:00
Sarah Sunday
139bde6420 [CI] Fork before install mac arm/intel steps, prefix with arch command 2025-06-21 13:53:40 -05:00
Sarah Sunday
0f551c8233 [CI] Always use arm deps 2025-06-21 13:41:51 -05:00
Sarah Sunday
608831265c [CI] Attempt to add intel mac builds with separate build step 2025-06-21 13:41:51 -05:00
Alexei Kotov
acd4e77a85 Merge branch 'revert-0589b57a' into 'master'
Revert "Merge branch 'landscape-data-bindings' into 'master'"

See merge request OpenMW/openmw!4723
2025-06-21 20:25:37 +03:00
Alexei Kotov
3ff7dedfd1 Revert "Merge branch 'landscape-data-bindings' into 'master'"
This reverts merge request !4500
2025-06-21 19:03:11 +03:00
Cody Glassman
0589b57a47 Merge branch 'landscape-data-bindings' into 'master'
Landscape height and texture bindings for Lua (Revised)

See merge request OpenMW/openmw!4500
2025-06-21 08:49:38 -07:00
psi29a
8367604331 Merge branch 'path-delousing' into 'master'
Handle paths passed on the command line properly

Closes #8567

See merge request OpenMW/openmw!4721
2025-06-21 10:00:23 +00:00
Andrew Lanzone
9380233ab7 Merge branch 'master' of https://gitlab.com/enoznal/openmw 2025-06-20 23:39:03 -07:00
Andrew Lanzone
143c14c556 Merge branch openmw:master into master 2025-06-21 06:38:19 +00:00
Andrew Lanzone
190680a3a9 Replace semi-janky rstick controller bindings with dpad 2025-06-20 23:37:53 -07:00
Andrew Lanzone
2905ed5fb1 Fix controller selection of nested dialog choices 2025-06-20 22:41:39 -07:00
Cody Glassman
74c9da78d3 docs - dropdown toc 2025-06-20 17:23:03 -07:00
Cody Glassman
ac400f0ebc docs - dropdown toc 2025-06-20 17:17:13 -07:00
Cody Glassman
3abc86be73 docs - fix interfaces 2025-06-20 13:05:15 -07:00
Cody Glassman
320b2cf55e docs - adjust more ordering and add interfaces to package table 2025-06-20 13:00:30 -07:00
Sebastian Fieber
b1326e4554 update doc for getTextureAt 2025-06-20 22:00:02 +02:00
Cody Glassman
3bdf57f7c1 docs - support prism and reorder some TOC 2025-06-20 10:42:35 -07:00
Cody Glassman
79f18effdd docs - unhide a TOC 2025-06-20 06:23:54 -07:00
Cody Glassman
39917f1ebe docs - address more naming consistency with hyphens 2025-06-20 06:12:55 -07:00
Cody Glassman
8b56415597 docs - remove ligature usage in code blocks 2025-06-19 20:32:15 -07:00
Cody Glassman
cc5540039e docs - better contrast for luadoc 2025-06-19 19:32:57 -07:00
Sebastian Fieber
1ac407f32b fix rebase error 2025-06-19 22:17:26 +02:00
Sebastian Fieber
0e68e36aa7 that shouldn't have been touched 2025-06-19 22:17:26 +02:00
Sebastian Fieber
3207f3a387 clang-format 2025-06-19 22:17:26 +02:00
Sebastian Fieber
732fb4affe inline fillLandData and return empty table instead of throwing 2025-06-19 22:17:26 +02:00
Sebastian Fieber
03e4735b19 add #8112 to changelog 2025-06-19 22:17:26 +02:00
Sebastian Fieber
3e0685e4a6 don't double sample + only allow default worldspace 2025-06-19 22:17:26 +02:00
Sebastian Fieber
effb3de2a7 const 2025-06-19 22:17:26 +02:00
Sebastian Fieber
76e2c77517 check for lcell also 2025-06-19 22:17:26 +02:00
Sebastian Fieber
4ede868ed2 fix typo 2025-06-19 22:17:26 +02:00
Sebastian Fieber
8de0ccc82c remove redundant code 2025-06-19 22:17:26 +02:00
Sebastian Fieber
7c76387ffe no interior cell + make cellOrName mandatory 2025-06-19 22:17:26 +02:00
Sebastian Fieber
5d0986e812 Misc::NotNullPtr<MWWorld::ESMStore> to MWWorld::ESMStore& store 2025-06-19 22:17:26 +02:00
Sebastian Fieber
6671c12ad2 reorder of documentation for landbindings in core.lua 2025-06-19 22:17:26 +02:00
Sebastian Fieber
47453b307a no auto in landbindings.cpp 2025-06-19 22:17:26 +02:00
Sebastian Fieber
f3128f9c7b remove unused include 2025-06-19 22:17:26 +02:00
Sebastian Fieber
8954f45867 fixes for landbindings.cpp 2025-06-19 22:17:26 +02:00
Sebastian Fieber
fc772744d2 don't touch ESMTerrain::Storage 2025-06-19 22:17:26 +02:00
Sebastian Fieber
3d07b63ad8 don't copy store 2025-06-19 22:17:26 +02:00
Sebastian Fieber
940e73a356 landbindings - static to anonymous namespace + use references 2025-06-19 22:17:26 +02:00
Sebastian Fieber
ea02c69186 fix index check + cast to size_t 2025-06-19 22:17:26 +02:00
Sebastian Fieber
4182279f72 deduplication for landbindings.cpp + slight api changes
- remove textureId from return
- return plugin name instead of plugin id
2025-06-19 22:17:26 +02:00
Calandiel
dcf0c6e314 simplify texture retrieval for land bindings 2025-06-19 22:17:26 +02:00
Calandiel
901c6b94a6 remove unnecessary land loading 2025-06-19 22:17:26 +02:00
Calandiel
c711179b8f apply changes requested in the code review 2025-06-19 22:17:26 +02:00
Calandiel
378093791b update the docs for land functions 2025-06-19 22:17:26 +02:00
Sebastian Fieber
8917103bf3 put land bindings in a table in openmw.core 2025-06-19 22:17:26 +02:00
Calandiel
336275292e reorder includes 2025-06-19 22:17:26 +02:00
Calandiel
3b962e3fd4 reorder includes 2025-06-19 22:17:26 +02:00
Calandiel
22a0dce4a6 reorder includes 2025-06-19 22:17:26 +02:00
Calandiel
fe68a098ea reorder includes 2025-06-19 22:17:26 +02:00
Sebastian Fieber
1521d5195a add bindings for land textures 2025-06-19 22:17:26 +02:00
Calandiel
283be9f4f0 add docs for the new binding 2025-06-19 22:17:26 +02:00
Calandiel
910690c7e5 expose a terrain height getter 2025-06-19 22:17:26 +02:00
AnyOldName3
71d334fe79 Fix MacOS even more 2025-06-19 19:55:26 +01:00
Cody Glassman
d500f801cc docs - support flyout selector addon 2025-06-19 10:12:59 -07:00
AnyOldName3
bee9716262 Fix getLocalPath for MacOS 2025-06-19 16:32:21 +01:00
Alexei Kotov
5938ba528f Export symbols for openmw binary under Clang (#8039) 2025-06-19 14:43:10 +03:00
Andrew Lanzone
50e5863749 Use shoulder buttons on wait menu, similar to other slider menus 2025-06-18 19:46:22 -07:00
Cody Glassman
b0fb0024bc docs - fix padding to accomodate hidden element 2025-06-18 17:58:38 -07:00
Cody Glassman
37e0566745 docs - upgrade theme 2025-06-18 17:48:09 -07:00
AnyOldName3
323ee5f79d Remove a line break that clang-format was fussing about 2025-06-19 00:27:08 +01:00
AnyOldName3
f7b8091117 Add missing semicolon 2025-06-19 00:23:52 +01:00
AnyOldName3
276e0e6765 Remove vestigial include 2025-06-19 00:22:58 +01:00
AnyOldName3
9a28216cda Update changelog 2025-06-19 00:19:22 +01:00
AnyOldName3
acbc0a9b8f Fix launching other binaries when the CWD is not the binary directory 2025-06-19 00:19:14 +01:00
Cody Glassman
fa0b3a04df docs - change theme for luadoc monospace to match theme 2025-06-18 10:29:05 -07:00
psi29a
efbef1ec96 Merge branch 'nonusercontent' into 'master'
Handle implicitly checked files more consistently (#8563)

See merge request OpenMW/openmw!4716
2025-06-18 15:53:34 +00:00
Cody Glassman
dab2538e0c docs - unify usage of code blocks in install openmw 2025-06-18 06:33:14 -07:00
Cody Glassman
638ceb73b7 docs - fix layout shift when expanding TOC 2025-06-18 06:16:09 -07:00
Cody Glassman
23a6208537 Revert "docs - chevron 7 locked"
This reverts commit 4e32e9f127.
2025-06-17 21:05:41 -07:00
Cody Glassman
4e32e9f127 docs - chevron 7 locked 2025-06-17 21:01:03 -07:00
Cody Glassman
b7a1f76f4d docs - make table headers real headers 2025-06-17 18:22:26 -07:00
Cody Glassman
cd1bd0eeaf docs - enable scroll to top widget 2025-06-17 18:01:49 -07:00
Cody Glassman
d81c666a2c docs - increase width of left TOC on large screens 2025-06-17 17:59:30 -07:00
Cody Glassman
45d73957c1 docs - style left TOC scroll 2025-06-17 17:55:52 -07:00
Cody Glassman
733631a771 docs - more styling 2025-06-17 17:39:10 -07:00
Cody Glassman
36941bf4e9 docs - add table hover highlight and increase max width 2025-06-17 16:31:18 -07:00
Cody Glassman
49a651761f docs - clean up styles and add comments for each override 2025-06-17 16:14:19 -07:00
Cody Glassman
e649498f06 docs - adjust styling for em 2025-06-17 15:54:04 -07:00
Cody Glassman
4032f4e06c docs - more restructuring 2025-06-17 11:42:13 -07:00
Cody Glassman
8439ac1b4e docs - revert bump in sphinx version 2025-06-17 11:05:08 -07:00
Cody Glassman
766b8f3145 docs - more restructuring 2025-06-17 11:03:55 -07:00
Alexei Kotov
5cc5307c10 Merge branch 'upgrade-mac-qt6' into 'master'
[CI] Mac - use qt@6

See merge request OpenMW/openmw!4719
2025-06-17 19:12:37 +03:00
Alexei Kotov
4a6d2465b4 Remove Qt PATH adjustment (Qt6 is symlinked) 2025-06-17 19:11:39 +03:00
Cody Glassman
30b27c966f docs - switch to awesome sphinx theme 2025-06-17 08:44:15 -07:00
psi29a
323e83784f Merge branch 'master' into 'master'
Changed desktop files to appropriately use StartupWMClass. What this does is...

See merge request OpenMW/openmw!4714
2025-06-17 07:52:32 +00:00
Claire
f84983a5d4 Changed desktop files to appropriately use StartupWMClass. What this does is... 2025-06-17 07:52:31 +00:00
Cody Glassman
1de86f95ac docs - slightly less ugly dark mode code blocks 2025-06-16 16:41:37 -07:00
Cody Glassman
f9af61f096 docs - use shortened context for player 2025-06-16 16:35:24 -07:00
Cody Glassman
21cf7bb397 docs - add context tags to interfaces and aux packages 2025-06-16 16:32:51 -07:00
AnyOldName3
2ce4571c3a Handle paths passed on the command line properly
Fixes https://gitlab.com/OpenMW/openmw/-/issues/8567.

Also maybe horribly breaks lots of things because it removes some insanity from https://gitlab.com/OpenMW/openmw/-/merge_requests/86, which would set the CWD to the local directory just in case any local-relative paths were expressed relatively without the explicit base being the local path.
2025-06-17 00:26:06 +01:00
Cody Glassman
132ff5294c docs - bump documentor commit 2025-06-16 16:19:20 -07:00
Cody Glassman
522a572032 docs - clean up styling for dark mode 2025-06-16 16:05:43 -07:00
Cody Glassman
49865b1aa1 docs - fix package version and logo 2025-06-16 15:55:59 -07:00
Cody Glassman
8d7bdc2e61 docs - remove unused sphinx theme from requirements.txt 2025-06-16 15:39:49 -07:00
Cody Glassman
302d92561d docs - begin restructing docs 2025-06-16 15:36:43 -07:00
Sarah Sunday
6d89ae1a75 [CI] Mac - use qt@6 2025-06-14 16:09:07 -05:00
Andrew Lanzone
0a03403277 Fix closing dialogue when a choice is active; improve scrolling 2025-06-14 13:42:51 -07:00
Andrew Lanzone
8d545a43d5 Scrolll the list of quests in controller mode 2025-06-14 13:14:32 -07:00
Andrew Lanzone
ef651ee187 Update swedish translation for putting an item in a container 2025-06-14 13:13:36 -07:00
Alexei Kotov
e7305e7c97 Merge branch 'colorfullights' into 'master'
Use the Color type for Light colours in Lua

Closes #8558

See merge request OpenMW/openmw!4715
2025-06-14 00:36:45 +03:00
Alexei Kotov
780a4904bd Handle implicitly checked files more consistently (#8563) 2025-06-13 22:14:08 +03:00
Andrew Lanzone
0502366be9 Merge branch openmw:master into master 2025-06-13 04:44:05 +00:00
Andrew Lanzone
b4ede02cce Move hardcoded strings to i10n 2025-06-12 21:43:01 -07:00
Alexei Kotov
019af35278 Merge branch 'ESSImportRegression' into 'master'
Import ESS kill count / selected spell as RefIDs, handle old INFO records

Closes #8559

See merge request OpenMW/openmw!4712
2025-06-12 23:28:15 +03:00
Aussiemon
f085717aef Import ESS kill count / selected spell as RefIDs, handle old INFO records 2025-06-12 23:28:14 +03:00
Evil Eye
45a51bceb2 Implement equal_to for Color 2025-06-12 17:48:11 +02:00
Evil Eye
be0cbb7277 Use the Color type for Light colours in Lua 2025-06-12 17:17:28 +02:00
Andrew Lanzone
e01b8d372c In controller mode, make focused spell blue to match other menus 2025-06-11 23:16:08 -07:00
Alexei Kotov
b988190fba Merge branch 'add-missing-line-break' into 'master'
Add missing line break

See merge request OpenMW/openmw!4713
2025-06-11 16:22:55 +03:00
AnyOldName3
d8c764ba5a Add missing line break
The bullet points don't render correctly without it.
2025-06-11 14:02:58 +01:00
psi29a
5163214878 Merge branch 'readfileqlists' into 'master'
Optimize value deduping in Qt openmw.cfg loading

See merge request OpenMW/openmw!4708
2025-06-11 09:37:56 +00:00
psi29a
d2e7da0c19 Merge branch 'crash-catcher-errors' into 'master'
Emit visible errors when crash dump creation fails

See merge request OpenMW/openmw!4711
2025-06-11 07:26:11 +00:00
Andrew Lanzone
1e3ddee291 Remove default string when creating a potion that won't work 2025-06-10 21:42:51 -07:00
AnyOldName3
a179001052 Empty commit 2025-06-10 14:48:24 +01:00
Alexei Kotov
0df8869f59 Cache computed supported directions
Invalidated when animation sources are cleared or added
2025-06-10 12:09:59 +03:00
Andrew Lanzone
47b3674bac Update controller focus to use a message box's default focus if available 2025-06-09 22:03:12 -07:00
Andrew Lanzone
57ae097257 Add controller support to the companion window; also fix giving stacks 2025-06-09 19:23:49 -07:00
Andrew Lanzone
4e2e8d1a81 Apply 1 suggestion(s) to 1 file(s)
Co-authored-by: Joakim Berg <zapp90@gmail.com>
2025-06-10 01:08:04 +00:00
AnyOldName3
7347f4f4e3 Some review stuff 2025-06-09 14:13:50 +01:00
AnyOldName3
9010a5bb32 Emit visible errors when crash dump creation fails
Also possibly fix the errors, as I was getting them when I started testing, and then wasn't by the time I'd got the code how I wanted it.
However, nothing in this commit looks like it *should* fix any errors.
2025-06-09 00:20:58 +01:00
Andrew Lanzone
f6b06057fa Fix clang warning 2025-06-08 13:51:09 -07:00
Andrew Lanzone
8094761c3e Fix sign-compare warnings 2025-06-08 02:28:42 -07:00
Andrew Lanzone
81720892f9 Fix compiler warnings 2025-06-08 00:10:47 -07:00
Andrew Lanzone
ba9d85dc30 Run lupdate and add translations 2025-06-07 23:18:48 -07:00
Andrew Lanzone
be32cbb413 Fix clang format issues 2025-06-07 22:51:29 -07:00
Andy Lanzone
0ca6bc012c
Merge branch 'OpenMW:master' into master 2025-06-07 20:39:57 -07:00
Alexei Kotov
de158a476c Optimize value deduping in Qt openmw.cfg parsing 2025-06-07 11:37:57 +03:00
Andrew Lanzone
ea70f2b5c2 Show tooltips in controller mode on spell menus 2025-06-07 00:35:46 -07:00
psi29a
1c242425b0 Merge branch 'finite_number' into 'master'
Reduce code duplication for finite number and add tests

See merge request OpenMW/openmw!4707
2025-06-06 22:14:32 +00:00
psi29a
85742a190a Merge branch 'animatedmenus' into 'master'
Render openmw.animation inaccessible in menu and global scripts

See merge request OpenMW/openmw!4674
2025-06-06 12:21:01 +00:00
Andrew Lanzone
b1989ffdf7 Limit size of inventory menu in controller mode 2025-06-06 00:34:42 -07:00
Andrew Lanzone
b2a5ded929 Fix scrolling list of items to repair or recharge 2025-06-06 00:34:23 -07:00
Andrew Lanzone
dc68f28a40 Disable right stick from panning map if zooming maps is enabled 2025-06-06 00:34:01 -07:00
elsid
267ce1ec9b
Reduce code duplication for finite number 2025-06-06 00:05:07 +02:00
elsid
178f216317
Add Lua test for passing a NaN value 2025-06-05 23:58:41 +02:00
Evil Eye
c05d2d1d38 Restrict openmw.animation to local scripts 2025-06-05 20:15:40 +02:00
Evil Eye
360abd9b90 Render openmw.animation inaccessible in menu scripts 2025-06-05 20:13:36 +02:00
psi29a
093b562f58 Merge branch 'moreFiniteFreezes' into 'master'
Protect more bindings from non-finite numbers

See merge request OpenMW/openmw!4704
2025-06-05 11:31:39 +00:00
Aussiemon
0d96d71be6 Change World.setGameTimeScale to float 2025-06-04 11:40:53 -06:00
Andrew Lanzone
c35e0d7336 Add menu click sounds to some menus when activated by the controller 2025-06-03 21:57:43 -07:00
Andrew Lanzone
2dfe1ef7b1 Show L1 and R1 buttons next to tabs 2025-06-03 21:23:21 -07:00
Andrew Lanzone
ae676e1d70 Fix not checking bounds in some controller menus 2025-06-03 20:17:53 -07:00
Aussiemon
e2cf80e3a6 Protect more bindings from non-finite numbers 2025-06-03 19:34:10 -06:00
Andrew Lanzone
a824993a60 Fix controller tooltips in magic menu appearing for wrong spell 2025-06-03 08:56:39 -07:00
Andrew Lanzone
a6d03717cb Hide cursor icon when showing controller tooltips 2025-06-03 00:44:45 -07:00
psi29a
cf258821b4 Merge branch 'hexplusone' into 'master'
Correctly format single digit hex values

Closes #8541

See merge request OpenMW/openmw!4700
2025-06-03 06:41:04 +00:00
psi29a
a74b6690a7 Merge branch 'linearbloom' into 'master'
Avoid negative base pow UB in linear bloom

See merge request OpenMW/openmw!4702
2025-06-03 06:40:40 +00:00
Andy Lanzone
43b5176367
Merge branch 'OpenMW:master' into master 2025-06-02 00:47:04 -07:00
Andrew Lanzone
e50822d1d2 Remember the selected dialog topic when new topics are added to the list 2025-06-02 00:41:09 -07:00
Andrew Lanzone
6da6b9b98f Update controller support for scroll window to use the keybaord for smoother scrolling 2025-06-02 00:17:10 -07:00
Andrew Lanzone
8ae193abe8 Fix issue when selecting an inventory item with the tooltip visible 2025-06-02 00:11:01 -07:00
psi29a
1fff2f0199 Merge branch 'setnew' into 'master'
Don't use item(QString) while marking new content files

See merge request OpenMW/openmw!4701
2025-06-02 07:08:05 +00:00
Andrew Lanzone
21286aa376 Change 'Back' to 'Cancel' in button prompts to match windows 2025-06-01 23:27:49 -07:00
Andy Lanzone
51f9ce890e
Merge branch 'OpenMW:master' into master 2025-06-01 22:57:37 -07:00
Andrew Lanzone
6bb92c0589 Clean up logs 2025-06-01 22:55:21 -07:00
Andrew Lanzone
ea71a0bb4f Make controller selection wrap in inventory or containers 2025-06-01 22:13:58 -07:00
Andrew Lanzone
df237b5f9b Add controller support to quick key menu 2025-06-01 21:34:20 -07:00
Andrew Lanzone
2aa9847b24 Update controller buttons for character creation and level up 2025-06-01 16:27:49 -07:00
Andrew Lanzone
263863f3f2 Fix modals opening above inventory causing it to change size 2025-06-01 16:22:22 -07:00
Alexei Kotov
7113cef501 Avoid negative x pow UB in linear bloom 2025-06-02 00:59:32 +03:00
Alexei Kotov
ecc9e8f5cd Merge branch 'silencedcode' into 'master'
Remove dead code

See merge request OpenMW/openmw!4699
2025-06-01 23:23:35 +03:00
psi29a
79a2735e19 Merge branch 'datachanged' into 'master'
Launcher: Reload cells after a short delay (#8478)

See merge request OpenMW/openmw!4664
2025-06-01 10:47:23 +00:00
psi29a
65155a6e6a Merge branch 'datachangedcalls' into 'master'
Content selector: Cut down on unnecessary dataChanged calls (#8478)

See merge request OpenMW/openmw!4671
2025-06-01 10:46:45 +00:00
Andrew Lanzone
95ed6b51da Allow navigating journal indices with a controller 2025-06-01 01:49:57 -07:00
Andrew Lanzone
63a533cd51 Add controller support to the level up dialog 2025-05-31 20:23:29 -07:00
Andrew Lanzone
e3a9b71bb9 Add helper function for toggling controller focus on lists 2025-05-31 19:43:28 -07:00
Andrew Lanzone
2dc1d8fed7 Add controller support to merchant repair window 2025-05-31 19:24:27 -07:00
Andrew Lanzone
cbe74cdab4 Add controller support to repair and recharge menus 2025-05-31 18:58:30 -07:00
Alexei Kotov
3dfc3d7022 Don't use item(QString) while marking new content files 2025-06-01 03:22:18 +03:00
Andrew Lanzone
d3c7904e64 Rename controller help function in item view 2025-05-31 16:34:07 -07:00
Andrew Lanzone
5276d7bab2 Several tweaks to the inventory menu 2025-05-31 16:02:13 -07:00
Andy Lanzone
6185683ca3
Merge branch 'OpenMW:master' into master 2025-05-31 15:29:25 -07:00
Andrew Lanzone
2d532100eb Add controller supoprt to enchanting menu 2025-05-31 15:28:13 -07:00
Andrew Lanzone
40441a065a Add controller support to alcmhemy menu 2025-05-31 11:58:35 -07:00
Evil Eye
9929c35021 Correctly format single digit hex values 2025-05-31 15:43:50 +02:00
Evil Eye
4e8a713819 Remove dead code 2025-05-31 15:26:11 +02:00
Andrew Lanzone
d18413f63a Add controller support to spell making window 2025-05-30 01:10:57 -07:00
psi29a
0c6c71f6cb Merge branch 'qprogressbar' into 'master'
Increment some new Qt progress bars the canonical way

See merge request OpenMW/openmw!4698
2025-05-30 07:22:35 +00:00
psi29a
ed03babb08 Merge branch 'consolesearch' into 'master'
Uncursify forward/reverse console search (#8532)

Closes #8532

See merge request OpenMW/openmw!4697
2025-05-30 07:21:26 +00:00
Alexei Kotov
e7976a544a Increment some new Qt progress bars the canonical way 2025-05-29 03:33:03 +03:00
Alexei Kotov
f7a33d24e2 Uncursify forward/reverse console search (#8532)
Correct search start/end calculation, give normal search the memo that the end iterator's meaning changed and fix broken invalid range guards.
2025-05-28 22:11:22 +03:00
Andrew Lanzone
af27e9e5d6 Allow shoulder buttons to jump count slider to either extreme 2025-05-27 22:51:03 -07:00
Andrew Lanzone
451d68461c Add controller support to skill and attribute menus 2025-05-27 22:40:00 -07:00
Alexei Kotov
b0d389319c Merge branch 'layer_desync' into 'master'
Prevent conflicts between UI layer insertions

See merge request OpenMW/openmw!4696
2025-05-27 17:45:11 +03:00
uramer
32169155bb Fix before insert index 2025-05-27 11:56:16 +00:00
Andrew Lanzone
f67aae086a Improve scrolling in list windows and fix a crash in a few menus when no items are selectable 2025-05-26 23:07:20 -07:00
Andrew Lanzone
274434e0d6 Add controller support to travel window 2025-05-26 22:52:10 -07:00
Andrew Lanzone
14b0c9afbe Add controller support to barter window 2025-05-26 21:08:05 -07:00
psi29a
8060a89bf6 Merge branch 'CameraSetYawCrash' into 'master'
Prevent hard freeze when camera receives invalid inputs from Lua

Closes #8503

See merge request OpenMW/openmw!4681
2025-05-26 07:22:11 +00:00
Aussiemon
d2f1eeff98 Prevent hard freeze when camera receives invalid inputs from Lua 2025-05-26 07:22:10 +00:00
Andrew Lanzone
71fd8b8840 Add controller support to spell buying and training windows 2025-05-25 23:14:13 -07:00
Andrew Lanzone
cd745c7df3 Swap some controller button assignments 2025-05-25 22:51:43 -07:00
Andrew Lanzone
25fa9484d3 Add a default save game name in controller mode 2025-05-25 22:08:43 -07:00
Andrew Lanzone
d6ed416402 Allow pinning map window in controller mode 2025-05-25 16:12:19 -07:00
uramer
b7b6a41aec Bump API revision 2025-05-25 12:32:31 +02:00
uramer
fa3e8ea74d Prevent conflicts between UI layer insertions 2025-05-25 12:32:29 +02:00
Andrew Lanzone
45de167b6b Adjust layer of controller button overlay so it doesn't hide tooltips 2025-05-24 21:29:06 -07:00
Andrew Lanzone
d6c23f7664 Add controller support to map's node dialog 2025-05-24 21:28:43 -07:00
Andrew Lanzone
cf26020ed6 Fix several minor issues with controller inventory menus 2025-05-24 20:56:43 -07:00
Andrew Lanzone
3eec24b2a6 Limit the size of controller-focused inventory windows on large screens 2025-05-24 20:08:45 -07:00
Andrew Lanzone
f1c34ea7b1 Add a tab bar above inventory to show active tab and change tabs with mouse 2025-05-24 16:00:13 -07:00
Andrew Lanzone
d759418f01 Add controller support for all four inventory menus 2025-05-24 14:17:41 -07:00
psi29a
8a10de5fed Merge branch 'kaamatan-seminggu-lagi-8165' into 'master'
Remove redundant activate check in `activateBy` #8165

See merge request OpenMW/openmw!4690
2025-05-24 12:35:09 +00:00
Kuyondo
86783e8758 also for creatures 2025-05-23 23:46:42 +08:00
Kuyondo
2df7ded814 respawning npc respawns in origin cell 2025-05-23 18:15:24 +08:00
psi29a
42ca8e31eb Merge branch 'equipunequip' into 'master'
Allow equip attach/detach keys to coincide with the start key

See merge request OpenMW/openmw!4691
2025-05-23 07:26:58 +00:00
psi29a
a8334a237b Merge branch 'supernamespace' into 'master'
Fix compilation on MSVC

See merge request OpenMW/openmw!4692
2025-05-23 07:25:07 +00:00
Aussiemon
192cf1535b Fix second instance of mPickpocketDetected set after use 2025-05-22 16:10:05 -06:00
Aussiemon
b5aaf4ca30 Fix mPickpocketDetected flag being set after use 2025-05-22 16:03:52 -06:00
Evil Eye
5cf8191cea Fix compilation on MSVC 2025-05-22 17:31:33 +02:00
Alexei Kotov
e3daff7b17 Support extended selection in the directory picker (#8113) 2025-05-22 15:49:54 +03:00
Alexei Kotov
e8b0ee874f Launcher: Reload cells after a short delay (#8478) 2025-05-22 15:42:56 +03:00
Alexei Kotov
2342dbe0f5 Merge branch 'fix_launcher_ui_freeze' into 'master'
Make launcher UI on content files selection more responsive (#8478)

See merge request OpenMW/openmw!4682
2025-05-22 15:37:23 +03:00
psi29a
6ef3c089bf Merge branch 'flagsgamefiles' into 'master'
Make the horrifying content model flags() game search less horrifying (#8478)

See merge request OpenMW/openmw!4688
2025-05-22 09:45:30 +00:00
elsid
157e8c763c
Show progress dialog for setting content list 2025-05-22 07:47:58 +02:00
elsid
3955428f87
Show progress dialog on updating content selection 2025-05-22 07:47:38 +02:00
Alexei Kotov
9387f50f77 Allow equip attach/detach keys to coincide with the start key 2025-05-22 04:53:34 +03:00
Alexei Kotov
5ffcd21eee Content selector: Cut down on unnecessary dataChanged calls (#8478)
setData shouldn't do dataChanged calls setCheckState already does
setCheckState should emit dataChanged for downstream dependencies unconditionally
setCheckState shouldn't emit dataChanged for upstream dependencies that weren't enabled
2025-05-22 01:01:41 +03:00
elsid
0fc22b2b2d
Check selected files existence in the reload cells thread
This reduces UI reponse time.
2025-05-21 22:11:22 +02:00
Kuyondo
b7a7936dd6 api revision 73 to 74 2025-05-22 02:49:45 +08:00
Kuyondo
30da6dc508 allow activateBy to trigger handlers 2025-05-22 02:45:29 +08:00
Andrew Lanzone
5e3a49ade5 Make right stick scroll dialog history 2025-05-20 22:41:17 -07:00
Andrew Lanzone
ba0a579371 Play correct sound and update button overlay when swapping between menus 2025-05-20 19:32:13 -07:00
psi29a
b7a48e1d78 Merge branch 'disable-shadows-even-harder' into 'master'
Disable shadows even harder

Closes #8514

See merge request OpenMW/openmw!4686
2025-05-20 14:12:57 +00:00
Alexei Kotov
2c6d11f95e Make the horrifying content model flags() game search less horrifying
Properly exit early and cache game file check result
2025-05-20 16:15:16 +03:00
Andrew Lanzone
23c733ef94 Use wrap helper function to simplify some controller handler logic 2025-05-20 00:27:14 -07:00
Andrew Lanzone
f03f242e4a Allow controller to select choice text in dialogue 2025-05-20 00:12:34 -07:00
Andrew Lanzone
f36401438f Move wrap function to windowbase so all windows can use it 2025-05-19 23:43:28 -07:00
AnyOldName3
47fff7f998 Disable shadows even harder
On GPUs that can detect when all fragments in an execution group take the same branch, this might run faster. Even if it doesn't, it might suppress any weirdness coming from sampling the dummy shadow maps.
2025-05-19 15:06:19 +01:00
Andrew Lanzone
0aad0d379a Minimal controller support for dialog window 2025-05-18 22:45:22 -07:00
Andrew Lanzone
a144793753 Fix Y button changing character 2025-05-18 22:45:03 -07:00
Andrew Lanzone
f80d46dc94 Add controller support to count dialog 2025-05-18 15:34:22 -07:00
Evil Eye
045640303f Merge branch 'cleanup/menu-interfaces' into 'master'
FIX: Correctly describe interface availability of menu scripts

See merge request OpenMW/openmw!4683
2025-05-18 16:45:40 +00:00
Evil Eye
f32d62def8 Merge branch 'setcheckstateesmfile' into 'master'
Avoid repeated item(QString) in plugin toggling-related code

See merge request OpenMW/openmw!4678
2025-05-18 16:41:46 +00:00
Andrew Lanzone
f15cc663ae Remove old way of listening for gamepad mouse events 2025-05-18 01:42:11 -07:00
Andrew Lanzone
33a6189f7a Consolidate all gamepad cursor listening in controllermanager 2025-05-18 01:27:38 -07:00
Andrew Lanzone
e01291ec4a Add whole set of button icons 2025-05-17 22:32:03 -07:00
Dave Corley
b006cb9846 FIX: Correctly describe interface availability of menu scripts 2025-05-17 07:04:23 -07:00
Evil Eye
a7a072e3f8 Merge branch 'qfileinfo' into 'master'
Avoid unnecessary file system access in plugin toggling

See merge request OpenMW/openmw!4679
2025-05-17 10:25:02 +00:00
Evil Eye
52b3e0688a Merge branch 'refreshmodel' into 'master'
Fix out-of-bounds index dataChanged calls

See merge request OpenMW/openmw!4677
2025-05-17 10:24:58 +00:00
Andrew Lanzone
c0694d3c0e Add overlay showing what controller buttons do 2025-05-16 21:41:28 -07:00
Alexei Kotov
f7f5665588 Avoid repeated item(QString) in plugin toggling-related code 2025-05-15 23:17:17 +03:00
Alexei Kotov
89d6408587 Avoid unnecessary file system access in plugin toggling 2025-05-15 23:00:08 +03:00
Alexei Kotov
54eea09a9e Fix out-of-bounds index dataChanged calls 2025-05-15 21:18:10 +03:00
Andrew Lanzone
8c2ecc2a88 Allow LT and RT to toggle between open gui windows 2025-05-15 00:46:02 -07:00
Andrew Lanzone
f055ccf5ba Update item view to allow controller support; test it in Container menu 2025-05-14 02:31:32 -07:00
psi29a
6d97ea01b2 Merge branch 'packageusage' into 'master'
Update can be used column

See merge request OpenMW/openmw!4670
2025-05-13 20:30:46 +00:00
psi29a
0251b7c820 Merge branch 'uneventful' into 'master'
Don't trigger cell change logic when the player isn't changing cells

Closes #8469

See merge request OpenMW/openmw!4657
2025-05-13 20:30:28 +00:00
Andrew Lanzone
77e17743f7 Only use bumpers to turn pages in books 2025-05-12 22:37:11 -07:00
Andrew Lanzone
65bab3858a Add basic controller support to scrolls 2025-05-12 22:36:28 -07:00
Andrew Lanzone
9a72ecb61c Don't close a book with A 2025-05-12 20:32:59 -07:00
Andrew Lanzone
9aff9cb48e Swap Topics and Quests buttons 2025-05-12 20:31:15 -07:00
Andrew Lanzone
07be682b88 Better controller support for journal; mouse for topic index A-Z 2025-05-12 20:10:13 -07:00
Andrew Lanzone
fa52fea59b Better joystick/mouse coordination in save game diaglog 2025-05-12 20:09:24 -07:00
Andrew Lanzone
a78bdee941 Reset selected button when confirmation dialog is reopened 2025-05-12 20:08:47 -07:00
Andrew Lanzone
4bad7a3074 Update character creation controller support to work better with gamepad mouse mode 2025-05-12 02:20:28 -07:00
Andrew Lanzone
83162477ec Basic controller support for all character creation windows 2025-05-12 01:34:28 -07:00
Andrew Lanzone
c4a87cfe4d Fix selecting saves with mouse controller 2025-05-11 22:59:11 -07:00
Andrew Lanzone
8f415ceab6 Convert UI widgets to local scrollbar implementation 2025-05-11 22:30:58 -07:00
Andrew Lanzone
b2620c861a Add scrollbar override to capture mouse hover events 2025-05-11 22:24:05 -07:00
Andrew Lanzone
5e7761bef1 Add controller support to text input menu 2025-05-11 14:56:58 -07:00
Andrew Lanzone
1e200ed048 Add controller support to race menu 2025-05-11 14:48:42 -07:00
Andrew Lanzone
c9ce93a22f Controller menus: don't wrap focus when only two buttons 2025-05-11 13:48:50 -07:00
Evil Eye
9756d3d84f Update can be used column 2025-05-11 13:38:39 +02:00
Andrew Lanzone
4c5db612f0 Improve controller support for confirmation dialogs by highlighting selected choice 2025-05-11 00:32:29 -07:00
Andrew Lanzone
3b42d02cfc Add controller support to message boxes 2025-05-11 00:20:31 -07:00
Andrew Lanzone
80166cddd0 Make main menu honor controller mouse clicks 2025-05-11 00:19:01 -07:00
Andrew Lanzone
be298f78cb Basic controller support for the books 2025-05-10 23:17:23 -07:00
Andrew Lanzone
bb88becc2b Basic controller support for the journal 2025-05-10 22:50:16 -07:00
Andrew Lanzone
58c4e0ddf7 Minimal controller bindings for save/load window 2025-05-10 01:41:53 -07:00
Andrew Lanzone
2970913d55 Minimal controller bindings for settings window 2025-05-09 23:44:06 -07:00
Andrew Lanzone
fc86878922 Allow exiting credits by pressing B 2025-05-09 23:43:29 -07:00
Andy Lanzone
b4e0590a10
Merge branch 'OpenMW:master' into master 2025-05-09 22:57:21 -07:00
Andrew Lanzone
a8824b46a8 Add first batch of controller-enabled windows 2025-05-09 22:56:04 -07:00
Evil Eye
9ea1afedcc Merge branch 'baiki-isActive-kembalikan-bool' into 'master'
self:isActive() returns bool

See merge request OpenMW/openmw!4663
2025-05-09 15:17:08 +00:00
Kuyondo
087349a3e5 bump lua API_REVISION 72 to 73 2025-05-09 19:06:24 +08:00
Alexei Kotov
8966b5292b Merge branch 'bug8465' into 'master'
Bug 8465: Fix anti-aliasing on macOS

Closes #8465

See merge request OpenMW/openmw!4665
2025-05-09 04:45:31 +03:00
thagberg
2bcbb2d01c Update authors 2025-05-07 22:28:35 -04:00
thagberg
4297ef2f97 Add changelog 2025-05-07 21:55:58 -04:00
thagberg
883f9e5049 Fix anti-aliasing on macOS
Blitting to the resolve FBO in OSG::RenderStage was causing a GL_INVALID_FRAMEBUFFER_OPERATION due to a mismatch in attached colorbuffers between the FBOs bound in read and draw slots. This was because the normal attachment was invariantly attached to FBO_Interrupt, but not to other FBOs.
2025-05-07 16:31:22 -04:00
psi29a
1f724cc336 Merge branch 'postprocessingglslversion' into 'master'
Fix post-processing shader glsl_version bumping

See merge request OpenMW/openmw!4653
2025-05-07 17:57:15 +00:00
Kuyondo
77bd2250b0 isactive return bool now 2025-05-07 11:24:09 +08:00
Evil Eye
1d736bcf79 Merge branch 'fix_launcher_crash' into 'master'
Wait for the reloading cells thread on DataFilesPage destruction (#8445)

Closes #8445

See merge request OpenMW/openmw!4661
2025-05-06 18:37:04 +00:00
Evil Eye
d1196ea667 Ignore resistances for base diseases 2025-05-06 20:09:48 +02:00
Andrew Lanzone
71aa11404c Add checkbox to enable controller menus to openmw launcher. 2025-05-05 22:47:55 -07:00
elsid
4a18c23e2d
Wait for the reloading cells thread on DataFilesPage destruction
Run a single thread and notify it when it has to reload cells.
2025-05-04 21:59:49 +02:00
Alexei Kotov
0d27dc2336 Merge branch 'fognearisafloat' into 'master'
Tiny fix in omwfx docs

See merge request OpenMW/openmw!4656
2025-05-03 21:30:07 +03:00
Evil Eye
87014016a2 Stop postponing physics for objects that _don't_ have physics 2025-05-03 17:25:27 +02:00
Evil Eye
57c40bc052 Don't trigger cell change logic when the player isn't changing cells 2025-05-03 16:26:39 +02:00
epochwon
9e80c27002 changed fognear to a float instead of a vec2 2025-05-02 15:42:15 -04:00
psi29a
0e76a6edb5 Merge branch 'custom-config-directory-documentation' into 'master'
Add documentation for custom config directories

See merge request OpenMW/openmw!4633
2025-05-01 11:42:57 +00:00
Evil Eye
a37758a165 Merge branch 'jinja' into 'master'
Bump jinja2

See merge request OpenMW/openmw!4654
2025-04-30 18:43:29 +00:00
Evil Eye
36e34426bb Merge branch 'fix_warnings' into 'master'
Fix warnings

See merge request OpenMW/openmw!4651
2025-04-30 18:43:14 +00:00
Alexei Kotov
7a0e3aaf11 Bump jinja2 2025-04-29 19:50:02 +03:00
Alexei Kotov
c7f6de472f Merge branch 'fix_cobertura_path' into 'master'
Fix path for junit reports

See merge request OpenMW/openmw!4650
2025-04-29 19:32:36 +03:00
elsid
52281a5e32
Fix path for junit reports 2025-04-29 08:34:09 +02:00
Alexei Kotov
72e73784fb Fix post-processing shader glsl_version bumping 2025-04-29 04:25:24 +03:00
elsid
b5f8a0ecdb
Fix warning: -Wstring-compare
In file included from ../../../components/esm/defs.hpp:7,
                 from ../../../apps/components_tests/esm/test_fixed_string.cpp:1:
In function 'bool ESM::operator==(const FixedString<capacity>&, const char (&)[rhsSize]) [with long unsigned int capacity = 4; long unsigned int rhsSize = 12]',
    inlined from 'virtual void {anonymous}::EsmFixedString_empty_strings_Test::TestBody()' at ../../../apps/components_tests/esm/test_fixed_string.cpp:82:13:
../../../components/esm/esmcommon.hpp:142:85: error: 'int strncmp(const char*, const char*, size_t)' of strings of length 0 and 4 and bound of 4 evaluates to nonzero [-Werror=string-compare]
  142 |         return strnlen(rhs, rhsSize) == strnlen(lhs.mData, capacity) && std::strncmp(lhs.mData, rhs, capacity) == 0;
      |                                                                         ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
2025-04-28 22:07:00 +02:00
elsid
a5826b75e0
Disable -Werror for ASAN builds
To avoid warnings like:

In file included from /usr/include/c++/13/regex:50,
                 from ../../components/lua/yamlloader.cpp:6:
In constructor 'std::function<_Res(_ArgTypes ...)>::function(std::function<_Res(_ArgTypes ...)>&&) [with _Res = bool; _ArgTypes = {char}]',
    inlined from 'std::__detail::_State<_Char_type>::_State(std::__detail::_State<_Char_type>&&) [with _Char_type = char]' at /usr/include/c++/13/bits/regex_automaton.h:149:4,
    inlined from 'std::__detail::_StateIdT std::__detail::_NFA<_TraitsT>::_M_insert_subexpr_begin() [with _TraitsT = std::__cxx11::regex_traits<char>]' at /usr/include/c++/13/bits/regex_automaton.h:281:24:
/usr/include/c++/13/bits/std_function.h:405:42: error: '*(std::function<bool(char)>*)((char*)&__tmp + offsetof(std::__detail::_StateT, std::__detail::_State<char>::<unnamed>.std::__detail::_State_base::<unnamed>)).std::function<bool(char)>::_M_invoker' may be used uninitialized [-Werror=maybe-uninitialized]
  405 |       : _Function_base(), _M_invoker(__x._M_invoker)
      |                                      ~~~~^~~~~~~~~~
In file included from /usr/include/c++/13/regex:65:
/usr/include/c++/13/bits/regex_automaton.h: In member function 'std::__detail::_StateIdT std::__detail::_NFA<_TraitsT>::_M_insert_subexpr_begin() [with _TraitsT = std::__cxx11::regex_traits<char>]':
/usr/include/c++/13/bits/regex_automaton.h:279:17: note: '__tmp' declared here
  279 |         _StateT __tmp(_S_opcode_subexpr_begin);
      |                 ^~~~~

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105562.
2025-04-28 22:07:00 +02:00
elsid
875a45837a
Disable -Warray-bounds due to GCC bug
To avoid getting warnings like:

In file included from ../../../extern/sol3/sol/compatibility.hpp:46,
                 from ../../../extern/sol3/sol/bytecode.hpp:27,
                 from ../../../extern/sol3/sol/sol.hpp:51,
                 from ../../../components/lua/luastate.hpp:8,
                 from ../../../apps/openmw/mwlua/context.hpp:4,
                 from ../../../apps/openmw/mwlua/soundbindings.hpp:6,
                 from ../../../apps/openmw/mwlua/soundbindings.cpp:1:
In member function 'void sol::stack::field_getter<T, global, raw, <template-parameter-1-4> >::get(lua_State*, Key&&, int) [with Key = const char (&)[7]; T = char [7]; bool global = false; bool raw = false; <template-parameter-1-4> = void]',
    inlined from 'void sol::stack::get_field(lua_State*, Key&&, int) [with bool global = false; bool raw = false; Key = const char (&)[7]]' at ../../../extern/sol3/sol/stack_core.hpp:1210:62,
    inlined from 'sol::stack::probe sol::stack::probe_field_getter<T, P, global, raw, <template-parameter-1-5> >::get(lua_State*, Key&&, int) [with Key = const char (&)[7]; T = char [7]; P = float; bool b = false; bool raw = false; <template-parameter-1-5> = void]' at ../../../extern/sol3/sol/stack_probe.hpp:41:21,
    inlined from 'sol::stack::probe sol::stack::probe_field_getter<T, P, global, raw, <template-parameter-1-5> >::get(lua_State*, Key&&, int) [with Key = const char (&)[6]; T = char [6]; P = float; bool b = false; bool raw = false; <template-parameter-1-5> = void]' at ../../../extern/sol3/sol/stack_probe.hpp:35:9,
    inlined from 'sol::stack::probe sol::stack::probe_get_field(lua_State*, Key&&, int) [with bool global = false; bool raw = false; C = float; Key = const char (&)[6]]' at ../../../extern/sol3/sol/stack_core.hpp:1230:78,
    inlined from 'decltype(auto) sol::basic_table_core<<anonymous>, <template-parameter-1-2> >::traverse_get_deep_optional(int&, int, Key&&, Keys&& ...) const [with bool global = false; bool raw = false; sol::detail::insert_mode mode = sol::detail::none; T = sol::optional<float>; Key = const char (&)[6]; Keys = {}; bool top_level = false; ref_t = sol::basic_reference<false>]' at ../../../extern/sol3/sol/table_core.hpp:217:62,
    inlined from 'decltype(auto) sol::basic_table_core<<anonymous>, <template-parameter-1-2> >::traverse_get_single(int, Keys&& ...) const [with bool raw = false; Ret = sol::optional<float>; Keys = {const char (&)[6]}; bool top_level = false; ref_t = sol::basic_reference<false>]' at ../../../extern/sol3/sol/table_core.hpp:123:83,
    inlined from 'decltype(auto) sol::basic_table_core<<anonymous>, <template-parameter-1-2> >::traverse_get_single_maybe_tuple(int, Key&&) const [with bool raw = false; Ret = sol::optional<float>; Key = const char (&)[6]; bool top_level = false; ref_t = sol::basic_reference<false>]' at ../../../extern/sol3/sol/table_core.hpp:113:41,
    inlined from 'decltype(auto) sol::basic_table_core<<anonymous>, <template-parameter-1-2> >::tuple_get(int, Keys&& ...) const [with bool raw = false; Ret = {sol::optional<float>}; Keys = {const char (&)[6]}; bool top_level = false; ref_t = sol::basic_reference<false>]' at ../../../extern/sol3/sol/table_core.hpp:93:56,
    inlined from 'decltype(auto) sol::basic_table_core<<anonymous>, <template-parameter-1-2> >::get(Keys&& ...) const [with Ret = {sol::optional<float>}; Keys = {const char (&)[6]}; bool top_level = false; ref_t = sol::basic_reference<false>]' at ../../../extern/sol3/sol/table_core.hpp:422:35,
    inlined from 'decltype(auto) sol::basic_table_core<<anonymous>, <template-parameter-1-2> >::get_or(Key&&, T&&) const [with T = float; Key = const char (&)[6]; bool top_level = false; ref_t = sol::basic_reference<false>]' at ../../../extern/sol3/sol/table_core.hpp:428:41,
    inlined from '{anonymous}::PlaySoundArgs {anonymous}::getPlaySoundArgs(const sol::optional<sol::basic_table_core<false, sol::basic_reference<false> > >&)' at ../../../apps/openmw/mwlua/soundbindings.cpp:62:42:
../../../extern/sol3/sol/stack_field.hpp:116:49: error: array subscript 'const char [7][0]' is partly outside array bounds of 'const char [6]' [-Werror=array-bounds=]
  116 |                                                 lua_getfield(L, tableindex, &key[0]);
      |                                                 ^~~~~~~~~~~~

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105438.

Simplified example: https://godbolt.org/z/ccPje4nK1.
2025-04-28 22:06:51 +02:00
elsid
891d6fd0ba
Fix warning: -Wmaybe-uninitialized
In member function 'ESM::RefId {anonymous}::IdGettingVisitor::operator()(const MWWorld::Ptr&) const',
    inlined from 'constexpr _Res std::__invoke_impl(__invoke_other, _Fn&&, _Args&& ...) [with _Res = ESM::RefId; _Fn = {anonymous}::IdGettingVisitor; _Args = {const MWWorld::Ptr&}]' at /usr/include/c++/13/bits/invoke.h:61:36,
    inlined from 'constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = {anonymous}::IdGettingVisitor; _Args = {const MWWorld::Ptr&}]' at /usr/include/c++/13/bits/invoke.h:96:40,
    inlined from 'static constexpr decltype(auto) std::__detail::__variant::__gen_vtable_impl<std::__detail::__variant::_Multi_array<_Result_type (*)(_Visitor, _Variants ...)>, std::integer_sequence<long unsigned int, __indices ...> >::__visit_invoke(_Visitor&&, _Variants ...) [with _Result_type = std::__detail::__variant::__deduce_visit_result<ESM::RefId>; _Visitor = {anonymous}::IdGettingVisitor&&; _Variants = {const std::variant<MWWorld::Ptr, std::pair<ESM::FormId, ESM::RefId> >&}; long unsigned int ...__indices = {0}]' at /usr/include/c++/13/variant:1060:24,
    inlined from 'constexpr decltype(auto) std::__do_visit(_Visitor&&, _Variants&& ...) [with _Result_type = __detail::__variant::__deduce_visit_result<ESM::RefId>; _Visitor = {anonymous}::IdGettingVisitor; _Variants = {const variant<MWWorld::Ptr, pair<ESM::FormId, ESM::RefId> >&}]' at /usr/include/c++/13/variant:1815:5,
    inlined from 'constexpr std::__detail::__variant::__visit_result_t<_Visitor, _Variants ...> std::visit(_Visitor&&, _Variants&& ...) [with _Visitor = {anonymous}::IdGettingVisitor; _Variants = {const variant<MWWorld::Ptr, pair<ESM::FormId, ESM::RefId> >&}]' at /usr/include/c++/13/variant:1878:34,
    inlined from 'ESM::RefId MWScript::GlobalScriptDesc::getId() const' at ../../../apps/openmw/mwscript/globalscripts.cpp:120:26:
../../../apps/openmw/mwscript/globalscripts.cpp:91:35: error: '*(const uint32_t*)((char*)&<unnamed> + offsetof(ESM::RefId, ESM::RefId::mValue.std::variant<ESM::EmptyRefId, ESM::ESM3ExteriorCellRefId, ESM::StringRefId, ESM::FormId, ESM::GeneratedRefId, ESM::IndexRefId>::<unnamed>.std::__detail::__variant::_Variant_base<ESM::EmptyRefId, ESM::ESM3ExteriorCellRefId, ESM::StringRefId, ESM::FormId, ESM::GeneratedRefId, ESM::IndexRefId>::<unnamed>.std::__detail::__variant::_Move_assign_base<true, ESM::EmptyRefId, ESM::ESM3ExteriorCellRefId, ESM::StringRefId, ESM::FormId, ESM::GeneratedRefId, ESM::IndexRefId>::<unnamed>.std::__detail::__variant::_Copy_assign_base<true, ESM::EmptyRefId, ESM::ESM3ExteriorCellRefId, ESM::StringRefId, ESM::FormId, ESM::GeneratedRefId, ESM::IndexRefId>::<unnamed>.std::__detail::__variant::_Move_ctor_base<true, ESM::EmptyRefId, ESM::ESM3ExteriorCellRefId, ESM::StringRefId, ESM::FormId, ESM::GeneratedRefId, ESM::IndexRefId>::<unnamed>.std::__detail::__variant::_Copy_ctor_base<true, ESM::EmptyRefId, ESM::ESM3ExteriorCellRefId, ESM::StringRefId, ESM::FormId, ESM::GeneratedRefId, ESM::IndexRefId>::<unnamed>.std::__detail::__variant::_Variant_storage<true, ESM::EmptyRefId, ESM::ESM3ExteriorCellRefId, ESM::StringRefId, ESM::FormId, ESM::GeneratedRefId, ESM::IndexRefId>::_M_u))' may be used uninitialized [-Werror=maybe-uninitialized]
   91 |                 return ESM::RefId();
      |                                   ^
../../../apps/openmw/mwscript/globalscripts.cpp: In member function 'ESM::RefId MWScript::GlobalScriptDesc::getId() const':
../../../apps/openmw/mwscript/globalscripts.cpp:91:35: note: '<anonymous>' declared here
   91 |                 return ESM::RefId();
      |                                   ^
2025-04-28 22:00:03 +02:00
Alexei Kotov
55107e0913 Merge branch 'idle_select_to_group_name' into 'master'
Use string_view for sIdleSelectToGroupName

See merge request OpenMW/openmw!4646
2025-04-28 03:02:17 +03:00
AnyOldName3
897b502b0f Field lists for tokens 2025-04-26 19:09:59 +01:00
AnyOldName3
cbf0760adf Configuration sources to bulleted list 2025-04-26 18:57:57 +01:00
Alexei Kotov
58fcc8f66d Require a non-empty argument in ShowMap (#8466) 2025-04-26 13:29:01 +03:00
Alexei Kotov
011dfb305c Merge branch 'navmeshtool_lib' into 'master'
Do not build navmeshtool translation units twice

See merge request OpenMW/openmw!4647
2025-04-25 21:40:57 +03:00
elsid
fc4cc3255d
Do not build navmeshtool translation units twice 2025-04-24 23:03:07 +02:00
elsid
f487a6332b
Use string_view for sIdleSelectToGroupName 2025-04-24 23:01:30 +02:00
Kindi
0247082e19 fix signedness, remove extra semicolon, update offer 2025-04-24 20:24:55 +08:00
psi29a
80d6f020ed Merge branch 'apt_get_retry' into 'master'
Retry apt-get update and add-apt-repository

See merge request OpenMW/openmw!4639
2025-04-24 09:07:20 +00:00
psi29a
c7c95c5a85 Merge branch 'fix-bug-8462' into 'master'
Set SDL_HINT_MAC_OPENGL_ASYNC_DISPATCH.

Closes #8225 and #8462

See merge request OpenMW/openmw!4641
2025-04-24 09:06:27 +00:00
Sam Kaufman
1948ab21f7 Set SDL_HINT_MAC_OPENGL_ASYNC_DISPATCH.
This fixes bugs #8225 and #8462.
2025-04-23 20:33:56 -07:00
Alexei Kotov
ca3a286cc4 Merge branch 'master' into 'master'
FIX: Clarify that `ignore` field of raycast options types are a list and not a single object

See merge request OpenMW/openmw!4613
2025-04-24 02:09:47 +03:00
Evil Eye
ab5070328d Merge branch 'powershell-multiline-exit' into 'master'
Detect failures in multiline PowerShell commands

See merge request OpenMW/openmw!4645
2025-04-23 18:54:47 +00:00
Evil Eye
23522ed314 Merge branch 'missing_enum' into 'master'
Add missing TargetPolygonNotFound enum value to lua bindings

See merge request OpenMW/openmw!4643
2025-04-23 18:54:46 +00:00
Evil Eye
b4d5013679 Merge branch 'lua_state' into 'master'
Use unique_ptr to handle lua state lifetime

See merge request OpenMW/openmw!4636
2025-04-23 18:54:40 +00:00
Dave Corley
5ef2cf23b3 CLEANUP: Loop param, also, is a bool 2025-04-23 11:20:46 -07:00
Kindi
4b94b6f678 also update draganddrop and trade items 2025-04-23 21:19:52 +08:00
elsid
8ee0c9e7be
Retry apt-get update and add-apt-repository 2025-04-22 23:05:27 +02:00
AnyOldName3
19725473d7 Detect failures in multiline PowerShell commands
GitLab inserts a check for failure after each command in our `script`.
This is documented here https://docs.gitlab.com/runner/shells/#powershell

However, it doesn't detect failures if we run commands back to back.

This adds the checks GitLab would have added for us if we were able to make it do that.
2025-04-22 20:58:43 +01:00
psi29a
aed135a7c0 Merge branch 'bump-cache-key' into 'master'
Increment cache keys missed in !4450

Closes #8463

See merge request OpenMW/openmw!4644
2025-04-22 07:05:45 +00:00
AnyOldName3
928bbed09b Increment cache keys missed in !4450
It changed the filenames for deps, so we've got two copies of the deps in the cache, and now we're running out of disk space.
2025-04-21 22:52:24 +01:00
elsid
626d7b2282
Add missing TargetPolygonNotFound enum value to lua bindings 2025-04-21 16:36:19 +02:00
Kindi
bdf025a532 also update companion window and tradewindow 2025-04-21 19:33:31 +08:00
Kindi
a9870bbcde update container window when item is added or removed 2025-04-21 19:33:22 +08:00
Kindi
15ceee4b1a also update companion window and tradewindow 2025-04-21 19:29:57 +08:00
Kindi
0547f09bf0 update container window when item is added or removed 2025-04-21 19:29:57 +08:00
Evil Eye
e20d52d23c Merge branch 'namespace_typo' into 'master'
Fix typo in namespace name

See merge request OpenMW/openmw!4635
2025-04-21 08:41:27 +00:00
Evil Eye
05c624bc34 Merge branch 'rm_using_namespace_fallback' into 'master'
Remove redundant using namespace Fallback

See merge request OpenMW/openmw!4638
2025-04-21 08:39:48 +00:00
Evil Eye
5a42db3256 Merge branch 'static_assert' into 'master'
Use static_assert for compile time check

See merge request OpenMW/openmw!4637
2025-04-21 08:35:17 +00:00
AnyOldName3
e2e7b58b3a Handle normalHeightMap as special case 2025-04-20 23:55:38 +01:00
Aussiemon
22c01b22c1 Clang format 2025-04-19 23:06:30 -06:00
Aussiemon
085e5d1988 Calculate spell cost when building buying window 2025-04-19 22:31:58 -06:00
elsid
6f89d38b78
Replace includes by forward declaration 2025-04-20 02:28:34 +02:00
AnyOldName3
4707c7e2fc Format 2025-04-20 00:17:03 +01:00
AnyOldName3
115fc08904 Don't forget parallax when reapplying shader visitor
Fixes https://gitlab.com/OpenMW/openmw/-/issues/8341

I don't think this should go into 0.49 because there may be implications beyond what I've thought of and I'd rather we had a full dev cycle to notice any regressions.

The fix is a little janky, but makes use of some dead code we've had since the introduction of normal-height maps nearly a decade ago, so it's a safe bet that it was never intended to be dead code.
The main effect of the jankiness is that we'll add some pointless @defines for normalHeightMap that none of our shaders use and which will always be zero.
2025-04-20 00:12:53 +01:00
AnyOldName3
c0a05f5d13 Add documentation for custom config directories
Also includes examples for portable installs and profiles.
2025-04-19 19:14:18 +01:00
elsid
042c4b2b9d
Use static_assert for compile time check 2025-04-18 14:38:23 +02:00
elsid
f80283422f
Use unique_ptr to handle lua state lifetime 2025-04-18 14:01:07 +02:00
elsid
972995d124
Fix typo in namespace name 2025-04-18 12:27:48 +02:00
elsid
0d5e9ef85f
Remove redundant using namespace Fallback
C++ has ADL to find overloads. using namespace does nothing in this
case.
2025-04-18 12:27:37 +02:00
psi29a
87d77a6882 Merge branch 'rippleshaders' into 'master'
Fix crash if ripple pipeline shaders are unavailable

See merge request OpenMW/openmw!4622
2025-04-17 09:26:12 +00:00
Alexei Kotov
c1c8769742 Merge branch 'clang_tidy_identifier_naming' into 'master'
Enable identifier naming clang-tidy check (#8424)

See merge request OpenMW/openmw!4631
2025-04-14 13:39:09 +03:00
Alexei Kotov
271ab2e109 Merge branch 'dont-ask-the-disk-for-things-we-already-know' into 'master'
Avoid IO in resolveParentFileIndices

See merge request OpenMW/openmw!4627
2025-04-14 13:11:57 +03:00
Alexei Kotov
583620e607 Merge branch 'patch-1' into 'master'
Crimes.lua wrong type for victim aware

See merge request OpenMW/openmw!4623
2025-04-14 09:44:45 +03:00
psi29a
6dd2cac3ec Merge branch 'better-freeze-catcher' into 'master'
Improve Windows crash/freeze catcher UX

See merge request OpenMW/openmw!4630
2025-04-13 20:57:12 +00:00
Alexei Kotov
6aed2d8284 Bump Crimes interface version 2025-04-13 14:05:07 +03:00
elsid
84f471ce5c
Enable identifier naming clang-tidy check 2025-04-13 09:59:51 +02:00
AnyOldName3
deb070389f Improve Windows crash/freeze catcher UX
* Change crash log to crash dump in messages.
* Make the freeze catcher popup disappear more quickly when OpenMW thaws - we got a few freeze dumps from after a thaw.
* Improve freeze catcher message - hopefully fewer users think it's a false positive they're expected to put up with and we get future reports sooner.
2025-04-12 18:38:55 +01:00
Alexei Kotov
f7f148a6ca Merge branch 'fix-debug-config' into 'master'
Fix Windows Debug build

See merge request OpenMW/openmw!4629
2025-04-12 17:35:03 +03:00
AnyOldName3
a5a6f33578 Manual reformatting that wasn't done automatically on my machine 2025-04-11 17:41:40 +01:00
AnyOldName3
d74a0edb82 Format 2025-04-11 17:37:55 +01:00
AnyOldName3
396cd1c727 Fix Windows Debug build
This was a regression from https://gitlab.com/OpenMW/openmw/-/merge_requests/4596

Also move more things into the anonymous namespace because there's not really a reason not to and I had to rearrange things anyway.
2025-04-11 17:33:19 +01:00
AnyOldName3
31fcc5e126 Add test for new ReadersCache functions 2025-04-11 17:30:56 +01:00
Dave Corley
22172f3b0e FIX: useAmbientLighting arg of addVfx options is a bool 2025-04-10 11:48:57 -07:00
Dave Corley
b68935e917 FIX: Model param of addVfx should not be a header 2025-04-10 11:44:34 -07:00
Dave Corley
e512a8e74f FIX: Add a name to options table in castRenderingRay 2025-04-10 11:42:24 -07:00
AnyOldName3
48572e4c96 Even more elses 2025-04-10 18:32:52 +01:00
Dave Corley
1d1ae1c906 CLEANUP: But it can also be a single object 2025-04-10 10:15:31 -07:00
Dave Corley
586467540b FIX: Clarify that ignore field of raycast options types are a list and not a single object 2025-04-10 10:15:31 -07:00
AnyOldName3
37dc1a6a76 Remove redundant elses 2025-04-10 16:51:23 +01:00
AnyOldName3
15162a734d Avoid IO in resolveParentFileIndices
In the olden days, we passed it a vector of open ESMReader instances, as they knew the filenames and sizes, so were a convenient source of this knowledge.

When the ReadersCache was introduced as a pool of readers to limit the maximum number of simultaneously open file handles (to avoid going over the OS' limit) it was a poor substitute.
* We iterate over all the earlier readers in order in a double loop, which is the worst case scenario for an LRU pool as once we're past the size limit, we're guaranteed maximum thrashing - the least recently used item is the most likely to be used next, so the worst to evict.
* We didn't want to read any ESM files, just know whether they'd been read and what their sizes were, so didn't want to open a file handle, which the ReadersCache forced us to do.

Obviously, opening lots of file handles isn't fast, and as this was an operation done for each content file which iterated over the file's masters and within that loop iterated over every loaded file, that's O(n^3) complexity in the worst case, and for things like delta plugin merged plugins, they hit the worst case in long load orders.

This resolves the freeze reported as https://gitlab.com/OpenMW/openmw/-/issues/8425, but there may be other freezes on launch.
2025-04-10 16:16:19 +01:00
Alexei Kotov
ec77ec299d Rescale the base travel cost by the number of followers (#8446)
Rather than the offered price.
2025-04-10 16:24:36 +03:00
psi29a
ea8369eff0 Merge branch 'dont-redraw-the-whole-gui-every-time-we-change-the-tiniest-thing' into 'master'
Be more careful when we tell Qt that data has changed

Closes #8405

See merge request OpenMW/openmw!4621
2025-04-09 11:19:32 +00:00
AnyOldName3
096759435a Add progress bars where the launcher can be limited by IO
I tested this with a USB3 external hard drive.

These two places were the only ones where we're IO-bound and block the main thread, so they're the only ones that need progress bars.

If trying to replicate this test, then it's important to unplug the hard drive between each repeat.
Apparently Windows is excellent at disk caching these days as it takes a minute and a half to start the launcher with Total Overhaul on this drive when it's just been plugged in, but less time than the first launch after a reboot on an NVME drive once the cache has been warmed up.
2025-04-09 01:36:52 +01:00
AnyOldName3
894ea4ba62 Don't precompute load order errors after every change
It's much slower than doing it on demand as it only takes a microsecond, but for a really big load order, there are hundreds of thousands of intermediate calls before everything's set up and we can draw the GUI.
2025-04-08 01:19:24 +01:00
AnyOldName3
d6b61f1f54 Sprinkle some const&
QStringView required more fighting as loads of call sites take a const&
2025-04-08 00:34:45 +01:00
AnyOldName3
e779f115ef Exclude directories from containsDataFiles
Also include capo's microoptimisation even though it doesn't make things any faster.
2025-04-07 16:11:27 +01:00
psi29a
428044abe2 Merge branch 'moveoutalready' into 'master'
Open the data directory file picker at the last opened location

Closes #8426

See merge request OpenMW/openmw!4606
2025-04-07 11:04:26 +00:00
psi29a
bd1c2a11d7 Merge branch 'herbalfish' into 'master'
Fix some graphic herbalism issues

See merge request OpenMW/openmw!4624
2025-04-07 11:03:55 +00:00
psi29a
0c4c202998 Merge branch 'ifavideofallsintheforest' into 'master'
Pause menu video playback when OpenMW is minimized

Closes #8441

See merge request OpenMW/openmw!4625
2025-04-07 11:03:37 +00:00
Alexei Kotov
8419116cae Fix crash if ripple pipeline shaders are unavailable 2025-04-07 03:31:32 +03:00
psi29a
8a0f513094 Merge branch 'fix_clang_tidy' into 'master'
Fix clang tidy checks

See merge request OpenMW/openmw!4619
2025-04-06 17:54:20 +00:00
Evil Eye
1667b11564 Pause menu video playback when OpenMW is minimized 2025-04-06 19:42:04 +02:00
psi29a
b29d89bd6a Merge branch 'enchantment404' into 'master'
Allow referenced enchantments to be missing on equipped items

See merge request OpenMW/openmw!4617
2025-04-06 16:06:10 +00:00
psi29a
211a5e5bda Merge branch 'lightminimumradius' into 'master'
Give point lights a minimum radius of 16

See merge request OpenMW/openmw!4601
2025-04-06 16:03:35 +00:00
psi29a
2ed14de41f Merge branch 'objectrootless' into 'master'
Account for creatures not having a model in more places

Closes #8439

See merge request OpenMW/openmw!4618
2025-04-06 16:01:50 +00:00
Evil Eye
d826962eaa Don't assume unresolved containers contain no visible items 2025-04-06 11:02:31 +02:00
Evil Eye
962ef91e25 Allow skinned plants to be harvested 2025-04-06 11:01:26 +02:00
Chronolegionnaire
ed62f9b12b Lua api demands a boolean for victim aware but crimes.lua looks for a number. Which makes scripts that call the crime interface unable to provide a value other than nil for victim aware. 2025-04-06 06:27:40 +00:00
AnyOldName3
973282e471 Optimise ContentSelectorModel::ContentModel::item
This saves about 5% of remaining launcher startup time

Not using fileProperty avoids loads of QVariant conversions.
2025-04-06 02:46:31 +01:00
AnyOldName3
7bad2864d9 Reuse QIcon
This saves more than 15% of launcher startup time on my machine (after the prior improvements - it's way less without those)
2025-04-06 02:40:42 +01:00
AnyOldName3
1237746549 Be more careful when we tell Qt that data has changed
Unchecking files only changes whether they're checked, and doesn't completely rearrange the table and change the number of elements it has, so we only need to change the check state, not the whole layout.

It's way faster to just query all the data once after setting a content list than it is to query the data for all files between the old and new location of a file when we change any file's location in the load order.
2025-04-06 01:31:05 +01:00
elsid
7254bb74a4
Enable modernize-avoid-bind clang-tidy check 2025-04-05 12:55:18 +02:00
elsid
3af2091b28
Use prefix with dot for clang-analyzer-optin. checks 2025-04-05 12:55:18 +02:00
elsid
621a0a15a3
Disable clang-analyzer-cplusplus.NewDelete clang-tidy check 2025-04-05 12:55:18 +02:00
elsid
c34b0f90d7
Avoid clang-tidy checks duplication 2025-04-05 12:55:17 +02:00
elsid
e098770ba2
Use custom clang-tidy config for extern/ 2025-04-05 12:55:17 +02:00
elsid
7c45a564a1
Fix clang-analyzer-deadcode.DeadStores 2025-04-05 12:55:17 +02:00
elsid
da388c93eb
Remove boost-* clang-tidy checks
There are only:
* https://clang.llvm.org/extra/clang-tidy/checks/boost/use-ranges.html
* https://clang.llvm.org/extra/clang-tidy/checks/boost/use-to-string.html

None of them makes sense in this project.
2025-04-05 12:55:17 +02:00
elsid
d609bd1ab1
Fix clang-tidy header filter 2025-04-05 12:55:17 +02:00
Evil Eye
15f4368fe6 Account for creatures not having a model in more places 2025-04-05 10:19:50 +02:00
Alexei Kotov
3901084cc2 Merge branch 'cmake_minimum_required_macos' into 'master'
Remove cmake_minimum_required for osx install script

See merge request OpenMW/openmw!4615
2025-04-05 08:54:09 +03:00
Kindi
a5580718f7 clangformat 2025-04-05 11:26:34 +08:00
Alexei Kotov
065a388632 Allow enchantments to be missing on equipped items 2025-04-05 01:10:41 +03:00
Kindi
71a6b26b4f add missing semicolon, add leading whitespace, 2025-04-04 19:47:47 +08:00
Kindi
0a49c5f71e show global script variables in showVars 2025-04-04 15:36:01 +08:00
Kindi
0eb2ced072 update spell windows after selecting spell using quickkey 2025-04-04 12:58:07 +08:00
elsid
9a6807f862
Remove cmake_minimum_required for osx install script 2025-04-03 23:01:36 +02:00
Alexei Kotov
468724075e Restore 0.45.0 pin button visibility conditions (#8437) 2025-04-03 11:09:50 +03:00
Alexei Kotov
3523ba564a Merge branch 'non-deprecated-known-folder-api' into 'master'
Use non-deprecated known folder API

See merge request OpenMW/openmw!4603
2025-04-02 19:20:21 +03:00
Alexei Kotov
1629ea32f7 Merge branch 'rm_unused' into 'master'
Remove declaration without definition

See merge request OpenMW/openmw!4607
2025-04-01 23:35:49 +03:00
Alexei Kotov
17938cdb7e Make the crosshair smaller 2025-04-01 01:25:08 +03:00
Evil Eye
86426aa87b Open the data directory file picker at the last opened location 2025-03-31 17:11:09 +02:00
elsid
a61ce111a5
Remove declaration without definition 2025-03-31 00:28:06 +02:00
Alexei Kotov
11c2fd9e3d Merge branch 'master' into 'master'
FIX: Remove outdated instructions for ubuntu installation

See merge request OpenMW/openmw!4605
2025-03-29 02:47:16 +03:00
Dave Corley
b6be7cdd56 CLEANUP: Use apt instead of apt-get 2025-03-28 22:27:30 +00:00
Dave Corley
caef91d261 FIX: Remove outdated instructions for ubuntu installation 2025-03-27 14:55:05 -07:00
psi29a
72aefbf191 Merge branch 'lua_save_load_test' into 'master'
Add Lua integration tests for loading and saving

See merge request OpenMW/openmw!4604
2025-03-27 11:05:12 +00:00
psi29a
747771ac5e Merge branch 'fontexport' into 'master'
Restore --export-fonts option functionality

See merge request OpenMW/openmw!4561
2025-03-27 11:04:35 +00:00
psi29a
5f413e7b4d Merge branch 'navigator_debug_mesh' into 'master'
Make navigator debug meshes generation safer

See merge request OpenMW/openmw!4602
2025-03-27 11:04:18 +00:00
elsid
2ebdc43bbe
Add test for load while teleporting
To reproduce #8311.

Load game while landracer is scheduled to teleport from different cell.
2025-03-25 23:41:04 +01:00
elsid
536325e0ba
Add test for saving and loading the game 2025-03-25 23:40:58 +01:00
elsid
cbcd4f6acd
Move matchers to different module 2025-03-25 23:24:24 +01:00
Evil Eye
9570b29a0a Merge branch 'lua_test_menu' into 'master'
Run Lua integration tests starting with menu script

See merge request OpenMW/openmw!4556
2025-03-25 16:54:41 +00:00
AnyOldName3
166852254f Use non-deprecated known folder API
SHGetFolderPathW was deprecated in Windows Vista nearly two decades ago. ShGetKnownFolderPath is the replacement.

Also log if there was an error. Someone seemed to be getting an error on Discord, despite other apps being able to get the path just fine with these functions.

Also don't pass the flags to create the folders if they don't exist. We probably don't have the right permissions and if they don't exist, then there are bigger problems. Maybe this will fix the issue the user was having.

Also add a comment about global config on Windows being fundamentally wrong.
2025-03-25 01:32:44 +00:00
Alexei Kotov
f8be5fdd2a Give point lights a minimum radius of 16 2025-03-24 22:14:08 +03:00
Alexei Kotov
652113c46d Don't enable water collision when collision is disabled (#8414) 2025-03-24 21:26:37 +03:00
elsid
ada48d9021
Reduce a chance to have a deadlock in the AsyncNavMeshUpdater
* Do not fail tile generation if debug mesh writing fails.
* Mark some functions as noexcept to better crash than have a deadlock.
* Unlock tile and remove job if there on exception while processing it.
2025-03-23 23:33:40 +01:00
elsid
7112217adc
Use temporary directory for tests output 2025-03-23 23:33:40 +01:00
elsid
87a2f776b7
Add version to the recast log prefix 2025-03-23 23:33:39 +01:00
Evil Eye
73811b45b1 Clarify the resetInitialPosition loop 2025-03-23 21:44:04 +01:00
Evil Eye
88cac9b0fa Reset initial wander position when commanding actors and don't create return packages when stacking actual ai packages 2025-03-23 18:25:20 +01:00
psi29a
d13f108779 Merge branch 'nbsp' into 'master'
Non-breaking space-related fixes (#8378)

Closes #8378

See merge request OpenMW/openmw!4592
2025-03-23 16:27:07 +00:00
Evil Eye
57fb334a6e Merge branch 'recast_log_level' into 'master'
Support max log level for Recast via env variable

See merge request OpenMW/openmw!4596
2025-03-23 14:50:11 +00:00
Alexei Kotov
7fb5d4f47a Inform the player about both resting hindrances (#8408) 2025-03-23 03:38:21 +03:00
Alexei Kotov
88c673de51 Merge branch 'luadoc' into 'master'
Fix minor documentation errors

See merge request OpenMW/openmw!4595
2025-03-22 14:22:51 +03:00
elsid
51258662b5
Support max log level for Recast via env variable
Do not write to log if log message level is greater than one speficied
in the OPENMW_RECAST_MAX_LOG_LEVEL env variable. Use Error by default.
2025-03-21 15:34:47 +01:00
Alexei Kotov
d6916c35bc Only print the player name if it doesn't match the profile 2025-03-21 04:10:52 +03:00
Alexei Kotov
8634b6c3ac Revise saved game dialog save info layout (#8313) 2025-03-21 03:18:32 +03:00
Evil Eye
e5e21eef20 Fix minor documentation errors 2025-03-20 20:08:31 +01:00
psi29a
057c85b710 Merge branch 'esmtool_qust_subrecords' into 'master'
Skip SLSD, SCVR, SCRV subrecords in QUST record

See merge request OpenMW/openmw!4589
2025-03-18 13:18:15 +00:00
psi29a
241a24564a Merge branch 'doubleexit' into 'master'
Don't assume there is a GUI mode in exitCurrentGuiMode (#8380)

Closes #8380

See merge request OpenMW/openmw!4590
2025-03-18 13:16:23 +00:00
Alexei Kotov
cd3980eca4 Make figure space non-breaking 2025-03-18 10:29:29 +03:00
Alexei Kotov
c2744a1846 Change substitute character in Mystic Cards from question mark to underscore 2025-03-18 00:50:03 +03:00
Alexei Kotov
8d0dcb774f Add no-break space to MysticCards 2025-03-18 00:49:51 +03:00
Alexei Kotov
b5a2a4e52d Render no-break space in books, don't consider narrow NBSP breaking 2025-03-17 22:03:38 +03:00
Alexei Kotov
887e1c04ef Spell buying window layout tweaks 2025-03-16 13:53:43 +03:00
Alexei Kotov
4db41c2111 Merchant repair menu layout tweaks 2025-03-16 13:16:59 +03:00
Alexei Kotov
e4ae0c9a95 Don't assume there is a GUI mode in exitCurrentGuiMode (#8380) 2025-03-16 09:06:01 +03:00
elsid
e5f6b77c29
Skip SLSD, SCVR, SCRV subrecords in QUST record
Present in:

Fallout 3 GOTY English/Data/Anchorage.esm
Fallout 3 GOTY English/Data/BrokenSteel.esm
Fallout 3 GOTY English/Data/PointLookout.esm
Fallout 3 GOTY English/Data/ThePitt.esm
Fallout 3 GOTY English/Data/Zeta.esm
2025-03-15 13:11:26 +01:00
Evil Eye
2b5d076ff8 Merge branch 'followmeifyouwanttohit' into 'master'
Don't use attack strength as "hit ready" flag

See merge request OpenMW/openmw!4583
2025-03-15 12:02:35 +00:00
psi29a
2ca1850ea9 Merge branch 'clang19' into 'master'
Clang 19 build fix (!4549 without sol update)

See merge request OpenMW/openmw!4585
2025-03-14 14:47:20 +00:00
psi29a
9a35e3f64d Merge branch 'ripplinglogs' into 'master'
Only log ripples pipeline once

See merge request OpenMW/openmw!4584
2025-03-14 13:17:14 +00:00
Alexei Kotov
34a5eb7512 Editor: Account for pixel ratio in instance mode mouse coordinates conversion (#6573) 2025-03-13 20:06:20 +03:00
Alexei Kotov
fdba5d4cb7 Merge branch 'padgame' into 'master'
Distinguish between I.Controls and I.GamepadControls

See merge request OpenMW/openmw!4582
2025-03-12 08:59:39 +03:00
Alexei Kotov
ced142da92 Lift upstream sol::optional::emplace Clang 19 build fix 2025-03-12 00:05:20 +03:00
Alexei Kotov
71ef86078c Clip HUD item widgets to not overlap the borders (#7740) 2025-03-11 22:21:42 +03:00
elsid
e5ad1cd214 Do not use no longer supported std::char_traits
/usr/bin/../include/c++/v1/string_view:300:42: error: implicit instantiation of undefined template 'std::char_traits<signed char>'
  300 |   static_assert(is_same<_CharT, typename traits_type::char_type>::value,
      |                                          ^
/home/elsid/dev/openmw/components/to_utf8/to_utf8.cpp:55:41: note: in instantiation of template class 'std::basic_string_view<signed char>' requested here
   55 |     std::basic_string_view<signed char> getTranslationArray(FromType sourceEncoding)
      |                                         ^
/usr/bin/../include/c++/v1/__fwd/string.h:23:29: note: template is declared here
   23 | struct _LIBCPP_TEMPLATE_VIS char_traits;
      |                             ^

std::char_traits support for non char types was removed from libc++19:
https://reviews.llvm.org/D157058.
2025-03-11 20:32:36 +03:00
Alexei Kotov
9f85e51934 Only log ripples pipeline once 2025-03-11 17:37:18 +03:00
Alexei Kotov
569ed4559f Merge branch 'fix_msvc_warnings' into 'master'
Fix msvc warnings

See merge request OpenMW/openmw!4579
2025-03-11 00:55:32 +03:00
Alexei Kotov
5354a5f786 Don't use attack strength as "hit ready" flag
This unbreaks follow animations' strength dependence
2025-03-11 00:44:35 +03:00
Evil Eye
c691917172 Distinguish between I.Controls and I.GamepadControls 2025-03-10 16:37:13 +01:00
psi29a
73bb17009e Merge branch 'getsoundplaying' into 'master'
Don't require a reference for GetSoundPlaying (#8389)

Closes #8389

See merge request OpenMW/openmw!4576
2025-03-10 08:13:23 +00:00
Alexei Kotov
3f63700e99 Improve topic and magic effect list padding accuracy
This also touches the quest list, but there are bigger problems with the journal than just padding
2025-03-10 05:48:54 +03:00
elsid
51d73e37df
Fix msvc warnings
components\lua\configuration.cpp(133): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
components\esm3\effectlist.cpp(35): warning C4267: '=': conversion from 'size_t' to 'uint32_t', possible loss of data
components_tests\misc\testmathutil.cpp(54): warning C4305: 'argument': truncation from 'const double' to 'osg::Vec3f::value_type'
components_tests\misc\testmathutil.cpp(62): warning C4305: 'argument': truncation from 'const double' to 'osg::Vec3f::value_type'
components_tests\misc\testmathutil.cpp(131): warning C4305: 'argument': truncation from 'const double' to 'osg::Vec3f::value_type'
components_tests\misc\testmathutil.cpp(135): warning C4305: 'argument': truncation from 'const double' to 'osg::Vec3f::value_type'
components_tests\misc\testmathutil.cpp(135): warning C4305: 'argument': truncation from 'const double' to 'osg::Vec3f::value_type'
components_tests\misc\testmathutil.cpp(139): warning C4305: 'argument': truncation from 'const double' to 'osg::Vec3f::value_type'
2025-03-09 17:55:17 +01:00
Alexei Kotov
a49a900a7b Merge branch 'fix_lua_teleport' into 'master'
Merge deleted refs when unloading a cell (#8311)

Closes #8311

See merge request OpenMW/openmw!4575
2025-03-09 15:51:01 +03:00
Alexei Kotov
01ea2ad08c Merge branch 'fix_delete_game_ub' into 'master'
Avoid accessing removed character on deleting last save (#8387)

Closes #8387

See merge request OpenMW/openmw!4574
2025-03-09 10:42:11 +03:00
Alexei Kotov
8cb1838c4a Don't require a reference for GetSoundPlaying (#8389) 2025-03-09 00:52:00 +03:00
elsid
2892e19c43
Run integration tests with verbose output 2025-03-08 13:14:23 +01:00
elsid
0e19b1dd75
Run Lua integration tests starting with menu script
This allows writing tests for menu scripts.

Keep global script as entry point to morrowind tests.

Fix menu.newGame and menu.loadGame to hide main menu.
2025-03-08 13:14:20 +01:00
elsid
f800f63ee5
Merge deleted refs when unloading a cell
To unload objects scheduled to be teleported.
2025-03-08 12:48:28 +01:00
elsid
5776eea1b0
Avoid accessing removed character on deleting last save 2025-03-08 00:34:27 +01:00
Alexei Kotov
5f92d520ee Merge branch 'mainmembers' into 'master'
Fix more potential use-after-free issues

See merge request OpenMW/openmw!4566
2025-03-07 00:25:35 +03:00
Evil Eye
9bf6a15ff5 Force move the captured string 2025-03-06 17:32:56 +01:00
psi29a
c5a1ca7c3e Merge branch 'changelog' into 'master'
Add addressed Korean font issue (#8378) to the changelog

Closes #8378

See merge request OpenMW/openmw!4573
2025-03-06 12:22:58 +00:00
Alexei Kotov
59edf4750b Fix Travel window header alignment 2025-03-06 01:16:45 +03:00
elsid
7a9c2d5e88
Split local and global event handlers 2025-03-05 22:18:46 +01:00
elsid
981ca957c1
Register global tests to run them 2025-03-05 22:18:46 +01:00
elsid
8b62f02523
Use world.players to initialize player in global tests 2025-03-05 22:18:46 +01:00
elsid
c298210844
Make integration_tests.py output more verbose
* Make it look more like googletest.
* Print total and failed number of tests.
* Print failed tests names.
* Print duration of each test and total.
* Hide all logs by default.
2025-03-05 22:18:46 +01:00
elsid
f80c7b2355
Expect openmw.cfg to exist 2025-03-05 22:18:47 +01:00
Alexei Kotov
124ada8d14 Add addressed Korean font issue (#8378) to the changelog 2025-03-06 00:18:10 +03:00
psi29a
95312139d5 Merge branch 'context_matters' into 'master'
Fix in-game actions not clearing because of input bindings only initializing in menu context

See merge request OpenMW/openmw!4570
2025-03-05 21:18:02 +00:00
psi29a
8bbb46b52c Merge branch 'frankfontaine' into 'master'
Properly implement bitmap font kerning (#8378)

See merge request OpenMW/openmw!4565
2025-03-05 21:16:19 +00:00
Alexei Kotov
918a6352e4 Let cancelled bound item effect remain active for the frame 2025-03-05 23:53:31 +03:00
Alexei Kotov
5b18edf938 Interrupt bound item effect if equipment failed (#8383) 2025-03-05 20:24:02 +03:00
psi29a
888415059c Merge branch 'fontainofdreams' into 'master'
Allow bitmap font texture reading to end prematurely (#8378)

See merge request OpenMW/openmw!4564
2025-03-05 13:11:10 +00:00
psi29a
1e0bdcc270 Merge branch 'elefont' into 'master'
Further revise bitmap glyph replacements (#7531)

See merge request OpenMW/openmw!4563
2025-03-05 13:09:53 +00:00
Alexei Kotov
97717e6fce Merge branch 'fix_lua_vfs_crash' into 'master'
Fix crash on LuaManager::clear triggered by vfs (#8370)

Closes #8370

See merge request OpenMW/openmw!4559
2025-03-05 04:51:47 +03:00
uramer
990096ff9b Fix in-game actions not clearing because of input bindings only initializing in menu context 2025-03-04 21:08:26 +01:00
Alexei Kotov
82307d4e6b Merge branch 'lua_player_attack_test' into 'master'
Direct player attack lower by target's half height

See merge request OpenMW/openmw!4562
2025-03-04 22:49:32 +03:00
Alexei Kotov
61e2117e9d Remove excessive spacing between travel destination and price 2025-03-04 04:03:37 +03:00
Evil Eye
b0e9df0139 Ensure class members are tied to the main Lua state 2025-03-03 19:37:07 +01:00
Evil Eye
f0cee09b7c Extend lifetime of strings placed on the action queue 2025-03-03 19:36:54 +01:00
Alexei Kotov
6e9d15f91d Merge branch 'keep-menu-actions-after-load' into 'master'
#8365 Keep MENU-registered input actions between games

See merge request OpenMW/openmw!4554
2025-03-03 18:10:12 +00:00
Evil Eye
62d1cdcdac Merge branch 'lua_hide_main_menu' into 'master'
Hide main menu on new and loading game from menu scripts

See merge request OpenMW/openmw!4560
2025-03-03 15:39:05 +00:00
Alexei Kotov
fd358396fc Properly implement bitmap font kerning 2025-03-03 08:42:39 +03:00
Alexei Kotov
24468fd965 Allow bitmap font texture to end prematurely 2025-03-03 08:29:00 +03:00
Alexei Kotov
c8fe596fc4 Add some remaining missing bitmap substitutions 2025-03-03 08:02:34 +03:00
Alexei Kotov
c50d8195bb Remove custom substitutions for glyphs that may exist in the font 2025-03-03 08:02:16 +03:00
elsid
7670afcba1
Direct player attack lower by target's half height
To make sure it always hits the target.
2025-03-03 00:18:42 +01:00
Alexei Kotov
dc3264a3a5 Restore --export-fonts option functionality 2025-03-02 22:33:06 +03:00
elsid
1bb3198b71
Fix crash on LuaManager::clear triggered by vfs
See https://gitlab.com/OpenMW/openmw/-/issues/8370#note_2370896069.

=================================================================
==8699==ERROR: AddressSanitizer: heap-use-after-free on address 0x50800060d4b0 at pc 0x7254de50893e bp 0x7fffa97f9700 sp 0x7fffa97f96f0
READ of size 8 at 0x50800060d4b0 thread T0
    #0 0x7254de50893d  (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x6293d) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #1 0x7254de50ccad in lua_rawgeti (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x66cad) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #2 0x7254de5d4cab in luaL_unref (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x12ecab) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #3 0x5f96378dd1e9 in sol::stateless_reference::deref(lua_State*) const /home/elsid/dev/openmw/extern/sol3/sol/reference.hpp:440
    #4 0x5f96378dd1e9 in sol::basic_reference<false>::deref() const /home/elsid/dev/openmw/extern/sol3/sol/reference.hpp:545
    #5 0x5f96378dd1e9 in sol::basic_reference<false>::~basic_reference() /home/elsid/dev/openmw/extern/sol3/sol/reference.hpp:635
    #6 0x5f96378dd1e9 in sol::basic_object_base<sol::basic_reference<false> >::~basic_object_base() /home/elsid/dev/openmw/extern/sol3/sol/object_base.hpp:33
    #7 0x5f96378dd1e9 in sol::basic_object<sol::basic_reference<false> >::~basic_object() /home/elsid/dev/openmw/extern/sol3/sol/object.hpp:35
    #8 0x5f96378dd1e9 in ~<lambda> /home/elsid/dev/openmw/apps/openmw/mwlua/vfsbindings.cpp:195
    #9 0x5f96378dd1e9 in ~functor_function /home/elsid/dev/openmw/extern/sol3/sol/function_types_stateful.hpp:32
    #10 0x5f96378dd1e9 in destroy_at<sol::function_detail::functor_function<MWLua::initVFSPackage(const Context&)::<lambda(sol::this_state, sol::object)>::<lambda()>, false, true> > /usr/include/c++/14.2.1/bits/stl_construct.h:88
    #11 0x5f96378dd1e9 in destroy<sol::function_detail::functor_function<MWLua::initVFSPackage(const Context&)::<lambda(sol::this_state, sol::object)>::<lambda()>, false, true> > /usr/include/c++/14.2.1/bits/alloc_traits.h:599
    #12 0x5f96378dd1e9 in user_alloc_destroy<sol::function_detail::functor_function<MWLua::initVFSPackage(const Context&)::<lambda(sol::this_state, sol::object)>::<lambda()>, false, true> > /home/elsid/dev/openmw/extern/sol3/sol/stack_core.hpp:460
    #13 0x5f963a31e305 in int sol::detail::trampoline<int (*&)(lua_State*)>(lua_State*, int (*&)(lua_State*)) /home/elsid/dev/openmw/extern/sol3/sol/trampoline.hpp:158
    #14 0x5f963a31e89c in sol::detail::c_trampoline(lua_State*, int (*)(lua_State*)) /home/elsid/dev/openmw/extern/sol3/sol/trampoline.hpp:183
    #15 0x7254de4dc13a  (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x3613a) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #16 0x7254de4deac4  (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x38ac4) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #17 0x7254de4df1a2  (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x391a2) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #18 0x7254de4e1cf2  (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x3bcf2) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #19 0x7254de4e2a37  (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x3ca37) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #20 0x7254de50f4a4 in lua_gc (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x694a4) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #21 0x5f96371f615c in MWLua::LuaManager::clear() /home/elsid/dev/openmw/apps/openmw/mwlua/luamanagerimp.cpp:348
    #22 0x5f96371f91ea in MWLua::LuaManager::noGame() /home/elsid/dev/openmw/apps/openmw/mwlua/luamanagerimp.cpp:397
    #23 0x5f963a1c7170 in MWState::StateManager::cleanup(bool) /home/elsid/dev/openmw/apps/openmw/mwstate/statemanagerimp.cpp:71
    #24 0x5f963a1cabfe in MWState::StateManager::newGame(bool) /home/elsid/dev/openmw/apps/openmw/mwstate/statemanagerimp.cpp:169
    #25 0x5f963a1c7aa4 in MWState::StateManager::update(float) /home/elsid/dev/openmw/apps/openmw/mwstate/statemanagerimp.cpp:761
    #26 0x5f963a230bab in OMW::Engine::frame(unsigned int, float) /home/elsid/dev/openmw/apps/openmw/engine.cpp:238
    #27 0x5f963a2442f3 in OMW::Engine::go() /home/elsid/dev/openmw/apps/openmw/engine.cpp:1032
    #28 0x5f963633b3a7 in runApplication(int, char**) /home/elsid/dev/openmw/apps/openmw/main.cpp:228
    #29 0x5f963b375b45 in Debug::wrapApplication(int (*)(int, char**), int, char**, std::basic_string_view<char, std::char_traits<char> >) /home/elsid/dev/openmw/components/debug/debugging.cpp:457
    #30 0x5f9636331695 in main /home/elsid/dev/openmw/apps/openmw/main.cpp:240
    #31 0x7254db435487  (/usr/lib/libc.so.6+0x27487) (BuildId: 0b707b217b15b106c25fe51df3724b25848310c0)
    #32 0x7254db43554b in __libc_start_main (/usr/lib/libc.so.6+0x2754b) (BuildId: 0b707b217b15b106c25fe51df3724b25848310c0)
    #33 0x5f9636331464 in _start (/home/elsid/dev/openmw/build/gcc/asan/openmw+0x10db464) (BuildId: ac74a52ca60e8913bef6eb6b3b23d6de648cf3c9)

0x50800060d4b0 is located 16 bytes inside of 96-byte region [0x50800060d4a0,0x50800060d500)
freed by thread T0 here:
    #0 0x7254e2afc102 in free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52
    #1 0x5f963a2f84e7 in LuaUtil::LuaState::trackingAllocator(void*, void*, unsigned long, unsigned long) /home/elsid/dev/openmw/components/lua/luastate.cpp:107
    #2 0x7254de4f7779  (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x51779) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #3 0x7254de4de7f3  (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x387f3) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #4 0x7254de4e1a9a  (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x3ba9a) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #5 0x7254de4e2a37  (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x3ca37) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #6 0x7254de50f4a4 in lua_gc (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x694a4) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #7 0x5f96371f615c in MWLua::LuaManager::clear() /home/elsid/dev/openmw/apps/openmw/mwlua/luamanagerimp.cpp:348
    #8 0x5f96371f91ea in MWLua::LuaManager::noGame() /home/elsid/dev/openmw/apps/openmw/mwlua/luamanagerimp.cpp:397
    #9 0x5f963a1c7170 in MWState::StateManager::cleanup(bool) /home/elsid/dev/openmw/apps/openmw/mwstate/statemanagerimp.cpp:71
    #10 0x5f963a1cabfe in MWState::StateManager::newGame(bool) /home/elsid/dev/openmw/apps/openmw/mwstate/statemanagerimp.cpp:169
    #11 0x5f963a1c7aa4 in MWState::StateManager::update(float) /home/elsid/dev/openmw/apps/openmw/mwstate/statemanagerimp.cpp:761
    #12 0x5f963a230bab in OMW::Engine::frame(unsigned int, float) /home/elsid/dev/openmw/apps/openmw/engine.cpp:238
    #13 0x5f963a2442f3 in OMW::Engine::go() /home/elsid/dev/openmw/apps/openmw/engine.cpp:1032
    #14 0x5f963633b3a7 in runApplication(int, char**) /home/elsid/dev/openmw/apps/openmw/main.cpp:228
    #15 0x5f963b375b45 in Debug::wrapApplication(int (*)(int, char**), int, char**, std::basic_string_view<char, std::char_traits<char> >) /home/elsid/dev/openmw/components/debug/debugging.cpp:457
    #16 0x5f9636331695 in main /home/elsid/dev/openmw/apps/openmw/main.cpp:240
    #17 0x7254db435487  (/usr/lib/libc.so.6+0x27487) (BuildId: 0b707b217b15b106c25fe51df3724b25848310c0)
    #18 0x7254db43554b in __libc_start_main (/usr/lib/libc.so.6+0x2754b) (BuildId: 0b707b217b15b106c25fe51df3724b25848310c0)
    #19 0x5f9636331464 in _start (/home/elsid/dev/openmw/build/gcc/asan/openmw+0x10db464) (BuildId: ac74a52ca60e8913bef6eb6b3b23d6de648cf3c9)

previously allocated by thread T20 here:
    #0 0x7254e2afc3c2 in realloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:85
    #1 0x5f963a2f7080 in LuaUtil::LuaState::trackingAllocator(void*, void*, unsigned long, unsigned long) /home/elsid/dev/openmw/components/lua/luastate.cpp:110
    #2 0x7254de4e2fc8  (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x3cfc8) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #3 0x7254de4f7476  (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x51476) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #4 0x7254de50c456 in lua_newthread (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x66456) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #5 0x7254de5d53e5  (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x12f3e5) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
    #6 0x7254de4dc0c5  (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x360c5) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)

Thread T20 created by T0 here:
    #0 0x7254e2af44cb in pthread_create /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_interceptors.cpp:245
    #1 0x7254db6e2071 in __gthread_create /usr/src/debug/gcc/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:676
    #2 0x7254db6e2071 in std:🧵:_M_start_thread(std::unique_ptr<std:🧵:_State, std::default_delete<std:🧵:_State> >, void (*)()) /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:172
    #3 0x5f96380fa2eb in thread<MWLua::Worker::Worker(MWLua::LuaManager&)::<lambda()> > /usr/include/c++/14.2.1/bits/std_thread.h:173
    #4 0x5f96380fa2eb in MWLua::Worker::Worker(MWLua::LuaManager&) /home/elsid/dev/openmw/apps/openmw/mwlua/worker.cpp:18
    #5 0x5f963a23faf4 in std::__detail::_MakeUniq<MWLua::Worker>::__single_object std::make_unique<MWLua::Worker, MWLua::LuaManager&>(MWLua::LuaManager&) /usr/include/c++/14.2.1/bits/unique_ptr.h:1077
    #6 0x5f963a23faf4 in OMW::Engine::prepareEngine() /home/elsid/dev/openmw/apps/openmw/engine.cpp:920
    #7 0x5f963a2413ae in OMW::Engine::go() /home/elsid/dev/openmw/apps/openmw/engine.cpp:952
    #8 0x5f963633b3a7 in runApplication(int, char**) /home/elsid/dev/openmw/apps/openmw/main.cpp:228
    #9 0x5f963b375b45 in Debug::wrapApplication(int (*)(int, char**), int, char**, std::basic_string_view<char, std::char_traits<char> >) /home/elsid/dev/openmw/components/debug/debugging.cpp:457
    #10 0x5f9636331695 in main /home/elsid/dev/openmw/apps/openmw/main.cpp:240
    #11 0x7254db435487  (/usr/lib/libc.so.6+0x27487) (BuildId: 0b707b217b15b106c25fe51df3724b25848310c0)
    #12 0x7254db43554b in __libc_start_main (/usr/lib/libc.so.6+0x2754b) (BuildId: 0b707b217b15b106c25fe51df3724b25848310c0)
    #13 0x5f9636331464 in _start (/home/elsid/dev/openmw/build/gcc/asan/openmw+0x10db464) (BuildId: ac74a52ca60e8913bef6eb6b3b23d6de648cf3c9)

SUMMARY: AddressSanitizer: heap-use-after-free (/home/elsid/dev/LuaJIT/build/gcc/asan/install/lib/libluajit-5.1.so.2+0x6293d) (BuildId: 1249151684379d19b11900f406fea9704a6375cb)
Shadow bytes around the buggy address:
  0x50800060d200: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 fa
  0x50800060d280: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 fa
  0x50800060d300: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 fa
  0x50800060d380: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 fa
  0x50800060d400: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 fa
=>0x50800060d480: fa fa fa fa fd fd[fd]fd fd fd fd fd fd fd fd fd
  0x50800060d500: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50800060d580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50800060d600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50800060d680: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50800060d700: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==8699==ABORTING
2025-03-01 15:54:24 +01:00
elsid
d400c0959c
Hide main menu on new and loading game from menu scripts 2025-02-28 18:11:22 +01:00
Alexei Kotov
ec2c031792 Make powers immune to silence (#8371) 2025-02-27 18:27:10 +03:00
uramer
3a98b945a8 Keep MENU-registered input actions between games 2025-02-26 16:56:41 +01:00
Alexei Kotov
a6676fd6f3 Merge branch 'actionshaveeffects' into 'master'
Turn ActorActiveEffects:remove into a delayed action

Closes #8317, #8350, and #8366

See merge request OpenMW/openmw!4553
2025-02-24 22:49:52 +00:00
Alexei Kotov
73bb281f34 Merge branch 'toscrollornottoscroll' into 'master'
Don't create a scrollbar that cannot be scrolled

Closes #8364

See merge request OpenMW/openmw!4552
2025-02-24 21:35:19 +00:00
Evil Eye
f891a7c3b3 Turn ActorActiveEffects:remove into a delayed action 2025-02-24 17:07:32 +01:00
psi29a
614ca25d3b Merge branch 'changelog' into 'master'
Move #6097 from 0.49.0 to 0.48.0 changelog

See merge request OpenMW/openmw!4544
2025-02-24 08:34:56 +00:00
psi29a
74018162c7 Merge branch 'deordmitri-master-patch-83688' into 'master'
Update install-game-files.rst

See merge request OpenMW/openmw!4269
2025-02-24 08:33:13 +00:00
Evil Eye
3e3dfac4e0 Don't create a scrollbar that cannot be scrolled 2025-02-23 10:48:13 +01:00
Alexei Kotov
dad22cb672 Apply jvoisin's suggestion to install-game-files.rst 2025-02-22 22:37:58 +00:00
Alexei Kotov
cf7e276a6a Remove file name exceptions (#7249) 2025-02-23 00:18:07 +03:00
Alexei Kotov
72cbf61b43 Rename apps/openmw/mwsound files and classes to follow naming conventions 2025-02-23 00:18:07 +03:00
Alexei Kotov
fc850cfe69 Rename components/crashcatcher files to follow naming conventions 2025-02-23 00:18:07 +03:00
Alexei Kotov
ac9505b536 Rename components/to_utf8 directory and files to follow naming conventions 2025-02-23 00:18:07 +03:00
Alexei Kotov
89426af94a Rename apps/components_tests files to follow naming conventions 2025-02-22 23:47:12 +03:00
Alexei Kotov
a3e19f9bb7 Rename apps/openmw_tests files to follow naming conventions 2025-02-22 23:47:12 +03:00
Alexei Kotov
dd16c87080 Rename components/platform files to follow naming conventions 2025-02-22 23:47:11 +03:00
Alexei Kotov
b997386cd3 Rename android-main.cpp to follow naming conventions 2025-02-22 23:47:09 +03:00
Alexei Kotov
7df74664e4 Rename gl4es-init.cpp/h to follow naming conventions 2025-02-22 21:49:49 +03:00
Alexei Kotov
3793ff8be8 Standardize components/fx file include guards 2025-02-22 21:14:58 +03:00
Alexei Kotov
5d5595cc5b Standardize components/bsa file include guards and order 2025-02-22 21:12:28 +03:00
Alexei Kotov
8b911ce3eb Rename components/fx files to follow naming conventions 2025-02-22 21:00:40 +03:00
Alexei Kotov
0254feefe3 Rename bsa_file.cpp/hpp to follow naming conventions 2025-02-22 20:52:39 +03:00
Evil Eye
07cc2a72bb Merge branch 'automove' into 'master'
Don't disable automove when the player can't move (#8358)

Closes #8358

See merge request OpenMW/openmw!4547
2025-02-22 11:18:39 +00:00
Alexei Kotov
835ad09657 Move #6097 from 0.49.0 to 0.48.0 changelog 2025-02-21 11:39:54 +03:00
Alexei Kotov
cd53cbbea2 Don't disable automove when the player can't move (#8358) 2025-02-21 01:38:08 +03:00
psi29a
5b788baa35 Merge branch 'screening' into 'master'
Editor: Fall back to the closest screen when necessary (#8354)

Closes #8354

See merge request OpenMW/openmw!4542
2025-02-19 11:27:33 +00:00
Alexei Kotov
04689334c5 Editor: Use the first/primary screen as last resort 2025-02-18 22:28:54 +03:00
Alexei Kotov
d71e4ec9f0 Editor: Fall back to the closest screen when necessary (#8354) 2025-02-18 13:31:13 +03:00
psi29a
6ede5635b3 Merge branch 'edgelord' into 'master'
Fix UB when pathgrid geometry is generated and all pathgrid edges are invalid

See merge request OpenMW/openmw!4541
2025-02-17 15:01:15 +00:00
Alexei Kotov
602a429a68 Fix UB when pathgrid geometry is generated and all pathgrid edges are invalid 2025-02-16 17:46:52 +03:00
psi29a
3b05ec0ab1 Merge branch 'countteleportula' into 'master'
Include Ptrs with a count of 0 in cell unloading

Closes #8311

See merge request OpenMW/openmw!4536
2025-02-14 18:25:14 +00:00
Alexei Kotov
1a9e29844b Implement TCB interpolation for vectors and scalars (#2379) 2025-02-13 13:41:34 +03:00
Evil Eye
ad8f6e5eb6 Include Ptrs with a count of 0 in cell unloading 2025-02-12 22:07:30 +01:00
psi29a
63e3b8f41b Merge branch 'levelledcreatures' into 'master'
Avoid reference to temporary in levelled creatures bindings (#8347)

Closes #8347

See merge request OpenMW/openmw!4535
2025-02-11 20:34:20 +00:00
psi29a
19793c21b4 Merge branch 'menucrash' into 'master'
Clear queued scripts when clearing the Lua manager

Closes #8346

See merge request OpenMW/openmw!4537
2025-02-11 20:33:11 +00:00
Evil Eye
86d56a0b1a Clear queued scripts when clearing the Lua manager 2025-02-10 20:04:24 +01:00
psi29a
782c274d86 Merge branch 'shutupsdl' into 'master'
Silence SDL3 window/display events coming from SDL2-compat

See merge request OpenMW/openmw!4531
2025-02-10 16:58:28 +00:00
psi29a
d2610973dd Merge branch 'shutupssg' into 'master'
Add a dummy serializer for billboards

See merge request OpenMW/openmw!4532
2025-02-10 16:58:21 +00:00
psi29a
3405dbab6d Merge branch 'nifboolvectors' into 'master'
Optimize NIF boolean list reading

See merge request OpenMW/openmw!4534
2025-02-10 16:57:53 +00:00
Alexei Kotov
5626d925e3 Avoid reference to temporary in levelled creatures bindings (#8347) 2025-02-10 13:07:31 +03:00
Alexei Kotov
c1960635d2 Optimize NIF boolean vector reading 2025-02-07 04:55:06 +03:00
Alexei Kotov
eaf9488ba0 Silence SDL3 window/display events coming from SDL2-compat 2025-02-04 20:30:19 +03:00
Alexei Kotov
cfa1ad0b33 Add a dummy serializer for billboards 2025-02-04 20:22:14 +03:00
Alexei Kotov
0f9be64904 Use the final effect cost to calculate enchantment price (#8340) 2025-02-04 09:21:13 +03:00
Evil Eye
7d2dd3422d Ignore missing global variables when filtering dialogue 2025-01-21 20:31:12 +01:00
Evil Eye
a645ec0910 Allow filters to apply to creatures 2025-01-21 20:25:13 +01:00
Evil Eye
3b50bcfb3a Allow GetSpellEffects to detect enchantments by id 2025-01-19 20:07:53 +01:00
AnyOldName3
84c497b1fb capitulate 2025-01-17 01:45:09 +00:00
AnyOldName3
33553c0cf7 Handle encoding a bit more cleverly
* use the value from the existing openmw.cfg if it exists and we weren't told to use something else on the command line
* write the value to openmw.cfg if it wasn't there or we've overridden it
2025-01-17 01:34:08 +00:00
AnyOldName3
e345fca99a trim_ws, too 2025-01-17 01:21:24 +00:00
AnyOldName3
88fe079f95 Don't mangle settings with the comment character in their value
'#' is a valid character in setting values - it's only a comment if it's the first non-" \t\r\n" character on a line.
Making the comment ignoring match the parser we use elsewhere should avoid mangling data.
2025-01-17 00:53:19 +00:00
Evil Eye
40cba7962c Bump us up to 0.50.0 2025-01-06 16:43:54 +01:00
Bob Tuttle
3ef2084f80 Update install-game-files.rst 2024-07-22 20:19:21 +00:00
1113 changed files with 62015 additions and 17791 deletions

View file

@ -1,18 +1,22 @@
Checks: > Checks: >
-*, -*,
boost-*,
portability-*, portability-*,
-portability-template-virtual-member-function,
clang-analyzer-*, clang-analyzer-*,
-clang-analyzer-optin*, -clang-analyzer-optin.*,
-clang-analyzer-cplusplus.NewDeleteLeaks, -clang-analyzer-cplusplus.NewDeleteLeaks,
-clang-analyzer-cplusplus.NewDelete,
-clang-analyzer-core.CallAndMessage, -clang-analyzer-core.CallAndMessage,
-modernize-avoid-bind modernize-avoid-bind,
WarningsAsErrors: > readability-identifier-naming
-*, WarningsAsErrors: '*'
boost-*, HeaderFilterRegex: '(apps|components)/'
portability-*, CheckOptions:
clang-analyzer-*, - key: readability-identifier-naming.ConceptCase
-clang-analyzer-optin*, value: CamelCase
-clang-analyzer-cplusplus.NewDeleteLeaks, - key: readability-identifier-naming.NamespaceCase
-clang-analyzer-core.CallAndMessage value: CamelCase
HeaderFilterRegex: '^(apps|components)' - key: readability-identifier-naming.NamespaceIgnoredRegexp
value: 'bpo|osg(DB|FX|Particle|Shadow|Viewer|Util)?'
- key: readability-identifier-naming.LocalVariableCase
value: camelBack

View file

@ -73,7 +73,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install Building Dependencies - name: Install Building Dependencies
run: CI/before_install.osx.sh run: CI/before_install.macos.sh
- name: Prime ccache - name: Prime ccache
uses: hendrikmuhs/ccache-action@v1 uses: hendrikmuhs/ccache-action@v1
@ -82,11 +82,9 @@ jobs:
max-size: 1000M max-size: 1000M
- name: Configure - name: Configure
run: CI/before_script.osx.sh run: CI/before_script.macos.sh
- name: Build - name: Build
run: | run: CI/macos/build.sh
cd build
make -j $(sysctl -n hw.logicalcpu) package
Output-Envs: Output-Envs:
name: Read .env file and expose it as output name: Read .env file and expose it as output
@ -106,7 +104,6 @@ jobs:
fail-fast: true fail-fast: true
matrix: matrix:
image: image:
- "2019"
- "2022" - "2022"
uses: ./.github/workflows/windows.yml uses: ./.github/workflows/windows.yml

View file

@ -4,9 +4,13 @@ on:
workflow_call: workflow_call:
inputs: inputs:
image: image:
description: MSVC image (2019/2022) description: Window Server image
required: true required: true
type: string type: string
msvc:
description: MSVC version (2019/2022)
default: "2022"
type: string
vcpkg-deps-tag: vcpkg-deps-tag:
description: Git tag of our deps description: Git tag of our deps
required: true required: true
@ -45,7 +49,7 @@ jobs:
- name: Download prebuilt vcpkg packages - name: Download prebuilt vcpkg packages
working-directory: ${{ github.workspace }}/deps working-directory: ${{ github.workspace }}/deps
run: | run: |
$MANIFEST = "vcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }}.txt" $MANIFEST = "vcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }}.txt"
curl --fail --retry 3 -L -o "$MANIFEST" "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/$MANIFEST" curl --fail --retry 3 -L -o "$MANIFEST" "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/$MANIFEST"
$lines = Get-Content "$MANIFEST" $lines = Get-Content "$MANIFEST"
$URL = $lines[0] $URL = $lines[0]
@ -61,7 +65,7 @@ jobs:
- name: Extract archived prebuilt vcpkg packages - name: Extract archived prebuilt vcpkg packages
working-directory: ${{ github.workspace }}/deps working-directory: ${{ github.workspace }}/deps
run: 7z x -y -ovcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }} $env:archive run: 7z x -y -ovcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }} $env:archive
- name: Cache Qt - name: Cache Qt
id: qt-cache id: qt-cache
@ -94,12 +98,12 @@ jobs:
-B ${{ github.workspace }}/build -B ${{ github.workspace }}/build
-G Ninja -G Ninja
-D CMAKE_BUILD_TYPE=${{ inputs.build-type }} -D CMAKE_BUILD_TYPE=${{ inputs.build-type }}
-D CMAKE_TOOLCHAIN_FILE='${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }}/scripts/buildsystems/vcpkg.cmake' -D CMAKE_TOOLCHAIN_FILE='${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }}/scripts/buildsystems/vcpkg.cmake'
-D CMAKE_PREFIX_PATH='${{ github.workspace }}/deps/Qt/6.6.3/msvc2019_64' -D CMAKE_PREFIX_PATH='${{ github.workspace }}/deps/Qt/6.6.3/msvc2019_64'
${{ inputs.package && '-D CMAKE_CXX_FLAGS_RELEASE="/O2 /Ob2 /DNDEBUG /Zi"' || '' }} ${{ inputs.package && '-D CMAKE_CXX_FLAGS_RELEASE="/O2 /Ob2 /DNDEBUG /Zi"' || '' }}
${{ inputs.package && '-D "CMAKE_EXE_LINKER_FLAGS_RELEASE=/DEBUG /INCREMENTAL:NO"' || '' }} ${{ inputs.package && '-D "CMAKE_EXE_LINKER_FLAGS_RELEASE=/DEBUG /INCREMENTAL:NO"' || '' }}
-D LuaJit_INCLUDE_DIR='${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/include/luajit' -D LuaJit_INCLUDE_DIR='${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/include/luajit'
-D LuaJit_LIBRARY='${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/lib/lua51.lib' -D LuaJit_LIBRARY='${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/lib/lua51.lib'
-D BUILD_BENCHMARKS=${{ ! inputs.package }} -D BUILD_BENCHMARKS=${{ ! inputs.package }}
-D BUILD_COMPONENTS_TESTS=${{ ! inputs.package }} -D BUILD_COMPONENTS_TESTS=${{ ! inputs.package }}
-D BUILD_OPENMW_TESTS=${{ ! inputs.package }} -D BUILD_OPENMW_TESTS=${{ ! inputs.package }}
@ -114,9 +118,9 @@ jobs:
- name: Copy missing DLLs - name: Copy missing DLLs
run: | run: |
cp ${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/bin/Release/MyGUIEngine.dll ${{ github.workspace }}/build cp ${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/bin/Release/MyGUIEngine.dll ${{ github.workspace }}/build
cp -Filter *.dll -Recurse ${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/bin/osgPlugins-3.6.5 ${{ github.workspace }}/build cp -Filter *.dll -Recurse ${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/bin/osgPlugins-3.6.5 ${{ github.workspace }}/build
cp ${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/bin/*.dll ${{ github.workspace }}/build cp ${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/bin/*.dll ${{ github.workspace }}/build
- name: Copy Qt DLLs - name: Copy Qt DLLs
working-directory: ${{ github.workspace }}/deps/Qt/6.6.3/msvc2019_64 working-directory: ${{ github.workspace }}/deps/Qt/6.6.3/msvc2019_64
@ -172,7 +176,7 @@ jobs:
env: env:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
run: | run: |
job_url=$(gh run --repo ${{ github.repository }} view ${{ github.run_id }} --json jobs --jq '.jobs[] | select(.name == "windows-${{ inputs.image }}") | .url') job_url=$(gh run --repo ${{ github.repository }} view ${{ github.run_id }} --json jobs --jq '.jobs[] | select(.name == "windows-${{ inputs.msvc }}") | .url')
printf "Ref ${{ github.ref }}\nJob ${job_url}\nCommit ${{ github.sha }}\n" > install/CI-ID.txt printf "Ref ${{ github.ref }}\nJob ${job_url}\nCommit ${{ github.sha }}\n" > install/CI-ID.txt
cp install/CI-ID.txt pdb/CI-ID.txt cp install/CI-ID.txt pdb/CI-ID.txt
cp install/CI-ID.txt SymStore/CI-ID.txt cp install/CI-ID.txt SymStore/CI-ID.txt
@ -180,19 +184,19 @@ jobs:
- name: Store OpenMW archived pdb files - name: Store OpenMW archived pdb files
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: openmw-windows-${{ inputs.image }}-pdb-${{ github.sha }} name: openmw-windows-${{ inputs.msvc }}-pdb-${{ github.sha }}
path: ${{ github.workspace }}/pdb/* path: ${{ github.workspace }}/pdb/*
- name: Store OpenMW build artifacts - name: Store OpenMW build artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: openmw-windows-${{ inputs.image }}-${{ github.sha }} name: openmw-windows-${{ inputs.msvc }}-${{ github.sha }}
path: ${{ github.workspace }}/install/* path: ${{ github.workspace }}/install/*
- name: Store symbol server artifacts - name: Store symbol server artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: openmw-windows-${{ inputs.image }}-sym-store-${{ github.sha }} name: openmw-windows-${{ inputs.msvc }}-sym-store-${{ github.sha }}
path: ${{ github.workspace }}/SymStore/* path: ${{ github.workspace }}/SymStore/*
- name: Upload to symbol server - name: Upload to symbol server

View file

@ -9,6 +9,8 @@ stages:
- test - test
workflow: workflow:
auto_cancel:
on_new_commit: interruptible
rules: rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
@ -27,14 +29,14 @@ variables:
.Ubuntu_Image: .Ubuntu_Image:
tags: tags:
- saas-linux-medium-amd64 - saas-linux-medium-amd64
image: ubuntu:22.04 image: ubuntu:24.04
rules: rules:
- if: $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"
Ubuntu_GCC_preprocess: Ubuntu_GCC_preprocess:
extends: .Ubuntu_Image extends: .Ubuntu_Image
cache: cache:
key: Ubuntu_GCC_preprocess.ubuntu_22.04.v1 key: Ubuntu_GCC_preprocess.ubuntu_24.04.v1
paths: paths:
- apt-cache/ - apt-cache/
- .cache/pip/ - .cache/pip/
@ -43,9 +45,12 @@ Ubuntu_GCC_preprocess:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
before_script: before_script:
- CI/install_debian_deps.sh openmw-deps openmw-deps-dynamic gcc_preprocess - CI/install_debian_deps.sh openmw-deps openmw-deps-dynamic gcc_preprocess
- pip3 install --user click termtables - pip3 install --user --break-system-packages click termtables
script: script:
- CI/ubuntu_gcc_preprocess.sh - CI/ubuntu_gcc_preprocess.sh
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ID != "7107382"
.Ubuntu: .Ubuntu:
extends: .Ubuntu_Image extends: .Ubuntu_Image
@ -56,6 +61,7 @@ Ubuntu_GCC_preprocess:
stage: build stage: build
variables: variables:
CMAKE_EXE_LINKER_FLAGS: -fuse-ld=mold CMAKE_EXE_LINKER_FLAGS: -fuse-ld=mold
OPENMW_CXX_FLAGS: "-Werror -Werror=implicit-fallthrough"
script: script:
- df -h - df -h
- export CCACHE_BASEDIR="`pwd`" - export CCACHE_BASEDIR="`pwd`"
@ -76,9 +82,9 @@ Ubuntu_GCC_preprocess:
- if [[ "${BUILD_TESTS_ONLY}" && ! "${BUILD_WITH_CODE_COVERAGE}" ]]; then ./openmw_detournavigator_navmeshtilescache_benchmark; fi - if [[ "${BUILD_TESTS_ONLY}" && ! "${BUILD_WITH_CODE_COVERAGE}" ]]; then ./openmw_detournavigator_navmeshtilescache_benchmark; fi
- if [[ "${BUILD_TESTS_ONLY}" && ! "${BUILD_WITH_CODE_COVERAGE}" ]]; then ./openmw_esm_refid_benchmark; fi - if [[ "${BUILD_TESTS_ONLY}" && ! "${BUILD_WITH_CODE_COVERAGE}" ]]; then ./openmw_esm_refid_benchmark; fi
- if [[ "${BUILD_TESTS_ONLY}" && ! "${BUILD_WITH_CODE_COVERAGE}" ]]; then ./openmw_settings_access_benchmark; fi - if [[ "${BUILD_TESTS_ONLY}" && ! "${BUILD_WITH_CODE_COVERAGE}" ]]; then ./openmw_settings_access_benchmark; fi
- ccache -s - ccache -svv
- df -h - df -h
- if [[ "${BUILD_WITH_CODE_COVERAGE}" ]]; then gcovr --xml-pretty --exclude-unreachable-branches --print-summary --root "${CI_PROJECT_DIR}" -j $(nproc) -o ../coverage.xml; fi - if [[ "${BUILD_WITH_CODE_COVERAGE}" ]]; then ~/.local/bin/gcovr --xml-pretty --exclude-unreachable-branches --gcov-ignore-parse-errors=negative_hits.warn_once_per_file --print-summary --root "${CI_PROJECT_DIR}" -j $(nproc) -o ../coverage.xml; fi
- ls | grep -v -e '^extern$' -e '^install$' -e '^components-tests.xml$' -e '^openmw-tests.xml$' -e '^openmw-cs-tests.xml$' | xargs -I '{}' rm -rf './{}' - ls | grep -v -e '^extern$' -e '^install$' -e '^components-tests.xml$' -e '^openmw-tests.xml$' -e '^openmw-cs-tests.xml$' | xargs -I '{}' rm -rf './{}'
- cd .. - cd ..
- df -h - df -h
@ -93,19 +99,20 @@ Ubuntu_GCC_preprocess:
Coverity: Coverity:
tags: tags:
- saas-linux-medium-amd64 - saas-linux-medium-amd64
image: ubuntu:22.04 image: ubuntu:24.04
stage: build stage: build
interruptible: false
rules: rules:
- if: $CI_PIPELINE_SOURCE == "schedule" - if: $CI_PIPELINE_SOURCE == "schedule"
cache: cache:
key: Coverity.ubuntu_22.04.v1 key: Coverity.ubuntu_24.04.v1
paths: paths:
- apt-cache/ - apt-cache/
- 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:
@ -121,23 +128,40 @@ 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 -s - 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
interruptible: false
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
cache: cache:
key: Ubuntu_GCC.ubuntu_22.04.v1 key: Ubuntu_GCC.ubuntu_24.04.v1
before_script: before_script:
- CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic - CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic
variables: variables:
@ -150,18 +174,20 @@ Ubuntu_GCC:
Ubuntu_GCC_asan: Ubuntu_GCC_asan:
extends: Ubuntu_GCC extends: Ubuntu_GCC
cache: cache:
key: Ubuntu_GCC_asan.ubuntu_22.04.v1 key: Ubuntu_GCC_asan.ubuntu_24.04.v1
variables: variables:
CMAKE_BUILD_TYPE: Debug CMAKE_BUILD_TYPE: Debug
CMAKE_CXX_FLAGS_DEBUG: -g -O1 -fno-omit-frame-pointer -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak CMAKE_CXX_FLAGS_DEBUG: -g -O1 -fno-omit-frame-pointer -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak
CMAKE_EXE_LINKER_FLAGS: -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak -fuse-ld=mold CMAKE_EXE_LINKER_FLAGS: -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak -fuse-ld=mold
BUILD_OPENMW_ONLY: 1 BUILD_OPENMW_ONLY: 1
# Disable -Werror due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105562
OPENMW_CXX_FLAGS: ""
Clang_Format: Clang_Format:
extends: .Ubuntu_Image extends: .Ubuntu_Image
stage: checks stage: checks
cache: cache:
key: Ubuntu_Clang_Format.ubuntu_22.04.v1 key: Ubuntu_Clang_Format.ubuntu_24.04.v1
paths: paths:
- apt-cache/ - apt-cache/
variables: variables:
@ -177,11 +203,11 @@ Lupdate:
extends: .Ubuntu_Image extends: .Ubuntu_Image
stage: checks stage: checks
cache: cache:
key: Ubuntu_lupdate.ubuntu_22.04.v1 key: Ubuntu_lupdate.ubuntu_24.04.v1
paths: paths:
- apt-cache/ - apt-cache/
variables: variables:
LUPDATE: lupdate LUPDATE: /usr/lib/qt6/bin/lupdate
before_script: before_script:
- CI/install_debian_deps.sh openmw-qt-translations - CI/install_debian_deps.sh openmw-qt-translations
script: script:
@ -203,7 +229,7 @@ Teal:
Ubuntu_GCC_Debug: Ubuntu_GCC_Debug:
extends: .Ubuntu extends: .Ubuntu
cache: cache:
key: Ubuntu_GCC_Debug.ubuntu_22.04.v2 key: Ubuntu_GCC_Debug.ubuntu_24.04.v2
before_script: before_script:
- CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic - CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic
variables: variables:
@ -219,7 +245,7 @@ Ubuntu_GCC_Debug:
Ubuntu_GCC_tests: Ubuntu_GCC_tests:
extends: Ubuntu_GCC extends: Ubuntu_GCC
cache: cache:
key: Ubuntu_GCC_tests.ubuntu_22.04.v1 key: Ubuntu_GCC_tests.ubuntu_24.04.v1
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -228,12 +254,12 @@ Ubuntu_GCC_tests:
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA} name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
when: always when: always
reports: reports:
junit: build/*_tests.xml junit: build/*-tests.xml
.Ubuntu_GCC_tests_Debug: .Ubuntu_GCC_tests_Debug:
extends: Ubuntu_GCC extends: Ubuntu_GCC
cache: cache:
key: Ubuntu_GCC_tests_Debug.ubuntu_22.04.v1 key: Ubuntu_GCC_tests_Debug.ubuntu_24.04.v1
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -244,12 +270,12 @@ Ubuntu_GCC_tests:
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA} name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
when: always when: always
reports: reports:
junit: build/*_tests.xml junit: build/*-tests.xml
Ubuntu_GCC_tests_asan: Ubuntu_GCC_tests_asan:
extends: Ubuntu_GCC extends: Ubuntu_GCC
cache: cache:
key: Ubuntu_GCC_tests_asan.ubuntu_22.04.v1 key: Ubuntu_GCC_tests_asan.ubuntu_24.04.v1
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -257,17 +283,22 @@ Ubuntu_GCC_tests_asan:
CMAKE_CXX_FLAGS_DEBUG: -g -O1 -fno-omit-frame-pointer -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak CMAKE_CXX_FLAGS_DEBUG: -g -O1 -fno-omit-frame-pointer -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak
CMAKE_EXE_LINKER_FLAGS: -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak -fuse-ld=mold CMAKE_EXE_LINKER_FLAGS: -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak -fuse-ld=mold
ASAN_OPTIONS: halt_on_error=1:strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1 ASAN_OPTIONS: halt_on_error=1:strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
# Disable -Werror due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105562
OPENMW_CXX_FLAGS: ""
artifacts: artifacts:
paths: [] paths: []
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA} name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
when: always when: always
reports: reports:
junit: build/*_tests.xml junit: build/*-tests.xml
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ID != "7107382"
Ubuntu_GCC_tests_ubsan: Ubuntu_GCC_tests_ubsan:
extends: Ubuntu_GCC extends: Ubuntu_GCC
cache: cache:
key: Ubuntu_GCC_tests_ubsan.ubuntu_22.04.v1 key: Ubuntu_GCC_tests_ubsan.ubuntu_24.04.v1
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -279,12 +310,15 @@ Ubuntu_GCC_tests_ubsan:
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA} name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
when: always when: always
reports: reports:
junit: build/*_tests.xml junit: build/*-tests.xml
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ID != "7107382"
.Ubuntu_GCC_tests_tsan: .Ubuntu_GCC_tests_tsan:
extends: Ubuntu_GCC extends: Ubuntu_GCC
cache: cache:
key: Ubuntu_GCC_tests_tsan.ubuntu_22.04.v1 key: Ubuntu_GCC_tests_tsan.ubuntu_24.04.v1
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -297,16 +331,20 @@ Ubuntu_GCC_tests_ubsan:
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA} name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
when: always when: always
reports: reports:
junit: build/*_tests.xml junit: build/*-tests.xml
Ubuntu_GCC_tests_coverage: Ubuntu_GCC_tests_coverage:
extends: .Ubuntu_GCC_tests_Debug extends: .Ubuntu_GCC_tests_Debug
cache: cache:
key: Ubuntu_GCC_tests_coverage.ubuntu_22.04.v1 key: Ubuntu_GCC_tests_coverage.ubuntu_24.04.v1
paths:
- .cache/pip
variables: variables:
BUILD_WITH_CODE_COVERAGE: 1 BUILD_WITH_CODE_COVERAGE: 1
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
before_script: before_script:
- CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic openmw-coverage - CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic openmw-coverage
- pipx install gcovr
coverage: /^\s*lines:\s*\d+.\d+\%/ coverage: /^\s*lines:\s*\d+.\d+\%/
artifacts: artifacts:
paths: [] paths: []
@ -316,7 +354,10 @@ Ubuntu_GCC_tests_coverage:
coverage_report: coverage_report:
coverage_format: cobertura coverage_format: cobertura
path: coverage.xml path: coverage.xml
junit: build/*_tests.xml junit: build/*-tests.xml
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ID != "7107382"
.Ubuntu_Static_Deps: .Ubuntu_Static_Deps:
extends: Ubuntu_Clang extends: Ubuntu_Clang
@ -328,7 +369,7 @@ Ubuntu_GCC_tests_coverage:
- "CI/**/*" - "CI/**/*"
- ".gitlab-ci.yml" - ".gitlab-ci.yml"
cache: cache:
key: Ubuntu_Static_Deps.ubuntu_22.04.v1 key: Ubuntu_Static_Deps.ubuntu_24.04.v1
paths: paths:
- apt-cache/ - apt-cache/
- ccache/ - ccache/
@ -345,7 +386,7 @@ Ubuntu_GCC_tests_coverage:
.Ubuntu_Static_Deps_tests: .Ubuntu_Static_Deps_tests:
extends: .Ubuntu_Static_Deps extends: .Ubuntu_Static_Deps
cache: cache:
key: Ubuntu_Static_Deps_tests.ubuntu_22.04.v1 key: Ubuntu_Static_Deps_tests.ubuntu_24.04.v1
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -357,14 +398,14 @@ Ubuntu_GCC_tests_coverage:
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA} name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
when: always when: always
reports: reports:
junit: build/*_tests.xml junit: build/*-tests.xml
Ubuntu_Clang: Ubuntu_Clang:
extends: .Ubuntu extends: .Ubuntu
before_script: before_script:
- CI/install_debian_deps.sh clang openmw-deps openmw-deps-dynamic - CI/install_debian_deps.sh clang openmw-deps openmw-deps-dynamic
cache: cache:
key: Ubuntu_Clang.ubuntu_22.04.v2 key: Ubuntu_Clang.ubuntu_24.04.v2
variables: variables:
CC: clang CC: clang
CXX: clang++ CXX: clang++
@ -377,7 +418,7 @@ Ubuntu_Clang:
before_script: before_script:
- CI/install_debian_deps.sh clang clang-tidy openmw-deps openmw-deps-dynamic - CI/install_debian_deps.sh clang clang-tidy openmw-deps openmw-deps-dynamic
cache: cache:
key: Ubuntu_Clang_Tidy.ubuntu_22.04.v1 key: Ubuntu_Clang_Tidy.ubuntu_24.04.v1
variables: variables:
CMAKE_BUILD_TYPE: Debug CMAKE_BUILD_TYPE: Debug
CMAKE_CXX_FLAGS_DEBUG: -O0 CMAKE_CXX_FLAGS_DEBUG: -O0
@ -388,15 +429,19 @@ Ubuntu_Clang:
- mkdir -pv "${CCACHE_DIR}" - mkdir -pv "${CCACHE_DIR}"
- ccache -z -M "${CCACHE_SIZE}" - ccache -z -M "${CCACHE_SIZE}"
- CI/before_script.linux.sh - CI/before_script.linux.sh
- cp extern/.clang-tidy build/.clang-tidy
- cd build - cd build
- find . -name *.o -exec touch {} \; - find . -name *.o -exec touch {} \;
- cmake --build . -- -j $(nproc) ${BUILD_TARGETS} - cmake --build . -- -j $(nproc) ${BUILD_TARGETS}
- ccache -s - ccache -svv
artifacts: artifacts:
paths: paths:
- build/ - build/
expire_in: 12h expire_in: 12h
timeout: 3h timeout: 3h
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ID != "7107382"
Ubuntu_Clang_Tidy_components: Ubuntu_Clang_Tidy_components:
extends: .Ubuntu_Clang_Tidy_Base extends: .Ubuntu_Clang_Tidy_Base
@ -409,7 +454,7 @@ Ubuntu_Clang_Tidy_openmw:
needs: needs:
- Ubuntu_Clang_Tidy_components - Ubuntu_Clang_Tidy_components
variables: variables:
BUILD_TARGETS: openmw BUILD_TARGETS: openmw openmw-tests
timeout: 3h timeout: 3h
Ubuntu_Clang_Tidy_openmw-cs: Ubuntu_Clang_Tidy_openmw-cs:
@ -425,13 +470,13 @@ Ubuntu_Clang_Tidy_other:
needs: needs:
- Ubuntu_Clang_Tidy_components - Ubuntu_Clang_Tidy_components
variables: variables:
BUILD_TARGETS: bsatool esmtool openmw-launcher openmw-iniimporter openmw-essimporter openmw-wizard niftest components-tests openmw-tests openmw-cs-tests openmw-navmeshtool openmw-bulletobjecttool BUILD_TARGETS: components-tests bsatool esmtool openmw-launcher openmw-iniimporter openmw-essimporter openmw-wizard niftest openmw-navmeshtool openmw-bulletobjecttool
timeout: 3h timeout: 3h
.Ubuntu_Clang_tests: .Ubuntu_Clang_tests:
extends: Ubuntu_Clang extends: Ubuntu_Clang
cache: cache:
key: Ubuntu_Clang_tests.ubuntu_22.04.v1 key: Ubuntu_Clang_tests.ubuntu_24.04.v1
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -440,12 +485,12 @@ Ubuntu_Clang_Tidy_other:
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA} name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
when: always when: always
reports: reports:
junit: build/*_tests.xml junit: build/*-tests.xml
Ubuntu_Clang_tests_Debug: Ubuntu_Clang_tests_Debug:
extends: Ubuntu_Clang extends: Ubuntu_Clang
cache: cache:
key: Ubuntu_Clang_tests_Debug.ubuntu_22.04.v1 key: Ubuntu_Clang_tests_Debug.ubuntu_24.04.v1
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -455,21 +500,21 @@ Ubuntu_Clang_tests_Debug:
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA} name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
when: always when: always
reports: reports:
junit: build/*_tests.xml junit: build/*-tests.xml
.Ubuntu_integration_tests_base: .Ubuntu_integration_tests_base:
extends: .Ubuntu_Image extends: .Ubuntu_Image
stage: test stage: test
variables: variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
EXAMPLE_SUITE_REVISION: f51b832e033429a7cdc520e0e48d7dfdb9141caa EXAMPLE_SUITE_REVISION: 3e01d10e073474a886a9efe3658088db14869627
cache: cache:
paths: paths:
- .cache/pip - .cache/pip
- apt-cache/ - apt-cache/
before_script: before_script:
- CI/install_debian_deps.sh $OPENMW_DEPS - CI/install_debian_deps.sh $OPENMW_DEPS
- pip3 install --user numpy matplotlib termtables click - pip3 install --user --break-system-packages numpy matplotlib termtables click
script: script:
- CI/run_integration_tests.sh - CI/run_integration_tests.sh
after_script: after_script:
@ -480,7 +525,7 @@ Ubuntu_Clang_integration_tests:
needs: needs:
- Ubuntu_Clang - Ubuntu_Clang
cache: cache:
key: Ubuntu_Clang_integration_tests.ubuntu_22.04.v2 key: Ubuntu_Clang_integration_tests.ubuntu_24.04.v2
variables: variables:
OPENMW_DEPS: openmw-integration-tests OPENMW_DEPS: openmw-integration-tests
@ -489,27 +534,35 @@ Ubuntu_GCC_integration_tests_asan:
needs: needs:
- Ubuntu_GCC_asan - Ubuntu_GCC_asan
cache: cache:
key: Ubuntu_GCC_integration_tests_asan.ubuntu_22.04.v1 key: Ubuntu_GCC_integration_tests_asan.ubuntu_24.04.v1
variables: variables:
OPENMW_DEPS: openmw-integration-tests libasan6 OPENMW_DEPS: openmw-integration-tests libasan
ASAN_OPTIONS: halt_on_error=1:strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:detect_leaks=0 ASAN_OPTIONS: halt_on_error=1:strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:detect_leaks=0
.MacOS: .MacOS:
stage: build stage: build
rules: rules:
- if: $CI_PROJECT_ID == "7107382" - if: $CI_PROJECT_ID != "7107382"
when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: manual
- if: $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "schedule"
image: macos-15-xcode-16
tags:
- saas-macos-medium-m1
cache: cache:
paths: paths:
- ccache/ - ccache/
script: script:
- CI/before_install.osx.sh - CI/before_install.macos.sh
- export CCACHE_BASEDIR="$(pwd)" - export CCACHE_BASEDIR="$(pwd)"
- export CCACHE_DIR="$(pwd)/ccache" - export CCACHE_DIR="$(pwd)/ccache"
- mkdir -pv "${CCACHE_DIR}" - mkdir -pv "${CCACHE_DIR}"
- ccache -z -M "${CCACHE_SIZE}" - CI/macos/ccache_prep.sh
- CI/before_script.osx.sh - CI/before_script.macos.sh
- cd build; make -j $(sysctl -n hw.logicalcpu) package - CI/macos/build.sh
- for dmg in *.dmg; do mv "$dmg" "${dmg%.dmg}_${CI_COMMIT_REF_NAME##*/}.dmg"; done - cd build
- for dmg in *.dmg; do mv "$dmg" "${dmg%.dmg}_${DMG_IDENTIFIER}_${CI_COMMIT_REF_NAME##*/}.dmg"; done
- | - |
if [[ -n "${AWS_ACCESS_KEY_ID}" ]]; then if [[ -n "${AWS_ACCESS_KEY_ID}" ]]; then
echo "[default]" > ~/.s3cfg echo "[default]" > ~/.s3cfg
@ -524,20 +577,33 @@ Ubuntu_GCC_integration_tests_asan:
s3cmd put "${dmg}" s3://openmw-artifacts/${artifactDirectory} s3cmd put "${dmg}" s3://openmw-artifacts/${artifactDirectory}
done done
fi fi
- ccache -s - ../CI/macos/ccache_save.sh
artifacts: artifacts:
paths: paths:
- build/OpenMW-*.dmg - build/OpenMW-*.dmg
macOS14_Xcode15_arm64: macOS15_Xcode16_amd64:
extends: .MacOS extends: .MacOS
image: macos-14-xcode-15
tags:
- saas-macos-medium-m1
cache: cache:
key: macOS14_Xcode15_arm64.v1 key: macOS15_Xcode16_amd64.v1
variables: variables:
CCACHE_SIZE: 3G CCACHE_SIZE: 3G
DMG_IDENTIFIER: amd64
MACOS_AMD64: true
HOMEBREW_NO_AUTO_UPDATE: 1
HOMEBREW_NO_EMOJI: true
HOMEBREW_NO_INSTALL_CLEANUP: true
macOS15_Xcode16_arm64:
extends: .MacOS
cache:
key: macOS15_Xcode16_arm64.v1
variables:
DMG_IDENTIFIER: arm64
CCACHE_SIZE: 3G
HOMEBREW_NO_AUTO_UPDATE: 1
HOMEBREW_NO_EMOJI: true
HOMEBREW_NO_INSTALL_CLEANUP: true
.Compress_And_Upload_Symbols_Base: .Compress_And_Upload_Symbols_Base:
extends: .Ubuntu_Image extends: .Ubuntu_Image
@ -632,12 +698,16 @@ macOS14_Xcode15_arm64:
- | - |
if (Get-ChildItem -Recurse *.pdb) { if (Get-ChildItem -Recurse *.pdb) {
7z a -tzip "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" '*.pdb' CI-ID.txt 7z a -tzip "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" '*.pdb' CI-ID.txt
if(!$?) { Exit $LASTEXITCODE }
if (Test-Path env:AWS_ACCESS_KEY_ID) { if (Test-Path env:AWS_ACCESS_KEY_ID) {
aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" s3://openmw-artifacts/${artifactDirectory} aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" s3://openmw-artifacts/${artifactDirectory}
if(!$?) { Exit $LASTEXITCODE }
} }
Push-Location .. Push-Location ..
..\CI\Store-Symbols.ps1 -SkipCompress ..\CI\Store-Symbols.ps1 -SkipCompress
if(!$?) { Exit $LASTEXITCODE }
7z a -tzip "..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_sym_store.zip"))" '.\SymStore\*' $config\CI-ID.txt 7z a -tzip "..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_sym_store.zip"))" '.\SymStore\*' $config\CI-ID.txt
if(!$?) { Exit $LASTEXITCODE }
Pop-Location Pop-Location
Get-ChildItem -Recurse *.pdb | Remove-Item Get-ChildItem -Recurse *.pdb | Remove-Item
} }
@ -645,13 +715,20 @@ macOS14_Xcode15_arm64:
- | - |
if (Test-Path env:AWS_ACCESS_KEY_ID) { if (Test-Path env:AWS_ACCESS_KEY_ID) {
aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}.zip"))" s3://openmw-artifacts/${artifactDirectory} aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}.zip"))" s3://openmw-artifacts/${artifactDirectory}
if(!$?) { Exit $LASTEXITCODE }
}
- |
if ($executables) {
foreach ($exe in $executables.Split(',')) {
& .\$exe
if(!$?) { Exit $LASTEXITCODE }
}
} }
- if ($executables) { foreach ($exe in $executables.Split(',')) { & .\$exe } }
after_script: after_script:
- Get-Volume - Get-Volume
- Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log - Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log
cache: cache:
key: ninja-2022-v11 key: ninja-2022-v13
paths: paths:
- ccache - ccache
- deps - deps
@ -779,12 +856,16 @@ macOS14_Xcode15_arm64:
- | - |
if (Get-ChildItem -Recurse *.pdb) { if (Get-ChildItem -Recurse *.pdb) {
7z a -tzip "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" '*.pdb' CI-ID.txt 7z a -tzip "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" '*.pdb' CI-ID.txt
if(!$?) { Exit $LASTEXITCODE }
if (Test-Path env:AWS_ACCESS_KEY_ID) { if (Test-Path env:AWS_ACCESS_KEY_ID) {
aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" s3://openmw-artifacts/${artifactDirectory} aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" s3://openmw-artifacts/${artifactDirectory}
if(!$?) { Exit $LASTEXITCODE }
} }
Push-Location .. Push-Location ..
..\CI\Store-Symbols.ps1 -SkipCompress ..\CI\Store-Symbols.ps1 -SkipCompress
if(!$?) { Exit $LASTEXITCODE }
7z a -tzip "..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_sym_store.zip"))" '.\SymStore\*' $config\CI-ID.txt 7z a -tzip "..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_sym_store.zip"))" '.\SymStore\*' $config\CI-ID.txt
if(!$?) { Exit $LASTEXITCODE }
Pop-Location Pop-Location
Get-ChildItem -Recurse *.pdb | Remove-Item Get-ChildItem -Recurse *.pdb | Remove-Item
} }
@ -792,13 +873,20 @@ macOS14_Xcode15_arm64:
- | - |
if (Test-Path env:AWS_ACCESS_KEY_ID) { if (Test-Path env:AWS_ACCESS_KEY_ID) {
aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}.zip"))" s3://openmw-artifacts/${artifactDirectory} aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}.zip"))" s3://openmw-artifacts/${artifactDirectory}
if(!$?) { Exit $LASTEXITCODE }
}
- |
if ($executables) {
foreach ($exe in $executables.Split(',')) {
& .\$exe
if(!$?) { Exit $LASTEXITCODE }
}
} }
- if ($executables) { foreach ($exe in $executables.Split(',')) { & .\$exe } }
after_script: after_script:
- Get-Volume - Get-Volume
- Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log - Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log
cache: cache:
key: msbuild-2022-v11 key: msbuild-2022-v13
paths: paths:
- deps - deps
- MSVC2022_64/deps/Qt - MSVC2022_64/deps/Qt
@ -899,7 +987,7 @@ Windows_MSBuild_CacheInit:
- cd build - cd build
- cmake --build . -- -j $(nproc) - cmake --build . -- -j $(nproc)
# - cmake --install . # no one uses builds anyway, disable until 'no space left' is resolved # - cmake --install . # no one uses builds anyway, disable until 'no space left' is resolved
- ccache -s - ccache -svv
- df -h - df -h
- ls | grep -v -e '^extern$' -e '^install$' | xargs -I '{}' rm -rf './{}' - ls | grep -v -e '^extern$' -e '^install$' | xargs -I '{}' rm -rf './{}'
- cd .. - cd ..
@ -927,7 +1015,7 @@ Windows_MSBuild_CacheInit:
paths: paths:
- .cache/pip - .cache/pip
before_script: before_script:
- pip3 install --user requests click discord_webhook - pip3 install --user --break-system-packages requests click discord_webhook
script: script:
- scripts/find_missing_merge_requests.py --project_id=$CI_PROJECT_ID --ignored_mrs_path=$CI_PROJECT_DIR/.resubmitted_merge_requests.txt - scripts/find_missing_merge_requests.py --project_id=$CI_PROJECT_ID --ignored_mrs_path=$CI_PROJECT_DIR/.resubmitted_merge_requests.txt

View file

@ -10,4 +10,4 @@ python:
build: build:
os: ubuntu-22.04 os: ubuntu-22.04
tools: tools:
python: "3.8" python: "3.9"

View file

@ -10,7 +10,8 @@ If you feel your name is missing from this list, please add it to `AUTHORS.md`.
Programmers Programmers
----------- -----------
Bret Curtis (psi29a) - Project leader 2019-present Alexey Dobrokhotov (Capo) - Project leader 2025-present
Bret Curtis (psi29a) - Project leader 2019-2025
Marc Zinnschlag (Zini) - Project leader 2010-2018 Marc Zinnschlag (Zini) - Project leader 2010-2018
Nicolay Korslund - Project leader 2008-2010 Nicolay Korslund - Project leader 2008-2010
scrawl - Top contributor scrawl - Top contributor
@ -49,10 +50,10 @@ Programmers
Berulacks Berulacks
Bo Svensson Bo Svensson
Britt Mathis (galdor557) Britt Mathis (galdor557)
Capostrophic
Carl Maxwell Carl Maxwell
cc9cii cc9cii
Cédric Mocquillon Cédric Mocquillon
Charles Horn
Chris Boyce (slothlife) Chris Boyce (slothlife)
Chris Robinson (KittyCat) Chris Robinson (KittyCat)
Chris Vigil Chris Vigil
@ -196,7 +197,7 @@ Programmers
Qlonever Qlonever
Radu-Marius Popovici (rpopovici) Radu-Marius Popovici (rpopovici)
Rafael Moura (dhustkoder) Rafael Moura (dhustkoder)
Randy Davin (Kindi) Randy Davin (Kuyondo)
rdimesio rdimesio
rexelion rexelion
riothamus riothamus
@ -232,6 +233,7 @@ Programmers
Tess (tescoShoppah) Tess (tescoShoppah)
thegriglat thegriglat
Thomas Luppi (Digmaster) Thomas Luppi (Digmaster)
Tim Hagberg (hazardMan)
tlmullis tlmullis
trav trav
tri4ng1e tri4ng1e

View file

@ -1,3 +1,97 @@
0.50.0
------
Bug #2967: Inventory windows don't update when changing items by script
Bug #4437: Transformations for NiSkinInstance are ignored
Bug #4885: Disable in dialogue result script causes a crash
Bug #5331: Pathfinding works incorrectly when actor is moved from one interior cell to another
Bug #6029: Hostile NPCs are perfectly aware of a player character with a 75% Chameleon effect
Bug #6039: Next Spell keybind fails while selected enchanted item has multiple copies
Bug #6573: Editor: Selection behaves incorrectly on high-DPI displays
Bug #6792: Birth sign info box has no line breaks
Bug #7371: Equipping item from inventory does not play a Down sound when equipping fails
Bug #7622: Player's marksman weapons don't work on close actors underwater
Bug #7649: The sound and vfx of resisted enchanted items' magic still play
Bug #7693: I.ItemUsage should return an item to the selected stack if equipping/consumption is denied
Bug #7740: Magic items in the HUD aren't composited correctly
Bug #7799: Picking up ingredients while object paging active grid is on may cause a hiccup
Bug #7871: Kwama Queen doesn't start combat with player
Bug #7979: Paralyzed NPCs battlecry
Bug #8012: Startcombat and Stopcombat do not affect music in the menu mode
Bug #8245: The console command ShowVars does not list global mwscripts
Bug #8265: Topics are linked incorrectly
Bug #8303: On target spells cast by non-actors should fire underwater
Bug #8309: RemoveSpell should instantly remove the spell's effects
Bug #8318: Missing global variables are not handled gracefully in dialogue conditions
Bug #8333: Quest status subrecords should not actually cause parsing to skip remaining data
Bug #8340: Multi-effect enchantments are too expensive
Bug #8341: Repeat shader visitor passes discard parallax
Bug #8349: Travel to non-existent cell causes persistent black screen
Bug #8359: Some quick keys menu related issues
Bug #8371: Silence affects powers
Bug #8375: Moon phase cycle doesn't match Morrowind
Bug #8383: Casting bound helm or boots on beast races doesn't cleanup properly
Bug #8385: Russian encoding broken with locale parameters and calendar
Bug #8399: Jail skill increases don't count as progress towards the next level
Bug #8404: Prevent merchant equipping breaks on lights
Bug #8408: OpenMW doesn't report all the potential resting hindrances
Bug #8414: Waterwalking works when collision is disabled
Bug #8431: Behaviour of removed items from a container is buggy
Bug #8432: Changing to and from an interior cell doesn't update collision
Bug #8433: Wandering NPCs are not capable of avoiding easy obstacles
Bug #8436: Spell selection in a pinned spellbook window doesn't update
Bug #8437: Pinned inventory window's pin button doesn't look pressed
Bug #8446: Travel prices are strangely inconsistent
Bug #8447: Werewolf swimming animation breaks in third person perspective
Bug #8459: Changing magic effect base cost doesn't change spell price
Bug #8466: Showmap "" reveals nameless cells
Bug #8485: Witchwither disease and probably other common diseases don't work correctly
Bug #8490: Normals on Water disappear when Water Shader is Enabled but Refraction is Disabled
Bug #8500: OpenMW Alarm behaviour doesn't match morrowind.exe
Bug #8519: Multiple bounty is sometimes assigned to player when detected during a pickpocketing action
Bug #8540: Magic resistance is applied to effects without a magnitude
Bug #8557: Charm's disposition changes capped on 100, uncapped below 0
Bug #8582: addScript-attached local scripts start out inactive
Bug #8584: Spacing of service menu list entries is inconsistent
Bug #8585: Dialogue topic list doesn't have enough padding
Bug #8587: Minor INI importer problems
Bug #8593: Render targets do not generate mipmaps
Bug #8598: Post processing shaders don't interact with the vfs correctly
Bug #8599: Non-ASCII paths in BSA files don't work
Bug #8606: Floating point imprecision can mess with container capacity
Bug #8609: The crosshair is too large
Bug #8610: Terrain normal maps using NormalGL format instead of NormalDX
Bug #8612: Using aiactivate on an ingredient when graphical herbalism is enabled triggers non-stop pickup sounds
Bug #8614: Lua garbage collection fails to remove unused data
Bug #8615: Rest/wait time progress speed is different from vanilla
Bug #8620: Create/CloneCommand can reuse refNums, causing severe issues in-game
Bug #8650: Some plants turn invisible when being called types.Container.inventory(cont):isResolved()
Feature #2522: Support quick item transfer
Feature #3740: Gamepad GUI Mode
Feature #3769: Allow GetSpellEffects on enchantments
Feature #6000: Oblivion terrain rendering
Feature #6976: [Lua] Weather API
Feature #7813: Add audio doppler for 3d sounds
Feature #7966: Add Lua read access to TES3 player's journal records
Feature #8077: Save settings changes when clicking "ok"/closing the window
Feature #8112: Expose landscape record data to Lua
Feature #8113: Support extended selection in autodetected subdirectory dialog
Feature #8139: Editor: Redesign the selection markers
Feature #8285: Expose list of active shaders in postprocessing API
Feature #8290: Show player gold in Spellmaking
Feature #8313: Show the character name in the savegame details
Feature #8320: Add access mwscript source text to lua api
Feature #8334: Lua: AddTopic equivalent
Feature #8355: Lua: Window visibility checking in interfaces.UI
Feature #8509: FillJournal script instruction
Feature #8579: Bulk (un)indentation in mwscript editor
Feature #8580: Sort characters in the save loading menu
Feature #8597: Lua: Add more built-in event handlers
Feature #8629: Expose path grid data to Lua
Feature #8642: Partially dehardcode on-hit mechanics
Feature #8654: Allow lua world.createRecord to create NPC records
Task #8578: Drop support for Qt5
0.49.0 0.49.0
------ ------
@ -35,7 +129,6 @@
Bug #5977: Fatigueless NPCs' corpse underwater changes animation on game load Bug #5977: Fatigueless NPCs' corpse underwater changes animation on game load
Bug #6025: Subrecords cannot overlap records Bug #6025: Subrecords cannot overlap records
Bug #6027: Collisionshape becomes spiderweb-like when the mesh is too complex Bug #6027: Collisionshape becomes spiderweb-like when the mesh is too complex
Bug #6097: Level Progress Tooltip Sometimes Not Updated
Bug #6146: Lua command `actor:setEquipment` doesn't trigger mwscripts when equipping or unequipping a scripted item Bug #6146: Lua command `actor:setEquipment` doesn't trigger mwscripts when equipping or unequipping a scripted item
Bug #6156: 1ft Charm or Sound magic effect vfx doesn't work properly Bug #6156: 1ft Charm or Sound magic effect vfx doesn't work properly
Bug #6190: Unintuitive sun specularity time of day dependence Bug #6190: Unintuitive sun specularity time of day dependence
@ -228,6 +321,17 @@
Bug #8252: Plugin dependencies are not required to be loaded Bug #8252: Plugin dependencies are not required to be loaded
Bug #8295: Post-processing chain is case-sensitive Bug #8295: Post-processing chain is case-sensitive
Bug #8299: Crash while smoothing landscape Bug #8299: Crash while smoothing landscape
Bug #8364: Crash when clicking scrollbar without handle (divide by zero)
Bug #8378: Korean bitmap fonts are unusable
Bug #8439: Creatures without models can crash the game
Bug #8441: Freeze when using video main menu replacers
Bug #8445: Launcher crashes on exit when cell name loading thread is still running
Bug #8462: Crashes when resizing the window on macOS
Bug #8465: Blue screen w/ antialiasing and post-processing on macOS
Bug #8503: Camera does not handle NaN gracefully
Bug #8541: Lua: util.color:asHex produces wrong output for some colors
Bug #8567: Token replacement does not work via CLI and relative paths passed via the command line are not relative to the CWD
Bug #8576: Crash on exit when unresolving containers with scripted items
Feature #1415: Infinite fall failsafe Feature #1415: Infinite fall failsafe
Feature #2566: Handle NAM9 records for manual cell references Feature #2566: Handle NAM9 records for manual cell references
Feature #3501: OpenMW-CS: Instance Editing - Shortcuts for axial locking Feature #3501: OpenMW-CS: Instance Editing - Shortcuts for axial locking
@ -392,6 +496,7 @@
Bug #6066: Addtopic "return" does not work from within script. No errors thrown Bug #6066: Addtopic "return" does not work from within script. No errors thrown
Bug #6067: ESP loader fails for certain subrecord orders Bug #6067: ESP loader fails for certain subrecord orders
Bug #6087: Bound items added directly to the inventory disappear if their corresponding spell effect ends Bug #6087: Bound items added directly to the inventory disappear if their corresponding spell effect ends
Bug #6097: Level Progress Tooltip Sometimes Not Updated
Bug #6101: Disarming trapped unlocked owned objects isn't considered a crime Bug #6101: Disarming trapped unlocked owned objects isn't considered a crime
Bug #6107: Fatigue is incorrectly recalculated when fortify effect is applied or removed Bug #6107: Fatigue is incorrectly recalculated when fortify effect is applied or removed
Bug #6109: Crash when playing a custom made menu_background file Bug #6109: Crash when playing a custom made menu_background file

7
CI/before_install.macos.sh Executable file
View file

@ -0,0 +1,7 @@
#!/bin/sh -ex
if [[ "${MACOS_AMD64}" ]]; then
./CI/macos/before_install.amd64.sh
else
./CI/macos/before_install.arm64.sh
fi

View file

@ -1,30 +0,0 @@
#!/bin/sh -ex
export HOMEBREW_NO_EMOJI=1
export HOMEBREW_NO_INSTALL_CLEANUP=1
export HOMEBREW_AUTOREMOVE=1
brew tap --repair
brew update --quiet
brew install curl xquartz gd fontconfig freetype harfbuzz brotli s3cmd
command -v ccache >/dev/null 2>&1 || brew install ccache
command -v cmake >/dev/null 2>&1 || brew install cmake
command -v qmake >/dev/null 2>&1 || brew install qt@5
export PATH="/opt/homebrew/opt/qt@5/bin:$PATH"
# Install deps
brew install openal-soft icu4c yaml-cpp sqlite
ccache --version
cmake --version
qmake --version
if [[ "${MACOS_AMD64}" ]]; then
curl -fSL -R -J https://gitlab.com/OpenMW/openmw-deps/-/raw/main/macos/openmw-deps-20240802.zip -o ~/openmw-deps.zip
unzip -o ~/openmw-deps.zip -d /tmp > /dev/null
else
curl -fSL -R -J https://gitlab.com/OpenMW/openmw-deps/-/raw/main/macos/openmw-deps-20240818-arm64.tar.xz -o ~/openmw-deps.tar.xz
tar xf ~/openmw-deps.tar.xz -C /tmp > /dev/null
fi

View file

@ -17,7 +17,7 @@ declare -a CMAKE_CONF_OPTS=(
-DBUILD_SHARED_LIBS="${BUILD_SHARED_LIBS:-OFF}" -DBUILD_SHARED_LIBS="${BUILD_SHARED_LIBS:-OFF}"
-DUSE_SYSTEM_TINYXML=ON -DUSE_SYSTEM_TINYXML=ON
-DOPENMW_USE_SYSTEM_RECASTNAVIGATION=ON -DOPENMW_USE_SYSTEM_RECASTNAVIGATION=ON
-DOPENMW_CXX_FLAGS="-Werror -Werror=implicit-fallthrough" # flags specific to OpenMW project -DOPENMW_CXX_FLAGS="${OPENMW_CXX_FLAGS}" # flags specific to OpenMW project
) )
if [[ "${CMAKE_EXE_LINKER_FLAGS}" ]]; then if [[ "${CMAKE_EXE_LINKER_FLAGS}" ]]; then
@ -38,7 +38,7 @@ fi
if [[ $CI_CLANG_TIDY ]]; then if [[ $CI_CLANG_TIDY ]]; then
CMAKE_CONF_OPTS+=( CMAKE_CONF_OPTS+=(
-DCMAKE_CXX_CLANG_TIDY="clang-tidy;--warnings-as-errors=*" -DCMAKE_CXX_CLANG_TIDY=clang-tidy
-DBUILD_COMPONENTS_TESTS=ON -DBUILD_COMPONENTS_TESTS=ON
-DBUILD_OPENMW_TESTS=ON -DBUILD_OPENMW_TESTS=ON
-DBUILD_OPENCS_TESTS=ON -DBUILD_OPENCS_TESTS=ON

77
CI/before_script.macos.sh Executable file
View file

@ -0,0 +1,77 @@
#!/bin/sh -e
# Silence a git warning
git config --global advice.detachedHead false
rm -fr build
mkdir build
cd build
DEPENDENCIES_ROOT="/tmp/openmw-deps"
if [[ "${MACOS_AMD64}" ]]; then
QT_PATH=$(arch -x86_64 /usr/local/bin/brew --prefix qt@6)
ICU_PATH=$(arch -x86_64 /usr/local/bin/brew --prefix icu4c)
OPENAL_PATH=$(arch -x86_64 /usr/local/bin/brew --prefix openal-soft)
CCACHE_EXECUTABLE=$(arch -x86_64 /usr/local/bin/brew --prefix ccache)/bin/ccache
else
QT_PATH=$(brew --prefix qt@6)
ICU_PATH=$(brew --prefix icu4c)
OPENAL_PATH=$(brew --prefix openal-soft)
CCACHE_EXECUTABLE=$(brew --prefix ccache)/bin/ccache
fi
declare -a CMAKE_CONF_OPTS=(
-D CMAKE_PREFIX_PATH="$DEPENDENCIES_ROOT;$QT_PATH;$OPENAL_PATH"
-D CMAKE_C_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE"
-D CMAKE_CXX_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE"
-D CMAKE_CXX_FLAGS="-stdlib=libc++"
-D CMAKE_C_COMPILER="clang"
-D CMAKE_CXX_COMPILER="clang++"
-D CMAKE_OSX_DEPLOYMENT_TARGET="13.6"
-D OPENMW_USE_SYSTEM_RECASTNAVIGATION=TRUE
-D Boost_INCLUDE_DIR="$DEPENDENCIES_ROOT/include"
-D OSGPlugins_LIB_DIR="$DEPENDENCIES_ROOT/lib/osgPlugins-3.6.5"
-D ICU_ROOT="$ICU_PATH"
-D OPENMW_OSX_DEPLOYMENT=TRUE
)
declare -a BUILD_OPTS=(
-D BUILD_OPENMW=TRUE
-D BUILD_OPENCS=TRUE
-D BUILD_ESMTOOL=TRUE
-D BUILD_BSATOOL=TRUE
-D BUILD_ESSIMPORTER=TRUE
-D BUILD_NIFTEST=TRUE
-D BUILD_NAVMESHTOOL=TRUE
-D BUILD_BULLETOBJECTTOOL=TRUE
-G"Unix Makefiles"
)
if [[ "${MACOS_AMD64}" ]]; then
CMAKE_CONF_OPTS+=(
-D CMAKE_OSX_ARCHITECTURES="x86_64"
)
fi
if [[ "${CMAKE_BUILD_TYPE}" ]]; then
CMAKE_CONF_OPTS+=(
-D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
)
else
CMAKE_CONF_OPTS+=(
-D CMAKE_BUILD_TYPE=RelWithDebInfo
)
fi
if [[ "${MACOS_AMD64}" ]]; then
arch -x86_64 cmake \
"${CMAKE_CONF_OPTS[@]}" \
"${BUILD_OPTS[@]}" \
..
else
cmake \
"${CMAKE_CONF_OPTS[@]}" \
"${BUILD_OPTS[@]}" \
..
fi

View file

@ -377,6 +377,8 @@ case $VS_VERSION in
MSVC_DISPLAY_YEAR="2022" MSVC_DISPLAY_YEAR="2022"
QT_MSVC_YEAR="2019" QT_MSVC_YEAR="2019"
VCPKG_TRIPLET="x64-windows"
;; ;;
16|16.0|2019 ) 16|16.0|2019 )
@ -386,6 +388,8 @@ case $VS_VERSION in
MSVC_DISPLAY_YEAR="2019" MSVC_DISPLAY_YEAR="2019"
QT_MSVC_YEAR="2019" QT_MSVC_YEAR="2019"
VCPKG_TRIPLET="x64-windows-2019"
;; ;;
15|15.0|2017 ) 15|15.0|2017 )
@ -546,7 +550,7 @@ fi
QT_VER='6.6.3' QT_VER='6.6.3'
AQT_VERSION='v3.1.15' AQT_VERSION='v3.1.15'
VCPKG_TAG="2024-11-10" VCPKG_TAG="2025-07-23"
VCPKG_PATH="vcpkg-x64-${VS_VERSION:?}-${VCPKG_TAG:?}" VCPKG_PATH="vcpkg-x64-${VS_VERSION:?}-${VCPKG_TAG:?}"
VCPKG_PDB_PATH="vcpkg-x64-${VS_VERSION:?}-pdb-${VCPKG_TAG:?}" VCPKG_PDB_PATH="vcpkg-x64-${VS_VERSION:?}-pdb-${VCPKG_TAG:?}"
VCPKG_MANIFEST="${VCPKG_PATH:?}.txt" VCPKG_MANIFEST="${VCPKG_PATH:?}.txt"
@ -633,16 +637,16 @@ printf "vcpkg packages ${VCPKG_TAG:?}... "
fi fi
add_cmake_opts -DCMAKE_TOOLCHAIN_FILE="$(real_pwd)/${VCPKG_PATH:?}/scripts/buildsystems/vcpkg.cmake" add_cmake_opts -DCMAKE_TOOLCHAIN_FILE="$(real_pwd)/${VCPKG_PATH:?}/scripts/buildsystems/vcpkg.cmake"
add_cmake_opts -DLuaJit_INCLUDE_DIR="$(real_pwd)/${VCPKG_PATH:?}/installed/x64-windows/include/luajit" add_cmake_opts -DLuaJit_INCLUDE_DIR="$(real_pwd)/${VCPKG_PATH:?}/installed/${VCPKG_TRIPLET}/include/luajit"
add_cmake_opts -DLuaJit_LIBRARY="$(real_pwd)/${VCPKG_PATH:?}/installed/x64-windows/lib/lua51.lib" add_cmake_opts -DLuaJit_LIBRARY="$(real_pwd)/${VCPKG_PATH:?}/installed/${VCPKG_TRIPLET}/lib/lua51.lib"
for CONFIGURATION in ${CONFIGURATIONS[@]}; do for CONFIGURATION in ${CONFIGURATIONS[@]}; do
if [[ ${CONFIGURATION:?} == "Debug" ]]; then if [[ ${CONFIGURATION:?} == "Debug" ]]; then
VCPKG_DLL_BIN="$(pwd)/${VCPKG_PATH:?}/installed/x64-windows/debug/bin" VCPKG_DLL_BIN="$(pwd)/${VCPKG_PATH:?}/installed/${VCPKG_TRIPLET}/debug/bin"
add_runtime_dlls ${CONFIGURATION:?} "${VCPKG_DLL_BIN:?}/Debug/MyGUIEngine_d.dll" add_runtime_dlls ${CONFIGURATION:?} "${VCPKG_DLL_BIN:?}/Debug/MyGUIEngine_d.dll"
else else
VCPKG_DLL_BIN="$(pwd)/${VCPKG_PATH:?}/installed/x64-windows/bin" VCPKG_DLL_BIN="$(pwd)/${VCPKG_PATH:?}/installed/${VCPKG_TRIPLET}/bin"
add_runtime_dlls ${CONFIGURATION:?} "${VCPKG_DLL_BIN:?}/Release/MyGUIEngine.dll" add_runtime_dlls ${CONFIGURATION:?} "${VCPKG_DLL_BIN:?}/Release/MyGUIEngine.dll"
fi fi
@ -704,17 +708,12 @@ printf "Qt ${QT_VER}... "
DLLSUFFIX="" DLLSUFFIX=""
fi fi
if [ "${QT_MAJOR_VER}" -eq 6 ]; then add_runtime_dlls $CONFIGURATION "$(pwd)/bin/Qt${QT_MAJOR_VER}"{Core,Gui,Network,OpenGL,OpenGLWidgets,Widgets,Svg}${DLLSUFFIX}.dll
add_runtime_dlls $CONFIGURATION "$(pwd)/bin/Qt${QT_MAJOR_VER}"{Core,Gui,Network,OpenGL,OpenGLWidgets,Widgets,Svg}${DLLSUFFIX}.dll
# Since Qt 6.7.0 plugin is called "qmodernwindowsstyle" # Since Qt 6.7.0 plugin is called "qmodernwindowsstyle"
if [ "${QT_MINOR_VER}" -ge 7 ]; then if [ "${QT_MINOR_VER}" -ge 7 ]; then
add_qt_style_dlls $CONFIGURATION "$(pwd)/plugins/styles/qmodernwindowsstyle${DLLSUFFIX}.dll" add_qt_style_dlls $CONFIGURATION "$(pwd)/plugins/styles/qmodernwindowsstyle${DLLSUFFIX}.dll"
else
add_qt_style_dlls $CONFIGURATION "$(pwd)/plugins/styles/qwindowsvistastyle${DLLSUFFIX}.dll"
fi
else else
add_runtime_dlls $CONFIGURATION "$(pwd)/bin/Qt${QT_MAJOR_VER}"{Core,Gui,Network,OpenGL,Widgets,Svg}${DLLSUFFIX}.dll
add_qt_style_dlls $CONFIGURATION "$(pwd)/plugins/styles/qwindowsvistastyle${DLLSUFFIX}.dll" add_qt_style_dlls $CONFIGURATION "$(pwd)/plugins/styles/qwindowsvistastyle${DLLSUFFIX}.dll"
fi fi

View file

@ -1,53 +0,0 @@
#!/bin/sh -e
# Silence a git warning
git config --global advice.detachedHead false
rm -fr build
mkdir build
cd build
DEPENDENCIES_ROOT="/tmp/openmw-deps"
QT_PATH=$(brew --prefix qt@5)
ICU_PATH=$(brew --prefix icu4c)
OPENAL_PATH=$(brew --prefix openal-soft)
CCACHE_EXECUTABLE=$(brew --prefix ccache)/bin/ccache
declare -a CMAKE_CONF_OPTS=(
-D CMAKE_PREFIX_PATH="$DEPENDENCIES_ROOT;$QT_PATH;$OPENAL_PATH"
-D CMAKE_C_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE"
-D CMAKE_CXX_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE"
-D CMAKE_CXX_FLAGS="-stdlib=libc++"
-D CMAKE_C_COMPILER="clang"
-D CMAKE_CXX_COMPILER="clang++"
-D CMAKE_OSX_DEPLOYMENT_TARGET="13.6"
-D OPENMW_USE_SYSTEM_RECASTNAVIGATION=TRUE
-D Boost_INCLUDE_DIR="$DEPENDENCIES_ROOT/include"
-D OSGPlugins_LIB_DIR="$DEPENDENCIES_ROOT/lib/osgPlugins-3.6.5"
-D ICU_ROOT="$ICU_PATH"
-D OPENMW_OSX_DEPLOYMENT=TRUE
)
if [[ "${CMAKE_BUILD_TYPE}" ]]; then
CMAKE_CONF_OPTS+=(
-D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
)
else
CMAKE_CONF_OPTS+=(
-D CMAKE_BUILD_TYPE=RelWithDebInfo
)
fi
cmake \
"${CMAKE_CONF_OPTS[@]}" \
-D BUILD_OPENMW=TRUE \
-D BUILD_OPENCS=TRUE \
-D BUILD_ESMTOOL=TRUE \
-D BUILD_BSATOOL=TRUE \
-D BUILD_ESSIMPORTER=TRUE \
-D BUILD_NIFTEST=TRUE \
-D BUILD_NAVMESHTOOL=TRUE \
-D BUILD_BULLETOBJECTTOOL=TRUE \
-G"Unix Makefiles" \
..

View file

@ -1,7 +1,6 @@
#!/bin/bash -ex #!/bin/bash -ex
git ls-files -- ':(exclude)extern/' '*.cpp' '*.hpp' '*.h' | git ls-files -- ':(exclude)extern/' '*.cpp' '*.hpp' '*.h' |
grep -vP '/[a-z0-9]+\.(cpp|hpp|h)$' | grep -vP '/[a-z0-9]+\.(cpp|hpp|h)$' &&
grep -vFf CI/file_name_exceptions.txt &&
( echo 'File names do not follow the naming convention, see https://wiki.openmw.org/index.php?title=Naming_Conventions#Files'; exit -1 ) ( echo 'File names do not follow the naming convention, see https://wiki.openmw.org/index.php?title=Naming_Conventions#Files'; exit -1 )
exit 0 exit 0

View file

@ -1,48 +0,0 @@
apps/openmw/android_main.cpp
apps/openmw/mwsound/efx-presets.h
apps/openmw/mwsound/ffmpeg_decoder.cpp
apps/openmw/mwsound/ffmpeg_decoder.hpp
apps/openmw/mwsound/openal_output.cpp
apps/openmw/mwsound/openal_output.hpp
apps/openmw/mwsound/sound_buffer.cpp
apps/openmw/mwsound/sound_buffer.hpp
apps/openmw/mwsound/sound_decoder.hpp
apps/openmw/mwsound/sound_output.hpp
apps/components_tests/esm/test_fixed_string.cpp
apps/components_tests/files/conversion_tests.cpp
apps/components_tests/lua/test_async.cpp
apps/components_tests/lua/test_configuration.cpp
apps/components_tests/lua/test_l10n.cpp
apps/components_tests/lua/test_lua.cpp
apps/components_tests/lua/test_scriptscontainer.cpp
apps/components_tests/lua/test_serialization.cpp
apps/components_tests/lua/test_storage.cpp
apps/components_tests/lua/test_ui_content.cpp
apps/components_tests/lua/test_utilpackage.cpp
apps/components_tests/lua/test_inputactions.cpp
apps/components_tests/lua/test_yaml.cpp
apps/components_tests/misc/test_endianness.cpp
apps/components_tests/misc/test_resourcehelpers.cpp
apps/components_tests/misc/test_stringops.cpp
apps/openmw_tests/mwdialogue/test_keywordsearch.cpp
apps/openmw_tests/mwscript/test_scripts.cpp
apps/openmw_tests/mwscript/test_utils.hpp
apps/openmw_tests/mwworld/test_store.cpp
components/bsa/bsa_file.cpp
components/bsa/bsa_file.hpp
components/crashcatcher/windows_crashcatcher.cpp
components/crashcatcher/windows_crashcatcher.hpp
components/crashcatcher/windows_crashmonitor.cpp
components/crashcatcher/windows_crashmonitor.hpp
components/crashcatcher/windows_crashshm.hpp
components/fx/lexer_types.hpp
components/fx/parse_constants.hpp
components/platform/file.posix.cpp
components/platform/file.stdio.cpp
components/platform/file.win32.cpp
components/sdlutil/gl4es_init.cpp
components/sdlutil/gl4es_init.h
components/to_utf8/gen_iconv.cpp
components/to_utf8/tables_gen.hpp
components/to_utf8/to_utf8.cpp
components/to_utf8/to_utf8.hpp

View file

@ -1 +1 @@
VCPKG_DEPS_TAG=2024-11-10 VCPKG_DEPS_TAG=2025-07-23

View file

@ -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
@ -33,10 +34,10 @@ declare -rA GROUPED_DEPS=(
libboost-system-dev libboost-iostreams-dev libboost-system-dev libboost-iostreams-dev
libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev
libsdl2-dev libqt5opengl5-dev qttools5-dev qttools5-dev-tools libopenal-dev libsdl2-dev libqt6opengl6-dev qt6-tools-dev qt6-tools-dev-tools libopenal-dev
libunshield-dev libtinyxml-dev libbullet-dev liblz4-dev libpng-dev libjpeg-dev libunshield-dev libtinyxml-dev libbullet-dev liblz4-dev libpng-dev libjpeg-dev
libluajit-5.1-dev librecast-dev libsqlite3-dev ca-certificates libicu-dev libluajit-5.1-dev librecast-dev libsqlite3-dev ca-certificates libicu-dev
libyaml-cpp-dev libqt5svg5 libqt5svg5-dev libyaml-cpp-dev libqt6svg6 libqt6svg6-dev
" "
# These dependencies can alternatively be built and linked statically. # These dependencies can alternatively be built and linked statically.
@ -57,22 +58,22 @@ declare -rA GROUPED_DEPS=(
libsdl2-dev libboost-system-dev libboost-filesystem-dev libgl-dev libsdl2-dev libboost-system-dev libboost-filesystem-dev libgl-dev
" "
[openmw-coverage]="gcovr" [openmw-coverage]="pipx"
[openmw-integration-tests]=" [openmw-integration-tests]="
ca-certificates ca-certificates
gdb gdb
git git
git-lfs git-lfs
libavcodec58 libavcodec60
libavformat58 libavformat60
libavutil56 libavutil58
libboost-iostreams1.74.0 libboost-iostreams1.83.0
libboost-program-options1.74.0 libboost-program-options1.83.0
libboost-system1.74.0 libboost-system1.83.0
libbullet3.24 libbullet3.24
libcollada-dom2.5-dp0 libcollada-dom2.5-dp0
libicu70 libicu74
libjpeg8 libjpeg8
libluajit-5.1-2 libluajit-5.1-2
liblz4-1 liblz4-1
@ -80,19 +81,19 @@ declare -rA GROUPED_DEPS=(
libopenal1 libopenal1
libopenscenegraph161 libopenscenegraph161
libpng16-16 libpng16-16
libqt5opengl5 libqt6opengl6
librecast1 librecast1
libsdl2-2.0-0 libsdl2-2.0-0
libsqlite3-0 libsqlite3-0
libswresample3 libswresample4
libswscale5 libswscale7
libtinyxml2.6.2v5 libtinyxml2.6.2v5
libyaml-cpp0.8 libyaml-cpp0.8
python3-pip python3-pip
xvfb xvfb
" "
[libasan6]="libasan6" [libasan]="libasan8"
[android]="binutils build-essential cmake ccache curl unzip git pkg-config" [android]="binutils build-essential cmake ccache curl unzip git pkg-config"
@ -102,8 +103,8 @@ declare -rA GROUPED_DEPS=(
" "
[openmw-qt-translations]=" [openmw-qt-translations]="
qttools5-dev qt6-tools-dev
qttools5-dev-tools qt6-tools-dev-tools
git-core git-core
" "
) )
@ -126,10 +127,24 @@ export APT_CACHE_DIR="${PWD}/apt-cache"
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
set -x set -x
mkdir -pv "$APT_CACHE_DIR" mkdir -pv "$APT_CACHE_DIR"
apt-get update -yqq
while true; do
apt-get update -yqq && break
done
apt-get -qq -o dir::cache::archives="$APT_CACHE_DIR" install -y --no-install-recommends software-properties-common gnupg >/dev/null apt-get -qq -o dir::cache::archives="$APT_CACHE_DIR" install -y --no-install-recommends software-properties-common gnupg >/dev/null
add-apt-repository -y ppa:openmw/openmw
add-apt-repository -y ppa:openmw/openmw-daily while true; do
add-apt-repository -y ppa:openmw/staging add-apt-repository -y ppa:openmw/openmw && break
done
while true; do
add-apt-repository -y ppa:openmw/openmw-daily && break
done
while true; do
add-apt-repository -y ppa:openmw/staging && break
done
apt-get -qq -o dir::cache::archives="$APT_CACHE_DIR" install -y --no-install-recommends "${deps[@]}" >/dev/null apt-get -qq -o dir::cache::archives="$APT_CACHE_DIR" install -y --no-install-recommends "${deps[@]}" >/dev/null
apt list --installed apt list --installed

View file

@ -0,0 +1,8 @@
#!/bin/sh -ex
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
arch -x86_64 /usr/local/bin/brew install curl xquartz gd fontconfig freetype harfbuzz brotli s3cmd ccache cmake qt@6 openal-soft icu4c yaml-cpp sqlite
curl -fSL -R -J https://gitlab.com/OpenMW/openmw-deps/-/raw/main/macos/openmw-deps-20240802.zip -o ~/openmw-deps.zip
unzip -o ~/openmw-deps.zip -d /tmp > /dev/null

View file

@ -0,0 +1,9 @@
#!/bin/sh -ex
brew tap --repair
brew update --quiet
brew install curl xquartz gd fontconfig freetype harfbuzz brotli s3cmd ccache cmake qt@6 openal-soft icu4c yaml-cpp sqlite
curl -fSL -R -J https://gitlab.com/OpenMW/openmw-deps/-/raw/main/macos/openmw-deps-20240818-arm64.tar.xz -o ~/openmw-deps.tar.xz
tar xf ~/openmw-deps.tar.xz -C /tmp > /dev/null

9
CI/macos/build.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/sh -ex
cd build
if [[ "${MACOS_AMD64}" ]]; then
arch -x86_64 make -j $(sysctl -n hw.logicalcpu) package
else
make -j $(sysctl -n hw.logicalcpu) package
fi

7
CI/macos/ccache_prep.sh Executable file
View file

@ -0,0 +1,7 @@
#!/bin/sh -ex
if [[ "${MACOS_AMD64}" ]]; then
arch -x86_64 ccache -z -M "${CCACHE_SIZE}"
else
ccache -z -M "${CCACHE_SIZE}"
fi

7
CI/macos/ccache_save.sh Executable file
View file

@ -0,0 +1,7 @@
#!/bin/sh -ex
if [[ "${MACOS_AMD64}" ]]; then
arch -x86_64 ccache -svv
else
ccache -svv
fi

View file

@ -9,7 +9,7 @@ git checkout FETCH_HEAD
cd .. cd ..
xvfb-run --auto-servernum --server-args='-screen 0 640x480x24x60' \ xvfb-run --auto-servernum --server-args='-screen 0 640x480x24x60' \
scripts/integration_tests.py --omw build/install/bin/openmw --workdir integration_tests_output example-suite/ scripts/integration_tests.py --verbose --omw build/install/bin/openmw --workdir integration_tests_output example-suite/
ls integration_tests_output/*.osg_stats.log | while read v; do ls integration_tests_output/*.osg_stats.log | while read v; do
scripts/osg_stats.py --stats '.*' --regexp_match < "${v}" scripts/osg_stats.py --stats '.*' --regexp_match < "${v}"

View file

@ -80,10 +80,10 @@ endif()
message(STATUS "Configuring OpenMW...") message(STATUS "Configuring OpenMW...")
set(OPENMW_VERSION_MAJOR 0) set(OPENMW_VERSION_MAJOR 0)
set(OPENMW_VERSION_MINOR 49) set(OPENMW_VERSION_MINOR 50)
set(OPENMW_VERSION_RELEASE 0) set(OPENMW_VERSION_RELEASE 0)
set(OPENMW_LUA_API_REVISION 70) set(OPENMW_LUA_API_REVISION 92)
set(OPENMW_POSTPROCESSING_API_REVISION 2) set(OPENMW_POSTPROCESSING_API_REVISION 3)
set(OPENMW_VERSION_COMMITHASH "") set(OPENMW_VERSION_COMMITHASH "")
set(OPENMW_VERSION_TAGHASH "") set(OPENMW_VERSION_TAGHASH "")
@ -249,12 +249,8 @@ endif()
find_package(LZ4 REQUIRED) find_package(LZ4 REQUIRED)
if (USE_QT) if (USE_QT)
find_package(QT REQUIRED COMPONENTS Core NAMES Qt6 Qt5) find_package(QT REQUIRED COMPONENTS Core NAMES Qt6)
if (QT_VERSION_MAJOR VERSION_EQUAL 5) find_package(Qt6 COMPONENTS Core Widgets Network OpenGL OpenGLWidgets LinguistTools Svg REQUIRED)
find_package(Qt5 5.15 COMPONENTS Core Widgets Network OpenGL LinguistTools Svg REQUIRED)
else()
find_package(Qt6 COMPONENTS Core Widgets Network OpenGL OpenGLWidgets LinguistTools Svg REQUIRED)
endif()
message(STATUS "Using Qt${QT_VERSION}") message(STATUS "Using Qt${QT_VERSION}")
endif() endif()
@ -466,7 +462,7 @@ find_package(Boost 1.70.0 CONFIG REQUIRED COMPONENTS ${BOOST_COMPONENTS} OPTIONA
if(OPENMW_USE_SYSTEM_MYGUI) if(OPENMW_USE_SYSTEM_MYGUI)
find_package(MyGUI 3.4.3 REQUIRED) find_package(MyGUI 3.4.3 REQUIRED)
endif() endif()
find_package(SDL2 2.0.10 REQUIRED) find_package(SDL2 2.0.20 REQUIRED)
find_package(OpenAL REQUIRED) find_package(OpenAL REQUIRED)
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
@ -590,25 +586,10 @@ if(OPENMW_LTO_BUILD)
endif() endif()
endif() endif()
if (APPLE)
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
set(OPENMW_CXX_FLAGS "-Wall -Wextra -Wundef -Wextra-semi -Wno-unused-parameter -pedantic -Wno-long-long -Wnon-virtual-dtor -Wunused ${OPENMW_CXX_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")
endif()
if (APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL Clang AND NOT APPLE)
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.6 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 3.6)
set(OPENMW_CXX_FLAGS "${OPENMW_CXX_FLAGS} -Wno-potentially-evaluated-expression")
endif ()
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU)
set(OPENMW_CXX_FLAGS "${OPENMW_CXX_FLAGS} -Wno-unused-but-set-parameter -Wduplicated-branches -Wduplicated-cond -Wlogical-op")
endif()
endif (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
# Extern # Extern
@ -619,8 +600,42 @@ if (BUILD_OPENCS OR BUILD_OPENCS_TESTS)
add_subdirectory (extern/osgQt) add_subdirectory (extern/osgQt)
endif() endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
add_compile_options("/W4")
set(WARNINGS_DISABLE
4100 # Unreferenced formal parameter (-Wunused-parameter)
4127 # Conditional expression is constant
4996 # Function was declared deprecated
5054 # Deprecated operations between enumerations of different types caused by Qt headers
)
foreach(d ${WARNINGS_DISABLE})
add_compile_options("/wd${d}")
endforeach(d)
if(OPENMW_MSVC_WERROR)
add_compile_options("/WX")
endif()
else ()
add_compile_options("-Wall" "-Wextra" "-Wundef" "-Wextra-semi" "-Wno-unused-parameter" "-pedantic" "-Wno-long-long" "-Wnon-virtual-dtor" "-Wunused")
if (CMAKE_CXX_COMPILER_ID STREQUAL Clang AND NOT APPLE)
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.6 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 3.6)
add_compile_options("-Wno-potentially-evaluated-expression")
endif ()
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU)
add_compile_options("-Wno-unused-but-set-parameter" "-Wduplicated-branches" "-Wduplicated-cond" "-Wlogical-op")
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105438
add_compile_options("-Wno-array-bounds")
endif()
endif ()
if (OPENMW_CXX_FLAGS) if (OPENMW_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPENMW_CXX_FLAGS}") separate_arguments(OPENMW_CXX_FLAGS NATIVE_COMMAND "${OPENMW_CXX_FLAGS}")
add_compile_options(${OPENMW_CXX_FLAGS})
endif() endif()
# Components # Components
@ -710,87 +725,9 @@ if (WIN32)
set_target_properties(openmw PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS") set_target_properties(openmw PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS")
endif() endif()
# Play a bit with the warning levels
set(WARNINGS "/W4")
set(WARNINGS_DISABLE
4100 # Unreferenced formal parameter (-Wunused-parameter)
4127 # Conditional expression is constant
4996 # Function was declared deprecated
5054 # Deprecated operations between enumerations of different types caused by Qt headers
)
foreach(d ${WARNINGS_DISABLE})
list(APPEND WARNINGS "/wd${d}")
endforeach(d)
if(OPENMW_MSVC_WERROR)
list(APPEND WARNINGS "/WX")
endif()
target_compile_options(components PRIVATE ${WARNINGS})
target_compile_options(osg-ffmpeg-videoplayer PRIVATE ${WARNINGS})
if (MSVC_VERSION GREATER_EQUAL 1915 AND MSVC_VERSION LESS 1920) if (MSVC_VERSION GREATER_EQUAL 1915 AND MSVC_VERSION LESS 1920)
target_compile_definitions(components INTERFACE _ENABLE_EXTENDED_ALIGNED_STORAGE) target_compile_definitions(components INTERFACE _ENABLE_EXTENDED_ALIGNED_STORAGE)
endif() endif()
if (BUILD_BSATOOL)
target_compile_options(bsatool PRIVATE ${WARNINGS})
endif()
if (BUILD_ESMTOOL)
target_compile_options(esmtool PRIVATE ${WARNINGS})
endif()
if (BUILD_ESSIMPORTER)
target_compile_options(openmw-essimporter PRIVATE ${WARNINGS})
endif()
if (BUILD_LAUNCHER)
target_compile_options(openmw-launcher PRIVATE ${WARNINGS})
endif()
if (BUILD_MWINIIMPORTER)
target_compile_options(openmw-iniimporter PRIVATE ${WARNINGS})
endif()
if (BUILD_OPENCS)
target_compile_options(openmw-cs PRIVATE ${WARNINGS})
endif()
if (BUILD_OPENMW)
target_compile_options(openmw PRIVATE ${WARNINGS})
endif()
if (BUILD_WIZARD)
target_compile_options(openmw-wizard PRIVATE ${WARNINGS})
endif()
if (BUILD_COMPONENTS_TESTS)
target_compile_options(components-tests PRIVATE ${WARNINGS})
endif()
if (BUILD_BENCHMARKS)
target_compile_options(openmw_detournavigator_navmeshtilescache_benchmark PRIVATE ${WARNINGS})
endif()
if (BUILD_NAVMESHTOOL)
target_compile_options(openmw-navmeshtool PRIVATE ${WARNINGS})
endif()
if (BUILD_BULLETOBJECTTOOL)
target_compile_options(openmw-bulletobjecttool PRIVATE ${WARNINGS} ${MT_BUILD})
endif()
if (BUILD_OPENCS_TESTS)
target_compile_options(openmw-cs-tests PRIVATE ${WARNINGS})
endif()
if (BUILD_OPENMW_TESTS)
target_compile_options(openmw-tests PRIVATE ${WARNINGS})
endif()
endif(MSVC) endif(MSVC)
# TODO: At some point release builds should not use the console but rather write to a log file # TODO: At some point release builds should not use the console but rather write to a log file
@ -860,7 +797,6 @@ if (OPENMW_OSX_DEPLOYMENT AND APPLE)
set(BU_CHMOD_BUNDLE_ITEMS ON) set(BU_CHMOD_BUNDLE_ITEMS ON)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
include(BundleUtilities) include(BundleUtilities)
cmake_minimum_required(VERSION 3.1)
" COMPONENT Runtime) " COMPONENT Runtime)
set(ABSOLUTE_PLUGINS "") set(ABSOLUTE_PLUGINS "")

View file

@ -5,7 +5,7 @@ OpenMW is an open-source open-world RPG game engine that supports playing Morrow
OpenMW also comes with OpenMW-CS, a replacement for Bethesda's Construction Set. OpenMW also comes with OpenMW-CS, a replacement for Bethesda's Construction Set.
* Version: 0.49.0 * Version: 0.50.0
* License: GPLv3 (see [LICENSE](https://gitlab.com/OpenMW/openmw/-/raw/master/LICENSE) for more information) * License: GPLv3 (see [LICENSE](https://gitlab.com/OpenMW/openmw/-/raw/master/LICENSE) for more information)
* Website: https://www.openmw.org * Website: https://www.openmw.org
* IRC: #openmw on irc.libera.chat * IRC: #openmw on irc.libera.chat

View file

@ -179,7 +179,7 @@ namespace
generateKeys(std::back_inserter(keys), keys.size() * (100 - hitPercentage) / 100, random); generateKeys(std::back_inserter(keys), keys.size() * (100 - hitPercentage) / 100, random);
std::size_t n = 0; std::size_t n = 0;
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
const auto& key = keys[n++ % keys.size()]; const auto& key = keys[n++ % keys.size()];
auto result = cache.get(key.mAgentBounds, key.mTilePosition, key.mRecastMesh); auto result = cache.get(key.mAgentBounds, key.mTilePosition, key.mRecastMesh);

View file

@ -104,7 +104,7 @@ namespace
std::minstd_rand random; std::minstd_rand random;
std::vector<ESM::RefId> refIds = generateStringRefIds(state.range(0), random); std::vector<ESM::RefId> refIds = generateStringRefIds(state.range(0), random);
std::size_t i = 0; std::size_t i = 0;
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(refIds[i].serialize()); benchmark::DoNotOptimize(refIds[i].serialize());
if (++i >= refIds.size()) if (++i >= refIds.size())
@ -118,7 +118,7 @@ namespace
std::vector<std::string> serializedRefIds std::vector<std::string> serializedRefIds
= generateSerializedStringRefIds(state.range(0), random, [](ESM::RefId v) { return v.serialize(); }); = generateSerializedStringRefIds(state.range(0), random, [](ESM::RefId v) { return v.serialize(); });
std::size_t i = 0; std::size_t i = 0;
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(ESM::RefId::deserialize(serializedRefIds[i])); benchmark::DoNotOptimize(ESM::RefId::deserialize(serializedRefIds[i]));
if (++i >= serializedRefIds.size()) if (++i >= serializedRefIds.size())
@ -131,7 +131,7 @@ namespace
std::minstd_rand random; std::minstd_rand random;
std::vector<ESM::RefId> refIds = generateStringRefIds(state.range(0), random); std::vector<ESM::RefId> refIds = generateStringRefIds(state.range(0), random);
std::size_t i = 0; std::size_t i = 0;
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(refIds[i].serializeText()); benchmark::DoNotOptimize(refIds[i].serializeText());
if (++i >= refIds.size()) if (++i >= refIds.size())
@ -145,7 +145,7 @@ namespace
std::vector<std::string> serializedRefIds std::vector<std::string> serializedRefIds
= generateSerializedStringRefIds(state.range(0), random, [](ESM::RefId v) { return v.serializeText(); }); = generateSerializedStringRefIds(state.range(0), random, [](ESM::RefId v) { return v.serializeText(); });
std::size_t i = 0; std::size_t i = 0;
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i])); benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i]));
if (++i >= serializedRefIds.size()) if (++i >= serializedRefIds.size())
@ -158,7 +158,7 @@ namespace
std::minstd_rand random; std::minstd_rand random;
std::vector<ESM::RefId> refIds = generateGeneratedRefIds(random); std::vector<ESM::RefId> refIds = generateGeneratedRefIds(random);
std::size_t i = 0; std::size_t i = 0;
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(refIds[i].serializeText()); benchmark::DoNotOptimize(refIds[i].serializeText());
if (++i >= refIds.size()) if (++i >= refIds.size())
@ -172,7 +172,7 @@ namespace
std::vector<std::string> serializedRefIds std::vector<std::string> serializedRefIds
= generateSerializedGeneratedRefIds(random, [](ESM::RefId v) { return v.serializeText(); }); = generateSerializedGeneratedRefIds(random, [](ESM::RefId v) { return v.serializeText(); });
std::size_t i = 0; std::size_t i = 0;
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i])); benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i]));
if (++i >= serializedRefIds.size()) if (++i >= serializedRefIds.size())
@ -185,7 +185,7 @@ namespace
std::minstd_rand random; std::minstd_rand random;
std::vector<ESM::RefId> refIds = generateIndexRefIds(random); std::vector<ESM::RefId> refIds = generateIndexRefIds(random);
std::size_t i = 0; std::size_t i = 0;
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(refIds[i].serializeText()); benchmark::DoNotOptimize(refIds[i].serializeText());
if (++i >= refIds.size()) if (++i >= refIds.size())
@ -199,7 +199,7 @@ namespace
std::vector<std::string> serializedRefIds std::vector<std::string> serializedRefIds
= generateSerializedIndexRefIds(random, [](ESM::RefId v) { return v.serializeText(); }); = generateSerializedIndexRefIds(random, [](ESM::RefId v) { return v.serializeText(); });
std::size_t i = 0; std::size_t i = 0;
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i])); benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i]));
if (++i >= serializedRefIds.size()) if (++i >= serializedRefIds.size())
@ -212,7 +212,7 @@ namespace
std::minstd_rand random; std::minstd_rand random;
std::vector<ESM::RefId> refIds = generateESM3ExteriorCellRefIds(random); std::vector<ESM::RefId> refIds = generateESM3ExteriorCellRefIds(random);
std::size_t i = 0; std::size_t i = 0;
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(refIds[i].serializeText()); benchmark::DoNotOptimize(refIds[i].serializeText());
if (++i >= refIds.size()) if (++i >= refIds.size())
@ -226,7 +226,7 @@ namespace
std::vector<std::string> serializedRefIds std::vector<std::string> serializedRefIds
= generateSerializedESM3ExteriorCellRefIds(random, [](ESM::RefId v) { return v.serializeText(); }); = generateSerializedESM3ExteriorCellRefIds(random, [](ESM::RefId v) { return v.serializeText(); });
std::size_t i = 0; std::size_t i = 0;
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i])); benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i]));
if (++i >= serializedRefIds.size()) if (++i >= serializedRefIds.size())

View file

@ -9,7 +9,7 @@ namespace
{ {
void settingsManager(benchmark::State& state) void settingsManager(benchmark::State& state)
{ {
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(Settings::Manager::getFloat("sky blending start", "Fog")); benchmark::DoNotOptimize(Settings::Manager::getFloat("sky blending start", "Fog"));
} }
@ -17,7 +17,7 @@ namespace
void settingsManager2(benchmark::State& state) void settingsManager2(benchmark::State& state)
{ {
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(Settings::Manager::getFloat("near clip", "Camera")); benchmark::DoNotOptimize(Settings::Manager::getFloat("near clip", "Camera"));
benchmark::DoNotOptimize(Settings::Manager::getBool("transparent postpass", "Post Processing")); benchmark::DoNotOptimize(Settings::Manager::getBool("transparent postpass", "Post Processing"));
@ -26,7 +26,7 @@ namespace
void settingsManager3(benchmark::State& state) void settingsManager3(benchmark::State& state)
{ {
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(Settings::Manager::getFloat("near clip", "Camera")); benchmark::DoNotOptimize(Settings::Manager::getFloat("near clip", "Camera"));
benchmark::DoNotOptimize(Settings::Manager::getBool("transparent postpass", "Post Processing")); benchmark::DoNotOptimize(Settings::Manager::getBool("transparent postpass", "Post Processing"));
@ -36,7 +36,7 @@ namespace
void localStatic(benchmark::State& state) void localStatic(benchmark::State& state)
{ {
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
static float v = Settings::Manager::getFloat("sky blending start", "Fog"); static float v = Settings::Manager::getFloat("sky blending start", "Fog");
benchmark::DoNotOptimize(v); benchmark::DoNotOptimize(v);
@ -45,7 +45,7 @@ namespace
void localStatic2(benchmark::State& state) void localStatic2(benchmark::State& state)
{ {
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
static float v1 = Settings::Manager::getFloat("near clip", "Camera"); static float v1 = Settings::Manager::getFloat("near clip", "Camera");
static bool v2 = Settings::Manager::getBool("transparent postpass", "Post Processing"); static bool v2 = Settings::Manager::getBool("transparent postpass", "Post Processing");
@ -56,7 +56,7 @@ namespace
void localStatic3(benchmark::State& state) void localStatic3(benchmark::State& state)
{ {
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
static float v1 = Settings::Manager::getFloat("near clip", "Camera"); static float v1 = Settings::Manager::getFloat("near clip", "Camera");
static bool v2 = Settings::Manager::getBool("transparent postpass", "Post Processing"); static bool v2 = Settings::Manager::getBool("transparent postpass", "Post Processing");
@ -69,7 +69,7 @@ namespace
void settingsStorage(benchmark::State& state) void settingsStorage(benchmark::State& state)
{ {
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
float v = Settings::fog().mSkyBlendingStart.get(); float v = Settings::fog().mSkyBlendingStart.get();
benchmark::DoNotOptimize(v); benchmark::DoNotOptimize(v);
@ -78,7 +78,7 @@ namespace
void settingsStorage2(benchmark::State& state) void settingsStorage2(benchmark::State& state)
{ {
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
bool v1 = Settings::postProcessing().mTransparentPostpass.get(); bool v1 = Settings::postProcessing().mTransparentPostpass.get();
float v2 = Settings::camera().mNearClip.get(); float v2 = Settings::camera().mNearClip.get();
@ -89,7 +89,7 @@ namespace
void settingsStorage3(benchmark::State& state) void settingsStorage3(benchmark::State& state)
{ {
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
bool v1 = Settings::postProcessing().mTransparentPostpass.get(); bool v1 = Settings::postProcessing().mTransparentPostpass.get();
float v2 = Settings::camera().mNearClip.get(); float v2 = Settings::camera().mNearClip.get();
@ -102,7 +102,7 @@ namespace
void settingsStorageGet(benchmark::State& state) void settingsStorageGet(benchmark::State& state)
{ {
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(Settings::get<float>("Fog", "sky blending start")); benchmark::DoNotOptimize(Settings::get<float>("Fog", "sky blending start"));
} }
@ -110,7 +110,7 @@ namespace
void settingsStorageGet2(benchmark::State& state) void settingsStorageGet2(benchmark::State& state)
{ {
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(Settings::get<bool>("Post Processing", "transparent postpass")); benchmark::DoNotOptimize(Settings::get<bool>("Post Processing", "transparent postpass"));
benchmark::DoNotOptimize(Settings::get<float>("Camera", "near clip")); benchmark::DoNotOptimize(Settings::get<float>("Camera", "near clip"));
@ -119,7 +119,7 @@ namespace
void settingsStorageGet3(benchmark::State& state) void settingsStorageGet3(benchmark::State& state)
{ {
for (auto _ : state) for ([[maybe_unused]] auto _ : state)
{ {
benchmark::DoNotOptimize(Settings::get<bool>("Post Processing", "transparent postpass")); benchmark::DoNotOptimize(Settings::get<bool>("Post Processing", "transparent postpass"));
benchmark::DoNotOptimize(Settings::get<float>("Camera", "near clip")); benchmark::DoNotOptimize(Settings::get<float>("Camera", "near clip"));

View file

@ -75,8 +75,8 @@ Allowed options)");
bpo::variables_map variables; bpo::variables_map variables;
try try
{ {
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv).options(all).positional(p).run(); bpo::parsed_options validOpts = bpo::command_line_parser(argc, argv).options(all).positional(p).run();
bpo::store(valid_opts, variables); bpo::store(validOpts, variables);
} }
catch (std::exception& e) catch (std::exception& e)
{ {

View file

@ -20,7 +20,7 @@
#include <components/resource/niffilemanager.hpp> #include <components/resource/niffilemanager.hpp>
#include <components/resource/scenemanager.hpp> #include <components/resource/scenemanager.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include <components/to_utf8/to_utf8.hpp> #include <components/toutf8/toutf8.hpp>
#include <components/version/version.hpp> #include <components/version/version.hpp>
#include <components/vfs/manager.hpp> #include <components/vfs/manager.hpp>
#include <components/vfs/registerarchives.hpp> #include <components/vfs/registerarchives.hpp>
@ -53,8 +53,6 @@ namespace
bpo::options_description makeOptionsDescription() bpo::options_description makeOptionsDescription()
{ {
using Fallback::FallbackMap;
bpo::options_description result; bpo::options_description result;
auto addOption = result.add_options(); auto addOption = result.add_options();
addOption("help", "print help message"); addOption("help", "print help message");
@ -87,7 +85,8 @@ namespace
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
"\n\twin1252 - Western European (Latin) alphabet, used by default"); "\n\twin1252 - Western European (Latin) alphabet, used by default");
addOption("fallback", bpo::value<FallbackMap>()->default_value(FallbackMap(), "")->multitoken()->composing(), addOption("fallback",
bpo::value<Fallback::FallbackMap>()->default_value(Fallback::FallbackMap(), "")->multitoken()->composing(),
"fallback values"); "fallback values");
Files::ConfigurationManager::addCommonOptions(result); Files::ConfigurationManager::addCommonOptions(result);
@ -126,6 +125,7 @@ namespace
} }
Files::ConfigurationManager config; Files::ConfigurationManager config;
config.processPaths(variables, std::filesystem::current_path());
config.readConfiguration(variables, desc); config.readConfiguration(variables, desc);
Debug::setupLogging(config.getLogPath(), applicationName); Debug::setupLogging(config.getLogPath(), applicationName);
@ -155,7 +155,7 @@ namespace
VFS::Manager vfs; VFS::Manager vfs;
VFS::registerArchives(&vfs, fileCollections, archives, true); VFS::registerArchives(&vfs, fileCollections, archives, true, &encoder.getStatelessEncoder());
Settings::Manager::load(config); Settings::Manager::load(config);

View file

@ -4,29 +4,28 @@ include_directories(SYSTEM ${GMOCK_INCLUDE_DIRS})
file(GLOB UNITTEST_SRC_FILES file(GLOB UNITTEST_SRC_FILES
main.cpp main.cpp
esm/test_fixed_string.cpp esm/testfixedstring.cpp
esm/variant.cpp
esm/testrefid.cpp esm/testrefid.cpp
esm/variant.cpp
lua/test_lua.cpp lua/testasync.cpp
lua/test_scriptscontainer.cpp lua/testconfiguration.cpp
lua/test_utilpackage.cpp lua/testinputactions.cpp
lua/test_serialization.cpp lua/testl10n.cpp
lua/test_configuration.cpp lua/testlua.cpp
lua/test_l10n.cpp lua/testscriptscontainer.cpp
lua/test_storage.cpp lua/testserialization.cpp
lua/test_async.cpp lua/teststorage.cpp
lua/test_inputactions.cpp lua/testuicontent.cpp
lua/test_yaml.cpp lua/testutilpackage.cpp
lua/testyaml.cpp
lua/test_ui_content.cpp
misc/compression.cpp misc/compression.cpp
misc/progressreporter.cpp misc/progressreporter.cpp
misc/test_endianness.cpp misc/testendianness.cpp
misc/test_resourcehelpers.cpp
misc/test_stringops.cpp
misc/testmathutil.cpp misc/testmathutil.cpp
misc/testresourcehelpers.cpp
misc/teststringops.cpp
nifloader/testbulletnifloader.cpp nifloader/testbulletnifloader.cpp
@ -64,8 +63,8 @@ file(GLOB UNITTEST_SRC_FILES
esmloader/esmdata.cpp esmloader/esmdata.cpp
esmloader/record.cpp esmloader/record.cpp
files/conversiontests.cpp
files/hash.cpp files/hash.cpp
files/conversion_tests.cpp
toutf8/toutf8.cpp toutf8/toutf8.cpp

View file

@ -5,7 +5,9 @@
#include <components/detournavigator/makenavmesh.hpp> #include <components/detournavigator/makenavmesh.hpp>
#include <components/detournavigator/navmeshdbutils.hpp> #include <components/detournavigator/navmeshdbutils.hpp>
#include <components/detournavigator/serialization.hpp> #include <components/detournavigator/serialization.hpp>
#include <components/files/conversion.hpp>
#include <components/loadinglistener/loadinglistener.hpp> #include <components/loadinglistener/loadinglistener.hpp>
#include <components/testing/util.hpp>
#include <BulletCollision/CollisionShapes/btBoxShape.h> #include <BulletCollision/CollisionShapes/btBoxShape.h>
@ -372,6 +374,106 @@ namespace
} }
} }
TEST_F(DetourNavigatorAsyncNavMeshUpdaterTest, should_write_debug_recast_mesh)
{
mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
addHeightFieldPlane(mRecastMeshManager);
mSettings.mEnableWriteRecastMeshToFile = true;
const std::filesystem::path dir = TestingOpenMW::outputDirPath("DetourNavigatorAsyncNavMeshUpdaterTest");
mSettings.mRecastMeshPathPrefix = Files::pathToUnicodeString(dir) + "/";
Log(Debug::Verbose) << mSettings.mRecastMeshPathPrefix;
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } };
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
updater.wait(WaitConditionType::allJobsDone, &mListener);
EXPECT_TRUE(std::filesystem::exists(dir / "0.0.recastmesh.obj"));
}
TEST_F(DetourNavigatorAsyncNavMeshUpdaterTest, should_write_debug_recast_mesh_with_revision)
{
mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
addHeightFieldPlane(mRecastMeshManager);
mSettings.mEnableWriteRecastMeshToFile = true;
mSettings.mEnableRecastMeshFileNameRevision = true;
const std::filesystem::path dir = TestingOpenMW::outputDirPath("DetourNavigatorAsyncNavMeshUpdaterTest");
mSettings.mRecastMeshPathPrefix = Files::pathToUnicodeString(dir) + "/";
Log(Debug::Verbose) << mSettings.mRecastMeshPathPrefix;
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } };
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
updater.wait(WaitConditionType::allJobsDone, &mListener);
EXPECT_TRUE(std::filesystem::exists(dir / "0.0.recastmesh.1.2.obj"));
}
TEST_F(DetourNavigatorAsyncNavMeshUpdaterTest, writing_recast_mesh_to_absent_file_should_not_fail_tile_generation)
{
mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
addHeightFieldPlane(mRecastMeshManager);
mSettings.mEnableWriteRecastMeshToFile = true;
const std::filesystem::path dir = TestingOpenMW::outputDir() / "absent";
mSettings.mRecastMeshPathPrefix = Files::pathToUnicodeString(dir) + "/";
Log(Debug::Verbose) << mSettings.mRecastMeshPathPrefix;
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } };
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
updater.wait(WaitConditionType::allJobsDone, &mListener);
EXPECT_NE(navMeshCacheItem->lockConst()->getImpl().getTileRefAt(0, 0, 0), 0u);
EXPECT_FALSE(std::filesystem::exists(dir));
}
TEST_F(DetourNavigatorAsyncNavMeshUpdaterTest, should_write_debug_navmesh)
{
mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
addHeightFieldPlane(mRecastMeshManager);
mSettings.mEnableWriteNavMeshToFile = true;
const std::filesystem::path dir = TestingOpenMW::outputDirPath("DetourNavigatorAsyncNavMeshUpdaterTest");
mSettings.mNavMeshPathPrefix = Files::pathToUnicodeString(dir) + "/";
Log(Debug::Verbose) << mSettings.mRecastMeshPathPrefix;
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } };
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
updater.wait(WaitConditionType::allJobsDone, &mListener);
EXPECT_TRUE(std::filesystem::exists(dir / "all_tiles_navmesh.bin"));
}
TEST_F(DetourNavigatorAsyncNavMeshUpdaterTest, should_write_debug_navmesh_with_revision)
{
mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
addHeightFieldPlane(mRecastMeshManager);
mSettings.mEnableWriteNavMeshToFile = true;
mSettings.mEnableNavMeshFileNameRevision = true;
const std::filesystem::path dir = TestingOpenMW::outputDirPath("DetourNavigatorAsyncNavMeshUpdaterTest");
mSettings.mNavMeshPathPrefix = Files::pathToUnicodeString(dir) + "/";
Log(Debug::Verbose) << mSettings.mRecastMeshPathPrefix;
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } };
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
updater.wait(WaitConditionType::allJobsDone, &mListener);
EXPECT_TRUE(std::filesystem::exists(dir / "all_tiles_navmesh.1.1.bin"));
}
TEST_F(DetourNavigatorAsyncNavMeshUpdaterTest, writing_navmesh_to_absent_file_should_not_fail_tile_generation)
{
mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
addHeightFieldPlane(mRecastMeshManager);
mSettings.mEnableWriteNavMeshToFile = true;
const std::filesystem::path dir = TestingOpenMW::outputDir() / "absent";
mSettings.mNavMeshPathPrefix = Files::pathToUnicodeString(dir) + "/";
Log(Debug::Verbose) << mSettings.mRecastMeshPathPrefix;
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } };
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
updater.wait(WaitConditionType::allJobsDone, &mListener);
EXPECT_NE(navMeshCacheItem->lockConst()->getImpl().getTileRefAt(0, 0, 0), 0u);
EXPECT_FALSE(std::filesystem::exists(dir));
}
struct DetourNavigatorSpatialJobQueueTest : Test struct DetourNavigatorSpatialJobQueueTest : Test
{ {
const AgentBounds mAgentBounds{ CollisionShapeType::Aabb, osg::Vec3f(1, 1, 1) }; const AgentBounds mAgentBounds{ CollisionShapeType::Aabb, osg::Vec3f(1, 1, 1) };

View file

@ -139,7 +139,7 @@ namespace
TEST_F(DetourNavigatorNavigatorTest, find_path_for_empty_should_return_empty) TEST_F(DetourNavigatorNavigatorTest, find_path_for_empty_should_return_empty)
{ {
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::NavMeshNotFound); Status::NavMeshNotFound);
EXPECT_EQ(mPath, std::deque<osg::Vec3f>()); EXPECT_EQ(mPath, std::deque<osg::Vec3f>());
} }
@ -147,7 +147,7 @@ namespace
TEST_F(DetourNavigatorNavigatorTest, find_path_for_existing_agent_with_no_navmesh_should_throw_exception) TEST_F(DetourNavigatorNavigatorTest, find_path_for_existing_agent_with_no_navmesh_should_throw_exception)
{ {
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds)); ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::StartPolygonNotFound); Status::StartPolygonNotFound);
} }
@ -156,7 +156,7 @@ namespace
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds)); ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds)); ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
mNavigator->removeAgent(mAgentBounds); mNavigator->removeAgent(mAgentBounds);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::StartPolygonNotFound); Status::StartPolygonNotFound);
} }
@ -172,7 +172,7 @@ namespace
updateGuard.reset(); updateGuard.reset();
mNavigator->wait(WaitConditionType::requiredTilesPresent, &mListener); mNavigator->wait(WaitConditionType::requiredTilesPresent, &mListener);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -194,7 +194,7 @@ namespace
updateGuard.reset(); updateGuard.reset();
mNavigator->wait(WaitConditionType::requiredTilesPresent, &mListener); mNavigator->wait(WaitConditionType::requiredTilesPresent, &mListener);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mStart, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mStart, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, ElementsAre(Vec3fEq(56.66666412353515625, 460, 1.99998295307159423828125))) << mPath; EXPECT_THAT(mPath, ElementsAre(Vec3fEq(56.66666412353515625, 460, 1.99998295307159423828125))) << mPath;
@ -218,7 +218,7 @@ namespace
mNavigator->update(mPlayerPosition, nullptr); mNavigator->update(mPlayerPosition, nullptr);
mNavigator->wait(WaitConditionType::allJobsDone, &mListener); mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -237,7 +237,7 @@ namespace
mPath.clear(); mPath.clear();
mOut = std::back_inserter(mPath); mOut = std::back_inserter(mPath);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -265,7 +265,7 @@ namespace
mNavigator->update(mPlayerPosition, nullptr); mNavigator->update(mPlayerPosition, nullptr);
mNavigator->wait(WaitConditionType::allJobsDone, &mListener); mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -285,7 +285,7 @@ namespace
mPath.clear(); mPath.clear();
mOut = std::back_inserter(mPath); mOut = std::back_inserter(mPath);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -318,7 +318,7 @@ namespace
mNavigator->update(mPlayerPosition, nullptr); mNavigator->update(mPlayerPosition, nullptr);
mNavigator->wait(WaitConditionType::allJobsDone, &mListener); mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -386,7 +386,7 @@ namespace
mNavigator->update(mPlayerPosition, nullptr); mNavigator->update(mPlayerPosition, nullptr);
mNavigator->wait(WaitConditionType::allJobsDone, &mListener); mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -421,7 +421,7 @@ namespace
mEnd.x() = 256; mEnd.x() = 256;
mEnd.z() = 300; mEnd.z() = 300;
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_swim, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_swim, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -453,8 +453,8 @@ namespace
mStart.x() = 256; mStart.x() = 256;
mEnd.x() = 256; mEnd.x() = 256;
EXPECT_EQ( EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_swim | Flag_walk, mAreaCosts, mEndTolerance,
findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_swim | Flag_walk, mAreaCosts, mEndTolerance, mOut), {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -487,8 +487,8 @@ namespace
mStart.x() = 256; mStart.x() = 256;
mEnd.x() = 256; mEnd.x() = 256;
EXPECT_EQ( EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_swim | Flag_walk, mAreaCosts, mEndTolerance,
findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_swim | Flag_walk, mAreaCosts, mEndTolerance, mOut), {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -520,7 +520,7 @@ namespace
mStart.x() = 256; mStart.x() = 256;
mEnd.x() = 256; mEnd.x() = 256;
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -549,7 +549,7 @@ namespace
mNavigator->update(mPlayerPosition, nullptr); mNavigator->update(mPlayerPosition, nullptr);
mNavigator->wait(WaitConditionType::allJobsDone, &mListener); mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -577,7 +577,7 @@ namespace
mNavigator->update(mPlayerPosition, nullptr); mNavigator->update(mPlayerPosition, nullptr);
mNavigator->wait(WaitConditionType::allJobsDone, &mListener); mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -658,7 +658,7 @@ namespace
mNavigator->update(mPlayerPosition, nullptr); mNavigator->update(mPlayerPosition, nullptr);
mNavigator->wait(WaitConditionType::allJobsDone, &mListener); mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -781,7 +781,7 @@ namespace
mNavigator->update(mPlayerPosition, nullptr); mNavigator->update(mPlayerPosition, nullptr);
mNavigator->wait(WaitConditionType::requiredTilesPresent, &mListener); mNavigator->wait(WaitConditionType::requiredTilesPresent, &mListener);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -806,7 +806,7 @@ namespace
mNavigator->update(mPlayerPosition, nullptr); mNavigator->update(mPlayerPosition, nullptr);
mNavigator->wait(WaitConditionType::allJobsDone, &mListener); mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::PartialPath); Status::PartialPath);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -834,7 +834,7 @@ namespace
const float endTolerance = 1000.0f; const float endTolerance = 1000.0f;
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, endTolerance, mOut), EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, endTolerance, {}, mOut),
Status::Success); Status::Success);
EXPECT_THAT(mPath, EXPECT_THAT(mPath,
@ -979,6 +979,146 @@ namespace
EXPECT_EQ(usedNavMeshTiles, 854); EXPECT_EQ(usedNavMeshTiles, 854);
} }
TEST_F(DetourNavigatorNavigatorTest, find_path_should_return_path_around_steep_mountains)
{
const std::array<float, 5 * 5> heightfieldData{ {
0, 0, 0, 0, 0, // row 0
0, 0, 0, 0, 0, // row 1
0, 0, 1000, 0, 0, // row 2
0, 0, 1000, 0, 0, // row 3
0, 0, 0, 0, 0, // row 4
} };
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
const int cellSize = heightfieldTileSize * static_cast<int>(surface.mSize - 1);
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
mNavigator->update(mPlayerPosition, nullptr);
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
const osg::Vec3f start(56, 56, 12);
const osg::Vec3f end(464, 464, 12);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, start, end, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success);
EXPECT_THAT(mPath,
ElementsAre( //
Vec3fEq(56.66664886474609375, 56.66664886474609375, 11.33333301544189453125),
Vec3fEq(396.666656494140625, 79.33331298828125, 11.33333301544189453125),
Vec3fEq(430.666656494140625, 113.33331298828125, 11.33333301544189453125),
Vec3fEq(463.999969482421875, 463.999969482421875, 11.33333301544189453125)))
<< mPath;
}
TEST_F(DetourNavigatorNavigatorTest, find_path_should_return_path_around_steep_cliffs)
{
const std::array<float, 5 * 5> heightfieldData{ {
0, 0, 0, 0, 0, // row 0
0, 0, 0, 0, 0, // row 1
0, 0, -1000, 0, 0, // row 2
0, 0, -1000, 0, 0, // row 3
0, 0, 0, 0, 0, // row 4
} };
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
const int cellSize = heightfieldTileSize * static_cast<int>(surface.mSize - 1);
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
mNavigator->update(mPlayerPosition, nullptr);
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
const osg::Vec3f start(56, 56, 12);
const osg::Vec3f end(464, 464, 12);
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, start, end, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
Status::Success);
EXPECT_THAT(mPath,
ElementsAre( //
Vec3fEq(56.66664886474609375, 56.66664886474609375, 8.66659259796142578125),
Vec3fEq(385.33331298828125, 79.33331298828125, 8.66659259796142578125),
Vec3fEq(430.666656494140625, 124.66664886474609375, 8.66659259796142578125),
Vec3fEq(463.999969482421875, 463.999969482421875, 8.66659259796142578125)))
<< mPath;
}
TEST_F(DetourNavigatorNavigatorTest, find_path_should_return_path_with_checkpoints)
{
const std::array<float, 5 * 5> heightfieldData{ {
0, 0, 0, 0, 0, // row 0
0, 0, 0, 0, 0, // row 1
0, 0, 1000, 0, 0, // row 2
0, 0, 1000, 0, 0, // row 3
0, 0, 0, 0, 0, // row 4
} };
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
const int cellSize = heightfieldTileSize * static_cast<int>(surface.mSize - 1);
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
mNavigator->update(mPlayerPosition, nullptr);
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
const std::vector<osg::Vec3f> checkpoints = {
osg::Vec3f(400, 70, 12),
};
const osg::Vec3f start(56, 56, 12);
const osg::Vec3f end(464, 464, 12);
EXPECT_EQ(
findPath(*mNavigator, mAgentBounds, start, end, Flag_walk, mAreaCosts, mEndTolerance, checkpoints, mOut),
Status::Success);
EXPECT_THAT(mPath,
ElementsAre( //
Vec3fEq(56.66664886474609375, 56.66664886474609375, 11.33333301544189453125),
Vec3fEq(400, 70, 11.33333301544189453125),
Vec3fEq(430.666656494140625, 113.33331298828125, 11.33333301544189453125),
Vec3fEq(463.999969482421875, 463.999969482421875, 11.33333301544189453125)))
<< mPath;
}
TEST_F(DetourNavigatorNavigatorTest, find_path_should_skip_unreachable_checkpoints)
{
const std::array<float, 5 * 5> heightfieldData{ {
0, 0, 0, 0, 0, // row 0
0, 0, 0, 0, 0, // row 1
0, 0, 1000, 0, 0, // row 2
0, 0, 1000, 0, 0, // row 3
0, 0, 0, 0, 0, // row 4
} };
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
const int cellSize = heightfieldTileSize * static_cast<int>(surface.mSize - 1);
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
mNavigator->update(mPlayerPosition, nullptr);
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
const std::vector<osg::Vec3f> checkpoints = {
osg::Vec3f(400, 70, 10000),
osg::Vec3f(256, 256, 1000),
osg::Vec3f(-1000, -1000, 0),
};
const osg::Vec3f start(56, 56, 12);
const osg::Vec3f end(464, 464, 12);
EXPECT_EQ(
findPath(*mNavigator, mAgentBounds, start, end, Flag_walk, mAreaCosts, mEndTolerance, checkpoints, mOut),
Status::Success);
EXPECT_THAT(mPath,
ElementsAre( //
Vec3fEq(56.66664886474609375, 56.66664886474609375, 11.33333301544189453125),
Vec3fEq(396.666656494140625, 79.33331298828125, 11.33333301544189453125),
Vec3fEq(430.666656494140625, 113.33331298828125, 11.33333301544189453125),
Vec3fEq(463.999969482421875, 463.999969482421875, 11.33333301544189453125)))
<< mPath;
}
struct DetourNavigatorNavigatorNotSupportedAgentBoundsTest : TestWithParam<AgentBounds> struct DetourNavigatorNavigatorNotSupportedAgentBoundsTest : TestWithParam<AgentBounds>
{ {
}; };

View file

@ -74,19 +74,20 @@ namespace
TEST(EsmFixedString, empty_strings) TEST(EsmFixedString, empty_strings)
{ {
constexpr std::string_view someStr = "some string";
{ {
SCOPED_TRACE("4 bytes"); SCOPED_TRACE("4 bytes");
ESM::NAME empty = ESM::NAME(); ESM::NAME empty = ESM::NAME();
EXPECT_TRUE(empty == ""); EXPECT_TRUE(empty == "");
EXPECT_TRUE(empty == static_cast<uint32_t>(0)); EXPECT_TRUE(empty == static_cast<uint32_t>(0));
EXPECT_TRUE(empty != "some string"); EXPECT_TRUE(empty != someStr);
EXPECT_TRUE(empty != static_cast<uint32_t>(42)); EXPECT_TRUE(empty != static_cast<uint32_t>(42));
} }
{ {
SCOPED_TRACE("32 bytes"); SCOPED_TRACE("32 bytes");
ESM::NAME32 empty = ESM::NAME32(); ESM::NAME32 empty = ESM::NAME32();
EXPECT_TRUE(empty == ""); EXPECT_TRUE(empty == "");
EXPECT_TRUE(empty != "some string"); EXPECT_TRUE(empty != someStr);
} }
} }

View file

@ -88,4 +88,31 @@ namespace
EXPECT_EQ(reader->getFileOffset(), sInitialOffset); EXPECT_EQ(reader->getFileOffset(), sInitialOffset);
} }
} }
TEST_F(ESM3ReadersCacheWithContentFile, CachedSizeAndName)
{
ESM::ReadersCache readers(2);
{
readers.get(0)->openRaw(std::make_unique<std::istringstream>("123"), "closed0.omwaddon");
readers.get(1)->openRaw(std::make_unique<std::istringstream>("12345"), "closed1.omwaddon");
readers.get(2)->openRaw(std::make_unique<std::istringstream>("1234567"), "free.omwaddon");
}
auto busy = readers.get(3);
busy->openRaw(std::make_unique<std::istringstream>("123456789"), "busy.omwaddon");
EXPECT_EQ(readers.getFileSize(0), 3);
EXPECT_EQ(readers.getName(0), "closed0.omwaddon");
EXPECT_EQ(readers.getFileSize(1), 5);
EXPECT_EQ(readers.getName(1), "closed1.omwaddon");
EXPECT_EQ(readers.getFileSize(2), 7);
EXPECT_EQ(readers.getName(2), "free.omwaddon");
EXPECT_EQ(readers.getFileSize(3), 9);
EXPECT_EQ(readers.getName(3), "busy.omwaddon");
// not-yet-seen indices give zero for their size
EXPECT_EQ(readers.getFileSize(4), 0);
}
} }

View file

@ -723,7 +723,7 @@ namespace ESM
TEST_P(Esm3SaveLoadRecordTest, landShouldNotChange) TEST_P(Esm3SaveLoadRecordTest, landShouldNotChange)
{ {
LandRecordData data; LandRecordData data;
std::iota(data.mHeights.begin(), data.mHeights.end(), 1); std::iota(data.mHeights.begin(), data.mHeights.end(), 1.0f);
std::for_each(data.mHeights.begin(), data.mHeights.end(), [](float& v) { v *= Land::sHeightScale; }); std::for_each(data.mHeights.begin(), data.mHeights.end(), [](float& v) { v *= Land::sHeightScale; });
data.mMinHeight = *std::min_element(data.mHeights.begin(), data.mHeights.end()); data.mMinHeight = *std::min_element(data.mHeights.begin(), data.mHeights.end());
data.mMaxHeight = *std::max_element(data.mHeights.begin(), data.mHeights.end()); data.mMaxHeight = *std::max_element(data.mHeights.begin(), data.mHeights.end());

View file

@ -10,7 +10,7 @@
#include <components/esmloader/load.hpp> #include <components/esmloader/load.hpp>
#include <components/files/collections.hpp> #include <components/files/collections.hpp>
#include <components/files/multidircollection.hpp> #include <components/files/multidircollection.hpp>
#include <components/to_utf8/to_utf8.hpp> #include <components/toutf8/toutf8.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>

View file

@ -30,7 +30,7 @@ namespace
TEST(FilesGetHash, shouldClearErrors) TEST(FilesGetHash, shouldClearErrors)
{ {
const auto fileName = temporaryFilePath("fileName"); const auto fileName = outputFilePath("fileName");
std::string content; std::string content;
std::fill_n(std::back_inserter(content), 1, 'a'); std::fill_n(std::back_inserter(content), 1, 'a');
std::istringstream stream(content); std::istringstream stream(content);
@ -41,7 +41,7 @@ namespace
TEST_P(FilesGetHash, shouldReturnHashForStringStream) TEST_P(FilesGetHash, shouldReturnHashForStringStream)
{ {
const auto fileName = temporaryFilePath("fileName"); const auto fileName = outputFilePath("fileName");
std::string content; std::string content;
std::fill_n(std::back_inserter(content), GetParam().mSize, 'a'); std::fill_n(std::back_inserter(content), GetParam().mSize, 'a');
std::istringstream stream(content); std::istringstream stream(content);

View file

@ -5,7 +5,7 @@
namespace namespace
{ {
using namespace testing; using namespace testing;
using namespace fx::Lexer; using namespace Fx::Lexer;
struct LexerTest : Test struct LexerTest : Test
{ {

View file

@ -91,7 +91,7 @@ namespace
)" }; )" };
using namespace testing; using namespace testing;
using namespace fx; using namespace Fx;
struct TechniqueTest : Test struct TechniqueTest : Test
{ {
@ -113,7 +113,8 @@ namespace
void compile(const std::string& name) void compile(const std::string& name)
{ {
mTechnique = std::make_unique<Technique>(*mVFS.get(), mImageManager, name, 1, 1, true, true); mTechnique = std::make_unique<Technique>(
*mVFS.get(), mImageManager, Technique::makeFileName(name), name, 1, 1, true, true);
mTechnique->compile(); mTechnique->compile();
} }
}; };

View file

@ -38,10 +38,10 @@ namespace
sol::state lua; sol::state lua;
LuaUtil::InputAction::Registry registry; LuaUtil::InputAction::Registry registry;
LuaUtil::InputAction::Info a({ "a", LuaUtil::InputAction::Type::Boolean, "test", "a_name", "a_description", LuaUtil::InputAction::Info a({ "a", LuaUtil::InputAction::Type::Boolean, "test", "a_name", "a_description",
sol::make_object(lua, false) }); sol::make_object(lua, false), false });
registry.insert(a); registry.insert(a);
LuaUtil::InputAction::Info b({ "b", LuaUtil::InputAction::Type::Boolean, "test", "b_name", "b_description", LuaUtil::InputAction::Info b({ "b", LuaUtil::InputAction::Type::Boolean, "test", "b_name", "b_description",
sol::make_object(lua, false) }); sol::make_object(lua, false), false });
registry.insert(b); registry.insert(b);
LuaUtil::Callback bindA({ lua.load("return function() return true end")(), sol::table(lua, sol::create) }); LuaUtil::Callback bindA({ lua.load("return function() return true end")(), sol::table(lua, sol::create) });
LuaUtil::Callback bindBToA( LuaUtil::Callback bindBToA(

View file

@ -24,6 +24,8 @@ namespace
constexpr VFS::Path::NormalizedView test2EnPath("l10n/test2/en.yaml"); constexpr VFS::Path::NormalizedView test2EnPath("l10n/test2/en.yaml");
constexpr VFS::Path::NormalizedView test3EnPath("l10n/test3/en.yaml"); constexpr VFS::Path::NormalizedView test3EnPath("l10n/test3/en.yaml");
constexpr VFS::Path::NormalizedView test3DePath("l10n/test3/de.yaml"); constexpr VFS::Path::NormalizedView test3DePath("l10n/test3/de.yaml");
constexpr VFS::Path::NormalizedView test4RuPath("l10n/test4/ru.yaml");
constexpr VFS::Path::NormalizedView test4EnPath("l10n/test4/en.yaml");
VFSTestFile invalidScript("not a script"); VFSTestFile invalidScript("not a script");
VFSTestFile incorrectScript( VFSTestFile incorrectScript(
@ -69,6 +71,16 @@ currency: "You have {money, number, currency}"
VFSTestFile test2En(R"X( VFSTestFile test2En(R"X(
good_morning: "Morning!" good_morning: "Morning!"
you_have_arrows: "Arrows count: {count}" you_have_arrows: "Arrows count: {count}"
)X");
VFSTestFile test4Ru(R"X(
skill_increase: "Ваш навык {навык} увеличился до {value}"
acrobatics: "Акробатика"
)X");
VFSTestFile test4En(R"X(
stat_increase: "Your {stat} has increased to {value}"
speed: "Speed"
)X"); )X");
struct LuaL10nTest : Test struct LuaL10nTest : Test
@ -80,6 +92,8 @@ you_have_arrows: "Arrows count: {count}"
{ test2EnPath, &test2En }, { test2EnPath, &test2En },
{ test3EnPath, &test1En }, { test3EnPath, &test1En },
{ test3DePath, &test1De }, { test3DePath, &test1De },
{ test4RuPath, &test4Ru },
{ test4EnPath, &test4En },
}); });
LuaUtil::ScriptsConfiguration mCfg; LuaUtil::ScriptsConfiguration mCfg;
@ -91,7 +105,7 @@ you_have_arrows: "Arrows count: {count}"
lua.protectedCall([&](LuaUtil::LuaView& view) { lua.protectedCall([&](LuaUtil::LuaView& view) {
sol::state_view& l = view.sol(); sol::state_view& l = view.sol();
internal::CaptureStdout(); internal::CaptureStdout();
l10n::Manager l10nManager(mVFS.get()); L10n::Manager l10nManager(mVFS.get());
l10nManager.setPreferredLocales({ "de", "en" }); l10nManager.setPreferredLocales({ "de", "en" });
EXPECT_THAT(internal::GetCapturedStdout(), "Preferred locales: gmst de en\n"); EXPECT_THAT(internal::GetCapturedStdout(), "Preferred locales: gmst de en\n");
@ -169,6 +183,18 @@ you_have_arrows: "Arrows count: {count}"
l.safe_script("t3 = l10n('Test3', 'de')"); l.safe_script("t3 = l10n('Test3', 'de')");
l10nManager.setPreferredLocales({ "en" }); l10nManager.setPreferredLocales({ "en" });
EXPECT_EQ(get<std::string>(l, "t3('Hello {name}!', {name='World'})"), "Hallo World!"); EXPECT_EQ(get<std::string>(l, "t3('Hello {name}!', {name='World'})"), "Hallo World!");
// Test that formatting arguments use a correct encoding
l.safe_script("t4 = l10n('Test4', 'ru')");
l10nManager.setPreferredLocales({ "ru", "en" });
EXPECT_EQ(get<std::string>(l, "t4('skill_increase', {навык='Акробатика', value=100})"),
"Ваш навык Акробатика увеличился до 100");
EXPECT_EQ(get<std::string>(l, "t4('skill_increase', {навык=t4('acrobatics'), value=100})"),
"Ваш навык Акробатика увеличился до 100");
EXPECT_EQ(get<std::string>(l, "t4('stat_increase', {stat='Speed', value=100})"),
"Your Speed has increased to 100");
EXPECT_EQ(get<std::string>(l, "t4('stat_increase', {stat=t4('speed'), value=100})"),
"Your Speed has increased to 100");
}); });
} }
} }

View file

@ -285,17 +285,17 @@ CUSTOM: customdata.lua
EXPECT_TRUE(scripts.addCustomScript(getId(test2Path))); EXPECT_TRUE(scripts.addCustomScript(getId(test2Path)));
sol::state_view sol = mLua.unsafeState(); sol::state_view sol = mLua.unsafeState();
std::string X0 = LuaUtil::serialize(sol.create_table_with("x", 0.5)); std::string x0 = LuaUtil::serialize(sol.create_table_with("x", 0.5));
std::string X1 = LuaUtil::serialize(sol.create_table_with("x", 1.5)); std::string x1 = LuaUtil::serialize(sol.create_table_with("x", 1.5));
{ {
testing::internal::CaptureStdout(); testing::internal::CaptureStdout();
scripts.receiveEvent("SomeEvent", X1); scripts.receiveEvent("SomeEvent", x1);
EXPECT_EQ(internal::GetCapturedStdout(), ""); EXPECT_EQ(internal::GetCapturedStdout(), "");
} }
{ {
testing::internal::CaptureStdout(); testing::internal::CaptureStdout();
scripts.receiveEvent("Event1", X1); scripts.receiveEvent("Event1", x1);
EXPECT_EQ(internal::GetCapturedStdout(), EXPECT_EQ(internal::GetCapturedStdout(),
"Test[test2.lua]:\t event1 1.5\n" "Test[test2.lua]:\t event1 1.5\n"
"Test[stopevent.lua]:\t event1 1.5\n" "Test[stopevent.lua]:\t event1 1.5\n"
@ -303,21 +303,21 @@ CUSTOM: customdata.lua
} }
{ {
testing::internal::CaptureStdout(); testing::internal::CaptureStdout();
scripts.receiveEvent("Event2", X1); scripts.receiveEvent("Event2", x1);
EXPECT_EQ(internal::GetCapturedStdout(), EXPECT_EQ(internal::GetCapturedStdout(),
"Test[test2.lua]:\t event2 1.5\n" "Test[test2.lua]:\t event2 1.5\n"
"Test[test1.lua]:\t event2 1.5\n"); "Test[test1.lua]:\t event2 1.5\n");
} }
{ {
testing::internal::CaptureStdout(); testing::internal::CaptureStdout();
scripts.receiveEvent("Event1", X0); scripts.receiveEvent("Event1", x0);
EXPECT_EQ(internal::GetCapturedStdout(), EXPECT_EQ(internal::GetCapturedStdout(),
"Test[test2.lua]:\t event1 0.5\n" "Test[test2.lua]:\t event1 0.5\n"
"Test[stopevent.lua]:\t event1 0.5\n"); "Test[stopevent.lua]:\t event1 0.5\n");
} }
{ {
testing::internal::CaptureStdout(); testing::internal::CaptureStdout();
scripts.receiveEvent("Event2", X0); scripts.receiveEvent("Event2", x0);
EXPECT_EQ(internal::GetCapturedStdout(), EXPECT_EQ(internal::GetCapturedStdout(),
"Test[test2.lua]:\t event2 0.5\n" "Test[test2.lua]:\t event2 0.5\n"
"Test[test1.lua]:\t event2 0.5\n"); "Test[test1.lua]:\t event2 0.5\n");
@ -333,12 +333,12 @@ CUSTOM: customdata.lua
EXPECT_TRUE(scripts.addCustomScript(getId(test2Path))); EXPECT_TRUE(scripts.addCustomScript(getId(test2Path)));
sol::state_view sol = mLua.unsafeState(); sol::state_view sol = mLua.unsafeState();
std::string X = LuaUtil::serialize(sol.create_table_with("x", 0.5)); std::string x = LuaUtil::serialize(sol.create_table_with("x", 0.5));
{ {
testing::internal::CaptureStdout(); testing::internal::CaptureStdout();
scripts.update(1.5f); scripts.update(1.5f);
scripts.receiveEvent("Event1", X); scripts.receiveEvent("Event1", x);
EXPECT_EQ(internal::GetCapturedStdout(), EXPECT_EQ(internal::GetCapturedStdout(),
"Test[test1.lua]:\t update 1.5\n" "Test[test1.lua]:\t update 1.5\n"
"Test[test2.lua]:\t update 1.5\n" "Test[test2.lua]:\t update 1.5\n"
@ -352,7 +352,7 @@ CUSTOM: customdata.lua
scripts.removeScript(stopEventScriptId); scripts.removeScript(stopEventScriptId);
EXPECT_FALSE(scripts.hasScript(stopEventScriptId)); EXPECT_FALSE(scripts.hasScript(stopEventScriptId));
scripts.update(1.5f); scripts.update(1.5f);
scripts.receiveEvent("Event1", X); scripts.receiveEvent("Event1", x);
EXPECT_EQ(internal::GetCapturedStdout(), EXPECT_EQ(internal::GetCapturedStdout(),
"Test[test1.lua]:\t update 1.5\n" "Test[test1.lua]:\t update 1.5\n"
"Test[test2.lua]:\t update 1.5\n" "Test[test2.lua]:\t update 1.5\n"
@ -363,7 +363,7 @@ CUSTOM: customdata.lua
testing::internal::CaptureStdout(); testing::internal::CaptureStdout();
scripts.removeScript(getId(test1Path)); scripts.removeScript(getId(test1Path));
scripts.update(1.5f); scripts.update(1.5f);
scripts.receiveEvent("Event1", X); scripts.receiveEvent("Event1", x);
EXPECT_EQ(internal::GetCapturedStdout(), EXPECT_EQ(internal::GetCapturedStdout(),
"Test[test2.lua]:\t update 1.5\n" "Test[test2.lua]:\t update 1.5\n"
"Test[test2.lua]:\t event1 0.5\n"); "Test[test2.lua]:\t event1 0.5\n");
@ -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 }));

View file

@ -171,10 +171,10 @@ namespace
std::string serialized = LuaUtil::serialize(table); std::string serialized = LuaUtil::serialize(table);
EXPECT_EQ(serialized.size(), 139); EXPECT_EQ(serialized.size(), 139);
sol::table res_table = LuaUtil::deserialize(lua, serialized); sol::table resTable = LuaUtil::deserialize(lua, serialized);
sol::table res_readonly_table = LuaUtil::deserialize(lua, serialized, nullptr, true); sol::table resReadonlyTable = LuaUtil::deserialize(lua, serialized, nullptr, true);
for (auto t : { res_table, res_readonly_table }) for (auto t : { resTable, resReadonlyTable })
{ {
EXPECT_EQ(t.get<int>("aa"), 1); EXPECT_EQ(t.get<int>("aa"), 1);
EXPECT_EQ(t.get<bool>("ab"), true); EXPECT_EQ(t.get<bool>("ab"), true);
@ -185,8 +185,8 @@ namespace
EXPECT_EQ(t.get<osg::Vec2f>(2), osg::Vec2f(2, 1)); EXPECT_EQ(t.get<osg::Vec2f>(2), osg::Vec2f(2, 1));
} }
lua["t"] = res_table; lua["t"] = resTable;
lua["ro_t"] = res_readonly_table; lua["ro_t"] = resReadonlyTable;
EXPECT_NO_THROW(lua.safe_script("t.x = 5")); EXPECT_NO_THROW(lua.safe_script("t.x = 5"));
EXPECT_NO_THROW(lua.safe_script("t.nested.x = 5")); EXPECT_NO_THROW(lua.safe_script("t.nested.x = 5"));
EXPECT_ERROR(lua.safe_script("ro_t.x = 5"), "userdata value"); EXPECT_ERROR(lua.safe_script("ro_t.x = 5"), "userdata value");

View file

@ -9,22 +9,33 @@ namespace
{ {
using namespace testing; using namespace testing;
struct LuaUtilPackageTest : Test
{
LuaUtil::LuaState mLuaState{ nullptr, nullptr };
LuaUtilPackageTest()
{
mLuaState.addInternalLibSearchPath(
std::filesystem::path{ OPENMW_PROJECT_SOURCE_DIR } / "components" / "lua");
sol::state_view sol = mLuaState.unsafeState();
sol["util"] = LuaUtil::initUtilPackage(sol);
}
};
template <typename T> template <typename T>
T get(sol::state& lua, const std::string& luaCode) T get(sol::state_view& lua, const std::string& luaCode)
{ {
return lua.safe_script("return " + luaCode).get<T>(); return lua.safe_script("return " + luaCode).get<T>();
} }
std::string getAsString(sol::state& lua, std::string luaCode) std::string getAsString(sol::state_view& lua, std::string luaCode)
{ {
return LuaUtil::toString(lua.safe_script("return " + luaCode)); return LuaUtil::toString(lua.safe_script("return " + luaCode));
} }
TEST(LuaUtilPackageTest, Vector2) TEST_F(LuaUtilPackageTest, Vector2)
{ {
sol::state lua; sol::state_view lua = mLuaState.unsafeState();
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string);
lua["util"] = LuaUtil::initUtilPackage(lua);
lua.safe_script("v = util.vector2(3, 4)"); lua.safe_script("v = util.vector2(3, 4)");
EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), 3); EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), 3);
EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 4); EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 4);
@ -55,11 +66,9 @@ namespace
EXPECT_TRUE(get<bool>(lua, "swizzle['01'] == util.vector2(0, 1) and swizzle['0y'] == util.vector2(0, 2)")); EXPECT_TRUE(get<bool>(lua, "swizzle['01'] == util.vector2(0, 1) and swizzle['0y'] == util.vector2(0, 2)"));
} }
TEST(LuaUtilPackageTest, Vector3) TEST_F(LuaUtilPackageTest, Vector3)
{ {
sol::state lua; sol::state_view lua = mLuaState.unsafeState();
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string);
lua["util"] = LuaUtil::initUtilPackage(lua);
lua.safe_script("v = util.vector3(5, 12, 13)"); lua.safe_script("v = util.vector3(5, 12, 13)");
EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), 5); EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), 5);
EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 12); EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 12);
@ -94,11 +103,9 @@ namespace
get<bool>(lua, "swizzle['001'] == util.vector3(0, 0, 1) and swizzle['0yx'] == util.vector3(0, 2, 1)")); get<bool>(lua, "swizzle['001'] == util.vector3(0, 0, 1) and swizzle['0yx'] == util.vector3(0, 2, 1)"));
} }
TEST(LuaUtilPackageTest, Vector4) TEST_F(LuaUtilPackageTest, Vector4)
{ {
sol::state lua; sol::state_view lua = mLuaState.unsafeState();
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string);
lua["util"] = LuaUtil::initUtilPackage(lua);
lua.safe_script("v = util.vector4(5, 12, 13, 15)"); lua.safe_script("v = util.vector4(5, 12, 13, 15)");
EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), 5); EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), 5);
EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 12); EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 12);
@ -136,11 +143,9 @@ namespace
lua, "swizzle['0001'] == util.vector4(0, 0, 0, 1) and swizzle['0yx1'] == util.vector4(0, 2, 1, 1)")); lua, "swizzle['0001'] == util.vector4(0, 0, 0, 1) and swizzle['0yx1'] == util.vector4(0, 2, 1, 1)"));
} }
TEST(LuaUtilPackageTest, Color) TEST_F(LuaUtilPackageTest, Color)
{ {
sol::state lua; sol::state_view lua = mLuaState.unsafeState();
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string);
lua["util"] = LuaUtil::initUtilPackage(lua);
lua.safe_script("brown = util.color.rgba(0.75, 0.25, 0, 1)"); lua.safe_script("brown = util.color.rgba(0.75, 0.25, 0, 1)");
EXPECT_EQ(get<std::string>(lua, "tostring(brown)"), "(0.75, 0.25, 0, 1)"); EXPECT_EQ(get<std::string>(lua, "tostring(brown)"), "(0.75, 0.25, 0, 1)");
lua.safe_script("blue = util.color.rgb(0, 1, 0, 1)"); lua.safe_script("blue = util.color.rgb(0, 1, 0, 1)");
@ -155,11 +160,9 @@ namespace
EXPECT_TRUE(get<bool>(lua, "red:asRgb() == util.vector3(1, 0, 0)")); EXPECT_TRUE(get<bool>(lua, "red:asRgb() == util.vector3(1, 0, 0)"));
} }
TEST(LuaUtilPackageTest, Transform) TEST_F(LuaUtilPackageTest, Transform)
{ {
sol::state lua; sol::state_view lua = mLuaState.unsafeState();
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string);
lua["util"] = LuaUtil::initUtilPackage(lua);
lua["T"] = lua["util"]["transform"]; lua["T"] = lua["util"]["transform"];
lua["v"] = lua["util"]["vector3"]; lua["v"] = lua["util"]["vector3"];
EXPECT_ERROR(lua.safe_script("T.identity = nil"), "attempt to index"); EXPECT_ERROR(lua.safe_script("T.identity = nil"), "attempt to index");
@ -191,11 +194,9 @@ namespace
EXPECT_LT(get<float>(lua, "(rz_move_rx:inverse() * v(0, 1, 2) - v(1, 2, 3)):length()"), 1e-6); EXPECT_LT(get<float>(lua, "(rz_move_rx:inverse() * v(0, 1, 2) - v(1, 2, 3)):length()"), 1e-6);
} }
TEST(LuaUtilPackageTest, UtilityFunctions) TEST_F(LuaUtilPackageTest, UtilityFunctions)
{ {
sol::state lua; sol::state_view lua = mLuaState.unsafeState();
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string);
lua["util"] = LuaUtil::initUtilPackage(lua);
lua.safe_script("v = util.vector2(1, 0):rotate(math.rad(120))"); lua.safe_script("v = util.vector2(1, 0):rotate(math.rad(120))");
EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), -0.5f); EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), -0.5f);
EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 0.86602539f); EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 0.86602539f);
@ -203,6 +204,10 @@ namespace
EXPECT_FLOAT_EQ(get<float>(lua, "util.clamp(0.1, 0, 1.5)"), 0.1f); EXPECT_FLOAT_EQ(get<float>(lua, "util.clamp(0.1, 0, 1.5)"), 0.1f);
EXPECT_FLOAT_EQ(get<float>(lua, "util.clamp(-0.1, 0, 1.5)"), 0); EXPECT_FLOAT_EQ(get<float>(lua, "util.clamp(-0.1, 0, 1.5)"), 0);
EXPECT_FLOAT_EQ(get<float>(lua, "util.clamp(2.1, 0, 1.5)"), 1.5f); EXPECT_FLOAT_EQ(get<float>(lua, "util.clamp(2.1, 0, 1.5)"), 1.5f);
EXPECT_FLOAT_EQ(get<float>(lua, "util.round(2.1)"), 2.0f);
EXPECT_FLOAT_EQ(get<float>(lua, "util.round(-2.1)"), -2.0f);
EXPECT_FLOAT_EQ(get<float>(lua, "util.remap(5, 0, 10, 0, 100)"), 50.0f);
EXPECT_FLOAT_EQ(get<float>(lua, "util.remap(-5, 0, 10, 0, 100)"), -50.0f);
lua.safe_script("t = util.makeReadOnly({x = 1})"); lua.safe_script("t = util.makeReadOnly({x = 1})");
EXPECT_FLOAT_EQ(get<float>(lua, "t.x"), 1); EXPECT_FLOAT_EQ(get<float>(lua, "t.x"), 1);
EXPECT_ERROR(lua.safe_script("t.y = 2"), "userdata value"); EXPECT_ERROR(lua.safe_script("t.y = 2"), "userdata value");

View file

@ -2,6 +2,7 @@
#include <components/misc/strings/conversion.hpp> #include <components/misc/strings/conversion.hpp>
#include <components/settings/parser.hpp> #include <components/settings/parser.hpp>
#include <components/settings/values.hpp> #include <components/settings/values.hpp>
#include <components/testing/util.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -24,5 +25,9 @@ int main(int argc, char** argv)
Settings::StaticValues::init(); Settings::StaticValues::init();
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
const int result = RUN_ALL_TESTS();
if (result == 0)
std::filesystem::remove_all(TestingOpenMW::outputDir());
return result;
} }

View file

@ -51,7 +51,7 @@ namespace Misc
const std::pair<osg::Quat, osg::Vec3f> eulerAnglesXZQuat[] = { const std::pair<osg::Quat, osg::Vec3f> eulerAnglesXZQuat[] = {
{ {
osg::Quat(1, 0, 0, 0), osg::Quat(1, 0, 0, 0),
osg::Vec3f(0, 0, osg::PI), osg::Vec3f(0, 0, osg::PIf),
}, },
{ {
osg::Quat(0, 1, 0, 0), osg::Quat(0, 1, 0, 0),
@ -59,7 +59,7 @@ namespace Misc
}, },
{ {
osg::Quat(0, 0, 1, 0), osg::Quat(0, 0, 1, 0),
osg::Vec3f(0, 0, osg::PI), osg::Vec3f(0, 0, osg::PIf),
}, },
{ {
osg::Quat(0, 0, 0, 1), osg::Quat(0, 0, 0, 1),
@ -128,15 +128,15 @@ namespace Misc
const std::pair<osg::Quat, osg::Vec3f> eulerAnglesZYXQuat[] = { const std::pair<osg::Quat, osg::Vec3f> eulerAnglesZYXQuat[] = {
{ {
osg::Quat(1, 0, 0, 0), osg::Quat(1, 0, 0, 0),
osg::Vec3f(osg::PI, 0, 0), osg::Vec3f(osg::PIf, 0, 0),
}, },
{ {
osg::Quat(0, 1, 0, 0), osg::Quat(0, 1, 0, 0),
osg::Vec3f(osg::PI, 0, osg::PI), osg::Vec3f(osg::PIf, 0, osg::PIf),
}, },
{ {
osg::Quat(0, 0, 1, 0), osg::Quat(0, 0, 1, 0),
osg::Vec3f(0, 0, osg::PI), osg::Vec3f(0, 0, osg::PIf),
}, },
{ {
osg::Quat(0, 0, 0, 1), osg::Quat(0, 0, 0, 1),

View file

@ -26,6 +26,15 @@ namespace
std::unique_ptr<VFS::Manager> mVFS = TestingOpenMW::createTestVFS({}); std::unique_ptr<VFS::Manager> mVFS = TestingOpenMW::createTestVFS({});
constexpr VFS::Path::NormalizedView path("sound/foo.wav"); constexpr VFS::Path::NormalizedView path("sound/foo.wav");
EXPECT_EQ(correctSoundPath(path, *mVFS), "sound/foo.mp3"); EXPECT_EQ(correctSoundPath(path, *mVFS), "sound/foo.mp3");
auto correctESM4SoundPath = [](auto path, auto* vfs) {
return Misc::ResourceHelpers::correctResourcePath({ { "sound" } }, path, vfs, ".mp3");
};
EXPECT_EQ(correctESM4SoundPath("foo.WAV", mVFS.get()), "sound\\foo.mp3");
EXPECT_EQ(correctESM4SoundPath("SOUND/foo.WAV", mVFS.get()), "sound\\foo.mp3");
EXPECT_EQ(correctESM4SoundPath("DATA\\SOUND\\foo.WAV", mVFS.get()), "sound\\foo.mp3");
EXPECT_EQ(correctESM4SoundPath("\\Data/Sound\\foo.WAV", mVFS.get()), "sound\\foo.mp3");
} }
namespace namespace

View file

@ -16,7 +16,7 @@ namespace
ShaderManager mManager; ShaderManager mManager;
ShaderManager::DefineMap mDefines; ShaderManager::DefineMap mDefines;
ShaderManagerTest() { mManager.setShaderPath("tests_output"); } ShaderManagerTest() { mManager.setShaderPath(TestingOpenMW::outputDir()); }
template <class F> template <class F>
void withShaderFile(const std::string& content, F&& f) void withShaderFile(const std::string& content, F&& f)

View file

@ -1,5 +1,5 @@
#include <components/misc/strings/conversion.hpp> #include <components/misc/strings/conversion.hpp>
#include <components/to_utf8/to_utf8.hpp> #include <components/toutf8/toutf8.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>

View file

@ -101,9 +101,9 @@ Allowed options)");
try try
{ {
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv).options(all).positional(p).run(); bpo::parsed_options validOpts = bpo::command_line_parser(argc, argv).options(all).positional(p).run();
bpo::store(valid_opts, variables); bpo::store(validOpts, variables);
} }
catch (std::exception& e) catch (std::exception& e)
{ {
@ -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

View file

@ -1,5 +1,7 @@
#include "labels.hpp" #include "labels.hpp"
#include <format>
#include <components/esm3/dialoguecondition.hpp> #include <components/esm3/dialoguecondition.hpp>
#include <components/esm3/loadalch.hpp> #include <components/esm3/loadalch.hpp>
#include <components/esm3/loadbody.hpp> #include <components/esm3/loadbody.hpp>
@ -16,8 +18,6 @@
#include <components/esm3/loadspel.hpp> #include <components/esm3/loadspel.hpp>
#include <components/esm3/loadweap.hpp> #include <components/esm3/loadweap.hpp>
#include <components/misc/strings/format.hpp>
std::string_view bodyPartLabel(int idx) std::string_view bodyPartLabel(int idx)
{ {
if (idx >= 0 && idx <= 26) if (idx >= 0 && idx <= 26)
@ -675,7 +675,7 @@ std::string bodyPartFlags(int flags)
int unused = (0xFFFFFFFF ^ (ESM::BodyPart::BPF_Female | ESM::BodyPart::BPF_NotPlayable)); int unused = (0xFFFFFFFF ^ (ESM::BodyPart::BPF_Female | ESM::BodyPart::BPF_NotPlayable));
if (flags & unused) if (flags & unused)
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%08X)", flags); properties += std::format("(0x{:08X})", flags);
return properties; return properties;
} }
@ -699,7 +699,7 @@ std::string cellFlags(int flags)
^ (ESM::Cell::HasWater | ESM::Cell::Interior | ESM::Cell::NoSleep | ESM::Cell::QuasiEx | 0x00000040)); ^ (ESM::Cell::HasWater | ESM::Cell::Interior | ESM::Cell::NoSleep | ESM::Cell::QuasiEx | 0x00000040));
if (flags & unused) if (flags & unused)
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%08X)", flags); properties += std::format("(0x{:08X})", flags);
return properties; return properties;
} }
@ -717,7 +717,7 @@ std::string containerFlags(int flags)
int unused = (0xFFFFFFFF ^ (ESM::Container::Unknown | ESM::Container::Organic | ESM::Container::Respawn)); int unused = (0xFFFFFFFF ^ (ESM::Container::Unknown | ESM::Container::Organic | ESM::Container::Respawn));
if (flags & unused) if (flags & unused)
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%08X)", flags); properties += std::format("(0x{:08X})", flags);
return properties; return properties;
} }
@ -747,7 +747,7 @@ std::string creatureFlags(int flags)
| ESM::Creature::Bipedal | ESM::Creature::Respawn | ESM::Creature::Weapon | ESM::Creature::Essential)); | ESM::Creature::Bipedal | ESM::Creature::Respawn | ESM::Creature::Weapon | ESM::Creature::Essential));
if (flags & unused) if (flags & unused)
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%02X)", flags); properties += std::format("(0x{:02X})", flags);
return properties; return properties;
} }
@ -760,7 +760,7 @@ std::string enchantmentFlags(int flags)
properties += "Autocalc "; properties += "Autocalc ";
if (flags & (0xFFFFFFFF ^ ESM::Enchantment::Autocalc)) if (flags & (0xFFFFFFFF ^ ESM::Enchantment::Autocalc))
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%08X)", flags); properties += std::format("(0x{:08X})", flags);
return properties; return properties;
} }
@ -778,7 +778,7 @@ std::string landFlags(std::uint32_t flags)
int unused = 0xFFFFFFFF ^ (ESM::Land::Flag_HeightsNormals | ESM::Land::Flag_Colors | ESM::Land::Flag_Textures); int unused = 0xFFFFFFFF ^ (ESM::Land::Flag_HeightsNormals | ESM::Land::Flag_Colors | ESM::Land::Flag_Textures);
if (flags & unused) if (flags & unused)
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%08X)", flags); properties += std::format("(0x{:08X})", flags);
return properties; return properties;
} }
@ -794,7 +794,7 @@ std::string itemListFlags(int flags)
int unused = (0xFFFFFFFF ^ (ESM::ItemLevList::AllLevels | ESM::ItemLevList::Each)); int unused = (0xFFFFFFFF ^ (ESM::ItemLevList::AllLevels | ESM::ItemLevList::Each));
if (flags & unused) if (flags & unused)
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%08X)", flags); properties += std::format("(0x{:08X})", flags);
return properties; return properties;
} }
@ -808,7 +808,7 @@ std::string creatureListFlags(int flags)
int unused = (0xFFFFFFFF ^ ESM::CreatureLevList::AllLevels); int unused = (0xFFFFFFFF ^ ESM::CreatureLevList::AllLevels);
if (flags & unused) if (flags & unused)
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%08X)", flags); properties += std::format("(0x{:08X})", flags);
return properties; return properties;
} }
@ -840,7 +840,7 @@ std::string lightFlags(int flags)
| ESM::Light::Pulse | ESM::Light::PulseSlow | ESM::Light::Negative | ESM::Light::OffDefault)); | ESM::Light::Pulse | ESM::Light::PulseSlow | ESM::Light::Negative | ESM::Light::OffDefault));
if (flags & unused) if (flags & unused)
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%08X)", flags); properties += std::format("(0x{:08X})", flags);
return properties; return properties;
} }
@ -888,7 +888,7 @@ std::string magicEffectFlags(int flags)
if (flags & 0xFFFC0000) if (flags & 0xFFFC0000)
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%08X)", flags); properties += std::format("(0x{:08X})", flags);
return properties; return properties;
} }
@ -913,7 +913,7 @@ std::string npcFlags(int flags)
= (0xFF ^ (ESM::NPC::Base | ESM::NPC::Autocalc | ESM::NPC::Female | ESM::NPC::Respawn | ESM::NPC::Essential)); = (0xFF ^ (ESM::NPC::Base | ESM::NPC::Autocalc | ESM::NPC::Female | ESM::NPC::Respawn | ESM::NPC::Essential));
if (flags & unused) if (flags & unused)
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%02X)", flags); properties += std::format("(0x{:02X})", flags);
return properties; return properties;
} }
@ -930,7 +930,7 @@ std::string raceFlags(int flags)
int unused = (0xFFFFFFFF ^ (ESM::Race::Playable | ESM::Race::Beast)); int unused = (0xFFFFFFFF ^ (ESM::Race::Playable | ESM::Race::Beast));
if (flags & unused) if (flags & unused)
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%08X)", flags); properties += std::format("(0x{:08X})", flags);
return properties; return properties;
} }
@ -948,7 +948,7 @@ std::string spellFlags(int flags)
int unused = (0xFFFFFFFF ^ (ESM::Spell::F_Autocalc | ESM::Spell::F_PCStart | ESM::Spell::F_Always)); int unused = (0xFFFFFFFF ^ (ESM::Spell::F_Autocalc | ESM::Spell::F_PCStart | ESM::Spell::F_Always));
if (flags & unused) if (flags & unused)
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%08X)", flags); properties += std::format("(0x{:08X})", flags);
return properties; return properties;
} }
@ -967,7 +967,7 @@ std::string weaponFlags(int flags)
int unused = (0xFFFFFFFF ^ (ESM::Weapon::Magical | ESM::Weapon::Silver)); int unused = (0xFFFFFFFF ^ (ESM::Weapon::Magical | ESM::Weapon::Silver));
if (flags & unused) if (flags & unused)
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%08X)", flags); properties += std::format("(0x{:08X})", flags);
return properties; return properties;
} }
@ -987,7 +987,7 @@ std::string recordFlags(uint32_t flags)
int unused = ~(ESM::FLAG_Deleted | ESM::FLAG_Persistent | ESM::FLAG_Ignored | ESM::FLAG_Blocked); int unused = ~(ESM::FLAG_Deleted | ESM::FLAG_Persistent | ESM::FLAG_Ignored | ESM::FLAG_Blocked);
if (flags & unused) if (flags & unused)
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%08X)", flags); properties += std::format("(0x{:08X})", flags);
return properties; return properties;
} }
@ -1000,6 +1000,6 @@ std::string potionFlags(int flags)
properties += "Autocalc "; properties += "Autocalc ";
if (flags & (0xFFFFFFFF ^ ESM::Enchantment::Autocalc)) if (flags & (0xFFFFFFFF ^ ESM::Enchantment::Autocalc))
properties += "Invalid "; properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%08X)", flags); properties += std::format("(0x{:08X})", flags);
return properties; return properties;
} }

View file

@ -1,6 +1,7 @@
#include "record.hpp" #include "record.hpp"
#include "labels.hpp" #include "labels.hpp"
#include <format>
#include <iostream> #include <iostream>
#include <numeric> #include <numeric>
#include <sstream> #include <sstream>
@ -8,15 +9,13 @@
#include <components/esm3/cellstate.hpp> #include <components/esm3/cellstate.hpp>
#include <components/esm3/esmreader.hpp> #include <components/esm3/esmreader.hpp>
#include <components/misc/strings/conversion.hpp> #include <components/misc/strings/conversion.hpp>
#include <components/misc/strings/format.hpp>
namespace namespace
{ {
void printAIPackage(const ESM::AIPackage& p) void printAIPackage(const ESM::AIPackage& p)
{ {
std::cout << " AI Type: " << aiTypeLabel(p.mType) << " (" << Misc::StringUtils::format("0x%08X", p.mType) std::cout << std::format(" AI Type: {} (0x{:08X})\n", aiTypeLabel(p.mType), std::uint32_t(p.mType));
<< ")" << std::endl;
if (p.mType == ESM::AI_Wander) if (p.mType == ESM::AI_Wander)
{ {
std::cout << " Distance: " << p.mWander.mDistance << std::endl; std::cout << " Distance: " << p.mWander.mDistance << std::endl;
@ -51,7 +50,7 @@ namespace
} }
else else
{ {
std::cout << " BadPackage: " << Misc::StringUtils::format("0x%08X", p.mType) << std::endl; std::cout << std::format(" BadPackage: 0x{:08X}\n", std::uint32_t(p.mType));
} }
if (!p.mCellName.empty()) if (!p.mCellName.empty())
@ -60,81 +59,81 @@ namespace
std::string ruleString(const ESM::DialogueCondition& ss) std::string ruleString(const ESM::DialogueCondition& ss)
{ {
std::string_view type_str = "INVALID"; std::string_view typeStr = "INVALID";
std::string_view func_str; std::string_view funcStr;
switch (ss.mFunction) switch (ss.mFunction)
{ {
case ESM::DialogueCondition::Function_Global: case ESM::DialogueCondition::Function_Global:
type_str = "Global"; typeStr = "Global";
func_str = ss.mVariable; funcStr = ss.mVariable;
break; break;
case ESM::DialogueCondition::Function_Local: case ESM::DialogueCondition::Function_Local:
type_str = "Local"; typeStr = "Local";
func_str = ss.mVariable; funcStr = ss.mVariable;
break; break;
case ESM::DialogueCondition::Function_Journal: case ESM::DialogueCondition::Function_Journal:
type_str = "Journal"; typeStr = "Journal";
func_str = ss.mVariable; funcStr = ss.mVariable;
break; break;
case ESM::DialogueCondition::Function_Item: case ESM::DialogueCondition::Function_Item:
type_str = "Item count"; typeStr = "Item count";
func_str = ss.mVariable; funcStr = ss.mVariable;
break; break;
case ESM::DialogueCondition::Function_Dead: case ESM::DialogueCondition::Function_Dead:
type_str = "Dead"; typeStr = "Dead";
func_str = ss.mVariable; funcStr = ss.mVariable;
break; break;
case ESM::DialogueCondition::Function_NotId: case ESM::DialogueCondition::Function_NotId:
type_str = "Not ID"; typeStr = "Not ID";
func_str = ss.mVariable; funcStr = ss.mVariable;
break; break;
case ESM::DialogueCondition::Function_NotFaction: case ESM::DialogueCondition::Function_NotFaction:
type_str = "Not Faction"; typeStr = "Not Faction";
func_str = ss.mVariable; funcStr = ss.mVariable;
break; break;
case ESM::DialogueCondition::Function_NotClass: case ESM::DialogueCondition::Function_NotClass:
type_str = "Not Class"; typeStr = "Not Class";
func_str = ss.mVariable; funcStr = ss.mVariable;
break; break;
case ESM::DialogueCondition::Function_NotRace: case ESM::DialogueCondition::Function_NotRace:
type_str = "Not Race"; typeStr = "Not Race";
func_str = ss.mVariable; funcStr = ss.mVariable;
break; break;
case ESM::DialogueCondition::Function_NotCell: case ESM::DialogueCondition::Function_NotCell:
type_str = "Not Cell"; typeStr = "Not Cell";
func_str = ss.mVariable; funcStr = ss.mVariable;
break; break;
case ESM::DialogueCondition::Function_NotLocal: case ESM::DialogueCondition::Function_NotLocal:
type_str = "Not Local"; typeStr = "Not Local";
func_str = ss.mVariable; funcStr = ss.mVariable;
break; break;
default: default:
type_str = "Function"; typeStr = "Function";
func_str = ruleFunction(ss.mFunction); funcStr = ruleFunction(ss.mFunction);
break; break;
} }
std::string_view oper_str = "??"; std::string_view operStr = "??";
switch (ss.mComparison) switch (ss.mComparison)
{ {
case ESM::DialogueCondition::Comp_Eq: case ESM::DialogueCondition::Comp_Eq:
oper_str = "=="; operStr = "==";
break; break;
case ESM::DialogueCondition::Comp_Ne: case ESM::DialogueCondition::Comp_Ne:
oper_str = "!="; operStr = "!=";
break; break;
case ESM::DialogueCondition::Comp_Gt: case ESM::DialogueCondition::Comp_Gt:
oper_str = "> "; operStr = "> ";
break; break;
case ESM::DialogueCondition::Comp_Ge: case ESM::DialogueCondition::Comp_Ge:
oper_str = ">="; operStr = ">=";
break; break;
case ESM::DialogueCondition::Comp_Ls: case ESM::DialogueCondition::Comp_Ls:
oper_str = "< "; operStr = "< ";
break; break;
case ESM::DialogueCondition::Comp_Le: case ESM::DialogueCondition::Comp_Le:
oper_str = "<="; operStr = "<=";
break; break;
default: default:
break; break;
@ -143,8 +142,7 @@ namespace
std::ostringstream stream; std::ostringstream stream;
std::visit([&](auto value) { stream << value; }, ss.mValue); std::visit([&](auto value) { stream << value; }, ss.mValue);
std::string result std::string result = std::format("{:<12} {:<32} {:2} {}", typeStr, funcStr, operStr, stream.str());
= Misc::StringUtils::format("%-12s %-32s %2s %s", type_str, func_str, oper_str, stream.str());
return result; return result;
} }
@ -176,12 +174,10 @@ namespace
{ {
for (const ESM::Transport::Dest& dest : transport) for (const ESM::Transport::Dest& dest : transport)
{ {
std::cout << " Destination Position: " << Misc::StringUtils::format("%12.3f", dest.mPos.pos[0]) << "," std::cout << std::format(" Destination Position: ({:12.3f},{:12.3f},{:12.3f})\n", dest.mPos.pos[0],
<< Misc::StringUtils::format("%12.3f", dest.mPos.pos[1]) << "," dest.mPos.pos[1], dest.mPos.pos[2]);
<< Misc::StringUtils::format("%12.3f", dest.mPos.pos[2]) << ")" << std::endl; std::cout << std::format(" Destination Rotation: ({:9.6f},{:9.6f},{:9.6f})\n", dest.mPos.rot[0],
std::cout << " Destination Rotation: " << Misc::StringUtils::format("%9.6f", dest.mPos.rot[0]) << "," dest.mPos.rot[1], dest.mPos.rot[2]);
<< Misc::StringUtils::format("%9.6f", dest.mPos.rot[1]) << ","
<< Misc::StringUtils::format("%9.6f", dest.mPos.rot[2]) << ")" << std::endl;
if (!dest.mCellName.empty()) if (!dest.mCellName.empty())
std::cout << " Destination Cell: " << dest.mCellName << std::endl; std::cout << " Destination Cell: " << dest.mCellName << std::endl;
} }
@ -583,7 +579,7 @@ namespace EsmTool
std::cout << " Water Level: " << mData.mWater << std::endl; std::cout << " Water Level: " << mData.mWater << std::endl;
} }
else else
std::cout << " Map Color: " << Misc::StringUtils::format("0x%08X", mData.mMapColor) << std::endl; std::cout << std::format(" Map Color: 0x{:08X}\n", mData.mMapColor);
std::cout << " RefId counter: " << mData.mRefNumCounter << std::endl; std::cout << " RefId counter: " << mData.mRefNumCounter << std::endl;
std::cout << " Deleted: " << mIsDeleted << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl;
} }
@ -594,7 +590,7 @@ namespace EsmTool
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Description: " << mData.mDescription << std::endl; std::cout << " Description: " << mData.mDescription << std::endl;
std::cout << " Playable: " << mData.mData.mIsPlayable << std::endl; std::cout << " Playable: " << mData.mData.mIsPlayable << std::endl;
std::cout << " AI Services: " << Misc::StringUtils::format("0x%08X", mData.mData.mServices) << std::endl; std::cout << std::format(" AI Services: 0x{:08X}\n", mData.mData.mServices);
for (size_t i = 0; i < mData.mData.mAttribute.size(); ++i) for (size_t i = 0; i < mData.mData.mAttribute.size(); ++i)
std::cout << " Attribute" << (i + 1) << ": " << attributeLabel(mData.mData.mAttribute[i]) << " (" std::cout << " Attribute" << (i + 1) << ": " << attributeLabel(mData.mData.mAttribute[i]) << " ("
<< mData.mData.mAttribute[i] << ")" << std::endl; << mData.mData.mAttribute[i] << ")" << std::endl;
@ -642,8 +638,7 @@ namespace EsmTool
std::cout << " Flags: " << containerFlags(mData.mFlags) << std::endl; std::cout << " Flags: " << containerFlags(mData.mFlags) << std::endl;
std::cout << " Weight: " << mData.mWeight << std::endl; std::cout << " Weight: " << mData.mWeight << std::endl;
for (const ESM::ContItem& item : mData.mInventory.mList) for (const ESM::ContItem& item : mData.mInventory.mList)
std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount) std::cout << std::format(" Inventory: Count: {:4d} Item: ", item.mCount) << item.mItem << std::endl;
<< " Item: " << item.mItem << std::endl;
std::cout << " Deleted: " << mIsDeleted << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl;
} }
@ -680,8 +675,7 @@ namespace EsmTool
std::cout << " Gold: " << mData.mData.mGold << std::endl; std::cout << " Gold: " << mData.mData.mGold << std::endl;
for (const ESM::ContItem& item : mData.mInventory.mList) for (const ESM::ContItem& item : mData.mInventory.mList)
std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount) std::cout << std::format(" Inventory: Count: {:4d} Item: ", item.mCount) << item.mItem << std::endl;
<< " Item: " << item.mItem << std::endl;
for (const auto& spell : mData.mSpells.mList) for (const auto& spell : mData.mSpells.mList)
std::cout << " Spell: " << spell << std::endl; std::cout << " Spell: " << spell << std::endl;
@ -693,7 +687,7 @@ namespace EsmTool
std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl; std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl;
std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl; std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl;
std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl; std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl;
std::cout << " AI Services:" << Misc::StringUtils::format("0x%08X", mData.mAiData.mServices) << std::endl; std::cout << std::format(" AI Services:0x{:08X}\n", mData.mAiData.mServices);
for (const ESM::AIPackage& package : mData.mAiPackage.mList) for (const ESM::AIPackage& package : mData.mAiPackage.mList)
printAIPackage(package); printAIPackage(package);
@ -1068,8 +1062,7 @@ namespace EsmTool
} }
for (const ESM::ContItem& item : mData.mInventory.mList) for (const ESM::ContItem& item : mData.mInventory.mList)
std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount) std::cout << std::format(" Inventory: Count: {:4d} Item: ", item.mCount) << item.mItem << std::endl;
<< " Item: " << item.mItem << std::endl;
for (const auto& spell : mData.mSpells.mList) for (const auto& spell : mData.mSpells.mList)
std::cout << " Spell: " << spell << std::endl; std::cout << " Spell: " << spell << std::endl;
@ -1081,7 +1074,7 @@ namespace EsmTool
std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl; std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl;
std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl; std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl;
std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl; std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl;
std::cout << " AI Services:" << Misc::StringUtils::format("0x%08X", mData.mAiData.mServices) << std::endl; std::cout << std::format(" AI Services:0x{:08X}\n", mData.mAiData.mServices);
for (const ESM::AIPackage& package : mData.mAiPackage.mList) for (const ESM::AIPackage& package : mData.mAiPackage.mList)
printAIPackage(package); printAIPackage(package);
@ -1192,8 +1185,8 @@ namespace EsmTool
std::cout << " Variable: " << variable << std::endl; std::cout << " Variable: " << variable << std::endl;
std::cout << " ByteCode: "; std::cout << " ByteCode: ";
for (const unsigned char& byte : mData.mScriptData) for (unsigned char byte : mData.mScriptData)
std::cout << Misc::StringUtils::format("%02X", (int)(byte)); std::cout << std::format("{:02X}", byte);
std::cout << std::endl; std::cout << std::endl;
if (mPrintPlain) if (mPrintPlain)

View file

@ -15,7 +15,7 @@
#include <components/esm4/readerutils.hpp> #include <components/esm4/readerutils.hpp>
#include <components/esm4/records.hpp> #include <components/esm4/records.hpp>
#include <components/esm4/typetraits.hpp> #include <components/esm4/typetraits.hpp>
#include <components/to_utf8/to_utf8.hpp> #include <components/toutf8/toutf8.hpp>
namespace EsmTool namespace EsmTool
{ {

View file

@ -90,7 +90,7 @@ namespace ESSImport
scriptedAnim.mAbsolute = true; scriptedAnim.mAbsolute = true;
// Neither loop count nor queueing seems to be supported by the ess format. // Neither loop count nor queueing seems to be supported by the ess format.
scriptedAnim.mLoopCount = std::numeric_limits<size_t>::max(); scriptedAnim.mLoopCount = std::numeric_limits<size_t>::max();
state.mScriptedAnims.push_back(scriptedAnim); state.mScriptedAnims.push_back(std::move(scriptedAnim));
} }
else else
// TODO: Handle 0xFF index, which seems to be used for finished animations. // TODO: Handle 0xFF index, which seems to be used for finished animations.

View file

@ -303,7 +303,7 @@ namespace ESSImport
marker.mWorldY = notepos[1]; marker.mWorldY = notepos[1];
marker.mNote = std::move(note); marker.mNote = std::move(note);
marker.mCell = cell.mId; marker.mCell = cell.mId;
mMarkers.push_back(marker); mMarkers.push_back(std::move(marker));
} }
newcell.mRefs = std::move(cellrefs); newcell.mRefs = std::move(cellrefs);

View file

@ -181,14 +181,14 @@ namespace ESSImport
public: public:
void read(ESM::ESMReader& esm) override void read(ESM::ESMReader& esm) override
{ {
ESM::Class class_; ESM::Class classRecord;
bool isDeleted = false; bool isDeleted = false;
class_.load(esm, isDeleted); classRecord.load(esm, isDeleted);
if (class_.mId == "NEWCLASSID_CHARGEN") if (classRecord.mId == "NEWCLASSID_CHARGEN")
mContext->mCustomPlayerClassName = class_.mName; mContext->mCustomPlayerClassName = classRecord.mName;
mRecords[class_.mId] = class_; mRecords[classRecord.mId] = classRecord;
} }
}; };
@ -249,10 +249,10 @@ namespace ESSImport
{ {
ESM::InventoryState& invState = mContext->mPlayer.mObject.mInventory; ESM::InventoryState& invState = mContext->mPlayer.mObject.mInventory;
for (size_t i = 0; i < invState.mItems.size(); ++i) for (uint32_t i = 0; i < static_cast<uint32_t>(invState.mItems.size()); ++i)
{ {
// FIXME: in case of conflict (multiple items with this refID) use the already equipped one? // FIXME: in case of conflict (multiple items with this refID) use the already equipped one?
if (invState.mItems[i].mRef.mRefID == ESM::RefId::stringRefId(refr.mActorData.mSelectedEnchantItem)) if (invState.mItems[i].mRef.mRefID == refr.mActorData.mSelectedEnchantItem)
invState.mSelectedEnchantItem = i; invState.mSelectedEnchantItem = i;
} }
} }
@ -260,12 +260,12 @@ namespace ESSImport
void write(ESM::ESMWriter& esm) override void write(ESM::ESMWriter& esm) override
{ {
esm.startRecord(ESM::REC_ASPL); esm.startRecord(ESM::REC_ASPL);
esm.writeHNString("ID__", mSelectedSpell); esm.writeHNRefId("ID__", mSelectedSpell);
esm.endRecord(ESM::REC_ASPL); esm.endRecord(ESM::REC_ASPL);
} }
private: private:
std::string mSelectedSpell; ESM::RefId mSelectedSpell;
}; };
class ConvertPCDT : public Converter class ConvertPCDT : public Converter
@ -374,16 +374,16 @@ namespace ESSImport
void write(ESM::ESMWriter& esm) override void write(ESM::ESMWriter& esm) override
{ {
esm.startRecord(ESM::REC_DCOU); esm.startRecord(ESM::REC_DCOU);
for (auto it = mKillCounter.begin(); it != mKillCounter.end(); ++it) for (const auto& [id, count] : mKillCounter)
{ {
esm.writeHNString("ID__", it->first); esm.writeHNRefId("ID__", id);
esm.writeHNT("COUN", it->second); esm.writeHNT("COUN", count);
} }
esm.endRecord(ESM::REC_DCOU); esm.endRecord(ESM::REC_DCOU);
} }
private: private:
std::map<std::string, int> mKillCounter; std::map<ESM::RefId, int> mKillCounter;
}; };
class ConvertFACT : public Converter class ConvertFACT : public Converter
@ -584,7 +584,7 @@ namespace ESSImport
script.load(esm); script.load(esm);
ESM::GlobalScript out; ESM::GlobalScript out;
convertSCPT(script, out); convertSCPT(script, out);
mScripts.push_back(out); mScripts.push_back(std::move(out));
} }
void write(ESM::ESMWriter& esm) override void write(ESM::ESMWriter& esm) override
{ {

View file

@ -75,8 +75,8 @@ namespace ESSImport
// to change them ingame // to change them ingame
int mCombatStats[3][2]; int mCombatStats[3][2];
std::string mSelectedSpell; ESM::RefId mSelectedSpell;
std::string mSelectedEnchantItem; ESM::RefId mSelectedEnchantItem;
SCRI mSCRI; SCRI mSCRI;

View file

@ -107,12 +107,12 @@ namespace ESSImport
if (esm.isNextSub("WNAM")) if (esm.isNextSub("WNAM"))
{ {
std::string id = esm.getHString(); ESM::RefId spellRefId = esm.getRefId();
if (esm.isNextSub("XNAM")) if (esm.isNextSub("XNAM"))
mActorData.mSelectedEnchantItem = esm.getHString(); mActorData.mSelectedEnchantItem = esm.getRefId();
else else
mActorData.mSelectedSpell = std::move(id); mActorData.mSelectedSpell = std::move(spellRefId);
if (esm.isNextSub("YNAM")) if (esm.isNextSub("YNAM"))
esm.skipHSub(); // 4 byte, 0 esm.skipHSub(); // 4 byte, 0

View file

@ -25,7 +25,7 @@
#include <components/misc/constants.hpp> #include <components/misc/constants.hpp>
#include <components/to_utf8/to_utf8.hpp> #include <components/toutf8/toutf8.hpp>
#include "importercontext.hpp" #include "importercontext.hpp"
@ -136,9 +136,9 @@ namespace ESSImport
sub.mName = esm.retSubName().toString(); sub.mName = esm.retSubName().toString();
sub.mData.resize(esm.getSubSize()); sub.mData.resize(esm.getSubSize());
esm.getExact(sub.mData.data(), sub.mData.size()); esm.getExact(sub.mData.data(), sub.mData.size());
rec.mSubrecords.push_back(sub); rec.mSubrecords.push_back(std::move(sub));
} }
file.mRecords.push_back(rec); file.mRecords.push_back(std::move(rec));
} }
} }

View file

@ -7,7 +7,19 @@ namespace ESSImport
void INFO::load(ESM::ESMReader& esm) void INFO::load(ESM::ESMReader& esm)
{ {
mInfo = esm.getHNString("INAM"); if (esm.peekNextSub("XNAM"))
{
// TODO: Support older saves by turning XNAM into a RefId.
// XNAM is probably the number of the topic response within the topic record's linked list.
// Resolving this value will likely require loading Morrowind.esm.
esm.getSubName();
esm.skipHSub();
mInfo = ESM::RefId();
}
else
mInfo = esm.getHNRefId("INAM");
mActorRefId = esm.getHNString("ACDT"); mActorRefId = esm.getHNString("ACDT");
} }

View file

@ -3,6 +3,8 @@
#include <string> #include <string>
#include <components/esm/refid.hpp>
namespace ESM namespace ESM
{ {
class ESMReader; class ESMReader;
@ -13,7 +15,7 @@ namespace ESSImport
struct INFO struct INFO
{ {
std::string mInfo; ESM::RefId mInfo;
std::string mActorRefId; std::string mActorRefId;
void load(ESM::ESMReader& esm); void load(ESM::ESMReader& esm);

View file

@ -49,7 +49,7 @@ namespace ESSImport
} }
if (!separateStacks) if (!separateStacks)
mItems.push_back(item); mItems.push_back(std::move(item));
} }
// equipped items // equipped items

View file

@ -9,7 +9,7 @@ namespace ESSImport
{ {
while (esm.isNextSub("KNAM")) while (esm.isNextSub("KNAM"))
{ {
std::string refId = esm.getHString(); ESM::RefId refId = esm.getRefId();
int32_t count; int32_t count;
esm.getHNT(count, "CNAM"); esm.getHNT(count, "CNAM");
mKillCounter[refId] = count; mKillCounter[refId] = count;

View file

@ -3,7 +3,8 @@
#include <cstdint> #include <cstdint>
#include <map> #include <map>
#include <string>
#include <components/esm/refid.hpp>
namespace ESM namespace ESM
{ {
@ -18,8 +19,7 @@ namespace ESSImport
{ {
void load(ESM::ESMReader& esm); void load(ESM::ESMReader& esm);
/// RefId, kill count std::map<ESM::RefId, int32_t> mKillCounter;
std::map<std::string, int32_t> mKillCounter;
int32_t mWerewolfKills; int32_t mWerewolfKills;
}; };

View file

@ -38,7 +38,7 @@ namespace ESSImport
unsigned char xnam; // sentinel unsigned char xnam; // sentinel
esm.getHNT(xnam, "XNAM"); esm.getHNT(xnam, "XNAM");
mActiveSpells.push_back(spell); mActiveSpells.push_back(std::move(spell));
} }
} }

View file

@ -15,7 +15,7 @@ int main(int argc, char** argv)
{ {
bpo::options_description desc(R"(Syntax: openmw-essimporter <options> infile.ess outfile.omwsave bpo::options_description desc(R"(Syntax: openmw-essimporter <options> infile.ess outfile.omwsave
Allowed options)"); Allowed options)");
bpo::positional_options_description p_desc; bpo::positional_options_description positionalDesc;
auto addOption = desc.add_options(); auto addOption = desc.add_options();
addOption("help,h", "produce help message"); addOption("help,h", "produce help message");
addOption("mwsave,m", bpo::value<Files::MaybeQuotedPath>(), "morrowind .ess save file"); addOption("mwsave,m", bpo::value<Files::MaybeQuotedPath>(), "morrowind .ess save file");
@ -23,12 +23,13 @@ Allowed options)");
addOption("compare,c", "compare two .ess files"); addOption("compare,c", "compare two .ess files");
addOption("encoding", boost::program_options::value<std::string>()->default_value("win1252"), addOption("encoding", boost::program_options::value<std::string>()->default_value("win1252"),
"encoding of the save file"); "encoding of the save file");
p_desc.add("mwsave", 1).add("output", 1); positionalDesc.add("mwsave", 1).add("output", 1);
Files::ConfigurationManager::addCommonOptions(desc); Files::ConfigurationManager::addCommonOptions(desc);
bpo::variables_map variables; bpo::variables_map variables;
bpo::parsed_options parsed = bpo::command_line_parser(argc, argv).options(desc).positional(p_desc).run(); bpo::parsed_options parsed
= bpo::command_line_parser(argc, argv).options(desc).positional(positionalDesc).run();
bpo::store(parsed, variables); bpo::store(parsed, variables);
if (variables.count("help") || !variables.count("mwsave") || !variables.count("output")) if (variables.count("help") || !variables.count("mwsave") || !variables.count("output"))
@ -40,6 +41,7 @@ Allowed options)");
bpo::notify(variables); bpo::notify(variables);
Files::ConfigurationManager cfgManager(true); Files::ConfigurationManager cfgManager(true);
cfgManager.processPaths(variables, std::filesystem::current_path());
cfgManager.readConfiguration(variables, desc); cfgManager.readConfiguration(variables, desc);
const auto& essFile = variables["mwsave"].as<Files::MaybeQuotedPath>(); const auto& essFile = variables["mwsave"].as<Files::MaybeQuotedPath>();

View file

@ -8,7 +8,9 @@
#include <QList> #include <QList>
#include <QMessageBox> #include <QMessageBox>
#include <QPair> #include <QPair>
#include <QProgressDialog>
#include <QPushButton> #include <QPushButton>
#include <QTimer>
#include <algorithm> #include <algorithm>
#include <mutex> #include <mutex>
@ -37,8 +39,6 @@
#include "utils/profilescombobox.hpp" #include "utils/profilescombobox.hpp"
#include "utils/textinputdialog.hpp" #include "utils/textinputdialog.hpp"
#include "ui_directorypicker.h"
const char* Launcher::DataFilesPage::mDefaultContentListName = "Default"; const char* Launcher::DataFilesPage::mDefaultContentListName = "Default";
namespace namespace
@ -153,13 +153,16 @@ namespace Launcher
Launcher::DataFilesPage::DataFilesPage(const Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings, Launcher::DataFilesPage::DataFilesPage(const Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings,
Config::LauncherSettings& launcherSettings, MainDialog* parent) Config::LauncherSettings& launcherSettings, MainDialog* parent)
: QWidget(parent) : QWidget(parent)
, mDirectoryPickerDialog(new QDialog(this))
, mMainDialog(parent) , mMainDialog(parent)
, mCfgMgr(cfg) , mCfgMgr(cfg)
, mGameSettings(gameSettings) , mGameSettings(gameSettings)
, mLauncherSettings(launcherSettings) , mLauncherSettings(launcherSettings)
, mNavMeshToolInvoker(new Process::ProcessInvoker(this)) , mNavMeshToolInvoker(new Process::ProcessInvoker(this))
, mReloadCellsThread(&DataFilesPage::reloadCells, this)
{ {
ui.setupUi(this); ui.setupUi(this);
mDirectoryPicker.setupUi(mDirectoryPickerDialog);
setObjectName("DataFilesPage"); setObjectName("DataFilesPage");
mSelector = new ContentSelectorView::ContentSelector(ui.contentSelectorWidget, /*showOMWScripts=*/true); mSelector = new ContentSelectorView::ContentSelector(ui.contentSelectorWidget, /*showOMWScripts=*/true);
const QString encoding = mGameSettings.value("encoding", { "win1252" }).value; const QString encoding = mGameSettings.value("encoding", { "win1252" }).value;
@ -200,8 +203,24 @@ Launcher::DataFilesPage::DataFilesPage(const Files::ConfigurationManager& cfg, C
// the addons and don't want to get signals of the system doing it during startup. // the addons and don't want to get signals of the system doing it during startup.
connect(mSelector, &ContentSelectorView::ContentSelector::signalAddonDataChanged, this, connect(mSelector, &ContentSelectorView::ContentSelector::signalAddonDataChanged, this,
&DataFilesPage::slotAddonDataChanged); &DataFilesPage::slotAddonDataChanged);
mReloadCellsTimer = new QTimer(this);
mReloadCellsTimer->setSingleShot(true);
mReloadCellsTimer->setInterval(200);
connect(mReloadCellsTimer, &QTimer::timeout, this, &DataFilesPage::onReloadCellsTimerTimeout);
// Call manually to indicate all changes to addon data during startup. // Call manually to indicate all changes to addon data during startup.
slotAddonDataChanged(); onReloadCellsTimerTimeout();
}
Launcher::DataFilesPage::~DataFilesPage()
{
{
const std::lock_guard lock(mReloadCellsMutex);
mAbortReloadCells = true;
mStartReloadCells.notify_one();
}
mReloadCellsThread.join();
} }
void Launcher::DataFilesPage::buildView() void Launcher::DataFilesPage::buildView()
@ -247,6 +266,7 @@ void Launcher::DataFilesPage::buildView()
buildArchiveContextMenu(); buildArchiveContextMenu();
buildDataFilesContextMenu(); buildDataFilesContextMenu();
buildDirectoryPickerContextMenu();
} }
void Launcher::DataFilesPage::slotCopySelectedItemsPaths() void Launcher::DataFilesPage::slotCopySelectedItemsPaths()
@ -279,8 +299,10 @@ void Launcher::DataFilesPage::buildArchiveContextMenu()
&DataFilesPage::slotShowArchiveContextMenu); &DataFilesPage::slotShowArchiveContextMenu);
mArchiveContextMenu = new QMenu(ui.archiveListWidget); mArchiveContextMenu = new QMenu(ui.archiveListWidget);
mArchiveContextMenu->addAction(tr("&Check Selected"), this, SLOT(slotCheckMultiSelectedItems())); mArchiveContextMenu->addAction(tr("&Check Selected"), this,
mArchiveContextMenu->addAction(tr("&Uncheck Selected"), this, SLOT(slotUncheckMultiSelectedItems())); [this]() { setCheckStateForMultiSelectedItems(ui.archiveListWidget, Qt::Checked); });
mArchiveContextMenu->addAction(tr("&Uncheck Selected"), this,
[this]() { setCheckStateForMultiSelectedItems(ui.archiveListWidget, Qt::Unchecked); });
} }
void Launcher::DataFilesPage::buildDataFilesContextMenu() void Launcher::DataFilesPage::buildDataFilesContextMenu()
@ -295,6 +317,18 @@ void Launcher::DataFilesPage::buildDataFilesContextMenu()
tr("&Open Path in File Explorer"), this, &Launcher::DataFilesPage::slotOpenSelectedItemsPaths); tr("&Open Path in File Explorer"), this, &Launcher::DataFilesPage::slotOpenSelectedItemsPaths);
} }
void Launcher::DataFilesPage::buildDirectoryPickerContextMenu()
{
connect(mDirectoryPicker.dirListWidget, &QListWidget::customContextMenuRequested, this,
&DataFilesPage::slotShowDirectoryPickerContextMenu);
mDirectoryPickerMenu = new QMenu(mDirectoryPicker.dirListWidget);
mDirectoryPickerMenu->addAction(tr("&Check Selected"), this,
[this]() { setCheckStateForMultiSelectedItems(mDirectoryPicker.dirListWidget, Qt::Checked); });
mDirectoryPickerMenu->addAction(tr("&Uncheck Selected"), this,
[this]() { setCheckStateForMultiSelectedItems(mDirectoryPicker.dirListWidget, Qt::Unchecked); });
}
bool Launcher::DataFilesPage::loadSettings() bool Launcher::DataFilesPage::loadSettings()
{ {
ui.navMeshMaxSizeSpinBox->setValue(getMaxNavMeshDbFileSizeMiB()); ui.navMeshMaxSizeSpinBox->setValue(getMaxNavMeshDbFileSizeMiB());
@ -351,9 +385,17 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName)
if (!resourcesVfs.isEmpty()) if (!resourcesVfs.isEmpty())
directories.insert(0, { resourcesVfs }); directories.insert(0, { resourcesVfs });
QIcon containsDataIcon(":/images/openmw-plugin.png");
QProgressDialog progressBar("Adding data directories", {}, 0, static_cast<int>(directories.size()), this);
progressBar.setWindowModality(Qt::WindowModal);
std::unordered_set<QString> visitedDirectories; std::unordered_set<QString> visitedDirectories;
for (const Config::SettingValue& currentDir : directories) for (qsizetype i = 0; i < directories.size(); ++i)
{ {
progressBar.setValue(static_cast<int>(i));
const Config::SettingValue& currentDir = directories.at(i);
if (!visitedDirectories.insert(currentDir.value).second) if (!visitedDirectories.insert(currentDir.value).second)
continue; continue;
@ -402,7 +444,7 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName)
// Add a "data file" icon if the directory contains a content file // Add a "data file" icon if the directory contains a content file
if (mSelector->containsDataFiles(currentDir.value)) if (mSelector->containsDataFiles(currentDir.value))
{ {
item->setIcon(QIcon(":/images/openmw-plugin.png")); item->setIcon(containsDataIcon);
tooltip << tr("Contains content file(s)"); tooltip << tr("Contains content file(s)");
} }
@ -416,6 +458,7 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName)
} }
item->setToolTip(tooltip.join('\n')); item->setToolTip(tooltip.join('\n'));
} }
progressBar.setValue(progressBar.maximum());
mSelector->sortFiles(); mSelector->sortFiles();
QList<Config::SettingValue> selectedArchives = mGameSettings.getArchiveList(); QList<Config::SettingValue> selectedArchives = mGameSettings.getArchiveList();
@ -765,7 +808,7 @@ void Launcher::DataFilesPage::addSubdirectories(bool append)
return; return;
QString rootPath = QFileDialog::getExistingDirectory( QString rootPath = QFileDialog::getExistingDirectory(
this, tr("Select Directory"), QDir::homePath(), QFileDialog::ShowDirsOnly | QFileDialog::Option::ReadOnly); this, tr("Select Directory"), {}, QFileDialog::ShowDirsOnly | QFileDialog::Option::ReadOnly);
if (rootPath.isEmpty()) if (rootPath.isEmpty())
return; return;
@ -793,28 +836,22 @@ void Launcher::DataFilesPage::addSubdirectories(bool append)
return; return;
} }
QDialog dialog; mDirectoryPicker.dirListWidget->clear();
Ui::SelectSubdirs select;
select.setupUi(&dialog);
for (const auto& dir : subdirs) for (const auto& dir : subdirs)
{ {
if (!ui.directoryListWidget->findItems(dir, Qt::MatchFixedString).isEmpty()) if (!ui.directoryListWidget->findItems(dir, Qt::MatchFixedString).isEmpty())
continue; continue;
const auto lastRow = select.dirListWidget->count(); QListWidgetItem* newDir = new QListWidgetItem(dir, mDirectoryPicker.dirListWidget);
select.dirListWidget->addItem(dir); newDir->setCheckState(Qt::Unchecked);
select.dirListWidget->item(lastRow)->setCheckState(Qt::Unchecked);
} }
dialog.show(); if (mDirectoryPickerDialog->exec() == QDialog::Rejected)
if (dialog.exec() == QDialog::Rejected)
return; return;
for (int i = 0; i < select.dirListWidget->count(); ++i) for (int i = 0; i < mDirectoryPicker.dirListWidget->count(); ++i)
{ {
const auto* dir = select.dirListWidget->item(i); const auto* dir = mDirectoryPicker.dirListWidget->item(i);
if (dir->checkState() == Qt::Checked) if (dir->checkState() == Qt::Checked)
{ {
ui.directoryListWidget->insertItem(selectedRow, dir->text()); ui.directoryListWidget->insertItem(selectedRow, dir->text());
@ -865,38 +902,35 @@ void Launcher::DataFilesPage::removeDirectory()
refreshDataFilesView(); refreshDataFilesView();
} }
void Launcher::DataFilesPage::showContextMenu(QMenu* menu, QListWidget* list, const QPoint& pos)
{
QPoint globalPos = list->viewport()->mapToGlobal(pos);
menu->exec(globalPos);
}
void Launcher::DataFilesPage::slotShowArchiveContextMenu(const QPoint& pos) void Launcher::DataFilesPage::slotShowArchiveContextMenu(const QPoint& pos)
{ {
QPoint globalPos = ui.archiveListWidget->viewport()->mapToGlobal(pos); showContextMenu(mArchiveContextMenu, ui.archiveListWidget, pos);
mArchiveContextMenu->exec(globalPos);
} }
void Launcher::DataFilesPage::slotShowDataFilesContextMenu(const QPoint& pos) void Launcher::DataFilesPage::slotShowDataFilesContextMenu(const QPoint& pos)
{ {
QPoint globalPos = ui.directoryListWidget->viewport()->mapToGlobal(pos); showContextMenu(mDataFilesContextMenu, ui.directoryListWidget, pos);
mDataFilesContextMenu->exec(globalPos);
} }
void Launcher::DataFilesPage::setCheckStateForMultiSelectedItems(bool checked) void Launcher::DataFilesPage::slotShowDirectoryPickerContextMenu(const QPoint& pos)
{ {
Qt::CheckState checkState = checked ? Qt::Checked : Qt::Unchecked; showContextMenu(mDirectoryPickerMenu, mDirectoryPicker.dirListWidget, pos);
}
for (QListWidgetItem* selectedItem : ui.archiveListWidget->selectedItems()) void Launcher::DataFilesPage::setCheckStateForMultiSelectedItems(QListWidget* list, Qt::CheckState checkState)
{
for (QListWidgetItem* selectedItem : list->selectedItems())
{ {
selectedItem->setCheckState(checkState); selectedItem->setCheckState(checkState);
} }
} }
void Launcher::DataFilesPage::slotUncheckMultiSelectedItems()
{
setCheckStateForMultiSelectedItems(false);
}
void Launcher::DataFilesPage::slotCheckMultiSelectedItems()
{
setCheckStateForMultiSelectedItems(true);
}
void Launcher::DataFilesPage::moveSources(QListWidget* sourceList, int step) void Launcher::DataFilesPage::moveSources(QListWidget* sourceList, int step)
{ {
const QList<QPair<int, QListWidgetItem*>> sortedItems = sortedSelectedItems(sourceList, step > 0); const QList<QPair<int, QListWidgetItem*>> sortedItems = sortedSelectedItems(sourceList, step > 0);
@ -981,32 +1015,66 @@ bool Launcher::DataFilesPage::showDeleteMessageBox(const QString& text)
void Launcher::DataFilesPage::slotAddonDataChanged() void Launcher::DataFilesPage::slotAddonDataChanged()
{ {
QStringList selectedFiles = selectedFilePaths(); mReloadCellsTimer->start();
if (previousSelectedFiles != selectedFiles) }
void Launcher::DataFilesPage::onReloadCellsTimerTimeout()
{
const ContentSelectorModel::ContentFileList items = mSelector->selectedFiles();
QStringList selectedFiles;
for (const ContentSelectorModel::EsmFile* item : items)
selectedFiles.append(item->filePath());
if (mSelectedFiles != selectedFiles)
{ {
previousSelectedFiles = selectedFiles; const std::lock_guard lock(mReloadCellsMutex);
// Loading cells for core Morrowind + Expansions takes about 0.2 seconds, which is enough to cause a mSelectedFiles = std::move(selectedFiles);
// barely perceptible UI lag. Splitting into its own thread to alleviate that. mReloadCells = true;
std::thread loadCellsThread(&DataFilesPage::reloadCells, this, selectedFiles); mStartReloadCells.notify_one();
loadCellsThread.detach();
} }
} }
// Mutex lock to run reloadCells synchronously. void Launcher::DataFilesPage::reloadCells()
static std::mutex reloadCellsMutex;
void Launcher::DataFilesPage::reloadCells(QStringList selectedFiles)
{ {
// Use a mutex lock so that we can prevent two threads from executing the rest of this code at the same time QStringList selectedFiles;
// Based on https://stackoverflow.com/a/5429695/531762 std::unique_lock lock(mReloadCellsMutex);
std::unique_lock<std::mutex> lock(reloadCellsMutex);
// The following code will run only if there is not another thread currently running it while (true)
CellNameLoader cellNameLoader; {
QSet<QString> set = cellNameLoader.getCellNames(selectedFiles); mStartReloadCells.wait(lock);
QStringList cellNamesList(set.begin(), set.end());
std::sort(cellNamesList.begin(), cellNamesList.end()); if (mAbortReloadCells)
emit signalLoadedCellsChanged(cellNamesList); return;
if (!std::exchange(mReloadCells, false))
continue;
const QStringList newSelectedFiles = mSelectedFiles;
lock.unlock();
QStringList filteredFiles;
for (const QString& v : newSelectedFiles)
if (QFile::exists(v))
filteredFiles.append(v);
if (selectedFiles != filteredFiles)
{
selectedFiles = std::move(filteredFiles);
CellNameLoader cellNameLoader;
QSet<QString> set = cellNameLoader.getCellNames(selectedFiles);
QStringList cellNamesList(set.begin(), set.end());
std::sort(cellNamesList.begin(), cellNamesList.end());
emit signalLoadedCellsChanged(std::move(cellNamesList));
}
lock.lock();
if (mAbortReloadCells)
return;
}
} }
void Launcher::DataFilesPage::startNavMeshTool() void Launcher::DataFilesPage::startNavMeshTool()

View file

@ -2,6 +2,7 @@
#define DATAFILESPAGE_H #define DATAFILESPAGE_H
#include "ui_datafilespage.h" #include "ui_datafilespage.h"
#include "ui_directorypicker.h"
#include <components/process/processinvoker.hpp> #include <components/process/processinvoker.hpp>
@ -10,9 +11,14 @@
#include <QStringList> #include <QStringList>
#include <QWidget> #include <QWidget>
#include <condition_variable>
#include <mutex>
#include <thread>
class QSortFilterProxyModel; class QSortFilterProxyModel;
class QAbstractItemModel; class QAbstractItemModel;
class QMenu; class QMenu;
class QTimer;
namespace Files namespace Files
{ {
@ -41,12 +47,16 @@ namespace Launcher
ContentSelectorView::ContentSelector* mSelector; ContentSelectorView::ContentSelector* mSelector;
Ui::DataFilesPage ui; Ui::DataFilesPage ui;
QDialog* mDirectoryPickerDialog;
Ui::SelectSubdirs mDirectoryPicker;
QMenu* mArchiveContextMenu; QMenu* mArchiveContextMenu;
QMenu* mDataFilesContextMenu; QMenu* mDataFilesContextMenu;
QMenu* mDirectoryPickerMenu;
public: public:
explicit DataFilesPage(const Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings, explicit DataFilesPage(const Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings,
Config::LauncherSettings& launcherSettings, MainDialog* parent = nullptr); Config::LauncherSettings& launcherSettings, MainDialog* parent = nullptr);
~DataFilesPage();
QAbstractItemModel* profilesModel() const; QAbstractItemModel* profilesModel() const;
@ -81,8 +91,7 @@ namespace Launcher
void slotShowArchiveContextMenu(const QPoint& pos); void slotShowArchiveContextMenu(const QPoint& pos);
void slotShowDataFilesContextMenu(const QPoint& pos); void slotShowDataFilesContextMenu(const QPoint& pos);
void slotCheckMultiSelectedItems(); void slotShowDirectoryPickerContextMenu(const QPoint& pos);
void slotUncheckMultiSelectedItems();
void on_newProfileAction_triggered(); void on_newProfileAction_triggered();
void on_cloneProfileAction_triggered(); void on_cloneProfileAction_triggered();
@ -119,7 +128,7 @@ namespace Launcher
Config::LauncherSettings& mLauncherSettings; Config::LauncherSettings& mLauncherSettings;
QString mPreviousProfile; QString mPreviousProfile;
QStringList previousSelectedFiles; QStringList mSelectedFiles;
QString mDataLocal; QString mDataLocal;
QStringList mKnownArchives; QStringList mKnownArchives;
QStringList mNewDataDirs; QStringList mNewDataDirs;
@ -127,12 +136,21 @@ namespace Launcher
Process::ProcessInvoker* mNavMeshToolInvoker; Process::ProcessInvoker* mNavMeshToolInvoker;
NavMeshToolProgress mNavMeshToolProgress; NavMeshToolProgress mNavMeshToolProgress;
bool mReloadCells = false;
bool mAbortReloadCells = false;
std::mutex mReloadCellsMutex;
std::condition_variable mStartReloadCells;
std::thread mReloadCellsThread;
QTimer* mReloadCellsTimer;
void addArchive(const QString& name, Qt::CheckState selected, int row = -1); void addArchive(const QString& name, Qt::CheckState selected, int row = -1);
void addArchivesFromDir(const QString& dir); void addArchivesFromDir(const QString& dir);
void buildView(); void buildView();
void buildArchiveContextMenu(); void buildArchiveContextMenu();
void buildDataFilesContextMenu(); void buildDataFilesContextMenu();
void setCheckStateForMultiSelectedItems(bool checked); void buildDirectoryPickerContextMenu();
void showContextMenu(QMenu* menu, QListWidget* list, const QPoint& pos);
void setCheckStateForMultiSelectedItems(QListWidget* list, Qt::CheckState checkState);
void setProfile(int index, bool savePrevious); void setProfile(int index, bool savePrevious);
void setProfile(const QString& previous, const QString& current, bool savePrevious); void setProfile(const QString& previous, const QString& current, bool savePrevious);
void removeProfile(const QString& profile); void removeProfile(const QString& profile);
@ -140,7 +158,8 @@ namespace Launcher
void addProfile(const QString& profile, bool setAsCurrent); void addProfile(const QString& profile, bool setAsCurrent);
void checkForDefaultProfile(); void checkForDefaultProfile();
void populateFileViews(const QString& contentModelName); void populateFileViews(const QString& contentModelName);
void reloadCells(QStringList selectedFiles); void onReloadCellsTimerTimeout();
void reloadCells();
void refreshDataFilesView(); void refreshDataFilesView();
void updateNavMeshProgress(int minDataSize); void updateNavMeshProgress(int minDataSize);
void slotCopySelectedItemsPaths(); void slotCopySelectedItemsPaths();

View file

@ -242,11 +242,36 @@ void Launcher::GraphicsPage::handleWindowModeChange(Settings::WindowMode mode)
{ {
if (mode == Settings::WindowMode::Fullscreen || mode == Settings::WindowMode::WindowedFullscreen) if (mode == Settings::WindowMode::Fullscreen || mode == Settings::WindowMode::WindowedFullscreen)
{ {
QString customSizeMessage = tr("Custom window size is available only in Windowed mode.");
QString windowBorderMessage = tr("Window border is available only in Windowed mode.");
standardRadioButton->toggle(); standardRadioButton->toggle();
customRadioButton->setEnabled(false); customRadioButton->setEnabled(false);
customWidthSpinBox->setEnabled(false); customWidthSpinBox->setEnabled(false);
customHeightSpinBox->setEnabled(false); customHeightSpinBox->setEnabled(false);
windowBorderCheckBox->setEnabled(false); windowBorderCheckBox->setEnabled(false);
windowBorderCheckBox->setToolTip(windowBorderMessage);
customWidthSpinBox->setToolTip(customSizeMessage);
customHeightSpinBox->setToolTip(customSizeMessage);
customRadioButton->setToolTip(customSizeMessage);
}
if (mode == Settings::WindowMode::Fullscreen)
{
resolutionComboBox->setEnabled(true);
resolutionComboBox->setToolTip("");
standardRadioButton->setToolTip("");
}
else if (mode == Settings::WindowMode::WindowedFullscreen)
{
QString fullScreenMessage = tr("Windowed Fullscreen mode always uses the native display resolution.");
resolutionComboBox->setEnabled(false);
resolutionComboBox->setToolTip(fullScreenMessage);
standardRadioButton->setToolTip(fullScreenMessage);
// Assume that a first item is a native screen resolution
resolutionComboBox->setCurrentIndex(0);
} }
else else
{ {
@ -254,6 +279,13 @@ void Launcher::GraphicsPage::handleWindowModeChange(Settings::WindowMode mode)
customWidthSpinBox->setEnabled(true); customWidthSpinBox->setEnabled(true);
customHeightSpinBox->setEnabled(true); customHeightSpinBox->setEnabled(true);
windowBorderCheckBox->setEnabled(true); windowBorderCheckBox->setEnabled(true);
resolutionComboBox->setEnabled(true);
resolutionComboBox->setToolTip("");
standardRadioButton->setToolTip("");
windowBorderCheckBox->setToolTip("");
customWidthSpinBox->setToolTip("");
customHeightSpinBox->setToolTip("");
customRadioButton->setToolTip("");
} }
} }

View file

@ -88,11 +88,7 @@ void Launcher::ImportPage::on_importerButton_clicked()
// Create the file if it doesn't already exist, else the importer will fail // Create the file if it doesn't already exist, else the importer will fail
auto path = mCfgMgr.getUserConfigPath(); auto path = mCfgMgr.getUserConfigPath();
path /= "openmw.cfg"; path /= "openmw.cfg";
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QFile file(path); QFile file(path);
#else
QFile file(Files::pathToQString(path));
#endif
if (!file.exists()) if (!file.exists())
{ {

View file

@ -42,7 +42,7 @@ int runLauncher(int argc, char* argv[])
resourcesPath = Files::pathToQString(variables["resources"].as<Files::MaybeQuotedPath>().u8string()); resourcesPath = Files::pathToQString(variables["resources"].as<Files::MaybeQuotedPath>().u8string());
} }
l10n::installQtTranslations(app, "launcher", resourcesPath); L10n::installQtTranslations(app, "launcher", resourcesPath);
Launcher::MainDialog mainWin(configurationManager); Launcher::MainDialog mainWin(configurationManager);

View file

@ -497,11 +497,7 @@ bool Launcher::MainDialog::writeSettings()
} }
// Game settings // Game settings
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QFile file(userPath / Files::openmwCfgFile); QFile file(userPath / Files::openmwCfgFile);
#else
QFile file(Files::getUserConfigPathQString(mCfgMgr));
#endif
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) if (!file.open(QIODevice::ReadWrite | QIODevice::Text))
{ {

View file

@ -163,8 +163,6 @@ bool Launcher::SettingsPage::loadSettings()
loadSettingInt(Settings::physics().mAsyncNumThreads, *physicsThreadsSpinBox); loadSettingInt(Settings::physics().mAsyncNumThreads, *physicsThreadsSpinBox);
loadSettingBool( loadSettingBool(
Settings::game().mAllowActorsToFollowOverWaterSurface, *allowNPCToFollowOverWaterSurfaceCheckBox); Settings::game().mAllowActorsToFollowOverWaterSurface, *allowNPCToFollowOverWaterSurfaceCheckBox);
loadSettingBool(
Settings::game().mUnarmedCreatureAttacksDamageArmor, *unarmedCreatureAttacksDamageArmorCheckBox);
loadSettingInt(Settings::game().mActorCollisionShapeType, *actorCollisonShapeTypeComboBox); loadSettingInt(Settings::game().mActorCollisionShapeType, *actorCollisonShapeTypeComboBox);
} }
@ -293,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
@ -304,6 +303,9 @@ bool Launcher::SettingsPage::loadSettings()
loadSettingBool(Settings::gui().mColorTopicEnable, *changeDialogTopicsCheckBox); loadSettingBool(Settings::gui().mColorTopicEnable, *changeDialogTopicsCheckBox);
showOwnedComboBox->setCurrentIndex(Settings::game().mShowOwned); showOwnedComboBox->setCurrentIndex(Settings::game().mShowOwned);
loadSettingBool(Settings::gui().mStretchMenuBackground, *stretchBackgroundCheckBox); loadSettingBool(Settings::gui().mStretchMenuBackground, *stretchBackgroundCheckBox);
connect(controllerMenusCheckBox, &QCheckBox::toggled, this, &SettingsPage::slotControllerMenusToggled);
loadSettingBool(Settings::gui().mControllerMenus, *controllerMenusCheckBox);
loadSettingBool(Settings::gui().mControllerTooltips, *controllerMenuTooltipsCheckBox);
loadSettingBool(Settings::map().mAllowZooming, *useZoomOnMapCheckBox); loadSettingBool(Settings::map().mAllowZooming, *useZoomOnMapCheckBox);
loadSettingBool(Settings::game().mGraphicHerbalism, *graphicHerbalismCheckBox); loadSettingBool(Settings::game().mGraphicHerbalism, *graphicHerbalismCheckBox);
scalingSpinBox->setValue(Settings::gui().mScalingFactor); scalingSpinBox->setValue(Settings::gui().mScalingFactor);
@ -373,8 +375,6 @@ void Launcher::SettingsPage::saveSettings()
saveSettingInt(*physicsThreadsSpinBox, Settings::physics().mAsyncNumThreads); saveSettingInt(*physicsThreadsSpinBox, Settings::physics().mAsyncNumThreads);
saveSettingBool( saveSettingBool(
*allowNPCToFollowOverWaterSurfaceCheckBox, Settings::game().mAllowActorsToFollowOverWaterSurface); *allowNPCToFollowOverWaterSurfaceCheckBox, Settings::game().mAllowActorsToFollowOverWaterSurface);
saveSettingBool(
*unarmedCreatureAttacksDamageArmorCheckBox, Settings::game().mUnarmedCreatureAttacksDamageArmor);
saveSettingInt(*actorCollisonShapeTypeComboBox, Settings::game().mActorCollisionShapeType); saveSettingInt(*actorCollisonShapeTypeComboBox, Settings::game().mActorCollisionShapeType);
} }
@ -486,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
@ -497,6 +499,8 @@ void Launcher::SettingsPage::saveSettings()
saveSettingBool(*changeDialogTopicsCheckBox, Settings::gui().mColorTopicEnable); saveSettingBool(*changeDialogTopicsCheckBox, Settings::gui().mColorTopicEnable);
saveSettingInt(*showOwnedComboBox, Settings::game().mShowOwned); saveSettingInt(*showOwnedComboBox, Settings::game().mShowOwned);
saveSettingBool(*stretchBackgroundCheckBox, Settings::gui().mStretchMenuBackground); saveSettingBool(*stretchBackgroundCheckBox, Settings::gui().mStretchMenuBackground);
saveSettingBool(*controllerMenusCheckBox, Settings::gui().mControllerMenus);
saveSettingBool(*controllerMenuTooltipsCheckBox, Settings::gui().mControllerTooltips);
saveSettingBool(*useZoomOnMapCheckBox, Settings::map().mAllowZooming); saveSettingBool(*useZoomOnMapCheckBox, Settings::map().mAllowZooming);
saveSettingBool(*graphicHerbalismCheckBox, Settings::game().mGraphicHerbalism); saveSettingBool(*graphicHerbalismCheckBox, Settings::game().mGraphicHerbalism);
Settings::gui().mScalingFactor.set(scalingSpinBox->value()); Settings::gui().mScalingFactor.set(scalingSpinBox->value());
@ -555,6 +559,11 @@ void Launcher::SettingsPage::slotAnimSourcesToggled(bool checked)
} }
} }
void Launcher::SettingsPage::slotControllerMenusToggled(bool checked)
{
controllerMenuTooltipsCheckBox->setEnabled(checked);
}
void Launcher::SettingsPage::slotPostProcessToggled(bool checked) void Launcher::SettingsPage::slotPostProcessToggled(bool checked)
{ {
postprocessTransparentPostpassCheckBox->setEnabled(checked); postprocessTransparentPostpassCheckBox->setEnabled(checked);

View file

@ -34,6 +34,7 @@ namespace Launcher
void slotSkyBlendingToggled(bool checked); void slotSkyBlendingToggled(bool checked);
void slotShadowDistLimitToggled(bool checked); void slotShadowDistLimitToggled(bool checked);
void slotDistantLandToggled(bool checked); void slotDistantLandToggled(bool checked);
void slotControllerMenusToggled(bool checked);
private: private:
Config::GameSettings& mGameSettings; Config::GameSettings& mGameSettings;

View file

@ -25,7 +25,14 @@
</widget> </widget>
</item> </item>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QListWidget" name="dirListWidget"/> <widget class="QListWidget" name="dirListWidget">
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>

View file

@ -53,7 +53,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="10" column="1"> <item row="9" column="1">
<widget class="QCheckBox" name="normaliseRaceSpeedCheckBox"> <widget class="QCheckBox" name="normaliseRaceSpeedCheckBox">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Don't use race weight in NPC movement speed calculations.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Don't use race weight in NPC movement speed calculations.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -63,7 +63,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="1"> <item row="8" column="1">
<widget class="QCheckBox" name="classicCalmSpellsCheckBox"> <widget class="QCheckBox" name="classicCalmSpellsCheckBox">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stops combat with NPCs affected by Calm spells every frame -- like in Morrowind without the MCP.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stops combat with NPCs affected by Calm spells every frame -- like in Morrowind without the MCP.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -73,7 +73,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="12" column="1"> <item row="11" column="1">
<widget class="QCheckBox" name="avoidCollisionsCheckBox"> <widget class="QCheckBox" name="avoidCollisionsCheckBox">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If enabled NPCs apply evasion maneuver to avoid collisions with others.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If enabled NPCs apply evasion maneuver to avoid collisions with others.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -123,7 +123,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1"> <item row="5" column="1">
<widget class="QCheckBox" name="requireAppropriateAmmunitionCheckBox"> <widget class="QCheckBox" name="requireAppropriateAmmunitionCheckBox">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If enabled, a magical ammunition is required to bypass normal weapon resistance or weakness. If disabled, a magical ranged weapon or a magical ammunition is required.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If enabled, a magical ammunition is required to bypass normal weapon resistance or weakness. If disabled, a magical ranged weapon or a magical ammunition is required.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -133,7 +133,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="13" column="1"> <item row="12" column="1">
<widget class="QCheckBox" name="graphicHerbalismCheckBox"> <widget class="QCheckBox" name="graphicHerbalismCheckBox">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If this setting is true, containers supporting graphic herbalism will do so instead of opening the menu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If this setting is true, containers supporting graphic herbalism will do so instead of opening the menu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -143,7 +143,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="11" column="1"> <item row="10" column="1">
<widget class="QCheckBox" name="swimUpwardCorrectionCheckBox"> <widget class="QCheckBox" name="swimUpwardCorrectionCheckBox">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Makes player swim a bit upward from the line of sight. Applies only in third person mode. Intended to make simpler swimming without diving.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Makes player swim a bit upward from the line of sight. Applies only in third person mode. Intended to make simpler swimming without diving.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -153,7 +153,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="1"> <item row="7" column="1">
<widget class="QCheckBox" name="enchantedWeaponsMagicalCheckBox"> <widget class="QCheckBox" name="enchantedWeaponsMagicalCheckBox">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Make enchanted weapons without Magical flag bypass normal weapons resistance, like in Morrowind.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Make enchanted weapons without Magical flag bypass normal weapons resistance, like in Morrowind.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -183,7 +183,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1"> <item row="6" column="1">
<widget class="QCheckBox" name="canLootDuringDeathAnimationCheckBox"> <widget class="QCheckBox" name="canLootDuringDeathAnimationCheckBox">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If this setting is true, the player is allowed to loot actors (e.g. summoned creatures) during death animation, if they are not in combat. In this case we have to increment death counter and run disposed actor's script instantly.&lt;/p&gt;&lt;p&gt;If this setting is false, player has to wait until end of death animation in all cases. Makes using of summoned creatures exploit (looting summoned Dremoras and Golden Saints for expensive weapons) a lot harder. Conflicts with mannequin mods, which use SkipAnim to prevent end of death animation.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If this setting is true, the player is allowed to loot actors (e.g. summoned creatures) during death animation, if they are not in combat. In this case we have to increment death counter and run disposed actor's script instantly.&lt;/p&gt;&lt;p&gt;If this setting is false, player has to wait until end of death animation in all cases. Makes using of summoned creatures exploit (looting summoned Dremoras and Golden Saints for expensive weapons) a lot harder. Conflicts with mannequin mods, which use SkipAnim to prevent end of death animation.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -203,7 +203,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="1"> <item row="4" column="1">
<widget class="QCheckBox" name="classicReflectedAbsorbSpellsCheckBox"> <widget class="QCheckBox" name="classicReflectedAbsorbSpellsCheckBox">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Effects of reflected Absorb spells are not mirrored - like in Morrowind.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Effects of reflected Absorb spells are not mirrored - like in Morrowind.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -213,16 +213,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1">
<widget class="QCheckBox" name="unarmedCreatureAttacksDamageArmorCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Makes unarmed creature attacks able to reduce armor condition, just as attacks from NPCs and armed creatures.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Unarmed Creature Attacks Damage Armor</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>
@ -430,14 +420,14 @@
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="3" column="1">
<widget class="QCheckBox" name="smoothAnimTransitionsCheckBox"> <widget class="QCheckBox" name="smoothAnimTransitionsCheckBox">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If enabled - makes transitions between different animations/poses much smoother. Also allows to load animation blending config YAML files that can be bundled with animations in order to customise blending styles.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If enabled - makes transitions between different animations/poses much smoother. Also allows to load animation blending config YAML files that can be bundled with animations in order to customise blending styles.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Smooth Animation Transitions</string> <string>Smooth Animation Transitions</string>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</item> </item>
@ -1099,68 +1089,20 @@
<attribute name="title"> <attribute name="title">
<string>Audio</string> <string>Audio</string>
</attribute> </attribute>
<layout class="QVBoxLayout"> <layout class="QVBoxLayout" name="verticalLayout_3">
<item> <item>
<layout class="QHBoxLayout"> <layout class="QGridLayout" name="audioLayout">
<item> <item row="1" column="1">
<widget class="QLabel" name="audioDeviceSelectorLabel">
<property name="toolTip">
<string>Select your preferred audio device.</string>
</property>
<property name="text">
<string>Audio Device</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="audioDeviceSelectorComboBox">
<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="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Default</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel" name="enableHRTFLabel">
<property name="toolTip">
<string>This setting controls HRTF, which simulates 3D sound on stereo systems.</string>
</property>
<property name="text">
<string>HRTF</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="enableHRTFComboBox"> <widget class="QComboBox" name="enableHRTFComboBox">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>283</width> <width>0</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
@ -1184,11 +1126,74 @@
</item> </item>
</widget> </widget>
</item> </item>
</layout> <item row="1" column="0">
</item> <widget class="QLabel" name="enableHRTFLabel">
<item> <property name="toolTip">
<layout class="QHBoxLayout"> <string>This setting controls HRTF, which simulates 3D sound on stereo systems.</string>
<item> </property>
<property name="text">
<string>HRTF</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="cameraListenerCheckBox">
<property name="toolTip">
<string>In third-person view, use the camera as the sound listener instead of the player character.</string>
</property>
<property name="text">
<string>Use the Camera as the Sound Listener</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="dopplerLabel">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Controls the strength of the Doppler effect. Zero means it is completely disabled.&lt;/p&gt;&lt;p&gt;The Doppler effect increases or decreases the pitch of sounds relative to the velocity of the sound source and the listener.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Doppler Factor</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="dopplerSpinBox">
<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>
<item row="2" column="1">
<widget class="QComboBox" name="hrtfProfileSelectorComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Default</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="hrtfProfileSelectorLabel"> <widget class="QLabel" name="hrtfProfileSelectorLabel">
<property name="toolTip"> <property name="toolTip">
<string>Select your preferred HRTF profile.</string> <string>Select your preferred HRTF profile.</string>
@ -1198,17 +1203,27 @@
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="0" column="0">
<widget class="QComboBox" name="hrtfProfileSelectorComboBox"> <widget class="QLabel" name="audioDeviceSelectorLabel">
<property name="toolTip">
<string>Select your preferred audio device.</string>
</property>
<property name="text">
<string>Audio Device</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="audioDeviceSelectorComboBox">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>283</width> <width>0</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
@ -1224,16 +1239,6 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<widget class="QCheckBox" name="cameraListenerCheckBox">
<property name="toolTip">
<string>In third-person view, use the camera as the sound listener instead of the player character.</string>
</property>
<property name="text">
<string>Use the Camera as the Sound Listener</string>
</property>
</widget>
</item>
<item> <item>
<spacer> <spacer>
<property name="orientation"> <property name="orientation">
@ -1241,8 +1246,8 @@
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>0</width> <width>20</width>
<height>0</height> <height>40</height>
</size> </size>
</property> </property>
</spacer> </spacer>
@ -1398,6 +1403,29 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1">
<widget class="QCheckBox" name="controllerMenusCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Make it easier to use game menus with a controller.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Enable Controller Menus</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QCheckBox" name="controllerMenuTooltipsCheckBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When using controller menus, make tooltips visible by default.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Show Controller Tooltips By Default</string>
</property>
</widget>
</item>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="showOwnedLabel"> <widget class="QLabel" name="showOwnedLabel">
<property name="text"> <property name="text">

View file

@ -43,10 +43,10 @@ std::vector<std::string> Launcher::enumerateOpenALDevicesHrtf()
LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr; LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr;
void* funcPtr = alcGetProcAddress(device, "alcGetStringiSOFT"); void* funcPtr = alcGetProcAddress(device, "alcGetStringiSOFT");
memcpy(&alcGetStringiSOFT, &funcPtr, sizeof(funcPtr)); memcpy(&alcGetStringiSOFT, &funcPtr, sizeof(funcPtr));
ALCint num_hrtf; ALCint numHrtf;
alcGetIntegerv(device, ALC_NUM_HRTF_SPECIFIERS_SOFT, 1, &num_hrtf); alcGetIntegerv(device, ALC_NUM_HRTF_SPECIFIERS_SOFT, 1, &numHrtf);
ret.reserve(num_hrtf); ret.reserve(numHrtf);
for (ALCint i = 0; i < num_hrtf; ++i) for (ALCint i = 0; i < numHrtf; ++i)
{ {
const ALCchar* entry = alcGetStringiSOFT(device, ALC_HRTF_SPECIFIER_SOFT, i); const ALCchar* entry = alcGetStringiSOFT(device, ALC_HRTF_SPECIFIER_SOFT, i);
if (strcmp(entry, "") == 0) if (strcmp(entry, "") == 0)

View file

@ -9,7 +9,22 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
namespace sfs = std::filesystem; namespace
{
// from configfileparser.cpp
std::string trim_ws(const std::string& s)
{
std::string::size_type n, n2;
n = s.find_first_not_of(" \t\r\n");
if (n == std::string::npos)
return std::string();
else
{
n2 = s.find_last_not_of(" \t\r\n");
return s.substr(n, n2 - n + 1);
}
}
}
MwIniImporter::MwIniImporter() MwIniImporter::MwIniImporter()
: mVerbose(false) : mVerbose(false)
@ -311,10 +326,10 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::filesystem::pat
continue; continue;
} }
int comment_pos = static_cast<int>(utf8.find(';')); const std::string::size_type commentPos = utf8.find(';');
if (comment_pos > 0) if (commentPos != std::string::npos)
{ {
utf8 = utf8.substr(0, comment_pos); utf8 = utf8.substr(0, commentPos);
} }
int pos = static_cast<int>(utf8.find('=')); int pos = static_cast<int>(utf8.find('='));
@ -336,7 +351,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::filesystem::pat
if (it == map.end()) if (it == map.end())
it = map.emplace_hint(it, std::move(key), std::vector<std::string>()); it = map.emplace_hint(it, std::move(key), std::vector<std::string>());
it->second.push_back(std::string(value)); it->second.emplace_back(value);
} }
return map; return map;
@ -352,12 +367,10 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::filesystem::pat
std::string line; std::string line;
while (std::getline(file, line)) while (std::getline(file, line))
{ {
// ignore comments - keep in sync with configfileparser.cpp
// we cant say comment by only looking at first char anymore if (line.find('#') == line.find_first_not_of(" \t\r\n"))
int comment_pos = static_cast<int>(line.find('#'));
if (comment_pos > 0)
{ {
line = line.substr(0, comment_pos); continue;
} }
if (line.empty()) if (line.empty())
@ -373,12 +386,14 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::filesystem::pat
std::string key(line.substr(0, pos)); std::string key(line.substr(0, pos));
std::string value(line.substr(pos + 1)); std::string value(line.substr(pos + 1));
key = trim_ws(key);
value = trim_ws(value);
if (map.find(key) == map.end()) if (map.find(key) == map.end())
{ {
map.insert(std::make_pair(key, std::vector<std::string>())); map.insert(std::make_pair(key, std::vector<std::string>()));
} }
map[key].push_back(value); map[key].push_back(std::move(value));
} }
return map; return map;

View file

@ -8,7 +8,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <components/to_utf8/to_utf8.hpp> #include <components/toutf8/toutf8.hpp>
class MwIniImporter class MwIniImporter
{ {

View file

@ -10,7 +10,6 @@
#include <components/files/conversion.hpp> #include <components/files/conversion.hpp>
namespace bpo = boost::program_options; namespace bpo = boost::program_options;
namespace sfs = std::filesystem;
#ifndef _WIN32 #ifndef _WIN32
int main(int argc, char* argv[]) int main(int argc, char* argv[])
@ -63,7 +62,7 @@ int wmain(int argc, wchar_t* wargv[])
try try
{ {
bpo::options_description desc("Syntax: openmw-iniimporter <options> inifile configfile\nAllowed options"); bpo::options_description desc("Syntax: openmw-iniimporter <options> inifile configfile\nAllowed options");
bpo::positional_options_description p_desc; bpo::positional_options_description positionalDesc;
auto addOption = desc.add_options(); auto addOption = desc.add_options();
addOption("help,h", "produce help message"); addOption("help,h", "produce help message");
addOption("verbose,v", "verbose output"); addOption("verbose,v", "verbose output");
@ -80,11 +79,12 @@ int wmain(int argc, wchar_t* wargv[])
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
"\n\twin1252 - Western European (Latin) alphabet, used by default"); "\n\twin1252 - Western European (Latin) alphabet, used by default");
; ;
p_desc.add("ini", 1).add("cfg", 1); positionalDesc.add("ini", 1).add("cfg", 1);
bpo::variables_map vm; bpo::variables_map vm;
bpo::parsed_options parsed = bpo::command_line_parser(argc, argv).options(desc).positional(p_desc).run(); bpo::parsed_options parsed
= bpo::command_line_parser(argc, argv).options(desc).positional(positionalDesc).run();
bpo::store(parsed, vm); bpo::store(parsed, vm);
if (vm.count("help") || !vm.count("ini") || !vm.count("cfg")) if (vm.count("help") || !vm.count("ini") || !vm.count("cfg"))
@ -126,12 +126,20 @@ int wmain(int argc, wchar_t* wargv[])
MwIniImporter importer; MwIniImporter importer;
importer.setVerbose(vm.count("verbose") != 0); importer.setVerbose(vm.count("verbose") != 0);
MwIniImporter::multistrmap cfg = importer.loadCfgFile(cfgFile);
// Font encoding settings // Font encoding settings
std::string encoding(vm["encoding"].as<std::string>()); std::string encoding;
if (vm["encoding"].defaulted() && cfg.contains("encoding") && !cfg["encoding"].empty())
encoding = cfg["encoding"].back();
else
{
encoding = vm["encoding"].as<std::string>();
cfg["encoding"] = { encoding };
}
importer.setInputEncoding(ToUTF8::calculateEncoding(encoding)); importer.setInputEncoding(ToUTF8::calculateEncoding(encoding));
MwIniImporter::multistrmap ini = importer.loadIniFile(iniFile); MwIniImporter::multistrmap ini = importer.loadIniFile(iniFile);
MwIniImporter::multistrmap cfg = importer.loadCfgFile(cfgFile);
if (!vm.count("fonts")) if (!vm.count("fonts"))
{ {

View file

@ -1,20 +1,16 @@
set(NAVMESHTOOL set(NAVMESHTOOL_LIB
worldspacedata.cpp worldspacedata.cpp
navmesh.cpp navmesh.cpp
main.cpp
) )
source_group(apps\\navmeshtool FILES ${NAVMESHTOOL})
add_library(openmw-navmeshtool-lib STATIC source_group(apps\\navmeshtool FILES ${NAVMESHTOOL_LIB} main.cpp)
${NAVMESHTOOL}
) add_library(openmw-navmeshtool-lib STATIC ${NAVMESHTOOL_LIB})
if (ANDROID) if (ANDROID)
add_library(openmw-navmeshtool SHARED add_library(openmw-navmeshtool SHARED main.cpp)
main.cpp
)
else() else()
openmw_add_executable(openmw-navmeshtool ${NAVMESHTOOL}) openmw_add_executable(openmw-navmeshtool main.cpp)
endif() endif()
target_link_libraries(openmw-navmeshtool openmw-navmeshtool-lib) target_link_libraries(openmw-navmeshtool openmw-navmeshtool-lib)

View file

@ -25,7 +25,7 @@
#include <components/resource/niffilemanager.hpp> #include <components/resource/niffilemanager.hpp>
#include <components/resource/scenemanager.hpp> #include <components/resource/scenemanager.hpp>
#include <components/settings/values.hpp> #include <components/settings/values.hpp>
#include <components/to_utf8/to_utf8.hpp> #include <components/toutf8/toutf8.hpp>
#include <components/version/version.hpp> #include <components/version/version.hpp>
#include <components/vfs/manager.hpp> #include <components/vfs/manager.hpp>
#include <components/vfs/registerarchives.hpp> #include <components/vfs/registerarchives.hpp>
@ -62,8 +62,6 @@ namespace NavMeshTool
bpo::options_description makeOptionsDescription() bpo::options_description makeOptionsDescription()
{ {
using Fallback::FallbackMap;
bpo::options_description result; bpo::options_description result;
auto addOption = result.add_options(); auto addOption = result.add_options();
addOption("help", "print help message"); addOption("help", "print help message");
@ -145,6 +143,7 @@ namespace NavMeshTool
} }
Files::ConfigurationManager config; Files::ConfigurationManager config;
config.processPaths(variables, std::filesystem::current_path());
config.readConfiguration(variables, desc); config.readConfiguration(variables, desc);
Debug::setupLogging(config.getLogPath(), applicationName); Debug::setupLogging(config.getLogPath(), applicationName);
@ -190,7 +189,7 @@ namespace NavMeshTool
VFS::Manager vfs; VFS::Manager vfs;
VFS::registerArchives(&vfs, fileCollections, archives, true); VFS::registerArchives(&vfs, fileCollections, archives, true, &encoder.getStatelessEncoder());
Settings::Manager::load(config); Settings::Manager::load(config);
@ -225,7 +224,8 @@ namespace NavMeshTool
Resource::SceneManager sceneManager(&vfs, &imageManager, &nifFileManager, &bgsmFileManager, expiryDelay); Resource::SceneManager sceneManager(&vfs, &imageManager, &nifFileManager, &bgsmFileManager, expiryDelay);
Resource::BulletShapeManager bulletShapeManager(&vfs, &sceneManager, &nifFileManager, expiryDelay); Resource::BulletShapeManager bulletShapeManager(&vfs, &sceneManager, &nifFileManager, expiryDelay);
DetourNavigator::RecastGlobalAllocator::init(); DetourNavigator::RecastGlobalAllocator::init();
DetourNavigator::Settings navigatorSettings = DetourNavigator::makeSettingsFromSettingsManager(); DetourNavigator::Settings navigatorSettings
= DetourNavigator::makeSettingsFromSettingsManager(Debug::getRecastMaxLogLevel());
navigatorSettings.mRecast.mSwimHeightScale navigatorSettings.mRecast.mSwimHeightScale
= EsmLoader::getGameSetting(esmData.mGameSettings, "fSwimHeightScale").getFloat(); = EsmLoader::getGameSetting(esmData.mGameSettings, "fSwimHeightScale").getFloat();

View file

@ -201,8 +201,8 @@ namespace NavMeshTool
{ {
if (!land.has_value() || osg::Vec2i(land->mX, land->mY) != cellPosition if (!land.has_value() || osg::Vec2i(land->mX, land->mY) != cellPosition
|| (land->mDataTypes & ESM::Land::DATA_VHGT) == 0) || (land->mDataTypes & ESM::Land::DATA_VHGT) == 0)
return { HeightfieldPlane{ ESM::Land::DEFAULT_HEIGHT }, ESM::Land::DEFAULT_HEIGHT, return { HeightfieldPlane{ static_cast<float>(ESM::Land::DEFAULT_HEIGHT) },
ESM::Land::DEFAULT_HEIGHT }; static_cast<float>(ESM::Land::DEFAULT_HEIGHT), static_cast<float>(ESM::Land::DEFAULT_HEIGHT) };
ESM::Land::LandData& landData = *landDatas.emplace_back(std::make_unique<ESM::Land::LandData>()); ESM::Land::LandData& landData = *landDatas.emplace_back(std::make_unique<ESM::Land::LandData>());
land->loadData(ESM::Land::DATA_VHGT, landData); land->loadData(ESM::Land::DATA_VHGT, landData);

View file

@ -113,7 +113,7 @@ bool isBSA(const std::filesystem::path& path)
std::unique_ptr<VFS::Archive> makeArchive(const std::filesystem::path& path) std::unique_ptr<VFS::Archive> makeArchive(const std::filesystem::path& path)
{ {
if (isBSA(path)) if (isBSA(path))
return VFS::makeBsaArchive(path); return VFS::makeBsaArchive(path, nullptr);
if (std::filesystem::is_directory(path)) if (std::filesystem::is_directory(path))
return std::make_unique<VFS::FileSystemArchive>(path); return std::make_unique<VFS::FileSystemArchive>(path);
return nullptr; return nullptr;
@ -198,7 +198,7 @@ void readVFS(std::unique_ptr<VFS::Archive>&& archive, const std::filesystem::pat
{ {
try try
{ {
readVFS(VFS::makeBsaArchive(file.second), file.second, quiet); readVFS(VFS::makeBsaArchive(file.second, nullptr), file.second, quiet);
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
@ -235,8 +235,8 @@ Allowed options)");
bpo::variables_map variables; bpo::variables_map variables;
try try
{ {
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv).options(desc).positional(p).run(); bpo::parsed_options validOpts = bpo::command_line_parser(argc, argv).options(desc).positional(p).run();
bpo::store(valid_opts, variables); bpo::store(validOpts, variables);
bpo::notify(variables); bpo::notify(variables);
if (variables.count("help")) if (variables.count("help"))
{ {

View file

@ -88,7 +88,7 @@ opencs_units (view/render
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
previewwidget editmode instancemode instanceselectionmode instancemovemode previewwidget editmode instancemode instanceselectionmode instancemovemode
orbitcameramode pathgridmode selectionmode pathgridselectionmode cameracontroller orbitcameramode pathgridmode selectionmode pathgridselectionmode cameracontroller
cellwater terraintexturemode actor terrainselection terrainshapemode brushdraw commands cellwater terraintexturemode actor terrainselection terrainshapemode brushdraw commands objectmarker
) )
opencs_units (view/render opencs_units (view/render
@ -240,11 +240,7 @@ target_link_libraries(openmw-cs-lib
components_qt components_qt
) )
if (QT_VERSION_MAJOR VERSION_EQUAL 6) target_link_libraries(openmw-cs-lib Qt::Widgets Qt::Core Qt::Network Qt::OpenGL Qt::OpenGLWidgets Qt::Svg)
target_link_libraries(openmw-cs-lib Qt::Widgets Qt::Core Qt::Network Qt::OpenGL Qt::OpenGLWidgets Qt::Svg)
else()
target_link_libraries(openmw-cs-lib Qt::Widgets Qt::Core Qt::Network Qt::OpenGL Qt::Svg)
endif()
if (WIN32) if (WIN32)
target_sources(openmw-cs PRIVATE ${CMAKE_SOURCE_DIR}/files/windows/openmw-cs.exe.manifest) target_sources(openmw-cs PRIVATE ${CMAKE_SOURCE_DIR}/files/windows/openmw-cs.exe.manifest)

View file

@ -34,12 +34,10 @@
#include <components/misc/rng.hpp> #include <components/misc/rng.hpp>
#include <components/nifosg/nifloader.hpp> #include <components/nifosg/nifloader.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include <components/to_utf8/to_utf8.hpp> #include <components/toutf8/toutf8.hpp>
#include "view/doc/viewmanager.hpp" #include "view/doc/viewmanager.hpp"
using namespace Fallback;
CS::Editor::Editor(int argc, char** argv) CS::Editor::Editor(int argc, char** argv)
: mConfigVariables(readConfiguration()) : mConfigVariables(readConfiguration())
, mSettingsState(mCfgMgr) , mSettingsState(mCfgMgr)
@ -124,7 +122,10 @@ boost::program_options::variables_map CS::Editor::readConfiguration()
->default_value(std::vector<std::string>(), "fallback-archive") ->default_value(std::vector<std::string>(), "fallback-archive")
->multitoken()); ->multitoken());
addOption("fallback", addOption("fallback",
boost::program_options::value<FallbackMap>()->default_value(FallbackMap(), "")->multitoken()->composing(), boost::program_options::value<Fallback::FallbackMap>()
->default_value(Fallback::FallbackMap(), "")
->multitoken()
->composing(),
"fallback values"); "fallback values");
Files::ConfigurationManager::addCommonOptions(desc); Files::ConfigurationManager::addCommonOptions(desc);
@ -141,7 +142,7 @@ std::pair<Files::PathContainer, std::vector<std::string>> CS::Editor::readConfig
{ {
boost::program_options::variables_map& variables = mConfigVariables; boost::program_options::variables_map& variables = mConfigVariables;
Fallback::Map::init(variables["fallback"].as<FallbackMap>().mMap); Fallback::Map::init(variables["fallback"].as<Fallback::FallbackMap>().mMap);
mEncodingName = variables["encoding"].as<std::string>(); mEncodingName = variables["encoding"].as<std::string>();
mDocumentManager.setEncoding(ToUTF8::calculateEncoding(mEncodingName)); mDocumentManager.setEncoding(ToUTF8::calculateEncoding(mEncodingName));
@ -165,7 +166,7 @@ std::pair<Files::PathContainer, std::vector<std::string>> CS::Editor::readConfig
if (!local.empty()) if (!local.empty())
{ {
std::filesystem::create_directories(local); std::filesystem::create_directories(local);
dataLocal.push_back(local); dataLocal.push_back(std::move(local));
} }
mCfgMgr.filterOutNonExistingPaths(dataDirs); mCfgMgr.filterOutNonExistingPaths(dataDirs);
mCfgMgr.filterOutNonExistingPaths(dataLocal); mCfgMgr.filterOutNonExistingPaths(dataLocal);

View file

@ -12,7 +12,7 @@
#include <apps/opencs/model/world/universalid.hpp> #include <apps/opencs/model/world/universalid.hpp>
#include <components/files/multidircollection.hpp> #include <components/files/multidircollection.hpp>
#include <components/to_utf8/to_utf8.hpp> #include <components/toutf8/toutf8.hpp>
#include "../world/data.hpp" #include "../world/data.hpp"
#include "../world/idcompletionmanager.hpp" #include "../world/idcompletionmanager.hpp"

View file

@ -9,7 +9,7 @@
#include <vector> #include <vector>
#include <components/files/multidircollection.hpp> #include <components/files/multidircollection.hpp>
#include <components/to_utf8/to_utf8.hpp> #include <components/toutf8/toutf8.hpp>
#include "loader.hpp" #include "loader.hpp"

View file

@ -2,11 +2,8 @@
#include <utility> #include <utility>
#if defined(Q_OS_MAC)
#include <QCoreApplication> #include <QCoreApplication>
#include <QDir> #include <QDir>
#endif
#include <QProcess> #include <QProcess>
#include <QString> #include <QString>
#include <QStringList> #include <QStringList>
@ -55,16 +52,17 @@ void CSMDoc::Runner::start(bool delayed)
QString path = "openmw"; QString path = "openmw";
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
path.append(QString(".exe")); path.append(QLatin1String(".exe"));
#elif defined(Q_OS_MAC)
QDir dir(QCoreApplication::applicationDirPath());
dir.cdUp();
dir.cdUp();
dir.cdUp();
path = dir.absoluteFilePath(path.prepend("OpenMW.app/Contents/MacOS/"));
#else
path.prepend(QString("./"));
#endif #endif
QDir dir(QCoreApplication::applicationDirPath());
#ifdef Q_OS_MAC
// the CS and engine are in separate .app directories
dir.cdUp();
dir.cdUp();
dir.cdUp();
path.prepend("OpenMW.app/Contents/MacOS/");
#endif
path = dir.absoluteFilePath(path);
mStartup = new QTemporaryFile(this); mStartup = new QTemporaryFile(this);
mStartup->open(); mStartup->open();

View file

@ -3,7 +3,7 @@
#include <QObject> #include <QObject>
#include <components/to_utf8/to_utf8.hpp> #include <components/toutf8/toutf8.hpp>
#include "operation.hpp" #include "operation.hpp"
#include "savingstate.hpp" #include "savingstate.hpp"

Some files were not shown because too many files have changed in this diff Show more