mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-21 00:39:58 +00:00
Merge branch 'master' into 'openmw-confpyupdate'
There were conflicts as I'd based this off the original attempt to ensure the original contributor got credit. # Conflicts: # docs/source/conf.py
This commit is contained in:
commit
1e921162ee
@ -28,7 +28,9 @@
|
||||
Bug #7034: Misc items defined in one content file are not treated as keys if another content file uses them as such
|
||||
Bug #7042: Weapon follow animations that immediately follow the hit animations cause multiple hits
|
||||
Bug #7044: Changing a class' services does not affect autocalculated NPCs
|
||||
Bug #7054: Quests aren't sorted by name
|
||||
Bug #7084: Resurrecting an actor doesn't take into account base record changes
|
||||
Bug #7088: Deleting last save game of last character doesn't clear character name/details
|
||||
Feature #6447: Add LOD support to Object Paging
|
||||
Feature #6933: Support high-resolution cursor textures
|
||||
Feature #6945: Support S3TC-compressed and BGR/BGRA NiPixelData
|
||||
@ -37,6 +39,7 @@
|
||||
Feature #6995: Localize the "show effect duration" option
|
||||
Feature #7058: Implement TestModels (T3D) console command
|
||||
Feature #7087: Block resolution change in the Windowed Fullscreen mode
|
||||
Feature #7130: Ability to set MyGUI logging verbosity
|
||||
|
||||
0.48.0
|
||||
------
|
||||
@ -217,6 +220,7 @@
|
||||
Feature #5198: Implement "Magic effect expired" event
|
||||
Feature #5454: Clear active spells from actor when he disappears from scene
|
||||
Feature #5489: MCP: Telekinesis fix for activators
|
||||
Feature #5492: Let rain and snow collide with statics
|
||||
Feature #5701: Convert osgAnimation::RigGeometry to double-buffered custom version
|
||||
Feature #5737: OpenMW-CS: Handle instance move from one cell to another
|
||||
Feature #5928: Allow Glow in the Dahrk to be disabled
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <components/esm/esmcommon.hpp>
|
||||
#include <components/esm4/reader.hpp>
|
||||
#include <components/esm4/readerutils.hpp>
|
||||
#include <components/esm4/records.hpp>
|
||||
#include <components/to_utf8/to_utf8.hpp>
|
||||
|
||||
@ -69,6 +70,19 @@ namespace EsmTool
|
||||
template <class T>
|
||||
constexpr bool hasFormId = HasFormId<T>::value;
|
||||
|
||||
template <class T, class = std::void_t<>>
|
||||
struct HasRefId : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct HasRefId<T, std::void_t<decltype(T::mId)>> : std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
constexpr bool hasRefId = HasRefId<T>::value;
|
||||
|
||||
template <class T, class = std::void_t<>>
|
||||
struct HasFlags : std::false_type
|
||||
{
|
||||
@ -169,6 +183,8 @@ namespace EsmTool
|
||||
std::cout << "\n Record: " << ESM::NAME(reader.hdr().record.typeId).toStringView();
|
||||
if constexpr (hasFormId<T>)
|
||||
std::cout << "\n FormId: " << value.mFormId;
|
||||
if constexpr (hasRefId<T>)
|
||||
std::cout << "\n FormId: " << value.mId;
|
||||
if constexpr (hasFlags<T>)
|
||||
std::cout << "\n Record flags: " << recordFlags(value.mFlags);
|
||||
if constexpr (hasEditorId<T>)
|
||||
@ -182,60 +198,77 @@ namespace EsmTool
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
void readRecord(const Params& params, ESM4::Reader& reader)
|
||||
bool readRecord(const Params& params, ESM4::Reader& reader)
|
||||
{
|
||||
switch (static_cast<ESM4::RecordTypes>(reader.hdr().record.typeId))
|
||||
{
|
||||
case ESM4::REC_AACT:
|
||||
break;
|
||||
case ESM4::REC_ACHR:
|
||||
return readTypedRecord<ESM4::ActorCharacter>(params, reader);
|
||||
readTypedRecord<ESM4::ActorCharacter>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_ACRE:
|
||||
return readTypedRecord<ESM4::ActorCreature>(params, reader);
|
||||
readTypedRecord<ESM4::ActorCreature>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_ACTI:
|
||||
return readTypedRecord<ESM4::Activator>(params, reader);
|
||||
readTypedRecord<ESM4::Activator>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_ADDN:
|
||||
break;
|
||||
case ESM4::REC_ALCH:
|
||||
return readTypedRecord<ESM4::Potion>(params, reader);
|
||||
readTypedRecord<ESM4::Potion>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_ALOC:
|
||||
return readTypedRecord<ESM4::MediaLocationController>(params, reader);
|
||||
readTypedRecord<ESM4::MediaLocationController>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_AMMO:
|
||||
return readTypedRecord<ESM4::Ammunition>(params, reader);
|
||||
readTypedRecord<ESM4::Ammunition>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_ANIO:
|
||||
return readTypedRecord<ESM4::AnimObject>(params, reader);
|
||||
readTypedRecord<ESM4::AnimObject>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_APPA:
|
||||
return readTypedRecord<ESM4::Apparatus>(params, reader);
|
||||
readTypedRecord<ESM4::Apparatus>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_ARMA:
|
||||
return readTypedRecord<ESM4::ArmorAddon>(params, reader);
|
||||
readTypedRecord<ESM4::ArmorAddon>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_ARMO:
|
||||
return readTypedRecord<ESM4::Armor>(params, reader);
|
||||
readTypedRecord<ESM4::Armor>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_ARTO:
|
||||
break;
|
||||
case ESM4::REC_ASPC:
|
||||
return readTypedRecord<ESM4::AcousticSpace>(params, reader);
|
||||
readTypedRecord<ESM4::AcousticSpace>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_ASTP:
|
||||
break;
|
||||
case ESM4::REC_AVIF:
|
||||
break;
|
||||
case ESM4::REC_BOOK:
|
||||
return readTypedRecord<ESM4::Book>(params, reader);
|
||||
readTypedRecord<ESM4::Book>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_BPTD:
|
||||
return readTypedRecord<ESM4::BodyPartData>(params, reader);
|
||||
readTypedRecord<ESM4::BodyPartData>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_CAMS:
|
||||
break;
|
||||
case ESM4::REC_CCRD:
|
||||
break;
|
||||
case ESM4::REC_CELL:
|
||||
return readTypedRecord<ESM4::Cell>(params, reader);
|
||||
readTypedRecord<ESM4::Cell>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_CLAS:
|
||||
return readTypedRecord<ESM4::Class>(params, reader);
|
||||
readTypedRecord<ESM4::Class>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_CLFM:
|
||||
return readTypedRecord<ESM4::Colour>(params, reader);
|
||||
readTypedRecord<ESM4::Colour>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_CLMT:
|
||||
break;
|
||||
case ESM4::REC_CLOT:
|
||||
return readTypedRecord<ESM4::Clothing>(params, reader);
|
||||
readTypedRecord<ESM4::Clothing>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_CMNY:
|
||||
break;
|
||||
case ESM4::REC_COBJ:
|
||||
@ -243,25 +276,30 @@ namespace EsmTool
|
||||
case ESM4::REC_COLL:
|
||||
break;
|
||||
case ESM4::REC_CONT:
|
||||
return readTypedRecord<ESM4::Container>(params, reader);
|
||||
readTypedRecord<ESM4::Container>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_CPTH:
|
||||
break;
|
||||
case ESM4::REC_CREA:
|
||||
return readTypedRecord<ESM4::Creature>(params, reader);
|
||||
readTypedRecord<ESM4::Creature>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_CSTY:
|
||||
break;
|
||||
case ESM4::REC_DEBR:
|
||||
break;
|
||||
case ESM4::REC_DIAL:
|
||||
return readTypedRecord<ESM4::Dialogue>(params, reader);
|
||||
readTypedRecord<ESM4::Dialogue>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_DLBR:
|
||||
break;
|
||||
case ESM4::REC_DLVW:
|
||||
break;
|
||||
case ESM4::REC_DOBJ:
|
||||
return readTypedRecord<ESM4::DefaultObj>(params, reader);
|
||||
readTypedRecord<ESM4::DefaultObj>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_DOOR:
|
||||
return readTypedRecord<ESM4::Door>(params, reader);
|
||||
readTypedRecord<ESM4::Door>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_DUAL:
|
||||
break;
|
||||
case ESM4::REC_ECZN:
|
||||
@ -275,81 +313,103 @@ namespace EsmTool
|
||||
case ESM4::REC_EXPL:
|
||||
break;
|
||||
case ESM4::REC_EYES:
|
||||
return readTypedRecord<ESM4::Eyes>(params, reader);
|
||||
readTypedRecord<ESM4::Eyes>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_FACT:
|
||||
break;
|
||||
case ESM4::REC_FLOR:
|
||||
return readTypedRecord<ESM4::Flora>(params, reader);
|
||||
readTypedRecord<ESM4::Flora>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_FLST:
|
||||
return readTypedRecord<ESM4::FormIdList>(params, reader);
|
||||
readTypedRecord<ESM4::FormIdList>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_FSTP:
|
||||
break;
|
||||
case ESM4::REC_FSTS:
|
||||
break;
|
||||
case ESM4::REC_FURN:
|
||||
return readTypedRecord<ESM4::Furniture>(params, reader);
|
||||
readTypedRecord<ESM4::Furniture>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_GLOB:
|
||||
return readTypedRecord<ESM4::GlobalVariable>(params, reader);
|
||||
readTypedRecord<ESM4::GlobalVariable>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_GMST:
|
||||
break;
|
||||
case ESM4::REC_GRAS:
|
||||
return readTypedRecord<ESM4::Grass>(params, reader);
|
||||
readTypedRecord<ESM4::Grass>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_GRUP:
|
||||
break;
|
||||
case ESM4::REC_HAIR:
|
||||
return readTypedRecord<ESM4::Hair>(params, reader);
|
||||
readTypedRecord<ESM4::Hair>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_HAZD:
|
||||
break;
|
||||
case ESM4::REC_HDPT:
|
||||
return readTypedRecord<ESM4::HeadPart>(params, reader);
|
||||
readTypedRecord<ESM4::HeadPart>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_IDLE:
|
||||
// FIXME: ESM4::IdleAnimation::load does not work with Oblivion.esm
|
||||
// return readTypedRecord<ESM4::IdleAnimation>(params, reader);
|
||||
// readTypedRecord<ESM4::IdleAnimation>(params, reader);
|
||||
return true;
|
||||
break;
|
||||
case ESM4::REC_IDLM:
|
||||
return readTypedRecord<ESM4::IdleMarker>(params, reader);
|
||||
readTypedRecord<ESM4::IdleMarker>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_IMAD:
|
||||
break;
|
||||
case ESM4::REC_IMGS:
|
||||
break;
|
||||
case ESM4::REC_IMOD:
|
||||
return readTypedRecord<ESM4::ItemMod>(params, reader);
|
||||
readTypedRecord<ESM4::ItemMod>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_INFO:
|
||||
return readTypedRecord<ESM4::DialogInfo>(params, reader);
|
||||
readTypedRecord<ESM4::DialogInfo>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_INGR:
|
||||
return readTypedRecord<ESM4::Ingredient>(params, reader);
|
||||
readTypedRecord<ESM4::Ingredient>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_IPCT:
|
||||
break;
|
||||
case ESM4::REC_IPDS:
|
||||
break;
|
||||
case ESM4::REC_KEYM:
|
||||
return readTypedRecord<ESM4::Key>(params, reader);
|
||||
readTypedRecord<ESM4::Key>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_KYWD:
|
||||
break;
|
||||
case ESM4::REC_LAND:
|
||||
return readTypedRecord<ESM4::Land>(params, reader);
|
||||
readTypedRecord<ESM4::Land>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_LCRT:
|
||||
break;
|
||||
case ESM4::REC_LCTN:
|
||||
break;
|
||||
case ESM4::REC_LGTM:
|
||||
return readTypedRecord<ESM4::LightingTemplate>(params, reader);
|
||||
readTypedRecord<ESM4::LightingTemplate>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_LIGH:
|
||||
return readTypedRecord<ESM4::Light>(params, reader);
|
||||
readTypedRecord<ESM4::Light>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_LSCR:
|
||||
break;
|
||||
case ESM4::REC_LTEX:
|
||||
return readTypedRecord<ESM4::LandTexture>(params, reader);
|
||||
readTypedRecord<ESM4::LandTexture>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_LVLC:
|
||||
return readTypedRecord<ESM4::LevelledCreature>(params, reader);
|
||||
readTypedRecord<ESM4::LevelledCreature>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_LVLI:
|
||||
return readTypedRecord<ESM4::LevelledItem>(params, reader);
|
||||
readTypedRecord<ESM4::LevelledItem>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_LVLN:
|
||||
return readTypedRecord<ESM4::LevelledNpc>(params, reader);
|
||||
readTypedRecord<ESM4::LevelledNpc>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_LVSP:
|
||||
break;
|
||||
case ESM4::REC_MATO:
|
||||
return readTypedRecord<ESM4::Material>(params, reader);
|
||||
readTypedRecord<ESM4::Material>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_MATT:
|
||||
break;
|
||||
case ESM4::REC_MESG:
|
||||
@ -357,49 +417,66 @@ namespace EsmTool
|
||||
case ESM4::REC_MGEF:
|
||||
break;
|
||||
case ESM4::REC_MISC:
|
||||
return readTypedRecord<ESM4::MiscItem>(params, reader);
|
||||
readTypedRecord<ESM4::MiscItem>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_MOVT:
|
||||
break;
|
||||
case ESM4::REC_MSET:
|
||||
return readTypedRecord<ESM4::MediaSet>(params, reader);
|
||||
readTypedRecord<ESM4::MediaSet>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_MSTT:
|
||||
return readTypedRecord<ESM4::MovableStatic>(params, reader);
|
||||
readTypedRecord<ESM4::MovableStatic>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_MUSC:
|
||||
return readTypedRecord<ESM4::Music>(params, reader);
|
||||
readTypedRecord<ESM4::Music>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_MUST:
|
||||
break;
|
||||
case ESM4::REC_NAVI:
|
||||
return readTypedRecord<ESM4::Navigation>(params, reader);
|
||||
readTypedRecord<ESM4::Navigation>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_NAVM:
|
||||
return readTypedRecord<ESM4::NavMesh>(params, reader);
|
||||
readTypedRecord<ESM4::NavMesh>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_NOTE:
|
||||
return readTypedRecord<ESM4::Note>(params, reader);
|
||||
readTypedRecord<ESM4::Note>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_NPC_:
|
||||
return readTypedRecord<ESM4::Npc>(params, reader);
|
||||
readTypedRecord<ESM4::Npc>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_OTFT:
|
||||
return readTypedRecord<ESM4::Outfit>(params, reader);
|
||||
readTypedRecord<ESM4::Outfit>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_PACK:
|
||||
return readTypedRecord<ESM4::AIPackage>(params, reader);
|
||||
readTypedRecord<ESM4::AIPackage>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_PERK:
|
||||
break;
|
||||
case ESM4::REC_PGRD:
|
||||
return readTypedRecord<ESM4::Pathgrid>(params, reader);
|
||||
readTypedRecord<ESM4::Pathgrid>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_PGRE:
|
||||
return readTypedRecord<ESM4::PlacedGrenade>(params, reader);
|
||||
readTypedRecord<ESM4::PlacedGrenade>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_PHZD:
|
||||
break;
|
||||
case ESM4::REC_PROJ:
|
||||
break;
|
||||
case ESM4::REC_PWAT:
|
||||
return readTypedRecord<ESM4::PlaceableWater>(params, reader);
|
||||
readTypedRecord<ESM4::PlaceableWater>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_QUST:
|
||||
return readTypedRecord<ESM4::Quest>(params, reader);
|
||||
readTypedRecord<ESM4::Quest>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_RACE:
|
||||
return readTypedRecord<ESM4::Race>(params, reader);
|
||||
readTypedRecord<ESM4::Race>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_REFR:
|
||||
return readTypedRecord<ESM4::Reference>(params, reader);
|
||||
readTypedRecord<ESM4::Reference>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_REGN:
|
||||
return readTypedRecord<ESM4::Region>(params, reader);
|
||||
readTypedRecord<ESM4::Region>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_RELA:
|
||||
break;
|
||||
case ESM4::REC_REVB:
|
||||
@ -407,23 +484,30 @@ namespace EsmTool
|
||||
case ESM4::REC_RFCT:
|
||||
break;
|
||||
case ESM4::REC_ROAD:
|
||||
return readTypedRecord<ESM4::Road>(params, reader);
|
||||
readTypedRecord<ESM4::Road>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_SBSP:
|
||||
return readTypedRecord<ESM4::SubSpace>(params, reader);
|
||||
readTypedRecord<ESM4::SubSpace>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_SCEN:
|
||||
break;
|
||||
case ESM4::REC_SCOL:
|
||||
return readTypedRecord<ESM4::StaticCollection>(params, reader);
|
||||
readTypedRecord<ESM4::StaticCollection>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_SCPT:
|
||||
return readTypedRecord<ESM4::Script>(params, reader);
|
||||
readTypedRecord<ESM4::Script>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_SCRL:
|
||||
return readTypedRecord<ESM4::Scroll>(params, reader);
|
||||
readTypedRecord<ESM4::Scroll>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_SGST:
|
||||
return readTypedRecord<ESM4::SigilStone>(params, reader);
|
||||
readTypedRecord<ESM4::SigilStone>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_SHOU:
|
||||
break;
|
||||
case ESM4::REC_SLGM:
|
||||
return readTypedRecord<ESM4::SoulGem>(params, reader);
|
||||
readTypedRecord<ESM4::SoulGem>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_SMBN:
|
||||
break;
|
||||
case ESM4::REC_SMEN:
|
||||
@ -433,97 +517,56 @@ namespace EsmTool
|
||||
case ESM4::REC_SNCT:
|
||||
break;
|
||||
case ESM4::REC_SNDR:
|
||||
return readTypedRecord<ESM4::SoundReference>(params, reader);
|
||||
readTypedRecord<ESM4::SoundReference>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_SOPM:
|
||||
break;
|
||||
case ESM4::REC_SOUN:
|
||||
return readTypedRecord<ESM4::Sound>(params, reader);
|
||||
readTypedRecord<ESM4::Sound>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_SPEL:
|
||||
break;
|
||||
case ESM4::REC_SPGD:
|
||||
break;
|
||||
case ESM4::REC_STAT:
|
||||
return readTypedRecord<ESM4::Static>(params, reader);
|
||||
readTypedRecord<ESM4::Static>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_TACT:
|
||||
return readTypedRecord<ESM4::TalkingActivator>(params, reader);
|
||||
readTypedRecord<ESM4::TalkingActivator>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_TERM:
|
||||
return readTypedRecord<ESM4::Terminal>(params, reader);
|
||||
readTypedRecord<ESM4::Terminal>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_TES4:
|
||||
return readTypedRecord<ESM4::Header>(params, reader);
|
||||
readTypedRecord<ESM4::Header>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_TREE:
|
||||
return readTypedRecord<ESM4::Tree>(params, reader);
|
||||
readTypedRecord<ESM4::Tree>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_TXST:
|
||||
return readTypedRecord<ESM4::TextureSet>(params, reader);
|
||||
readTypedRecord<ESM4::TextureSet>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_VTYP:
|
||||
break;
|
||||
case ESM4::REC_WATR:
|
||||
break;
|
||||
case ESM4::REC_WEAP:
|
||||
return readTypedRecord<ESM4::Weapon>(params, reader);
|
||||
readTypedRecord<ESM4::Weapon>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_WOOP:
|
||||
break;
|
||||
case ESM4::REC_WRLD:
|
||||
return readTypedRecord<ESM4::World>(params, reader);
|
||||
readTypedRecord<ESM4::World>(params, reader);
|
||||
return true;
|
||||
case ESM4::REC_WTHR:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!params.mQuite)
|
||||
std::cout << "\n Unsupported record: " << ESM::NAME(reader.hdr().record.typeId).toStringView() << '\n';
|
||||
|
||||
reader.skipRecordData();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool readItem(const Params& params, ESM4::Reader& reader);
|
||||
|
||||
bool readGroup(const Params& params, ESM4::Reader& reader)
|
||||
{
|
||||
const ESM4::RecordHeader& header = reader.hdr();
|
||||
|
||||
if (!params.mQuite)
|
||||
std::cout << "\nGroup: " << toString(static_cast<ESM4::GroupType>(header.group.type)) << " "
|
||||
<< ESM::NAME(header.group.typeId).toStringView() << '\n';
|
||||
|
||||
switch (static_cast<ESM4::GroupType>(header.group.type))
|
||||
{
|
||||
case ESM4::Grp_RecordType:
|
||||
case ESM4::Grp_InteriorCell:
|
||||
case ESM4::Grp_InteriorSubCell:
|
||||
case ESM4::Grp_ExteriorCell:
|
||||
case ESM4::Grp_ExteriorSubCell:
|
||||
reader.enterGroup();
|
||||
return readItem(params, reader);
|
||||
case ESM4::Grp_WorldChild:
|
||||
case ESM4::Grp_CellChild:
|
||||
case ESM4::Grp_TopicChild:
|
||||
case ESM4::Grp_CellPersistentChild:
|
||||
case ESM4::Grp_CellTemporaryChild:
|
||||
case ESM4::Grp_CellVisibleDistChild:
|
||||
reader.adjustGRUPFormId();
|
||||
reader.enterGroup();
|
||||
if (!reader.hasMoreRecs())
|
||||
return false;
|
||||
return readItem(params, reader);
|
||||
}
|
||||
|
||||
reader.skipGroup();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readItem(const Params& params, ESM4::Reader& reader)
|
||||
{
|
||||
if (!reader.getRecordHeader() || !reader.hasMoreRecs())
|
||||
return false;
|
||||
|
||||
const ESM4::RecordHeader& header = reader.hdr();
|
||||
|
||||
if (header.record.typeId == ESM4::REC_GRUP)
|
||||
return readGroup(params, reader);
|
||||
|
||||
readRecord(params, reader);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int loadTes4(const Arguments& info, std::unique_ptr<std::ifstream>&& stream)
|
||||
@ -551,12 +594,15 @@ namespace EsmTool
|
||||
}
|
||||
}
|
||||
|
||||
while (reader.hasMoreRecs())
|
||||
{
|
||||
reader.exitGroupCheck();
|
||||
if (!readItem(params, reader))
|
||||
break;
|
||||
}
|
||||
auto visitorRec = [¶ms](ESM4::Reader& reader) { return readRecord(params, reader); };
|
||||
auto visitorGroup = [¶ms](ESM4::Reader& reader) {
|
||||
if (params.mQuite)
|
||||
return;
|
||||
auto groupType = static_cast<ESM4::GroupType>(reader.hdr().group.type);
|
||||
std::cout << "\nGroup: " << toString(groupType) << " "
|
||||
<< ESM::NAME(reader.hdr().group.typeId).toStringView() << '\n';
|
||||
};
|
||||
ESM4::ReaderUtils::readAll(reader, visitorRec, visitorGroup);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
|
@ -126,6 +126,7 @@ bool Launcher::AdvancedPage::loadSettings()
|
||||
antialiasAlphaTestCheckBox->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
loadSettingBool(adjustCoverageForAlphaTestCheckBox, "adjust coverage for alpha test", "Shaders");
|
||||
loadSettingBool(weatherParticleOcclusionCheckBox, "weather particle occlusion", "Shaders");
|
||||
loadSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game");
|
||||
connect(animSourcesCheckBox, &QCheckBox::toggled, this, &AdvancedPage::slotAnimSourcesToggled);
|
||||
loadSettingBool(animSourcesCheckBox, "use additional anim sources", "Game");
|
||||
@ -285,6 +286,7 @@ void Launcher::AdvancedPage::saveSettings()
|
||||
saveSettingBool(softParticlesCheckBox, "soft particles", "Shaders");
|
||||
saveSettingBool(antialiasAlphaTestCheckBox, "antialias alpha test", "Shaders");
|
||||
saveSettingBool(adjustCoverageForAlphaTestCheckBox, "adjust coverage for alpha test", "Shaders");
|
||||
saveSettingBool(weatherParticleOcclusionCheckBox, "weather particle occlusion", "Shaders");
|
||||
saveSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game");
|
||||
saveSettingBool(animSourcesCheckBox, "use additional anim sources", "Game");
|
||||
saveSettingBool(weaponSheathingCheckBox, "weapon sheathing", "Game");
|
||||
|
@ -490,13 +490,7 @@ namespace CSMWorld
|
||||
int Collection<ESXRecordT, IdAccessorT>::searchId(const ESM::RefId& id) const
|
||||
{
|
||||
|
||||
std::map<std::string, int>::const_iterator iter
|
||||
= mIndex.find(Misc::StringUtils::lowerCase(id.getRefIdString()));
|
||||
|
||||
if (iter == mIndex.end())
|
||||
return -1;
|
||||
|
||||
return iter->second;
|
||||
return searchId(id.getRefIdString());
|
||||
}
|
||||
|
||||
template <typename ESXRecordT, typename IdAccessorT>
|
||||
|
@ -1242,10 +1242,10 @@ bool CSMWorld::Data::continueLoading(CSMDoc::Messages& messages)
|
||||
case ESM::REC_DIAL:
|
||||
{
|
||||
ESM::Dialogue record;
|
||||
const std::string& recordIdString = record.mId.getRefIdString();
|
||||
bool isDeleted = false;
|
||||
|
||||
record.load(*mReader, isDeleted);
|
||||
const std::string& recordIdString = record.mId.getRefIdString();
|
||||
|
||||
if (isDeleted)
|
||||
{
|
||||
|
@ -23,7 +23,7 @@ add_openmw_dir (mwrender
|
||||
creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation screenshotmanager
|
||||
bulletdebugdraw globalmap characterpreview camera localmap water terrainstorage ripplesimulation
|
||||
renderbin actoranimation landmanager navmesh actorspaths recastmesh fogmanager objectpaging groundcover
|
||||
postprocessor pingpongcull luminancecalculator pingpongcanvas transparentpass navmeshmode
|
||||
postprocessor pingpongcull luminancecalculator pingpongcanvas transparentpass navmeshmode precipitationocclusion
|
||||
)
|
||||
|
||||
add_openmw_dir (mwinput
|
||||
|
@ -127,10 +127,10 @@ namespace MWClass
|
||||
if (!customData.mSpawn)
|
||||
return;
|
||||
|
||||
MWWorld::LiveCellRef<ESM::CreatureLevList>* ref = ptr.get<ESM::CreatureLevList>();
|
||||
|
||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
||||
const ESM::RefId& id = MWMechanics::getLevelledItem(ref->mBase, true, prng);
|
||||
const ESM::RefId& id = MWMechanics::getLevelledItem(
|
||||
store.get<ESM::CreatureLevList>().find(ptr.getCellRef().getRefId()), true, prng);
|
||||
|
||||
if (!id.empty())
|
||||
{
|
||||
@ -144,7 +144,6 @@ namespace MWClass
|
||||
customData.mSpawnActorId = -1;
|
||||
}
|
||||
|
||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
MWWorld::ManualRef manualRef(store, id);
|
||||
manualRef.getPtr().getCellRef().setPosition(ptr.getCellRef().getPosition());
|
||||
manualRef.getPtr().getCellRef().setScale(ptr.getCellRef().getScale());
|
||||
|
@ -104,20 +104,20 @@ namespace MWGui
|
||||
// - Shader editor
|
||||
|
||||
MyGUI::TabItem* itemLV = mTabControl->addItem("Log Viewer");
|
||||
itemLV->setCaptionWithReplacing(" #{DebugMenu:LogViewer} ");
|
||||
itemLV->setCaptionWithReplacing(" #{OMWEngine:LogViewer} ");
|
||||
mLogView
|
||||
= itemLV->createWidgetReal<MyGUI::EditBox>("LogEdit", MyGUI::FloatCoord(0, 0, 1, 1), MyGUI::Align::Stretch);
|
||||
mLogView->setEditReadOnly(true);
|
||||
|
||||
MyGUI::TabItem* itemLuaProfiler = mTabControl->addItem("Lua Profiler");
|
||||
itemLuaProfiler->setCaptionWithReplacing(" #{DebugMenu:LuaProfiler} ");
|
||||
itemLuaProfiler->setCaptionWithReplacing(" #{OMWEngine:LuaProfiler} ");
|
||||
mLuaProfiler = itemLuaProfiler->createWidgetReal<MyGUI::EditBox>(
|
||||
"LogEdit", MyGUI::FloatCoord(0, 0, 1, 1), MyGUI::Align::Stretch);
|
||||
mLuaProfiler->setEditReadOnly(true);
|
||||
|
||||
#ifndef BT_NO_PROFILE
|
||||
MyGUI::TabItem* item = mTabControl->addItem("Physics Profiler");
|
||||
item->setCaptionWithReplacing(" #{DebugMenu:PhysicsProfiler} ");
|
||||
item->setCaptionWithReplacing(" #{OMWEngine:PhysicsProfiler} ");
|
||||
mBulletProfilerEdit
|
||||
= item->createWidgetReal<MyGUI::EditBox>("LogEdit", MyGUI::FloatCoord(0, 0, 1, 1), MyGUI::Align::Stretch);
|
||||
#else
|
||||
|
@ -558,6 +558,7 @@ namespace
|
||||
|
||||
mModel->visitQuestNames(!mAllQuests, add);
|
||||
|
||||
list->sort();
|
||||
list->adjustSize();
|
||||
|
||||
if (mAllQuests)
|
||||
|
@ -329,26 +329,22 @@ namespace MWGui
|
||||
case fx::Technique::Status::Uncompiled:
|
||||
{
|
||||
if (technique->getDynamic())
|
||||
ss << "#{fontcolourhtml=header}#{PostProcessing:ShaderLocked}: #{fontcolourhtml=normal} "
|
||||
"#{PostProcessing:ShaderLockedDescription}"
|
||||
ss << "#{fontcolourhtml=header}#{OMWShaders:ShaderLocked}: #{fontcolourhtml=normal} "
|
||||
"#{OMWShaders:ShaderLockedDescription}"
|
||||
<< endl
|
||||
<< endl;
|
||||
ss << "#{fontcolourhtml=header}#{PostProcessing:Author}: #{fontcolourhtml=normal} " << author
|
||||
ss << "#{fontcolourhtml=header}#{OMWShaders:Author}: #{fontcolourhtml=normal} " << author << endl
|
||||
<< endl
|
||||
<< "#{fontcolourhtml=header}#{OMWShaders:Version}: #{fontcolourhtml=normal} " << version << endl
|
||||
<< endl
|
||||
<< "#{fontcolourhtml=header}#{OMWShaders:Description}: #{fontcolourhtml=normal} " << description
|
||||
<< endl
|
||||
<< endl
|
||||
<< "#{fontcolourhtml=header}#{PostProcessing:Version}: #{fontcolourhtml=normal} " << version
|
||||
<< endl
|
||||
<< endl
|
||||
<< "#{fontcolourhtml=header}#{PostProcessing:Description}: #{fontcolourhtml=normal} " << description
|
||||
<< endl
|
||||
<< endl
|
||||
<< "#{fontcolourhtml=header}#{PostProcessing:InInteriors}: #{fontcolourhtml=normal} "
|
||||
<< flag_interior
|
||||
<< "#{fontcolourhtml=header} #{PostProcessing:InExteriors}: #{fontcolourhtml=normal} "
|
||||
<< flag_exterior
|
||||
<< "#{fontcolourhtml=header} #{PostProcessing:Underwater}: #{fontcolourhtml=normal} "
|
||||
<< "#{fontcolourhtml=header}#{OMWShaders:InInteriors}: #{fontcolourhtml=normal} " << flag_interior
|
||||
<< "#{fontcolourhtml=header} #{OMWShaders:InExteriors}: #{fontcolourhtml=normal} " << flag_exterior
|
||||
<< "#{fontcolourhtml=header} #{OMWShaders:Underwater}: #{fontcolourhtml=normal} "
|
||||
<< flag_underwater
|
||||
<< "#{fontcolourhtml=header} #{PostProcessing:Abovewater}: #{fontcolourhtml=normal} "
|
||||
<< "#{fontcolourhtml=header} #{OMWShaders:Abovewater}: #{fontcolourhtml=normal} "
|
||||
<< flag_abovewater;
|
||||
break;
|
||||
}
|
||||
@ -370,7 +366,7 @@ namespace MWGui
|
||||
{
|
||||
MyGUI::Button* resetButton
|
||||
= mConfigArea->createWidget<MyGUI::Button>("MW_Button", { 0, 0, 0, 24 }, MyGUI::Align::Default);
|
||||
resetButton->setCaptionWithReplacing("#{PostProcessing:ResetShader}");
|
||||
resetButton->setCaptionWithReplacing("#{OMWShaders:ResetShader}");
|
||||
resetButton->setTextAlign(MyGUI::Align::Center);
|
||||
resetButton->eventMouseWheel += MyGUI::newDelegate(this, &PostProcessorHud::notifyMouseWheel);
|
||||
resetButton->eventMouseButtonClick
|
||||
|
@ -111,7 +111,7 @@ namespace MWGui
|
||||
onCharacterSelected(mCharacterSelection, nextCharacter);
|
||||
}
|
||||
else
|
||||
fillSaveList();
|
||||
mCharacterSelection->setIndexSelected(MyGUI::ITEM_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,7 +216,7 @@ namespace MWGui
|
||||
|
||||
mCharacterSelection->setIndexSelected(selectedIndex);
|
||||
if (selectedIndex == MyGUI::ITEM_NONE)
|
||||
mCharacterSelection->setCaptionWithReplacing("#{SavegameMenu:SelectCharacter}");
|
||||
mCharacterSelection->setCaptionWithReplacing("#{OMWEngine:SelectCharacter}");
|
||||
|
||||
fillSaveList();
|
||||
}
|
||||
@ -430,7 +430,7 @@ namespace MWGui
|
||||
if (Settings::Manager::getBool("timeplayed", "Saves"))
|
||||
{
|
||||
text << "\n"
|
||||
<< "#{SavegameMenu:TimePlayed}: " << formatTimeplayed(mCurrentSlot->mProfile.mTimePlayed);
|
||||
<< "#{OMWEngine:TimePlayed}: " << formatTimeplayed(mCurrentSlot->mProfile.mTimePlayed);
|
||||
}
|
||||
|
||||
mInfoText->setCaptionWithReplacing(text.str());
|
||||
|
@ -45,14 +45,14 @@ namespace
|
||||
std::string textureMipmappingToStr(const std::string& val)
|
||||
{
|
||||
if (val == "linear")
|
||||
return "#{SettingsMenu:TextureFilteringTrilinear}";
|
||||
return "#{OMWEngine:TextureFilteringTrilinear}";
|
||||
if (val == "nearest")
|
||||
return "#{SettingsMenu:TextureFilteringBilinear}";
|
||||
return "#{OMWEngine:TextureFilteringBilinear}";
|
||||
if (val == "none")
|
||||
return "#{SettingsMenu:TextureFilteringDisabled}";
|
||||
return "#{OMWEngine:TextureFilteringDisabled}";
|
||||
|
||||
Log(Debug::Warning) << "Warning: Invalid texture mipmap option: " << val;
|
||||
return "#{SettingsMenu:TextureFilteringOther}";
|
||||
return "#{OMWEngine:TextureFilteringOther}";
|
||||
}
|
||||
|
||||
std::string lightingMethodToStr(SceneUtil::LightingMethod method)
|
||||
@ -61,14 +61,14 @@ namespace
|
||||
switch (method)
|
||||
{
|
||||
case SceneUtil::LightingMethod::FFP:
|
||||
result = "#{SettingsMenu:LightingMethodLegacy}";
|
||||
result = "#{OMWEngine:LightingMethodLegacy}";
|
||||
break;
|
||||
case SceneUtil::LightingMethod::PerObjectUniform:
|
||||
result = "#{SettingsMenu:LightingMethodShadersCompatibility}";
|
||||
result = "#{OMWEngine:LightingMethodShadersCompatibility}";
|
||||
break;
|
||||
case SceneUtil::LightingMethod::SingleUBO:
|
||||
default:
|
||||
result = "#{SettingsMenu:LightingMethodShaders}";
|
||||
result = "#{OMWEngine:LightingMethodShaders}";
|
||||
break;
|
||||
}
|
||||
|
||||
@ -533,7 +533,7 @@ namespace MWGui
|
||||
_sender->setCaptionWithReplacing(_sender->getItemNameAt(_sender->getIndexSelected()));
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->interactiveMessageBox(
|
||||
"#{SettingsMenu:ChangeRequiresRestart}", { "#{sOK}" }, true);
|
||||
"#{OMWEngine:ChangeRequiresRestart}", { "#{sOK}" }, true);
|
||||
|
||||
Settings::Manager::setString("lighting method", "Shaders", *_sender->getItemDataAt<std::string>(pos));
|
||||
apply();
|
||||
@ -547,7 +547,7 @@ namespace MWGui
|
||||
_sender->setCaptionWithReplacing(_sender->getItemNameAt(_sender->getIndexSelected()));
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->interactiveMessageBox(
|
||||
"#{SettingsMenu:ChangeRequiresRestart}", { "#{sOK}" }, true);
|
||||
"#{OMWEngine:ChangeRequiresRestart}", { "#{sOK}" }, true);
|
||||
|
||||
std::vector<std::string> currentLocales = Settings::Manager::getStringArray("preferred locales", "General");
|
||||
if (currentLocales.size() <= langPriority)
|
||||
@ -601,7 +601,7 @@ namespace MWGui
|
||||
{
|
||||
std::vector<std::string> buttons = { "#{sYes}", "#{sNo}" };
|
||||
MWBase::Environment::get().getWindowManager()->interactiveMessageBox(
|
||||
"#{SettingsMenu:LightingResetToDefaults}", buttons, true);
|
||||
"#{OMWEngine:LightingResetToDefaults}", buttons, true);
|
||||
int selectedButton = MWBase::Environment::get().getWindowManager()->readPressedButton();
|
||||
if (selectedButton == 1 || selectedButton == -1)
|
||||
return;
|
||||
|
@ -5,75 +5,68 @@ namespace MWInput
|
||||
{
|
||||
enum Actions
|
||||
{
|
||||
// please add new actions at the bottom, in order to preserve the channel IDs in the key configuration files
|
||||
// Action IDs are used in the configuration file input_v3.xml
|
||||
|
||||
A_GameMenu,
|
||||
A_GameMenu = 0,
|
||||
|
||||
A_Unused,
|
||||
A_Screenshot = 2, // Take a screenshot
|
||||
|
||||
A_Screenshot, // Take a screenshot
|
||||
A_Inventory = 3, // Toggle inventory screen
|
||||
A_Console = 4, // Toggle console screen
|
||||
|
||||
A_Inventory, // Toggle inventory screen
|
||||
A_MoveLeft = 5, // Move player left / right
|
||||
A_MoveRight = 6,
|
||||
A_MoveForward = 7, // Forward / Backward
|
||||
A_MoveBackward = 8,
|
||||
|
||||
A_Console, // Toggle console screen
|
||||
A_Activate = 9,
|
||||
|
||||
A_MoveLeft, // Move player left / right
|
||||
A_MoveRight,
|
||||
A_MoveForward, // Forward / Backward
|
||||
A_MoveBackward,
|
||||
A_Use = 10, // Use weapon, spell, etc.
|
||||
A_Jump = 11,
|
||||
A_AutoMove = 12, // Toggle Auto-move forward
|
||||
A_Rest = 13, // Rest
|
||||
A_Journal = 14, // Journal
|
||||
A_Run = 17, // Run when held
|
||||
A_CycleSpellLeft = 18, // cycling through spells
|
||||
A_CycleSpellRight = 19,
|
||||
A_CycleWeaponLeft = 20, // Cycling through weapons
|
||||
A_CycleWeaponRight = 21,
|
||||
A_AlwaysRun = 23, // Toggle Walking/Running
|
||||
A_Sneak = 24,
|
||||
|
||||
A_Activate,
|
||||
A_QuickSave = 25,
|
||||
A_QuickLoad = 26,
|
||||
A_QuickMenu = 27,
|
||||
A_ToggleWeapon = 28,
|
||||
A_ToggleSpell = 29,
|
||||
|
||||
A_Use, // Use weapon, spell, etc.
|
||||
A_Jump,
|
||||
A_AutoMove, // Toggle Auto-move forward
|
||||
A_Rest, // Rest
|
||||
A_Journal, // Journal
|
||||
A_Weapon, // Draw/Sheath weapon
|
||||
A_Spell, // Ready/Unready Casting
|
||||
A_Run, // Run when held
|
||||
A_CycleSpellLeft, // cycling through spells
|
||||
A_CycleSpellRight,
|
||||
A_CycleWeaponLeft, // Cycling through weapons
|
||||
A_CycleWeaponRight,
|
||||
A_ToggleSneak, // Toggles Sneak
|
||||
A_AlwaysRun, // Toggle Walking/Running
|
||||
A_Sneak,
|
||||
A_TogglePOV = 30,
|
||||
|
||||
A_QuickSave,
|
||||
A_QuickLoad,
|
||||
A_QuickMenu,
|
||||
A_ToggleWeapon,
|
||||
A_ToggleSpell,
|
||||
A_QuickKey1 = 31,
|
||||
A_QuickKey2 = 32,
|
||||
A_QuickKey3 = 33,
|
||||
A_QuickKey4 = 34,
|
||||
A_QuickKey5 = 35,
|
||||
A_QuickKey6 = 36,
|
||||
A_QuickKey7 = 37,
|
||||
A_QuickKey8 = 38,
|
||||
A_QuickKey9 = 39,
|
||||
A_QuickKey10 = 40,
|
||||
|
||||
A_TogglePOV,
|
||||
A_QuickKeysMenu = 41,
|
||||
|
||||
A_QuickKey1,
|
||||
A_QuickKey2,
|
||||
A_QuickKey3,
|
||||
A_QuickKey4,
|
||||
A_QuickKey5,
|
||||
A_QuickKey6,
|
||||
A_QuickKey7,
|
||||
A_QuickKey8,
|
||||
A_QuickKey9,
|
||||
A_QuickKey10,
|
||||
A_ToggleHUD = 42,
|
||||
A_ToggleDebug = 43,
|
||||
|
||||
A_QuickKeysMenu,
|
||||
A_LookUpDown = 44, // Joystick look
|
||||
A_LookLeftRight = 45,
|
||||
A_MoveForwardBackward = 46,
|
||||
A_MoveLeftRight = 47,
|
||||
|
||||
A_ToggleHUD,
|
||||
A_ZoomIn = 48,
|
||||
A_ZoomOut = 49,
|
||||
|
||||
A_ToggleDebug,
|
||||
|
||||
A_LookUpDown, // Joystick look
|
||||
A_LookLeftRight,
|
||||
A_MoveForwardBackward,
|
||||
A_MoveLeftRight,
|
||||
|
||||
A_ZoomIn,
|
||||
A_ZoomOut,
|
||||
|
||||
A_TogglePostProcessorHUD,
|
||||
A_TogglePostProcessorHUD = 50,
|
||||
|
||||
A_Last // Marker for the last item
|
||||
};
|
||||
|
@ -441,13 +441,13 @@ namespace MWInput
|
||||
switch (action)
|
||||
{
|
||||
case A_Screenshot:
|
||||
return "#{SettingsMenu:Screenshot}";
|
||||
return "#{OMWEngine:Screenshot}";
|
||||
case A_ZoomIn:
|
||||
return "#{SettingsMenu:CameraZoomIn}";
|
||||
return "#{OMWEngine:CameraZoomIn}";
|
||||
case A_ZoomOut:
|
||||
return "#{SettingsMenu:CameraZoomOut}";
|
||||
return "#{OMWEngine:CameraZoomOut}";
|
||||
case A_ToggleHUD:
|
||||
return "#{SettingsMenu:ToggleHUD}";
|
||||
return "#{OMWEngine:ToggleHUD}";
|
||||
case A_Use:
|
||||
return "#{sUse}";
|
||||
case A_Activate:
|
||||
@ -519,7 +519,7 @@ namespace MWInput
|
||||
case A_QuickLoad:
|
||||
return "#{sQuickLoadCmd}";
|
||||
case A_TogglePostProcessorHUD:
|
||||
return "#{SettingsMenu:TogglePostProcessorHUD}";
|
||||
return "#{OMWEngine:TogglePostProcessorHUD}";
|
||||
default:
|
||||
return {}; // not configurable
|
||||
}
|
||||
|
@ -45,10 +45,23 @@ namespace MWLua
|
||||
cellT["gridX"] = sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->getGridX(); });
|
||||
cellT["gridY"] = sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->getGridY(); });
|
||||
cellT["hasWater"] = sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->hasWater(); });
|
||||
cellT["hasSky"] = sol::readonly_property([](const CellT& c) {
|
||||
return c.mStore->getCell()->isExterior() || (c.mStore->getCell()->mData.mFlags & ESM::Cell::QuasiEx) != 0;
|
||||
});
|
||||
cellT["isExterior"] = sol::readonly_property([](const CellT& c) { return c.mStore->isExterior(); });
|
||||
|
||||
// deprecated, use cell:hasTag("QuasiExterior") instead
|
||||
cellT["isQuasiExterior"] = sol::readonly_property(
|
||||
[](const CellT& c) { return (c.mStore->getCell()->mData.mFlags & ESM::Cell::QuasiEx) != 0; });
|
||||
|
||||
cellT["hasTag"] = [](const CellT& c, std::string_view tag) -> bool {
|
||||
if (tag == "NoSleep")
|
||||
return (c.mStore->getCell()->mData.mFlags & ESM::Cell::NoSleep) != 0;
|
||||
else if (tag == "QuasiExterior")
|
||||
return (c.mStore->getCell()->mData.mFlags & ESM::Cell::QuasiEx) != 0;
|
||||
return false;
|
||||
};
|
||||
|
||||
cellT["isInSameSpace"] = [](const CellT& c, const ObjectT& obj) {
|
||||
const MWWorld::Ptr& ptr = obj.ptr();
|
||||
if (!ptr.isInCell())
|
||||
|
@ -98,14 +98,11 @@ namespace MWLua
|
||||
{ "AutoMove", MWInput::A_AutoMove },
|
||||
{ "Rest", MWInput::A_Rest },
|
||||
{ "Journal", MWInput::A_Journal },
|
||||
{ "Weapon", MWInput::A_Weapon },
|
||||
{ "Spell", MWInput::A_Spell },
|
||||
{ "Run", MWInput::A_Run },
|
||||
{ "CycleSpellLeft", MWInput::A_CycleSpellLeft },
|
||||
{ "CycleSpellRight", MWInput::A_CycleSpellRight },
|
||||
{ "CycleWeaponLeft", MWInput::A_CycleWeaponLeft },
|
||||
{ "CycleWeaponRight", MWInput::A_CycleWeaponRight },
|
||||
{ "ToggleSneak", MWInput::A_ToggleSneak },
|
||||
{ "AlwaysRun", MWInput::A_AlwaysRun },
|
||||
{ "Sneak", MWInput::A_Sneak },
|
||||
|
||||
|
@ -401,7 +401,7 @@ namespace MWLua
|
||||
return localScripts->getActorControls();
|
||||
}
|
||||
|
||||
void LuaManager::addCustomLocalScript(const MWWorld::Ptr& ptr, int scriptId)
|
||||
void LuaManager::addCustomLocalScript(const MWWorld::Ptr& ptr, int scriptId, std::string_view initData)
|
||||
{
|
||||
LocalScripts* localScripts = ptr.getRefData().getLuaScripts();
|
||||
if (!localScripts)
|
||||
@ -411,7 +411,7 @@ namespace MWLua
|
||||
if (ptr.isInCell() && MWBase::Environment::get().getWorldScene()->isCellActive(*ptr.getCell()))
|
||||
mActiveLocalScripts.insert(localScripts);
|
||||
}
|
||||
localScripts->addCustomScript(scriptId);
|
||||
localScripts->addCustomScript(scriptId, initData);
|
||||
}
|
||||
|
||||
LocalScripts* LuaManager::createLocalScripts(
|
||||
|
@ -57,7 +57,7 @@ namespace MWLua
|
||||
void setupPlayer(const MWWorld::Ptr& ptr) override; // Should be called once after each "clear".
|
||||
|
||||
// Used only in Lua bindings
|
||||
void addCustomLocalScript(const MWWorld::Ptr&, int scriptId);
|
||||
void addCustomLocalScript(const MWWorld::Ptr&, int scriptId, std::string_view initData);
|
||||
void addUIMessage(std::string_view message) { mUIMessages.emplace_back(message); }
|
||||
void addInGameConsoleMessage(const std::string& msg, const Misc::Color& color)
|
||||
{
|
||||
|
@ -200,9 +200,8 @@ namespace MWLua
|
||||
|
||||
if constexpr (std::is_same_v<ObjectT, GObject>)
|
||||
{ // Only for global scripts
|
||||
objectT["addScript"] = [lua = context.mLua, luaManager = context.mLuaManager](
|
||||
const GObject& object, std::string_view path) {
|
||||
const LuaUtil::ScriptsConfiguration& cfg = lua->getConfiguration();
|
||||
objectT["addScript"] = [context](const GObject& object, std::string_view path, sol::object initData) {
|
||||
const LuaUtil::ScriptsConfiguration& cfg = context.mLua->getConfiguration();
|
||||
std::optional<int> scriptId = cfg.findId(path);
|
||||
if (!scriptId)
|
||||
throw std::runtime_error("Unknown script: " + std::string(path));
|
||||
@ -211,7 +210,12 @@ namespace MWLua
|
||||
"Script without CUSTOM tag can not be added dynamically: " + std::string(path));
|
||||
if (object.ptr().getType() == ESM::REC_STAT)
|
||||
throw std::runtime_error("Attaching scripts to Static is not allowed: " + std::string(path));
|
||||
luaManager->addCustomLocalScript(object.ptr(), *scriptId);
|
||||
if (initData != sol::nil)
|
||||
context.mLuaManager->addCustomLocalScript(object.ptr(), *scriptId,
|
||||
LuaUtil::serialize(initData.as<sol::table>(), context.mSerializer));
|
||||
else
|
||||
context.mLuaManager->addCustomLocalScript(
|
||||
object.ptr(), *scriptId, cfg[*scriptId].mInitializationData);
|
||||
};
|
||||
objectT["hasScript"] = [lua = context.mLua](const GObject& object, std::string_view path) {
|
||||
const LuaUtil::ScriptsConfiguration& cfg = lua->getConfiguration();
|
||||
|
@ -400,6 +400,9 @@ namespace MWMechanics
|
||||
{
|
||||
if (!mAnimation->isPlaying(mCurrentHit))
|
||||
{
|
||||
if (isKnockedOut() && mCurrentHit.empty() && knockout)
|
||||
return;
|
||||
|
||||
mHitState = CharState_None;
|
||||
mCurrentHit.clear();
|
||||
stats.setKnockedDown(false);
|
||||
@ -450,18 +453,6 @@ namespace MWMechanics
|
||||
mCurrentHit = chooseRandomGroup(hitStateToAnimGroup(CharState_Hit));
|
||||
}
|
||||
|
||||
if (!mAnimation->hasAnimation(mCurrentHit))
|
||||
{
|
||||
// The hit animation is missing. Reset the current hit state and immediately cancel all states as if the
|
||||
// animation were instantaneous.
|
||||
mHitState = CharState_None;
|
||||
mCurrentHit.clear();
|
||||
stats.setKnockedDown(false);
|
||||
stats.setHitRecovery(false);
|
||||
resetCurrentIdleState();
|
||||
return;
|
||||
}
|
||||
|
||||
// Cancel upper body animations
|
||||
if (isKnockedOut() || isKnockedDown())
|
||||
{
|
||||
@ -479,6 +470,12 @@ namespace MWMechanics
|
||||
}
|
||||
}
|
||||
|
||||
if (!mAnimation->hasAnimation(mCurrentHit))
|
||||
{
|
||||
mCurrentHit.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
mAnimation->play(
|
||||
mCurrentHit, priority, MWRender::Animation::BlendMask_All, true, 1, startKey, stopKey, 0.0f, ~0ul);
|
||||
}
|
||||
@ -755,7 +752,7 @@ namespace MWMechanics
|
||||
// FIXME: if one of the below states is close to their last animation frame (i.e. will be disabled in the coming
|
||||
// update), the idle animation should be displayed
|
||||
if (((mUpperBodyState != UpperBodyState::None && mUpperBodyState != UpperBodyState::WeaponEquipped)
|
||||
|| mMovementState != CharState_None || mHitState != CharState_None)
|
||||
|| mMovementState != CharState_None || !mCurrentHit.empty())
|
||||
&& !mPtr.getClass().isBipedal(mPtr))
|
||||
{
|
||||
resetCurrentIdleState();
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/Sequence>
|
||||
#include <osg/Switch>
|
||||
#include <osgAnimation/BasicAnimationManager>
|
||||
#include <osgUtil/IncrementalCompileOperation>
|
||||
|
||||
#include <components/esm3/esmreader.hpp>
|
||||
@ -643,7 +644,9 @@ namespace MWRender
|
||||
{
|
||||
if (cnode->getNumChildrenRequiringUpdateTraversal() > 0
|
||||
|| SceneUtil::hasUserDescription(cnode, Constants::NightDayLabel)
|
||||
|| SceneUtil::hasUserDescription(cnode, Constants::HerbalismLabel))
|
||||
|| SceneUtil::hasUserDescription(cnode, Constants::HerbalismLabel)
|
||||
|| (cnode->getName() == "Collada visual scene group"
|
||||
&& dynamic_cast<const osgAnimation::BasicAnimationManager*>(cnode->getUpdateCallback())))
|
||||
continue;
|
||||
else
|
||||
refnumSet->mRefnums.push_back(pair.first);
|
||||
|
170
apps/openmw/mwrender/precipitationocclusion.cpp
Normal file
170
apps/openmw/mwrender/precipitationocclusion.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
#include "precipitationocclusion.hpp"
|
||||
|
||||
#include <osgUtil/CullVisitor>
|
||||
|
||||
#include <components/misc/constants.hpp>
|
||||
#include <components/resource/resourcesystem.hpp>
|
||||
#include <components/resource/scenemanager.hpp>
|
||||
#include <components/sceneutil/depth.hpp>
|
||||
#include <components/sceneutil/positionattitudetransform.hpp>
|
||||
#include <components/sceneutil/util.hpp>
|
||||
#include <components/shader/shadermanager.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
||||
#include "vismask.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
class PrecipitationOcclusionUpdater : public SceneUtil::StateSetUpdater
|
||||
{
|
||||
public:
|
||||
PrecipitationOcclusionUpdater(osg::ref_ptr<osg::Texture2D> depthTexture)
|
||||
: mDepthTexture(depthTexture)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
void setDefaults(osg::StateSet* stateset) override
|
||||
{
|
||||
stateset->setTextureAttributeAndModes(3, mDepthTexture);
|
||||
stateset->addUniform(new osg::Uniform("orthoDepthMap", 3));
|
||||
stateset->addUniform(new osg::Uniform("depthSpaceMatrix", mDepthSpaceMatrix));
|
||||
}
|
||||
void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) override
|
||||
{
|
||||
osg::Camera* camera = nv->asCullVisitor()->getCurrentCamera();
|
||||
stateset->getUniform("depthSpaceMatrix")->set(camera->getViewMatrix() * camera->getProjectionMatrix());
|
||||
}
|
||||
|
||||
osg::Matrixf mDepthSpaceMatrix;
|
||||
osg::ref_ptr<osg::Texture2D> mDepthTexture;
|
||||
};
|
||||
|
||||
class DepthCameraUpdater : public SceneUtil::StateSetUpdater
|
||||
{
|
||||
public:
|
||||
DepthCameraUpdater()
|
||||
: mDummyTexture(new osg::Texture2D)
|
||||
{
|
||||
mDummyTexture->setInternalFormat(GL_RGB);
|
||||
mDummyTexture->setTextureSize(1, 1);
|
||||
|
||||
Shader::ShaderManager& shaderMgr
|
||||
= MWBase::Environment::get().getResourceSystem()->getSceneManager()->getShaderManager();
|
||||
osg::ref_ptr<osg::Shader> vertex
|
||||
= shaderMgr.getShader("precipitationdepth_vertex.glsl", {}, osg::Shader::VERTEX);
|
||||
osg::ref_ptr<osg::Shader> fragment
|
||||
= shaderMgr.getShader("precipitationdepth_fragment.glsl", {}, osg::Shader::FRAGMENT);
|
||||
mProgram = shaderMgr.getProgram(vertex, fragment);
|
||||
}
|
||||
|
||||
private:
|
||||
void setDefaults(osg::StateSet* stateset) override
|
||||
{
|
||||
stateset->addUniform(new osg::Uniform("projectionMatrix", osg::Matrixf()));
|
||||
stateset->setAttributeAndModes(mProgram, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
|
||||
stateset->setTextureAttributeAndModes(0, mDummyTexture);
|
||||
stateset->setRenderBinDetails(
|
||||
osg::StateSet::OPAQUE_BIN, "RenderBin", osg::StateSet::OVERRIDE_PROTECTED_RENDERBIN_DETAILS);
|
||||
}
|
||||
void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) override
|
||||
{
|
||||
osg::Camera* camera = nv->asCullVisitor()->getCurrentCamera();
|
||||
stateset->getUniform("projectionMatrix")->set(camera->getProjectionMatrix());
|
||||
}
|
||||
|
||||
osg::Matrixf mProjectionMatrix;
|
||||
osg::ref_ptr<osg::Texture2D> mDummyTexture;
|
||||
osg::ref_ptr<osg::Program> mProgram;
|
||||
};
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
PrecipitationOccluder::PrecipitationOccluder(
|
||||
osg::Group* skyNode, osg::Group* sceneNode, osg::Group* rootNode, osg::Camera* camera)
|
||||
: mSkyNode(skyNode)
|
||||
, mSceneNode(sceneNode)
|
||||
, mRootNode(rootNode)
|
||||
, mSceneCamera(camera)
|
||||
{
|
||||
constexpr int rttSize = 256;
|
||||
|
||||
mDepthTexture = new osg::Texture2D;
|
||||
mDepthTexture->setTextureSize(rttSize, rttSize);
|
||||
mDepthTexture->setSourceFormat(GL_DEPTH_COMPONENT);
|
||||
mDepthTexture->setInternalFormat(GL_DEPTH_COMPONENT24);
|
||||
mDepthTexture->setSourceType(GL_UNSIGNED_INT);
|
||||
mDepthTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_BORDER);
|
||||
mDepthTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_BORDER);
|
||||
mDepthTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
|
||||
mDepthTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
|
||||
mDepthTexture->setBorderColor(
|
||||
SceneUtil::AutoDepth::isReversed() ? osg::Vec4(0, 0, 0, 0) : osg::Vec4(1, 1, 1, 1));
|
||||
|
||||
mCamera = new osg::Camera;
|
||||
mCamera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
mCamera->setRenderOrder(osg::Camera::PRE_RENDER);
|
||||
mCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
|
||||
mCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT);
|
||||
mCamera->setNodeMask(Mask_RenderToTexture);
|
||||
mCamera->setCullMask(Mask_Scene | Mask_Object | Mask_Static);
|
||||
mCamera->setViewport(0, 0, rttSize, rttSize);
|
||||
mCamera->attach(osg::Camera::DEPTH_BUFFER, mDepthTexture);
|
||||
mCamera->addChild(mSceneNode);
|
||||
|
||||
SceneUtil::setCameraClearDepth(mCamera);
|
||||
}
|
||||
|
||||
void PrecipitationOccluder::update()
|
||||
{
|
||||
const osg::Vec3 pos = mSceneCamera->getInverseViewMatrix().getTrans();
|
||||
|
||||
const float zmin = pos.z() - mRange.z() - Constants::CellSizeInUnits;
|
||||
const float zmax = pos.z() + mRange.z() + Constants::CellSizeInUnits;
|
||||
const float near = 0;
|
||||
const float far = zmax - zmin;
|
||||
|
||||
const float left = -mRange.x() / 2;
|
||||
const float right = -left;
|
||||
const float top = mRange.y() / 2;
|
||||
const float bottom = -top;
|
||||
|
||||
if (SceneUtil::AutoDepth::isReversed())
|
||||
{
|
||||
mCamera->setProjectionMatrix(
|
||||
SceneUtil::getReversedZProjectionMatrixAsOrtho(left, right, bottom, top, near, far));
|
||||
}
|
||||
else
|
||||
{
|
||||
mCamera->setProjectionMatrix(osg::Matrixf::ortho(left, right, bottom, top, near, far));
|
||||
}
|
||||
|
||||
mCamera->setViewMatrixAsLookAt(
|
||||
osg::Vec3(pos.x(), pos.y(), zmax), osg::Vec3(pos.x(), pos.y(), zmin), osg::Vec3(0, 1, 0));
|
||||
}
|
||||
|
||||
void PrecipitationOccluder::enable()
|
||||
{
|
||||
mSkyNode->setCullCallback(new PrecipitationOcclusionUpdater(mDepthTexture));
|
||||
mCamera->setCullCallback(new DepthCameraUpdater);
|
||||
|
||||
mRootNode->removeChild(mCamera);
|
||||
mRootNode->addChild(mCamera);
|
||||
}
|
||||
|
||||
void PrecipitationOccluder::disable()
|
||||
{
|
||||
mSkyNode->setCullCallback(nullptr);
|
||||
mCamera->setCullCallback(nullptr);
|
||||
|
||||
mRootNode->removeChild(mCamera);
|
||||
}
|
||||
|
||||
void PrecipitationOccluder::updateRange(const osg::Vec3f range)
|
||||
{
|
||||
const osg::Vec3f margin = { -50, -50, 0 };
|
||||
mRange = range - margin;
|
||||
}
|
||||
}
|
33
apps/openmw/mwrender/precipitationocclusion.hpp
Normal file
33
apps/openmw/mwrender/precipitationocclusion.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef OPENMW_MWRENDER_PRECIPITATIONOCCLUSION_H
|
||||
#define OPENMW_MWRENDER_PRECIPITATIONOCCLUSION_H
|
||||
|
||||
#include <osg/Camera>
|
||||
#include <osg/Texture2D>
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
class PrecipitationOccluder
|
||||
{
|
||||
public:
|
||||
PrecipitationOccluder(osg::Group* skyNode, osg::Group* sceneNode, osg::Group* rootNode, osg::Camera* camera);
|
||||
|
||||
void update();
|
||||
|
||||
void enable();
|
||||
|
||||
void disable();
|
||||
|
||||
void updateRange(const osg::Vec3f range);
|
||||
|
||||
private:
|
||||
osg::Group* mSkyNode;
|
||||
osg::Group* mSceneNode;
|
||||
osg::Group* mRootNode;
|
||||
osg::ref_ptr<osg::Camera> mCamera;
|
||||
osg::ref_ptr<osg::Camera> mSceneCamera;
|
||||
osg::ref_ptr<osg::Texture2D> mDepthTexture;
|
||||
osg::Vec3f mRange;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -586,8 +586,8 @@ namespace MWRender
|
||||
|
||||
mFog = std::make_unique<FogManager>();
|
||||
|
||||
mSky = std::make_unique<SkyManager>(sceneRoot, resourceSystem->getSceneManager(), mSkyBlending);
|
||||
mSky->setCamera(mViewer->getCamera());
|
||||
mSky = std::make_unique<SkyManager>(
|
||||
sceneRoot, mRootNode, mViewer->getCamera(), resourceSystem->getSceneManager(), mSkyBlending);
|
||||
if (mSkyBlending)
|
||||
{
|
||||
int skyTextureUnit = mResourceSystem->getSceneManager()->getShaderManager().reserveGlobalTextureUnits(
|
||||
@ -771,9 +771,11 @@ namespace MWRender
|
||||
setAmbientColour(ambient);
|
||||
|
||||
osg::Vec4f diffuse = SceneUtil::colourFromRGB(cell->mAmbi.mSunlight);
|
||||
mSunLight->setDiffuse(diffuse);
|
||||
mSunLight->setSpecular(diffuse);
|
||||
mSunLight->setPosition(osg::Vec4f(-0.15f, 0.15f, 1.f, 0.f));
|
||||
setSunColour(diffuse, diffuse, 1.f);
|
||||
|
||||
const osg::Vec4f interiorSunPos = osg::Vec4f(-0.15f, 0.15f, 1.f, 0.f);
|
||||
mPostProcessor->getStateUpdater()->setSunPos(interiorSunPos, false);
|
||||
mSunLight->setPosition(interiorSunPos);
|
||||
}
|
||||
|
||||
void RenderingManager::setSunColour(const osg::Vec4f& diffuse, const osg::Vec4f& specular, float sunVis)
|
||||
|
@ -228,9 +228,10 @@ namespace
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager, bool enableSkyRTT)
|
||||
SkyManager::SkyManager(osg::Group* parentNode, osg::Group* rootNode, osg::Camera* camera,
|
||||
Resource::SceneManager* sceneManager, bool enableSkyRTT)
|
||||
: mSceneManager(sceneManager)
|
||||
, mCamera(nullptr)
|
||||
, mCamera(camera)
|
||||
, mAtmosphereNightRoll(0.f)
|
||||
, mCreated(false)
|
||||
, mIsStorm(false)
|
||||
@ -289,6 +290,8 @@ namespace MWRender
|
||||
mRootNode->setNodeMask(Mask_Sky);
|
||||
mRootNode->addChild(mEarlyRenderBinRoot);
|
||||
mUnderwaterSwitch = new UnderwaterSwitchCallback(skyroot);
|
||||
|
||||
mPrecipitationOccluder = std::make_unique<PrecipitationOccluder>(skyroot, parentNode, rootNode, camera);
|
||||
}
|
||||
|
||||
void SkyManager::create()
|
||||
@ -382,11 +385,6 @@ namespace MWRender
|
||||
mCreated = true;
|
||||
}
|
||||
|
||||
void SkyManager::setCamera(osg::Camera* camera)
|
||||
{
|
||||
mCamera = camera;
|
||||
}
|
||||
|
||||
void SkyManager::createRain()
|
||||
{
|
||||
if (mRainNode)
|
||||
@ -466,9 +464,11 @@ namespace MWRender
|
||||
mRainNode->setNodeMask(Mask_WeatherParticles);
|
||||
|
||||
mRainParticleSystem->setUserValue("simpleLighting", true);
|
||||
mRainParticleSystem->setUserValue("particleOcclusion", true);
|
||||
mSceneManager->recreateShaders(mRainNode);
|
||||
|
||||
mRootNode->addChild(mRainNode);
|
||||
mPrecipitationOccluder->enable();
|
||||
}
|
||||
|
||||
void SkyManager::destroyRain()
|
||||
@ -482,6 +482,7 @@ namespace MWRender
|
||||
mCounter = nullptr;
|
||||
mRainParticleSystem = nullptr;
|
||||
mRainShooter = nullptr;
|
||||
mPrecipitationOccluder->disable();
|
||||
}
|
||||
|
||||
SkyManager::~SkyManager()
|
||||
@ -563,6 +564,7 @@ namespace MWRender
|
||||
* osg::DegreesToRadians(360.f) / (3600 * 96.f);
|
||||
if (mAtmosphereNightNode->getNodeMask() != 0)
|
||||
mAtmosphereNightNode->setAttitude(osg::Quat(mAtmosphereNightRoll, osg::Vec3f(0, 0, 1)));
|
||||
mPrecipitationOccluder->update();
|
||||
}
|
||||
|
||||
void SkyManager::setEnabled(bool enabled)
|
||||
@ -606,6 +608,7 @@ namespace MWRender
|
||||
mPlacer->setZRange(-rainRange.z() / 2, rainRange.z() / 2);
|
||||
|
||||
mCounter->setNumberOfParticlesPerSecondToCreate(mRainMaxRaindrops / mRainEntranceSpeed * 20);
|
||||
mPrecipitationOccluder->updateRange(rainRange);
|
||||
}
|
||||
}
|
||||
|
||||
@ -671,6 +674,10 @@ namespace MWRender
|
||||
mRootNode->removeChild(mParticleNode);
|
||||
mParticleNode = nullptr;
|
||||
}
|
||||
if (mRainEffect.empty())
|
||||
{
|
||||
mPrecipitationOccluder->disable();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -693,6 +700,8 @@ namespace MWRender
|
||||
SceneUtil::FindByClassVisitor findPSVisitor("ParticleSystem");
|
||||
mParticleEffect->accept(findPSVisitor);
|
||||
|
||||
const osg::Vec3 defaultWrapRange = osg::Vec3(1024, 1024, 800);
|
||||
|
||||
for (unsigned int i = 0; i < findPSVisitor.mFoundNodes.size(); ++i)
|
||||
{
|
||||
osgParticle::ParticleSystem* ps
|
||||
@ -700,7 +709,7 @@ namespace MWRender
|
||||
|
||||
osg::ref_ptr<osgParticle::ModularProgram> program = new osgParticle::ModularProgram;
|
||||
if (!mIsStorm)
|
||||
program->addOperator(new WrapAroundOperator(mCamera, osg::Vec3(1024, 1024, 800)));
|
||||
program->addOperator(new WrapAroundOperator(mCamera, defaultWrapRange));
|
||||
program->addOperator(new WeatherAlphaOperator(mPrecipitationAlpha, false));
|
||||
program->setParticleSystem(ps);
|
||||
mParticleNode->addChild(program);
|
||||
@ -713,9 +722,16 @@ namespace MWRender
|
||||
}
|
||||
|
||||
ps->setUserValue("simpleLighting", true);
|
||||
ps->setUserValue("particleOcclusion", true);
|
||||
}
|
||||
|
||||
mSceneManager->recreateShaders(mParticleNode);
|
||||
|
||||
if (mCurrentParticleEffect == "meshes\\snow.nif")
|
||||
{
|
||||
mPrecipitationOccluder->enable();
|
||||
mPrecipitationOccluder->updateRange(defaultWrapRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <osg/Vec4f>
|
||||
#include <osg/ref_ptr>
|
||||
|
||||
#include "precipitationocclusion.hpp"
|
||||
#include "skyutil.hpp"
|
||||
|
||||
namespace osg
|
||||
@ -43,7 +44,8 @@ namespace MWRender
|
||||
class SkyManager
|
||||
{
|
||||
public:
|
||||
SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager, bool enableSkyRTT);
|
||||
SkyManager(osg::Group* parentNode, osg::Group* rootNode, osg::Camera* camera,
|
||||
Resource::SceneManager* sceneManager, bool enableSkyRTT);
|
||||
~SkyManager();
|
||||
|
||||
void update(float duration);
|
||||
@ -98,8 +100,6 @@ namespace MWRender
|
||||
|
||||
void listAssetsToPreload(std::vector<std::string>& models, std::vector<std::string>& textures);
|
||||
|
||||
void setCamera(osg::Camera* camera);
|
||||
|
||||
float getBaseWindSpeed() const;
|
||||
|
||||
void setSunglare(bool enabled);
|
||||
@ -151,6 +151,8 @@ namespace MWRender
|
||||
osg::ref_ptr<RainCounter> mCounter;
|
||||
osg::ref_ptr<RainShooter> mRainShooter;
|
||||
|
||||
std::unique_ptr<PrecipitationOccluder> mPrecipitationOccluder;
|
||||
|
||||
bool mCreated;
|
||||
|
||||
bool mIsStorm;
|
||||
|
@ -1,9 +1,14 @@
|
||||
#include "esmloader.hpp"
|
||||
#include "esmstore.hpp"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <components/esm/format.hpp>
|
||||
#include <components/esm3/esmreader.hpp>
|
||||
#include <components/esm3/readerscache.hpp>
|
||||
#include <components/esm4/reader.hpp>
|
||||
#include <components/files/conversion.hpp>
|
||||
#include <components/files/openfile.hpp>
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
@ -21,28 +26,47 @@ namespace MWWorld
|
||||
|
||||
void EsmLoader::load(const std::filesystem::path& filepath, int& index, Loading::Listener* listener)
|
||||
{
|
||||
const ESM::ReadersCache::BusyItem reader = mReaders.get(static_cast<std::size_t>(index));
|
||||
|
||||
reader->setEncoder(mEncoder);
|
||||
reader->setIndex(index);
|
||||
reader->open(filepath);
|
||||
reader->resolveParentFileIndices(mReaders);
|
||||
auto stream = Files::openBinaryInputFileStream(filepath);
|
||||
const ESM::Format format = ESM::readFormat(*stream);
|
||||
stream->seekg(0);
|
||||
|
||||
assert(reader->getGameFiles().size() == reader->getParentFileIndices().size());
|
||||
for (std::size_t i = 0, n = reader->getParentFileIndices().size(); i < n; ++i)
|
||||
if (i == static_cast<std::size_t>(reader->getIndex()))
|
||||
throw std::runtime_error("File " + Files::pathToUnicodeString(reader->getName()) + " asks for parent file "
|
||||
switch (format)
|
||||
{
|
||||
case ESM::Format::Tes3:
|
||||
{
|
||||
const ESM::ReadersCache::BusyItem reader = mReaders.get(static_cast<std::size_t>(index));
|
||||
reader->setEncoder(mEncoder);
|
||||
reader->setIndex(index);
|
||||
reader->open(filepath);
|
||||
reader->resolveParentFileIndices(mReaders);
|
||||
|
||||
assert(reader->getGameFiles().size() == reader->getParentFileIndices().size());
|
||||
for (std::size_t i = 0, n = reader->getParentFileIndices().size(); i < n; ++i)
|
||||
if (i == static_cast<std::size_t>(reader->getIndex()))
|
||||
throw std::runtime_error("File " + Files::pathToUnicodeString(reader->getName()) + " asks for parent file "
|
||||
+ reader->getGameFiles()[i].name
|
||||
+ ", but it is not available or has been loaded in the wrong order. "
|
||||
"Please run the launcher to fix this issue.");
|
||||
|
||||
mESMVersions[index] = reader->getVer();
|
||||
mStore.load(*reader, listener, mDialogue);
|
||||
mESMVersions[index] = reader->getVer();
|
||||
mStore.load(*reader, listener, mDialogue);
|
||||
|
||||
if (!mMasterFileFormat.has_value()
|
||||
&& (Misc::StringUtils::ciEndsWith(reader->getName().u8string(), u8".esm")
|
||||
|| Misc::StringUtils::ciEndsWith(reader->getName().u8string(), u8".omwgame")))
|
||||
mMasterFileFormat = reader->getFormat();
|
||||
if (!mMasterFileFormat.has_value()
|
||||
&& (Misc::StringUtils::ciEndsWith(reader->getName().u8string(), u8".esm")
|
||||
|| Misc::StringUtils::ciEndsWith(reader->getName().u8string(), u8".omwgame")))
|
||||
mMasterFileFormat = reader->getFormat();
|
||||
break;
|
||||
}
|
||||
case ESM::Format::Tes4:
|
||||
{
|
||||
ESM4::Reader readerESM4(std::move(stream), filepath);
|
||||
auto statelessEncoder = mEncoder->getStatelessEncoder();
|
||||
readerESM4.setEncoder(&statelessEncoder);
|
||||
mStore.loadESM4(readerESM4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace MWWorld */
|
||||
|
@ -14,6 +14,11 @@
|
||||
#include <components/misc/algorithm.hpp>
|
||||
|
||||
#include <components/esm4/common.hpp>
|
||||
#include <components/esm4/loadcell.hpp>
|
||||
#include <components/esm4/loadrefr.hpp>
|
||||
#include <components/esm4/loadstat.hpp>
|
||||
#include <components/esm4/reader.hpp>
|
||||
#include <components/esm4/readerutils.hpp>
|
||||
#include <components/esmloader/load.hpp>
|
||||
|
||||
#include "../mwmechanics/spelllist.hpp"
|
||||
@ -180,6 +185,35 @@ namespace MWWorld
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool typedReadRecordESM4(ESM4::Reader& reader, Store<T>& store)
|
||||
{
|
||||
auto recordType = static_cast<ESM4::RecordTypes>(reader.hdr().record.typeId);
|
||||
|
||||
ESM::RecNameInts esm4RecName = static_cast<ESM::RecNameInts>(ESM::esm4Recname(recordType));
|
||||
if constexpr (std::is_convertible_v<Store<T>*, DynamicStore*> && HasRecordId<T>::value)
|
||||
{
|
||||
if constexpr (ESM::isESM4Rec(T::sRecordId))
|
||||
{
|
||||
if (T::sRecordId == esm4RecName)
|
||||
{
|
||||
reader.getRecordData();
|
||||
T value;
|
||||
value.load(reader);
|
||||
store.insertStatic(value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool readRecord(ESM4::Reader& reader, ESMStore& store)
|
||||
{
|
||||
return std::apply([&reader](auto&... x) { return (ESMStoreImp::typedReadRecordESM4(reader, x) || ...); },
|
||||
store.mStoreImp->mStores);
|
||||
}
|
||||
};
|
||||
|
||||
int ESMStore::find(const ESM::RefId& id) const
|
||||
@ -338,6 +372,12 @@ namespace MWWorld
|
||||
}
|
||||
}
|
||||
|
||||
void ESMStore::loadESM4(ESM4::Reader& reader)
|
||||
{
|
||||
auto visitorRec = [this](ESM4::Reader& reader) { return ESMStoreImp::readRecord(reader, *this); };
|
||||
ESM4::ReaderUtils::readAll(reader, visitorRec, [](ESM4::Reader&) {});
|
||||
}
|
||||
|
||||
void ESMStore::setIdType(const ESM::RefId& id, ESM::RecNameInts type)
|
||||
{
|
||||
mStoreImp->mIds[id] = type;
|
||||
|
@ -24,6 +24,14 @@ namespace MWMechanics
|
||||
class SpellList;
|
||||
}
|
||||
|
||||
namespace ESM4
|
||||
{
|
||||
class Reader;
|
||||
struct Static;
|
||||
struct Cell;
|
||||
struct Reference;
|
||||
}
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
class ReadersCache;
|
||||
@ -78,7 +86,7 @@ namespace MWWorld
|
||||
class ESMStore
|
||||
{
|
||||
friend struct ESMStoreImp; // This allows StoreImp to extend esmstore without beeing included everywhere
|
||||
|
||||
public:
|
||||
using StoreTuple = std::tuple<Store<ESM::Activator>, Store<ESM::Potion>, Store<ESM::Apparatus>,
|
||||
Store<ESM::Armor>, Store<ESM::BodyPart>, Store<ESM::Book>, Store<ESM::BirthSign>, Store<ESM::Class>,
|
||||
Store<ESM::Clothing>, Store<ESM::Container>, Store<ESM::Creature>, Store<ESM::Dialogue>, Store<ESM::Door>,
|
||||
@ -95,8 +103,11 @@ namespace MWWorld
|
||||
Store<ESM::MagicEffect>, Store<ESM::Skill>,
|
||||
|
||||
// Special entry which is hardcoded and not loaded from an ESM
|
||||
Store<ESM::Attribute>>;
|
||||
Store<ESM::Attribute>,
|
||||
|
||||
Store<ESM4::Static>, Store<ESM4::Cell>, Store<ESM4::Reference>>;
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
static constexpr std::size_t getTypeIndex()
|
||||
{
|
||||
@ -162,6 +173,7 @@ namespace MWWorld
|
||||
void validateDynamic();
|
||||
|
||||
void load(ESM::ESMReader& esm, Loading::Listener* listener, ESM::Dialogue*& dialogue);
|
||||
void loadESM4(ESM4::Reader& esm);
|
||||
|
||||
template <class T>
|
||||
const Store<T>& get() const
|
||||
@ -252,6 +264,16 @@ namespace MWWorld
|
||||
|
||||
template <>
|
||||
const ESM::NPC* ESMStore::insert<ESM::NPC>(const ESM::NPC& npc);
|
||||
|
||||
template <class T, class = std::void_t<>>
|
||||
struct HasRecordId : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct HasRecordId<T, std::void_t<decltype(T::sRecordId)>> : std::true_type
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,18 +1,19 @@
|
||||
#include "store.hpp"
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
|
||||
#include <components/esm/records.hpp>
|
||||
#include <components/esm3/esmreader.hpp>
|
||||
#include <components/esm3/esmwriter.hpp>
|
||||
|
||||
#include <components/loadinglistener/loadinglistener.hpp>
|
||||
#include <components/misc/rng.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/esm/records.hpp>
|
||||
#include <components/esm3/esmreader.hpp>
|
||||
#include <components/esm3/esmwriter.hpp>
|
||||
#include <components/esm4/loadcell.hpp>
|
||||
#include <components/esm4/loadrefr.hpp>
|
||||
#include <components/esm4/loadstat.hpp>
|
||||
#include <components/loadinglistener/loadinglistener.hpp>
|
||||
#include <components/misc/rng.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
// TODO: Switch to C++23 to get a working version of std::unordered_map::erase
|
||||
@ -161,7 +162,15 @@ namespace MWWorld
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
std::stringstream msg;
|
||||
msg << T::getRecordType() << " '" << id << "' not found";
|
||||
if constexpr (!ESM::isESM4Rec(T::sRecordId))
|
||||
{
|
||||
msg << T::getRecordType();
|
||||
}
|
||||
else
|
||||
{
|
||||
msg << "ESM::REC_" << getRecNameString(T::sRecordId).toStringView();
|
||||
}
|
||||
msg << " '" << id << "' not found";
|
||||
throw std::runtime_error(msg.str());
|
||||
}
|
||||
return ptr;
|
||||
@ -171,8 +180,10 @@ namespace MWWorld
|
||||
{
|
||||
T record;
|
||||
bool isDeleted = false;
|
||||
|
||||
record.load(esm, isDeleted);
|
||||
if constexpr (!ESM::isESM4Rec(T::sRecordId))
|
||||
{
|
||||
record.load(esm, isDeleted);
|
||||
}
|
||||
|
||||
std::pair<typename Static::iterator, bool> inserted = mStatic.insert_or_assign(record.mId, record);
|
||||
if (inserted.second)
|
||||
@ -292,9 +303,12 @@ namespace MWWorld
|
||||
{
|
||||
for (typename Dynamic::const_iterator iter(mDynamic.begin()); iter != mDynamic.end(); ++iter)
|
||||
{
|
||||
writer.startRecord(T::sRecordId);
|
||||
iter->second.save(writer);
|
||||
writer.endRecord(T::sRecordId);
|
||||
if constexpr (!ESM::isESM4Rec(T::sRecordId))
|
||||
{
|
||||
writer.startRecord(T::sRecordId);
|
||||
iter->second.save(writer);
|
||||
writer.endRecord(T::sRecordId);
|
||||
}
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
@ -302,8 +316,10 @@ namespace MWWorld
|
||||
{
|
||||
T record;
|
||||
bool isDeleted = false;
|
||||
|
||||
record.load(reader, isDeleted);
|
||||
if constexpr (!ESM::isESM4Rec(T::sRecordId))
|
||||
{
|
||||
record.load(reader, isDeleted);
|
||||
}
|
||||
insert(record, overrideOnly);
|
||||
|
||||
return RecordId(record.mId, isDeleted);
|
||||
@ -1152,6 +1168,20 @@ namespace MWWorld
|
||||
|
||||
return mKeywordSearch;
|
||||
}
|
||||
|
||||
ESM::FixedString<6> getRecNameString(ESM::RecNameInts recName)
|
||||
{
|
||||
ESM::FixedString<6> name;
|
||||
name.assign("");
|
||||
ESM::NAME fourCCName(recName & ~ESM::sEsm4RecnameFlag);
|
||||
for (int i = 0; i < 4; i++)
|
||||
name.mData[i] = fourCCName.mData[i];
|
||||
if (ESM::isESM4Rec(recName))
|
||||
{
|
||||
name.mData[4] = '4';
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
template class MWWorld::TypedDynamicStore<ESM::Activator>;
|
||||
@ -1196,3 +1226,7 @@ template class MWWorld::TypedDynamicStore<ESM::Spell>;
|
||||
template class MWWorld::TypedDynamicStore<ESM::StartScript>;
|
||||
template class MWWorld::TypedDynamicStore<ESM::Static>;
|
||||
template class MWWorld::TypedDynamicStore<ESM::Weapon>;
|
||||
|
||||
template class MWWorld::TypedDynamicStore<ESM4::Static>;
|
||||
template class MWWorld::TypedDynamicStore<ESM4::Reference>;
|
||||
template class MWWorld::TypedDynamicStore<ESM4::Cell>;
|
||||
|
@ -517,6 +517,8 @@ namespace MWWorld
|
||||
const MWDialogue::KeywordSearch<std::string, int>& getDialogIdKeywordSearch() const;
|
||||
};
|
||||
|
||||
ESM::FixedString<6> getRecNameString(ESM::RecNameInts recName);
|
||||
|
||||
} // end namespace
|
||||
|
||||
#endif
|
||||
|
@ -2,142 +2,187 @@
|
||||
#include "components/esm/esmcommon.hpp"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(EsmFixedString, operator__eq_ne)
|
||||
namespace
|
||||
{
|
||||
TEST(EsmFixedString, operator__eq_ne)
|
||||
{
|
||||
SCOPED_TRACE("asdc == asdc");
|
||||
constexpr ESM::NAME name("asdc");
|
||||
char s[4] = { 'a', 's', 'd', 'c' };
|
||||
std::string ss(s, 4);
|
||||
{
|
||||
SCOPED_TRACE("asdc == asdc");
|
||||
constexpr ESM::NAME name("asdc");
|
||||
char s[4] = { 'a', 's', 'd', 'c' };
|
||||
std::string ss(s, 4);
|
||||
|
||||
EXPECT_TRUE(name == s);
|
||||
EXPECT_TRUE(name == ss.c_str());
|
||||
EXPECT_TRUE(name == ss);
|
||||
EXPECT_TRUE(name == s);
|
||||
EXPECT_TRUE(name == ss.c_str());
|
||||
EXPECT_TRUE(name == ss);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("asdc == asdcx");
|
||||
constexpr ESM::NAME name("asdc");
|
||||
char s[5] = { 'a', 's', 'd', 'c', 'x' };
|
||||
std::string ss(s, 5);
|
||||
|
||||
EXPECT_TRUE(name != s);
|
||||
EXPECT_TRUE(name != ss.c_str());
|
||||
EXPECT_TRUE(name != ss);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("asdc == asdc[NULL]");
|
||||
const ESM::NAME name("asdc");
|
||||
char s[5] = { 'a', 's', 'd', 'c', '\0' };
|
||||
std::string ss(s, 5);
|
||||
|
||||
EXPECT_TRUE(name == s);
|
||||
EXPECT_TRUE(name == ss.c_str());
|
||||
EXPECT_TRUE(name == ss);
|
||||
}
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("asdc == asdcx");
|
||||
constexpr ESM::NAME name("asdc");
|
||||
char s[5] = { 'a', 's', 'd', 'c', 'x' };
|
||||
std::string ss(s, 5);
|
||||
|
||||
EXPECT_TRUE(name != s);
|
||||
EXPECT_TRUE(name != ss.c_str());
|
||||
EXPECT_TRUE(name != ss);
|
||||
TEST(EsmFixedString, operator__eq_ne_const)
|
||||
{
|
||||
{
|
||||
SCOPED_TRACE("asdc == asdc (const)");
|
||||
constexpr ESM::NAME name("asdc");
|
||||
const char s[4] = { 'a', 's', 'd', 'c' };
|
||||
std::string ss(s, 4);
|
||||
|
||||
EXPECT_TRUE(name == s);
|
||||
EXPECT_TRUE(name == ss.c_str());
|
||||
EXPECT_TRUE(name == ss);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("asdc == asdcx (const)");
|
||||
constexpr ESM::NAME name("asdc");
|
||||
const char s[5] = { 'a', 's', 'd', 'c', 'x' };
|
||||
std::string ss(s, 5);
|
||||
|
||||
EXPECT_TRUE(name != s);
|
||||
EXPECT_TRUE(name != ss.c_str());
|
||||
EXPECT_TRUE(name != ss);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("asdc == asdc[NULL] (const)");
|
||||
constexpr ESM::NAME name("asdc");
|
||||
const char s[5] = { 'a', 's', 'd', 'c', '\0' };
|
||||
std::string ss(s, 5);
|
||||
|
||||
EXPECT_TRUE(name == s);
|
||||
EXPECT_TRUE(name == ss.c_str());
|
||||
EXPECT_TRUE(name == ss);
|
||||
}
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("asdc == asdc[NULL]");
|
||||
const ESM::NAME name("asdc");
|
||||
char s[5] = { 'a', 's', 'd', 'c', '\0' };
|
||||
std::string ss(s, 5);
|
||||
|
||||
EXPECT_TRUE(name == s);
|
||||
EXPECT_TRUE(name == ss.c_str());
|
||||
EXPECT_TRUE(name == ss);
|
||||
TEST(EsmFixedString, empty_strings)
|
||||
{
|
||||
{
|
||||
SCOPED_TRACE("4 bytes");
|
||||
ESM::NAME empty = ESM::NAME();
|
||||
EXPECT_TRUE(empty == "");
|
||||
EXPECT_TRUE(empty == static_cast<uint32_t>(0));
|
||||
EXPECT_TRUE(empty != "some string");
|
||||
EXPECT_TRUE(empty != static_cast<uint32_t>(42));
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("32 bytes");
|
||||
ESM::NAME32 empty = ESM::NAME32();
|
||||
EXPECT_TRUE(empty == "");
|
||||
EXPECT_TRUE(empty != "some string");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, assign_should_zero_untouched_bytes_for_4)
|
||||
{
|
||||
ESM::NAME value;
|
||||
value = static_cast<uint32_t>(0xFFFFFFFFu);
|
||||
value.assign(std::string(1, 'a'));
|
||||
EXPECT_EQ(value, static_cast<uint32_t>('a')) << value.toInt();
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, assign_should_only_truncate_for_4)
|
||||
{
|
||||
ESM::NAME value;
|
||||
value.assign(std::string(5, 'a'));
|
||||
EXPECT_EQ(value, std::string(4, 'a'));
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, assign_should_truncate_and_set_last_element_to_zero)
|
||||
{
|
||||
ESM::FixedString<17> value;
|
||||
value.assign(std::string(20, 'a'));
|
||||
EXPECT_EQ(value, std::string(16, 'a'));
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, assign_should_truncate_and_set_last_element_to_zero_for_32)
|
||||
{
|
||||
ESM::NAME32 value;
|
||||
value.assign(std::string(33, 'a'));
|
||||
EXPECT_EQ(value, std::string(31, 'a'));
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, assign_should_truncate_and_set_last_element_to_zero_for_64)
|
||||
{
|
||||
ESM::NAME64 value;
|
||||
value.assign(std::string(65, 'a'));
|
||||
EXPECT_EQ(value, std::string(63, 'a'));
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, assignment_operator_is_supported_for_uint32)
|
||||
{
|
||||
ESM::NAME value;
|
||||
value = static_cast<uint32_t>(0xFEDCBA98u);
|
||||
EXPECT_EQ(value, static_cast<uint32_t>(0xFEDCBA98u)) << value.toInt();
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, construction_from_uint32_is_supported)
|
||||
{
|
||||
constexpr ESM::NAME value(0xFEDCBA98u);
|
||||
EXPECT_EQ(value, static_cast<std::uint32_t>(0xFEDCBA98u)) << value.toInt();
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, construction_from_RecNameInts_is_supported)
|
||||
{
|
||||
constexpr ESM::NAME value(ESM::RecNameInts::REC_ACTI);
|
||||
EXPECT_EQ(value, static_cast<std::uint32_t>(ESM::RecNameInts::REC_ACTI)) << value.toInt();
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, equality_operator_for_not_convertible_to_uint32_with_string_literal)
|
||||
{
|
||||
const ESM::FixedString<5> value("abcd");
|
||||
EXPECT_EQ(value, "abcd");
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, equality_operator_for_not_convertible_to_uint32_with_fixed_size_char_array)
|
||||
{
|
||||
const ESM::FixedString<5> value("abcd");
|
||||
const char other[5] = { 'a', 'b', 'c', 'd', '\0' };
|
||||
EXPECT_EQ(value, other);
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, equality_operator_for_not_convertible_to_uint32_with_const_char_pointer)
|
||||
{
|
||||
const ESM::FixedString<5> value("abcd");
|
||||
const char other[5] = { 'a', 'b', 'c', 'd', '\0' };
|
||||
EXPECT_EQ(value, static_cast<const char*>(other));
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, equality_operator_for_not_convertible_to_uint32_with_string)
|
||||
{
|
||||
const ESM::FixedString<5> value("abcd");
|
||||
EXPECT_EQ(value, std::string("abcd"));
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, equality_operator_for_not_convertible_to_uint32_with_string_view)
|
||||
{
|
||||
const ESM::FixedString<5> value("abcd");
|
||||
const std::string other("abcd");
|
||||
EXPECT_EQ(value, std::string_view(other));
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, equality_operator_should_not_get_out_of_bounds)
|
||||
{
|
||||
ESM::FixedString<5> value;
|
||||
const char other[5] = { 'a', 'b', 'c', 'd', 'e' };
|
||||
std::memcpy(value.mData, other, sizeof(other));
|
||||
EXPECT_EQ(value, static_cast<const char*>(other));
|
||||
}
|
||||
}
|
||||
TEST(EsmFixedString, operator__eq_ne_const)
|
||||
{
|
||||
{
|
||||
SCOPED_TRACE("asdc == asdc (const)");
|
||||
constexpr ESM::NAME name("asdc");
|
||||
const char s[4] = { 'a', 's', 'd', 'c' };
|
||||
std::string ss(s, 4);
|
||||
|
||||
EXPECT_TRUE(name == s);
|
||||
EXPECT_TRUE(name == ss.c_str());
|
||||
EXPECT_TRUE(name == ss);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("asdc == asdcx (const)");
|
||||
constexpr ESM::NAME name("asdc");
|
||||
const char s[5] = { 'a', 's', 'd', 'c', 'x' };
|
||||
std::string ss(s, 5);
|
||||
|
||||
EXPECT_TRUE(name != s);
|
||||
EXPECT_TRUE(name != ss.c_str());
|
||||
EXPECT_TRUE(name != ss);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("asdc == asdc[NULL] (const)");
|
||||
constexpr ESM::NAME name("asdc");
|
||||
const char s[5] = { 'a', 's', 'd', 'c', '\0' };
|
||||
std::string ss(s, 5);
|
||||
|
||||
EXPECT_TRUE(name == s);
|
||||
EXPECT_TRUE(name == ss.c_str());
|
||||
EXPECT_TRUE(name == ss);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, empty_strings)
|
||||
{
|
||||
{
|
||||
SCOPED_TRACE("4 bytes");
|
||||
ESM::NAME empty = ESM::NAME();
|
||||
EXPECT_TRUE(empty == "");
|
||||
EXPECT_TRUE(empty == static_cast<uint32_t>(0));
|
||||
EXPECT_TRUE(empty != "some string");
|
||||
EXPECT_TRUE(empty != static_cast<uint32_t>(42));
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("32 bytes");
|
||||
ESM::NAME32 empty = ESM::NAME32();
|
||||
EXPECT_TRUE(empty == "");
|
||||
EXPECT_TRUE(empty != "some string");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, assign_should_zero_untouched_bytes_for_4)
|
||||
{
|
||||
ESM::NAME value;
|
||||
value = static_cast<uint32_t>(0xFFFFFFFFu);
|
||||
value.assign(std::string(1, 'a'));
|
||||
EXPECT_EQ(value, static_cast<uint32_t>('a')) << value.toInt();
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, assign_should_only_truncate_for_4)
|
||||
{
|
||||
ESM::NAME value;
|
||||
value.assign(std::string(5, 'a'));
|
||||
EXPECT_EQ(value, std::string(4, 'a'));
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, assign_should_truncate_and_set_last_element_to_zero)
|
||||
{
|
||||
ESM::FixedString<17> value;
|
||||
value.assign(std::string(20, 'a'));
|
||||
EXPECT_EQ(value, std::string(16, 'a'));
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, assign_should_truncate_and_set_last_element_to_zero_for_32)
|
||||
{
|
||||
ESM::NAME32 value;
|
||||
value.assign(std::string(33, 'a'));
|
||||
EXPECT_EQ(value, std::string(31, 'a'));
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, assign_should_truncate_and_set_last_element_to_zero_for_64)
|
||||
{
|
||||
ESM::NAME64 value;
|
||||
value.assign(std::string(65, 'a'));
|
||||
EXPECT_EQ(value, std::string(63, 'a'));
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, assignment_operator_is_supported_for_uint32)
|
||||
{
|
||||
ESM::NAME value;
|
||||
value = static_cast<uint32_t>(0xFEDCBA98u);
|
||||
EXPECT_EQ(value, static_cast<uint32_t>(0xFEDCBA98u)) << value.toInt();
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, construction_from_uint32_is_supported)
|
||||
{
|
||||
constexpr ESM::NAME value(0xFEDCBA98u);
|
||||
EXPECT_EQ(value, static_cast<std::uint32_t>(0xFEDCBA98u)) << value.toInt();
|
||||
}
|
||||
|
||||
TEST(EsmFixedString, construction_from_RecNameInts_is_supported)
|
||||
{
|
||||
constexpr ESM::NAME value(ESM::RecNameInts::REC_ACTI);
|
||||
EXPECT_EQ(value, static_cast<std::uint32_t>(ESM::RecNameInts::REC_ACTI)) << value.toInt();
|
||||
}
|
||||
|
@ -8,6 +8,12 @@
|
||||
#include <components/esm/records.hpp>
|
||||
#include <components/esm3/esmreader.hpp>
|
||||
#include <components/esm3/esmwriter.hpp>
|
||||
#include <components/esm4/common.hpp>
|
||||
#include <components/esm4/loadcell.hpp>
|
||||
#include <components/esm4/loadrefr.hpp>
|
||||
#include <components/esm4/loadstat.hpp>
|
||||
#include <components/esm4/reader.hpp>
|
||||
#include <components/esm4/readerutils.hpp>
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include <components/files/conversion.hpp>
|
||||
#include <components/loadinglistener/loadinglistener.hpp>
|
||||
@ -289,6 +295,41 @@ TEST_F(StoreTest, delete_test)
|
||||
ASSERT_TRUE(mEsmStore.get<RecordType>().getSize() == 1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static unsigned int hasSameRecordId(const MWWorld::Store<T>& store, ESM::RecNameInts RecName)
|
||||
{
|
||||
if constexpr (MWWorld::HasRecordId<T>::value)
|
||||
{
|
||||
return T::sRecordId == RecName ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void testRecNameIntCount(const MWWorld::Store<T>& store, const MWWorld::ESMStore::StoreTuple& stores)
|
||||
{
|
||||
if constexpr (MWWorld::HasRecordId<T>::value)
|
||||
{
|
||||
const unsigned int recordIdCount
|
||||
= std::apply([](auto&&... x) { return (hasSameRecordId(x, T::sRecordId) + ...); }, stores);
|
||||
ASSERT_EQ(recordIdCount, static_cast<unsigned int>(1))
|
||||
<< "The same RecNameInt is used twice ESM::REC_" << MWWorld::getRecNameString(T::sRecordId).toStringView();
|
||||
}
|
||||
}
|
||||
|
||||
static void testAllRecNameIntUnique(const MWWorld::ESMStore::StoreTuple& stores)
|
||||
{
|
||||
std::apply([&stores](auto&&... x) { (testRecNameIntCount(x, stores), ...); }, stores);
|
||||
}
|
||||
|
||||
TEST_F(StoreTest, eachRecordTypeShouldHaveUniqueRecordId)
|
||||
{
|
||||
testAllRecNameIntUnique(MWWorld::ESMStore::StoreTuple());
|
||||
}
|
||||
|
||||
/// Tests overwriting of records.
|
||||
TEST_F(StoreTest, overwrite_test)
|
||||
{
|
||||
|
@ -193,6 +193,7 @@ add_component_dir (esm4
|
||||
reader
|
||||
reference
|
||||
script
|
||||
readerutils
|
||||
)
|
||||
|
||||
add_component_dir (misc
|
||||
|
@ -276,7 +276,7 @@ namespace DetourNavigator
|
||||
const Loading::ScopedLoad load(listener);
|
||||
if (listener != nullptr)
|
||||
{
|
||||
listener->setLabel("#{Navigation:BuildingNavigationMesh}");
|
||||
listener->setLabel("#{OMWEngine:BuildingNavigationMesh}");
|
||||
listener->setProgressRange(maxProgress);
|
||||
}
|
||||
while (!mDone.wait_for(lock, std::chrono::milliseconds(20), isDone))
|
||||
|
@ -333,6 +333,11 @@ namespace ESM
|
||||
REC_MSET4 = esm4Recname(ESM4::REC_MSET) // Media Set
|
||||
};
|
||||
|
||||
constexpr bool isESM4Rec(RecNameInts RecName)
|
||||
{
|
||||
return RecName & sEsm4RecnameFlag;
|
||||
}
|
||||
|
||||
/// Common subrecords
|
||||
enum SubRecNameInts
|
||||
{
|
||||
|
@ -121,23 +121,23 @@ namespace ESM
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t capacity, class T, typename = std::enable_if_t<std::is_same_v<T, char>>>
|
||||
inline bool operator==(const FixedString<capacity>& lhs, const T* const& rhs) noexcept
|
||||
template <std::size_t capacity>
|
||||
inline bool operator==(const FixedString<capacity>& lhs, std::string_view rhs) noexcept
|
||||
{
|
||||
for (std::size_t i = 0; i < capacity; ++i)
|
||||
for (std::size_t i = 0, n = std::min(rhs.size(), capacity); i < n; ++i)
|
||||
{
|
||||
if (lhs.mData[i] != rhs[i])
|
||||
return false;
|
||||
if (lhs.mData[i] == '\0')
|
||||
return true;
|
||||
}
|
||||
return rhs[capacity] == '\0';
|
||||
return rhs.size() <= capacity || rhs[capacity] == '\0';
|
||||
}
|
||||
|
||||
template <std::size_t capacity>
|
||||
inline bool operator==(const FixedString<capacity>& lhs, const std::string& rhs) noexcept
|
||||
template <std::size_t capacity, class T, typename = std::enable_if_t<std::is_same_v<T, char>>>
|
||||
inline bool operator==(const FixedString<capacity>& lhs, const T* const& rhs) noexcept
|
||||
{
|
||||
return lhs == rhs.c_str();
|
||||
return lhs == std::string_view(rhs, capacity);
|
||||
}
|
||||
|
||||
template <std::size_t capacity, std::size_t rhsSize>
|
||||
@ -156,6 +156,12 @@ namespace ESM
|
||||
return lhs.toInt() == rhs.toInt();
|
||||
}
|
||||
|
||||
template <class T, typename = std::enable_if_t<std::is_same_v<T, char>>>
|
||||
inline bool operator==(const FixedString<4>& lhs, const T* const& rhs) noexcept
|
||||
{
|
||||
return lhs == std::string_view(rhs, 5);
|
||||
}
|
||||
|
||||
template <std::size_t capacity, class Rhs>
|
||||
inline bool operator!=(const FixedString<capacity>& lhs, const Rhs& rhs) noexcept
|
||||
{
|
||||
|
@ -29,6 +29,11 @@ namespace ESM
|
||||
return newRefId;
|
||||
}
|
||||
|
||||
RefId RefId::formIdRefId(const ESM4::FormId id)
|
||||
{
|
||||
return ESM::RefId::stringRefId(ESM4::formIdToString(id));
|
||||
}
|
||||
|
||||
bool RefId::operator==(std::string_view rhs) const
|
||||
{
|
||||
return Misc::StringUtils::ciEqual(mId, rhs);
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <components/esm4/formid.hpp>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
// RefId is used to represent an Id that identifies an ESM record. These Ids can then be used in
|
||||
@ -27,6 +29,7 @@ namespace ESM
|
||||
// RefIds that are as string in the code. For serialization, and display. Using explicit conversions make it
|
||||
// very clear where in the code we need to convert from string to RefId and Vice versa.
|
||||
static RefId stringRefId(std::string_view id);
|
||||
static RefId formIdRefId(const ESM4::FormId id);
|
||||
const std::string& getRefIdString() const { return mId; }
|
||||
|
||||
private:
|
||||
|
@ -32,12 +32,13 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <cfloat> // FLT_MAX for gcc
|
||||
#include <iostream> // FIXME: debug only
|
||||
#include <stdexcept>
|
||||
|
||||
#include <iostream> // FIXME: debug only
|
||||
|
||||
#include "reader.hpp"
|
||||
//#include "writer.hpp"
|
||||
// #include "writer.hpp"
|
||||
|
||||
#include <components/esm/refid.hpp>
|
||||
|
||||
// TODO: Try loading only EDID and XCLC (along with mFormId, mFlags and mParent)
|
||||
//
|
||||
@ -48,8 +49,9 @@
|
||||
// longer/shorter/same as loading the subrecords.
|
||||
void ESM4::Cell::load(ESM4::Reader& reader)
|
||||
{
|
||||
mFormId = reader.hdr().record.id;
|
||||
reader.adjustFormId(mFormId);
|
||||
auto formId = reader.hdr().record.id;
|
||||
reader.adjustFormId(formId);
|
||||
mId = ESM::RefId::formIdRefId(formId);
|
||||
mFlags = reader.hdr().record.flags;
|
||||
mParent = reader.currWorld();
|
||||
|
||||
@ -71,7 +73,7 @@ void ESM4::Cell::load(ESM4::Reader& reader)
|
||||
// WARN: we need to call setCurrCell (and maybe setCurrCellGrid?) again before loading
|
||||
// cell child groups if we are loading them after restoring the context
|
||||
// (may be easier to update the context before saving?)
|
||||
reader.setCurrCell(mFormId); // save for LAND (and other children) to access later
|
||||
reader.setCurrCell(formId); // save for LAND (and other children) to access later
|
||||
std::uint32_t esmVer = reader.esmVersion();
|
||||
bool isFONV = esmVer == ESM::VER_132 || esmVer == ESM::VER_133 || esmVer == ESM::VER_134;
|
||||
|
||||
|
@ -34,6 +34,9 @@
|
||||
#include "formid.hpp"
|
||||
#include "lighting.hpp"
|
||||
|
||||
#include <components/esm/defs.hpp>
|
||||
#include <components/esm/refid.hpp>
|
||||
|
||||
namespace ESM4
|
||||
{
|
||||
class Reader;
|
||||
@ -61,7 +64,7 @@ namespace ESM4
|
||||
{
|
||||
FormId mParent; // world formId (for grouping cells), from the loading sequence
|
||||
|
||||
FormId mFormId; // from the header
|
||||
ESM::RefId mId; // from the header
|
||||
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
||||
|
||||
std::string mEditorId;
|
||||
@ -95,6 +98,8 @@ namespace ESM4
|
||||
// void save(ESM4::Writer& writer) const;
|
||||
|
||||
void blank();
|
||||
|
||||
static constexpr ESM::RecNameInts sRecordId = ESM::REC_CELL4;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -30,14 +30,15 @@
|
||||
#include <stdexcept>
|
||||
|
||||
#include "reader.hpp"
|
||||
//#include "writer.hpp"
|
||||
// #include "writer.hpp"
|
||||
|
||||
void ESM4::Reference::load(ESM4::Reader& reader)
|
||||
{
|
||||
mFormId = reader.hdr().record.id;
|
||||
reader.adjustFormId(mFormId);
|
||||
auto formId = reader.hdr().record.id;
|
||||
reader.adjustFormId(formId);
|
||||
mId = ESM::RefId::formIdRefId(formId);
|
||||
mFlags = reader.hdr().record.flags;
|
||||
mParent = reader.currCell(); // NOTE: only for persistent refs?
|
||||
mParent = ESM::RefId::formIdRefId(reader.currCell()); // NOTE: only for persistent refs?
|
||||
|
||||
// TODO: Let the engine apply this? Saved games?
|
||||
// mInitiallyDisabled = ((mFlags & ESM4::Rec_Disabled) != 0) ? true : false;
|
||||
@ -60,7 +61,9 @@ void ESM4::Reference::load(ESM4::Reader& reader)
|
||||
break;
|
||||
case ESM4::SUB_NAME:
|
||||
{
|
||||
reader.getFormId(mBaseObj);
|
||||
FormId BaseId;
|
||||
reader.getFormId(BaseId);
|
||||
mBaseObj = ESM::RefId::formIdRefId(BaseId);
|
||||
#if 0
|
||||
if (mFlags & ESM4::Rec_Disabled)
|
||||
std::cout << "REFR disable at start " << formIdToString(mFormId) <<
|
||||
|
@ -31,6 +31,9 @@
|
||||
|
||||
#include "reference.hpp" // FormId, Placement, EnableParent
|
||||
|
||||
#include <components/esm/defs.hpp>
|
||||
#include <components/esm/refid.hpp>
|
||||
|
||||
namespace ESM4
|
||||
{
|
||||
class Reader;
|
||||
@ -71,15 +74,15 @@ namespace ESM4
|
||||
|
||||
struct Reference
|
||||
{
|
||||
FormId mParent; // cell FormId (currently persistent refs only), from the loading sequence
|
||||
// NOTE: for exterior cells it will be the dummy cell FormId
|
||||
ESM::RefId mParent; // cell FormId (currently persistent refs only), from the loading sequence
|
||||
// NOTE: for exterior cells it will be the dummy cell FormId
|
||||
|
||||
FormId mFormId; // from the header
|
||||
ESM::RefId mId; // from the header
|
||||
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
||||
|
||||
std::string mEditorId;
|
||||
std::string mFullName;
|
||||
FormId mBaseObj;
|
||||
ESM::RefId mBaseObj;
|
||||
|
||||
Placement mPlacement;
|
||||
float mScale = 1.0f;
|
||||
@ -110,6 +113,8 @@ namespace ESM4
|
||||
// void save(ESM4::Writer& writer) const;
|
||||
|
||||
void blank();
|
||||
|
||||
static constexpr ESM::RecNameInts sRecordId = ESM::REC_REFR4;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -30,12 +30,13 @@
|
||||
#include <stdexcept>
|
||||
|
||||
#include "reader.hpp"
|
||||
//#include "writer.hpp"
|
||||
// #include "writer.hpp"
|
||||
|
||||
void ESM4::Static::load(ESM4::Reader& reader)
|
||||
{
|
||||
mFormId = reader.hdr().record.id;
|
||||
reader.adjustFormId(mFormId);
|
||||
FormId formId = reader.hdr().record.id;
|
||||
reader.adjustFormId(formId);
|
||||
mId = ESM::RefId::formIdRefId(formId);
|
||||
mFlags = reader.hdr().record.flags;
|
||||
|
||||
while (reader.getSubRecordHeader())
|
||||
|
@ -33,6 +33,9 @@
|
||||
|
||||
#include "formid.hpp"
|
||||
|
||||
#include <components/esm/defs.hpp>
|
||||
#include <components/esm/refid.hpp>
|
||||
|
||||
namespace ESM4
|
||||
{
|
||||
class Reader;
|
||||
@ -40,7 +43,7 @@ namespace ESM4
|
||||
|
||||
struct Static
|
||||
{
|
||||
FormId mFormId; // from the header
|
||||
ESM::RefId mId; // from the header
|
||||
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
||||
|
||||
std::string mEditorId;
|
||||
@ -53,6 +56,8 @@ namespace ESM4
|
||||
// void save(ESM4::Writer& writer) const;
|
||||
|
||||
// void blank();
|
||||
|
||||
static constexpr ESM::RecNameInts sRecordId = ESM::REC_STAT4;
|
||||
};
|
||||
}
|
||||
|
||||
|
84
components/esm4/readerutils.hpp
Normal file
84
components/esm4/readerutils.hpp
Normal file
@ -0,0 +1,84 @@
|
||||
#ifndef OPENMW_COMPONENTS_ESM4_READERUTILS
|
||||
#define OPENMW_COMPONENTS_ESM4_READERUTILS
|
||||
|
||||
#include <components/esm4/reader.hpp>
|
||||
namespace ESM4
|
||||
{
|
||||
struct ReaderUtils
|
||||
{
|
||||
|
||||
/* RecordInvocable must be an invocable, takes an ESM4::Reader& as input, and outputs a boolean that indicates
|
||||
if the record was read or ignored. Will be invoked for every record
|
||||
|
||||
GroupInvocable's invocable must take a ESM4::Reader& as input, doesn't need to output anything. Will be invoked
|
||||
for every group*/
|
||||
template <typename RecordInvocable, typename GroupInvocable>
|
||||
static void readAll(ESM4::Reader& reader, RecordInvocable&& recordInvocable, GroupInvocable&& groupInvocable)
|
||||
{
|
||||
while (reader.hasMoreRecs())
|
||||
{
|
||||
reader.exitGroupCheck();
|
||||
if (!readItem(reader, recordInvocable, groupInvocable))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename RecordInvocable>
|
||||
static void readRecord(ESM4::Reader& reader, RecordInvocable&& recordInvocable)
|
||||
{
|
||||
if (!recordInvocable(reader))
|
||||
reader.skipRecordData();
|
||||
}
|
||||
|
||||
template <typename RecordInvocable, typename GroupInvocable>
|
||||
static bool readGroup(ESM4::Reader& reader, RecordInvocable&& recordInvocable, GroupInvocable&& groupInvocable)
|
||||
{
|
||||
const ESM4::RecordHeader& header = reader.hdr();
|
||||
|
||||
groupInvocable(reader);
|
||||
|
||||
switch (static_cast<ESM4::GroupType>(header.group.type))
|
||||
{
|
||||
case ESM4::Grp_RecordType:
|
||||
case ESM4::Grp_InteriorCell:
|
||||
case ESM4::Grp_InteriorSubCell:
|
||||
case ESM4::Grp_ExteriorCell:
|
||||
case ESM4::Grp_ExteriorSubCell:
|
||||
reader.enterGroup();
|
||||
return readItem(reader, recordInvocable, groupInvocable);
|
||||
case ESM4::Grp_WorldChild:
|
||||
case ESM4::Grp_CellChild:
|
||||
case ESM4::Grp_TopicChild:
|
||||
case ESM4::Grp_CellPersistentChild:
|
||||
case ESM4::Grp_CellTemporaryChild:
|
||||
case ESM4::Grp_CellVisibleDistChild:
|
||||
reader.adjustGRUPFormId();
|
||||
reader.enterGroup();
|
||||
if (!reader.hasMoreRecs())
|
||||
return false;
|
||||
return readItem(reader, recordInvocable, groupInvocable);
|
||||
}
|
||||
|
||||
reader.skipGroup();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename RecordInvocable, typename GroupInvocable>
|
||||
static bool readItem(ESM4::Reader& reader, RecordInvocable&& recordInvocable, GroupInvocable&& groupInvocable)
|
||||
{
|
||||
if (!reader.getRecordHeader() || !reader.hasMoreRecs())
|
||||
return false;
|
||||
|
||||
const ESM4::RecordHeader& header = reader.hdr();
|
||||
|
||||
if (header.record.typeId == ESM4::REC_GRUP)
|
||||
return readGroup(reader, recordInvocable, groupInvocable);
|
||||
|
||||
readRecord(reader, recordInvocable);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !OPENMW_COMPONENTS_ESM4_READERUTILS
|
@ -35,14 +35,13 @@ namespace LuaUtil
|
||||
mAPI.emplace(std::move(packageName), makeReadOnly(std::move(package)));
|
||||
}
|
||||
|
||||
bool ScriptsContainer::addCustomScript(int scriptId)
|
||||
bool ScriptsContainer::addCustomScript(int scriptId, std::string_view initData)
|
||||
{
|
||||
const ScriptsConfiguration& conf = mLua.getConfiguration();
|
||||
assert(conf.isCustomScript(scriptId));
|
||||
assert(mLua.getConfiguration().isCustomScript(scriptId));
|
||||
std::optional<sol::function> onInit, onLoad;
|
||||
bool ok = addScript(scriptId, onInit, onLoad);
|
||||
if (ok && onInit)
|
||||
callOnInit(scriptId, *onInit, conf[scriptId].mInitializationData);
|
||||
callOnInit(scriptId, *onInit, initData);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ namespace LuaUtil
|
||||
// new script, adds it to the container, and calls onInit for this script. Returns `true` if the script was
|
||||
// successfully added. The script should have CUSTOM flag. If the flag is not set, or file not found, or has
|
||||
// syntax errors, returns false. If such script already exists in the container, then also returns false.
|
||||
bool addCustomScript(int scriptId);
|
||||
bool addCustomScript(int scriptId, std::string_view initData = "");
|
||||
|
||||
bool hasScript(int scriptId) const { return mScripts.count(scriptId) != 0; }
|
||||
void removeScript(int scriptId);
|
||||
|
@ -37,4 +37,17 @@ namespace osgMyGUI
|
||||
<< separator << _line << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
MyGUI::LogLevel LogFacility::getCurrentLogLevel() const
|
||||
{
|
||||
switch (Debug::CurrentDebugLevel)
|
||||
{
|
||||
case Debug::Error:
|
||||
return MyGUI::LogLevel::Error;
|
||||
case Debug::Warning:
|
||||
return MyGUI::LogLevel::Warning;
|
||||
default:
|
||||
return MyGUI::LogLevel::Info;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,12 +47,14 @@ namespace osgMyGUI
|
||||
MyGUI::LevelLogFilter mFilter;
|
||||
MyGUI::LogSource mSource;
|
||||
|
||||
MyGUI::LogLevel getCurrentLogLevel() const;
|
||||
|
||||
public:
|
||||
LogFacility(const std::filesystem::path& output, bool console)
|
||||
: mFile(output)
|
||||
{
|
||||
mConsole.setEnabled(console);
|
||||
mFilter.setLoggingLevel(MyGUI::LogLevel::Info);
|
||||
mFilter.setLoggingLevel(getCurrentLogLevel());
|
||||
|
||||
mSource.addLogListener(&mFile);
|
||||
mSource.addLogListener(&mConsole);
|
||||
|
@ -636,6 +636,9 @@ namespace Resource
|
||||
|
||||
backToOriginTrans->addChild(newRiggeometryHolder);
|
||||
group->addChild(backToOriginTrans);
|
||||
|
||||
node->getOrCreateUserDataContainer()->addUserObject(
|
||||
new TemplateRef(newRiggeometryHolder->getGeometry(0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <components/sceneutil/morphgeometry.hpp>
|
||||
#include <components/sceneutil/riggeometry.hpp>
|
||||
#include <components/sceneutil/riggeometryosgaextension.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
#include <components/stereo/stereomanager.hpp>
|
||||
#include <components/vfs/manager.hpp>
|
||||
|
||||
@ -675,6 +676,11 @@ namespace Shader
|
||||
if (simpleLighting || dynamic_cast<osgParticle::ParticleSystem*>(&node))
|
||||
defineMap["forcePPL"] = "0";
|
||||
|
||||
bool particleOcclusion = false;
|
||||
node.getUserValue("particleOcclusion", particleOcclusion);
|
||||
defineMap["particleOcclusion"]
|
||||
= particleOcclusion && Settings::Manager::getBool("weather particle occlusion", "Shaders") ? "1" : "0";
|
||||
|
||||
if (reqs.mAlphaBlend && mSupportsNormalsRT)
|
||||
{
|
||||
if (reqs.mSoftParticles)
|
||||
|
@ -68,6 +68,8 @@ namespace ToUTF8
|
||||
/// ASCII-only string. Otherwise returns a view to the input.
|
||||
std::string_view getLegacyEnc(std::string_view input);
|
||||
|
||||
StatelessUtf8Encoder getStatelessEncoder() const { return mImpl; }
|
||||
|
||||
private:
|
||||
std::string mBuffer;
|
||||
StatelessUtf8Encoder mImpl;
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <MyGUI_Gui.h>
|
||||
#include <MyGUI_ImageBox.h>
|
||||
|
||||
#include <components/misc/strings/algorithm.hpp>
|
||||
|
||||
namespace Gui
|
||||
{
|
||||
|
||||
@ -124,6 +126,12 @@ namespace Gui
|
||||
return mItems[at];
|
||||
}
|
||||
|
||||
void MWList::sort()
|
||||
{
|
||||
// A special case for separators is not needed for now
|
||||
std::sort(mItems.begin(), mItems.end(), Misc::StringUtils::ciLess);
|
||||
}
|
||||
|
||||
void MWList::removeItem(const std::string& name)
|
||||
{
|
||||
assert(std::find(mItems.begin(), mItems.end(), name) != mItems.end());
|
||||
|
@ -35,6 +35,7 @@ namespace Gui
|
||||
*/
|
||||
void adjustSize();
|
||||
|
||||
void sort();
|
||||
void addItem(std::string_view name);
|
||||
void addSeparator(); ///< add a seperator between the current and the next item.
|
||||
void removeItem(const std::string& name);
|
||||
|
@ -49,8 +49,8 @@ pip3 install -r docs/requirements.txt
|
||||
sudo apt install luarocks
|
||||
git clone https://gitlab.com/ptmikheev/openmw-luadocumentor.git
|
||||
cd openmw-luadocumentor/luarocks
|
||||
luarocks --local pack openmwluadocumentor-0.1.1-1.rockspec
|
||||
luarocks --local install openmwluadocumentor-0.1.1-1.src.rock
|
||||
luarocks --local pack openmwluadocumentor-0.2.0-1.rockspec
|
||||
luarocks --local install openmwluadocumentor-0.2.0-1.src.rock
|
||||
```
|
||||
|
||||
**Windows**
|
||||
@ -61,8 +61,8 @@ luarocks --local install openmwluadocumentor-0.1.1-1.src.rock
|
||||
- `cd openmw-luadocumentor/luarocks`
|
||||
- open "Developer Command Prompt for VS <2017/2019>" in this directory and run:
|
||||
```bash
|
||||
luarocks --local pack openmwluadocumentor-0.1.1-1.rockspec
|
||||
luarocks --local install openmwluadocumentor-0.1.1-1.src.rock
|
||||
luarocks --local pack openmwluadocumentor-0.2.0-1.rockspec
|
||||
luarocks --local install openmwluadocumentor-0.2.0-1.src.rock
|
||||
```
|
||||
|
||||
### Generating HTML
|
||||
|
@ -59,7 +59,8 @@ Sources can be found in ``resources/vfs/openmw_aux``. In theory mods can overrid
|
||||
|
||||
.. include:: tables/aux_packages.rst
|
||||
|
||||
**Interfaces of built-in scripts**
|
||||
Interfaces of built-in scripts
|
||||
------------------------------
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 20 60
|
||||
|
@ -85,7 +85,7 @@ Let's write a simple example of a `Player script`:
|
||||
|
||||
.. code-block:: Lua
|
||||
|
||||
-- Save to my_lua_mod/example/player.lua
|
||||
-- Save to my_lua_mod/scripts/example/player.lua
|
||||
|
||||
local ui = require('openmw.ui')
|
||||
|
||||
@ -107,7 +107,7 @@ The options are:
|
||||
1. Create text file "my_lua_mod.omwscripts" with the following line:
|
||||
::
|
||||
|
||||
PLAYER: example/player.lua
|
||||
PLAYER: scripts/example/player.lua
|
||||
|
||||
2. (not implemented yet) Add the script in OpenMW CS on "Lua scripts" view and save as "my_lua_mod.omwaddon".
|
||||
|
||||
@ -122,6 +122,19 @@ Enable it in ``openmw.cfg`` the same way as any other mod:
|
||||
Now every time the player presses "X" on a keyboard, a message is shown.
|
||||
|
||||
|
||||
Lua scripts naming policy
|
||||
=========================
|
||||
|
||||
Technically scripts can be placed anywhere in the virtual file system, but we recommend to follow the naming policy and choose one of:
|
||||
|
||||
- ``scripts/<ModName>/<ScriptName>.lua``: general case.
|
||||
- ``scripts/<AuthorName>/<ModName>/<ScriptName>.lua``: if "ModName" is short and can potentially collide with other mods.
|
||||
- ``scripts/<ModName>.lua``: if it is a simple mod that consists from a single script, the script can placed to ``scripts/`` without subdirs.
|
||||
|
||||
``scripts/omw/`` is reserved for built-in scripts, don't use it in mods. Overriding built-in scripts is not recommended, prefer to adjust their behaviour via :ref:`Interfaces of built-in scripts` instead.
|
||||
|
||||
See also naming policy of :ref:`Localisation Files`.
|
||||
|
||||
Format of ``.omwscripts``
|
||||
=========================
|
||||
|
||||
@ -129,20 +142,20 @@ Format of ``.omwscripts``
|
||||
|
||||
# Lines starting with '#' are comments
|
||||
|
||||
GLOBAL: my_mod/some_global_script.lua
|
||||
GLOBAL: scripts/my_mod/some_global_script.lua
|
||||
|
||||
# Script that will be automatically attached to the player
|
||||
PLAYER: my_mod/player.lua
|
||||
PLAYER: scripts/my_mod/player.lua
|
||||
|
||||
# Local script that will be automatically attached to every NPC and every creature in the game
|
||||
NPC, CREATURE: my_mod/some_other_script.lua
|
||||
NPC, CREATURE: scripts/my_mod/some_other_script.lua
|
||||
|
||||
# Local script that can be attached to any object by a global script
|
||||
CUSTOM: my_mod/something.lua
|
||||
CUSTOM: scripts/my_mod/something.lua
|
||||
|
||||
# Local script that will be automatically attached to any Container AND can be
|
||||
# attached to any other object by a global script.
|
||||
CONTAINER, CUSTOM: my_mod/container.lua
|
||||
CONTAINER, CUSTOM: scripts/my_mod/container.lua
|
||||
|
||||
Each script is described by one line:
|
||||
``<flags>: <path to .lua file in virtual file system>``.
|
||||
|
@ -31,11 +31,26 @@ E.g. if you include ``en_US.yaml`` and ``en_GB.yaml`` localisation files, you sh
|
||||
Note that because of the fallbacks only messages which differ between variants need to be included in the country-specific localisation files.
|
||||
|
||||
Localisation Files
|
||||
--------------------------
|
||||
------------------
|
||||
|
||||
Localisation files (containing the message names and translations) should be stored in the
|
||||
VFS as files of the form ``l10n/<ContextName>/<Locale>.yaml``.
|
||||
|
||||
**Naming policy**
|
||||
|
||||
"ContextName" should be in line with :ref:`Lua scripts naming policy`:
|
||||
|
||||
- L10n files for ``scripts/<ModName>/<ScriptName>.lua`` should be placed to ``l10n/<ModName>/<Locale>.yaml``.
|
||||
- L10n files for ``scripts/<AuthorName>/<ModName>/<ScriptName>.lua`` should be placed to ``l10n/<AuthorName><ModName>/<Locale>.yaml``.
|
||||
|
||||
In most cases one mod should have only one l10n context. Don't create a new context for each single message. Really big mods with hundreds and thousands of messages can have several l10n contexts. In this case all context names should start with the name of the mod. I.e. ``<ContextName> = <ModName><Subcontext>`` (or ``<AuthorName><ModName><Subcontext>``).
|
||||
|
||||
L10n contexts with prefix "OMW" are reserved for the OpenMW itself (in particular for built-in scripts ``scripts/omw/``) and shouldn't be used in mods.
|
||||
|
||||
Built-in l10n contexts "Interface" and "Calendar" don't have the "OMW" prefix because these messages are more generic and can be reused in mods.
|
||||
|
||||
**Format**
|
||||
|
||||
Messages contents have the form of ICU MessageFormat strings.
|
||||
See `the Formatting Messages chapter of the ICU Guide <https://unicode-org.github.io/icu/userguide/format_parse/messages/>`_
|
||||
for a guide to MessageFormat, and see
|
||||
|
@ -287,3 +287,18 @@ the look of some particle systems.
|
||||
|
||||
Note that the rendering will act as if you have 'force shaders' option enabled.
|
||||
This means that shaders will be used to render all objects and the terrain.
|
||||
|
||||
weather particle occlusion
|
||||
--------------------------
|
||||
|
||||
:Type: boolean
|
||||
:Range: True/False
|
||||
:Default: False
|
||||
|
||||
Enables particle occlusion for rain and snow particle effects.
|
||||
When enabled, rain and snow will not clip through ceilings and overhangs.
|
||||
Currently this relies on an additional render pass, which may lead to a performance hit.
|
||||
|
||||
.. warning::
|
||||
This is an experimental feature that may cause visual oddities, especially when using default rain settings.
|
||||
It is recommended to at least double the rain diameter through `openmw.cfg`.`
|
||||
|
@ -20,53 +20,43 @@ set(BUILTIN_DATA_FILES
|
||||
fonts/MysticCards.omwfont
|
||||
fonts/MysticCardsFontLicense.txt
|
||||
|
||||
l10n/BuiltInShaders/de.yaml
|
||||
l10n/BuiltInShaders/en.yaml
|
||||
l10n/BuiltInShaders/ru.yaml
|
||||
l10n/BuiltInShaders/sv.yaml
|
||||
l10n/BuiltInShaders/fr.yaml
|
||||
# Month names and date formatting
|
||||
l10n/Calendar/de.yaml
|
||||
l10n/Calendar/en.yaml
|
||||
l10n/Calendar/ru.yaml
|
||||
l10n/Calendar/sv.yaml
|
||||
l10n/Calendar/fr.yaml
|
||||
l10n/DebugMenu/de.yaml
|
||||
l10n/DebugMenu/en.yaml
|
||||
l10n/DebugMenu/ru.yaml
|
||||
l10n/DebugMenu/sv.yaml
|
||||
l10n/DebugMenu/fr.yaml
|
||||
|
||||
# Generic UI messages that can be reused by mods
|
||||
l10n/Interface/de.yaml
|
||||
l10n/Interface/en.yaml
|
||||
l10n/Interface/ru.yaml
|
||||
l10n/Interface/sv.yaml
|
||||
l10n/Interface/fr.yaml
|
||||
l10n/Navigation/de.yaml
|
||||
l10n/Navigation/en.yaml
|
||||
l10n/Navigation/ru.yaml
|
||||
l10n/Navigation/sv.yaml
|
||||
l10n/Navigation/fr.yaml
|
||||
|
||||
# L10n for scripts/omw
|
||||
l10n/OMWCamera/de.yaml
|
||||
l10n/OMWCamera/en.yaml
|
||||
l10n/OMWCamera/ru.yaml
|
||||
l10n/OMWCamera/sv.yaml
|
||||
l10n/OMWCamera/fr.yaml
|
||||
l10n/OMWControls/en.yaml
|
||||
l10n/OMWControls/ru.yaml
|
||||
l10n/OMWControls/sv.yaml
|
||||
l10n/PostProcessing/de.yaml
|
||||
l10n/PostProcessing/en.yaml
|
||||
l10n/PostProcessing/ru.yaml
|
||||
l10n/PostProcessing/sv.yaml
|
||||
l10n/PostProcessing/fr.yaml
|
||||
l10n/SavegameMenu/de.yaml
|
||||
l10n/SavegameMenu/en.yaml
|
||||
l10n/SavegameMenu/ru.yaml
|
||||
l10n/SavegameMenu/sv.yaml
|
||||
l10n/SavegameMenu/fr.yaml
|
||||
l10n/SettingsMenu/de.yaml
|
||||
l10n/SettingsMenu/en.yaml
|
||||
l10n/SettingsMenu/ru.yaml
|
||||
l10n/SettingsMenu/sv.yaml
|
||||
l10n/SettingsMenu/fr.yaml
|
||||
|
||||
# L10n for OpenMW menus and non-game-specific messages
|
||||
l10n/OMWEngine/de.yaml
|
||||
l10n/OMWEngine/en.yaml
|
||||
l10n/OMWEngine/ru.yaml
|
||||
l10n/OMWEngine/sv.yaml
|
||||
l10n/OMWEngine/fr.yaml
|
||||
|
||||
# L10n for post-processing HUD and built-in shaders
|
||||
l10n/OMWShaders/de.yaml
|
||||
l10n/OMWShaders/en.yaml
|
||||
l10n/OMWShaders/ru.yaml
|
||||
l10n/OMWShaders/sv.yaml
|
||||
l10n/OMWShaders/fr.yaml
|
||||
|
||||
openmw_aux/util.lua
|
||||
openmw_aux/time.lua
|
||||
|
@ -1,7 +0,0 @@
|
||||
DisplayDepthName: "Visualisiert den Tiefenpuffer."
|
||||
DisplayDepthFactorDescription: "Bestimmt die Korrelation zwischen dem Pixeltiefenwert und seiner Ausgabefarbe. Hohe Werte führen zu einem helleren Bild."
|
||||
DisplayDepthFactorName: "Farbfaktor"
|
||||
ContrastLevelDescription: "Kontraststufe"
|
||||
ContrastLevelName: "Kontrast"
|
||||
GammaLevelDescription: "Gamma-Level"
|
||||
GammaLevelName: "Gamma"
|
@ -1,4 +0,0 @@
|
||||
DebugWindow: "Debug"
|
||||
LogViewer: "Protokollansicht"
|
||||
LuaProfiler: "Lua-Profiler"
|
||||
PhysicsProfiler: "Physik-Profiler"
|
@ -1,4 +0,0 @@
|
||||
DebugWindow: "Debug"
|
||||
LogViewer: "Log Viewer"
|
||||
LuaProfiler: "Lua Profiler"
|
||||
PhysicsProfiler: "Physics Profiler"
|
@ -1,3 +0,0 @@
|
||||
DebugWindow: "Fenêtre de débogage"
|
||||
LogViewer: "Journal"
|
||||
PhysicsProfiler: "Profileur des performances de la physique"
|
@ -1,4 +0,0 @@
|
||||
DebugWindow: "Меню отладки"
|
||||
LogViewer: "Журнал логов"
|
||||
LuaProfiler: "Профилировщик Луа"
|
||||
PhysicsProfiler: "Профилировщик физики"
|
@ -1,3 +0,0 @@
|
||||
DebugWindow: "Felsökning"
|
||||
LogViewer: "Loggvisare"
|
||||
PhysicsProfiler: "Fysikprofilerare"
|
@ -1 +0,0 @@
|
||||
BuildingNavigationMesh: "Baue Navigationsgitter"
|
@ -1 +0,0 @@
|
||||
BuildingNavigationMesh: "Building navigation mesh"
|
@ -1 +0,0 @@
|
||||
BuildingNavigationMesh: "Construction du mesh de navigation"
|
@ -1 +0,0 @@
|
||||
BuildingNavigationMesh: "Построение навигационной сетки"
|
@ -1 +0,0 @@
|
||||
BuildingNavigationMesh: "Bygger navigeringsmesh"
|
16
files/data/l10n/OMWControls/ru.yaml
Normal file
16
files/data/l10n/OMWControls/ru.yaml
Normal file
@ -0,0 +1,16 @@
|
||||
ControlsPage: "Управление OpenMW"
|
||||
ControlsPageDescription: "Дополнительные настройки, связанные с управлением игроком"
|
||||
|
||||
MovementSettings: "Движение"
|
||||
|
||||
alwaysRun: "Постоянный бег"
|
||||
alwaysRunDescription: |
|
||||
Когда эта настройка включена, по умолчанию персонаж бегает, в противном случае по умолчанию он ходит.
|
||||
Клавиша бега (по умолчанию Shift) инвертирует режим временно, а клавиша постоянного бега (Caps Lock) переключает эту настройку.
|
||||
|
||||
toggleSneak: "Переключение движения крадучись"
|
||||
toggleSneakDescription: |
|
||||
Эта настройка меняет поведение клавиши движения крадучись (по умолчанию Ctrl):
|
||||
чтобы красться, её достаточно нажать единожды для переключения положения, а не зажимать.
|
||||
Игрокам, которые много времени крадутся, может быть проще управлять персонажем, когда опция включена.
|
||||
|
@ -1,3 +1,24 @@
|
||||
# Debug window
|
||||
|
||||
DebugWindow: "Debug"
|
||||
LogViewer: "Protokollansicht"
|
||||
LuaProfiler: "Lua-Profiler"
|
||||
PhysicsProfiler: "Physik-Profiler"
|
||||
|
||||
|
||||
# Messages
|
||||
|
||||
BuildingNavigationMesh: "Baue Navigationsgitter"
|
||||
|
||||
|
||||
# Save game menu
|
||||
|
||||
SelectCharacter: "Charakterauswahl..."
|
||||
TimePlayed: "Spielzeit"
|
||||
|
||||
|
||||
# Settings menu
|
||||
|
||||
ActorsProcessingRange: "Akteur-Verarbeitungsreichweite"
|
||||
Anisotropy: "Anisotropie"
|
||||
CameraSensitivity: "Kameraempfindlichkeit"
|
@ -1,3 +1,24 @@
|
||||
# Debug window
|
||||
|
||||
DebugWindow: "Debug"
|
||||
LogViewer: "Log Viewer"
|
||||
LuaProfiler: "Lua Profiler"
|
||||
PhysicsProfiler: "Physics Profiler"
|
||||
|
||||
|
||||
# Messages
|
||||
|
||||
BuildingNavigationMesh: "Building navigation mesh"
|
||||
|
||||
|
||||
# Save game menu
|
||||
|
||||
SelectCharacter: "Select Character..."
|
||||
TimePlayed: "Time played"
|
||||
|
||||
|
||||
# Settings menu
|
||||
|
||||
ActorsProcessingRange: "Actors Processing Range"
|
||||
Anisotropy: "Anisotropy"
|
||||
CameraSensitivity: "Camera Sensitivity"
|
||||
@ -62,6 +83,6 @@ WaterShaderTextureQuality: "Texture quality"
|
||||
WindowBorder: "Window Border"
|
||||
WindowMode: "Window Mode"
|
||||
WindowModeFullscreen: "Fullscreen"
|
||||
WindowModeHint: "Hint: the Windowed Fullscreen mode\nalways uses a native screen resolution."
|
||||
WindowModeHint: "Hint: Windowed Fullscreen mode\nalways uses the native display resolution."
|
||||
WindowModeWindowed: "Windowed"
|
||||
WindowModeWindowedFullscreen: "Windowed Fullscreen"
|
@ -1,3 +1,23 @@
|
||||
# Debug window
|
||||
|
||||
DebugWindow: "Fenêtre de débogage"
|
||||
LogViewer: "Journal"
|
||||
PhysicsProfiler: "Profileur des performances de la physique"
|
||||
|
||||
|
||||
# Messages
|
||||
|
||||
BuildingNavigationMesh: "Construction du mesh de navigation"
|
||||
|
||||
|
||||
# Save game menu
|
||||
|
||||
SelectCharacter: "Sélection du personnage..."
|
||||
TimePlayed: "Temps de jeu"
|
||||
|
||||
|
||||
# Settings menu
|
||||
|
||||
ActorsProcessingRange: "Distance de traitement pour les personnages"
|
||||
Anisotropy: "Anisotropie"
|
||||
CameraSensitivity: "Sensibilité de la caméra"
|
@ -1,3 +1,24 @@
|
||||
# Debug window
|
||||
|
||||
DebugWindow: "Меню отладки"
|
||||
LogViewer: "Журнал логов"
|
||||
LuaProfiler: "Профилировщик Луа"
|
||||
PhysicsProfiler: "Профилировщик физики"
|
||||
|
||||
|
||||
# Messages
|
||||
|
||||
BuildingNavigationMesh: "Построение навигационной сетки"
|
||||
|
||||
|
||||
# Save game menu
|
||||
|
||||
SelectCharacter: "Выберите персонажа..."
|
||||
TimePlayed: "Время в игре"
|
||||
|
||||
|
||||
# Settings menu
|
||||
|
||||
ActorsProcessingRange: "Дальность обработки персонажей"
|
||||
Anisotropy: "Анизотропная фильтрация"
|
||||
CameraSensitivity: "Чувствительность камеры"
|
@ -1,3 +1,23 @@
|
||||
# Debug window
|
||||
|
||||
DebugWindow: "Felsökning"
|
||||
LogViewer: "Loggvisare"
|
||||
PhysicsProfiler: "Fysikprofilerare"
|
||||
|
||||
|
||||
# Messages
|
||||
|
||||
BuildingNavigationMesh: "Bygger navigeringsmesh"
|
||||
|
||||
|
||||
# Save game menu
|
||||
|
||||
SelectCharacter: "Välj spelfigur..."
|
||||
TimePlayed: "Speltid"
|
||||
|
||||
|
||||
# Settings menu
|
||||
|
||||
ActorsProcessingRange: "Processavstånd för figurer"
|
||||
Anisotropy: "Anisotropi"
|
||||
CameraSensitivity: "Kamerakänslighet"
|
@ -1,3 +1,5 @@
|
||||
# Post-processing HUD
|
||||
|
||||
Abovewater: "Überwasser"
|
||||
ActiveShaders: "Aktive Shader"
|
||||
Author: "Autor"
|
||||
@ -19,3 +21,14 @@ ShaderLockedDescription: "Kann nicht umgeschaltet oder verschoben werden, gesteu
|
||||
ShaderResetUniform: "r"
|
||||
Underwater: "Unterwasser"
|
||||
Version: "Version"
|
||||
|
||||
|
||||
# Built-in post-processing shaders
|
||||
|
||||
DisplayDepthName: "Visualisiert den Tiefenpuffer."
|
||||
DisplayDepthFactorDescription: "Bestimmt die Korrelation zwischen dem Pixeltiefenwert und seiner Ausgabefarbe. Hohe Werte führen zu einem helleren Bild."
|
||||
DisplayDepthFactorName: "Farbfaktor"
|
||||
ContrastLevelDescription: "Kontraststufe"
|
||||
ContrastLevelName: "Kontrast"
|
||||
GammaLevelDescription: "Gamma-Level"
|
||||
GammaLevelName: "Gamma"
|
@ -1,3 +1,30 @@
|
||||
# Post-processing HUD
|
||||
|
||||
Abovewater: "Abovewater"
|
||||
ActiveShaders: "Active Shaders"
|
||||
Author: "Author"
|
||||
Description: "Description"
|
||||
InactiveShaders: "Inactive Shaders"
|
||||
InExteriors: "Exteriors"
|
||||
InInteriors: "Interiors"
|
||||
KeyboardControls: |
|
||||
Keyboard controls:
|
||||
|
||||
Shift+Right-Arrow > Activate shader
|
||||
Shift+Left-Arrow > Deactive shader
|
||||
Shift+Up-Arrow > Move shader up
|
||||
Shift+Down-Arrow > Move shader down
|
||||
PostProcessHUD: "Postprocess HUD"
|
||||
ResetShader: "Reset shader to default state"
|
||||
ShaderLocked: "Locked"
|
||||
ShaderLockedDescription: "Cannot be toggled or moved, controlled by external Lua script"
|
||||
ShaderResetUniform: "r"
|
||||
Underwater: "Underwater"
|
||||
Version: "Version"
|
||||
|
||||
|
||||
# Built-in post-processing shaders
|
||||
|
||||
AdjustmentsDescription: "Colour adjustments."
|
||||
BloomDescription: "Bloom shader performing its calculations in (approximately) linear light."
|
||||
DebugDescription: "Debug shader."
|
@ -1,3 +1,30 @@
|
||||
# Post-processing HUD
|
||||
|
||||
Abovewater: "Hors de l'eau"
|
||||
ActiveShaders: "Shaders actifs"
|
||||
Author: "Auteur(e)"
|
||||
Description: "Description"
|
||||
InactiveShaders: "Shaders inactifs"
|
||||
InExteriors: "À l'extérieur"
|
||||
InInteriors: "En intérieur"
|
||||
KeyboardControls: |
|
||||
Raccourcis clavier:
|
||||
|
||||
Majuscule+Flèche droite > Active le shader
|
||||
Majuscule+Flèche gauche > Désactive le shader
|
||||
Majuscule+Flèche haut > Monte le shader dans la liste
|
||||
Majuscule+Flèche bas > Descend le shader dans la liste
|
||||
MainPassDescription: "Transmet les données de la scène aux shaders de post-traitement. Ne peut être déplacé ou supprimé."
|
||||
PostProcessHUD: "HUD de post-traitement"
|
||||
ResetShader: "Restaure le shader dans sa configuration par défaut"
|
||||
ShaderLocked: "Verrouillé"
|
||||
ShaderResetUniform: "r"
|
||||
Underwater: "Sous l'eau"
|
||||
Version: "Version"
|
||||
|
||||
|
||||
# Built-in post-processing shaders
|
||||
|
||||
AdjustmentsDescription: "Ajustements de l'image (couleurs, luminosité, contrastes...)."
|
||||
BloomDescription: "Flou lumineux, calculé (approximativement) de façon linéaire suivant l'intensité de la lumière."
|
||||
DebugDescription: "Shader de débogage."
|
@ -1,3 +1,30 @@
|
||||
# Post-processing HUD
|
||||
|
||||
Abovewater: "Над водой"
|
||||
ActiveShaders: "Включенные шейдеры"
|
||||
Author: "Автор"
|
||||
Description: "Описание"
|
||||
InactiveShaders: "Выключенные шейдеры"
|
||||
InExteriors: "Вне помещений"
|
||||
InInteriors: "В помещениях"
|
||||
KeyboardControls: |
|
||||
Управление с помощью клавиатуры:
|
||||
|
||||
Shift+Right-Arrow > Включить шейдер
|
||||
Shift+Left-Arrow > Выключить шейдер
|
||||
Shift+Up-Arrow > Передвинуть шейдер выше
|
||||
Shift+Down-Arrow > Передвинуть шейдер ниже
|
||||
PostProcessHUD: "Настройки постобработки"
|
||||
ResetShader: "Обнулить настройки этого шейдера"
|
||||
ShaderLocked: "Заблокирован"
|
||||
ShaderLockedDescription: "Не может быть выключен или передвинут, управляется внешним Lua-скриптом"
|
||||
ShaderResetUniform: "x"
|
||||
Underwater: "Под водой"
|
||||
Version: "Версия"
|
||||
|
||||
|
||||
# Built-in post-processing shaders
|
||||
|
||||
AdjustmentsDescription: "Коррекция цвета."
|
||||
DebugDescription: "Отладочный шейдер."
|
||||
DebugHeaderDepth: "Буфер глубины"
|
@ -1,3 +1,30 @@
|
||||
# Post-processing HUD
|
||||
|
||||
Abovewater: "Ovan vatten"
|
||||
ActiveShaders: "Aktiva shaders"
|
||||
Author: "Skapare" # Author = Författare, but författare sounds very book-author-ish. Skapare, meaning "creator", sounds better in Swedish in this case. Ok?
|
||||
Description: "Beskrivning"
|
||||
ActiveShaders: "Inaktiva shaders"
|
||||
InExteriors: "Exteriörer"
|
||||
InInteriors: "Interiörer"
|
||||
KeyboardControls: |
|
||||
Tangentbordskontroller:
|
||||
|
||||
Shift+Högerpil > Aktivera shader
|
||||
Shift+Vänsterpil > Avaktivera shader
|
||||
Shift+Pil upp > Flytta shader upp
|
||||
Shift+Pil ner > Flytta shader ner
|
||||
PostProcessHUD: "Postprocess HUD"
|
||||
ResetShader: "Återställ shader to ursprungligt läge"
|
||||
ShaderLocked: "Låst"
|
||||
ShaderLockedDescription: "Kan ej aktiveras/inaktiveras eller flyttas. Kontrolleras av externt Lua-skript"
|
||||
ShaderResetUniform: "r"
|
||||
Underwater: "Under vatten"
|
||||
Version: "Version"
|
||||
|
||||
|
||||
# Built-in post-processing shaders
|
||||
|
||||
AdjustmentsDescription: "Färgjusteringar."
|
||||
BloomDescription: "Bloomshader som utför sina beräkningar i (ungefärligt) linjärt ljus."
|
||||
DebugDescription: "Felsökningsshader."
|
||||
@ -10,7 +37,7 @@ DisplayNormalsName: "Visualisera normalvektorer" # på engelska står det "pass
|
||||
ContrastLevelDescription: "Kontrastnivå"
|
||||
ContrastLevelName: "Kontrast"
|
||||
GammaLevelDescription: "Gammanivå"
|
||||
# GammaLevelName: "Gamma" samma som engelska
|
||||
GammaLevelName: "Gamma" # samma som engelska
|
||||
StrengthLevelName: "Styrka"
|
||||
StrengthLevelDescription: "Effektens styrka."
|
||||
RadiusLevelName: "Radie"
|
@ -1,21 +0,0 @@
|
||||
Abovewater: "Abovewater"
|
||||
ActiveShaders: "Active Shaders"
|
||||
Author: "Author"
|
||||
Description: "Description"
|
||||
InactiveShaders: "Inactive Shaders"
|
||||
InExteriors: "Exteriors"
|
||||
InInteriors: "Interiors"
|
||||
KeyboardControls: |
|
||||
Keyboard controls:
|
||||
|
||||
Shift+Right-Arrow > Activate shader
|
||||
Shift+Left-Arrow > Deactive shader
|
||||
Shift+Up-Arrow > Move shader up
|
||||
Shift+Down-Arrow > Move shader down
|
||||
PostProcessHUD: "Postprocess HUD"
|
||||
ResetShader: "Reset shader to default state"
|
||||
ShaderLocked: "Locked"
|
||||
ShaderLockedDescription: "Cannot be toggled or moved, controlled by external Lua script"
|
||||
ShaderResetUniform: "r"
|
||||
Underwater: "Underwater"
|
||||
Version: "Version"
|
@ -1,21 +0,0 @@
|
||||
Abovewater: "Hors de l'eau"
|
||||
ActiveShaders: "Shaders actifs"
|
||||
Author: "Auteur(e)"
|
||||
Description: "Description"
|
||||
InactiveShaders: "Shaders inactifs"
|
||||
InExteriors: "À l'extérieur"
|
||||
InInteriors: "En intérieur"
|
||||
KeyboardControls: |
|
||||
Raccourcis clavier:
|
||||
|
||||
Majuscule+Flèche droite > Active le shader
|
||||
Majuscule+Flèche gauche > Désactive le shader
|
||||
Majuscule+Flèche haut > Monte le shader dans la liste
|
||||
Majuscule+Flèche bas > Descend le shader dans la liste
|
||||
MainPassDescription: "Transmet les données de la scène aux shaders de post-traitement. Ne peut être déplacé ou supprimé."
|
||||
PostProcessHUD: "HUD de post-traitement"
|
||||
ResetShader: "Restaure le shader dans sa configuration par défaut"
|
||||
ShaderLocked: "Verrouillé"
|
||||
ShaderResetUniform: "r"
|
||||
Underwater: "Sous l'eau"
|
||||
Version: "Version"
|
@ -1,21 +0,0 @@
|
||||
Abovewater: "Над водой"
|
||||
ActiveShaders: "Включенные шейдеры"
|
||||
Author: "Автор"
|
||||
Description: "Описание"
|
||||
InactiveShaders: "Выключенные шейдеры"
|
||||
InExteriors: "Вне помещений"
|
||||
InInteriors: "В помещениях"
|
||||
KeyboardControls: |
|
||||
Управление с помощью клавиатуры:
|
||||
|
||||
Shift+Right-Arrow > Включить шейдер
|
||||
Shift+Left-Arrow > Выключить шейдер
|
||||
Shift+Up-Arrow > Передвинуть шейдер выше
|
||||
Shift+Down-Arrow > Передвинуть шейдер ниже
|
||||
PostProcessHUD: "Настройки постобработки"
|
||||
ResetShader: "Обнулить настройки этого шейдера"
|
||||
ShaderLocked: "Заблокирован"
|
||||
ShaderLockedDescription: "Не может быть выключен или передвинут, управляется внешним Lua-скриптом"
|
||||
ShaderResetUniform: "x"
|
||||
Underwater: "Под водой"
|
||||
Version: "Версия"
|
@ -1,22 +0,0 @@
|
||||
Abovewater: "Ovan vatten"
|
||||
ActiveShaders: "Aktiva shaders"
|
||||
Author: "Skapare" # Author = Författare, but författare sounds very book-author-ish. Skapare, meaning "creator", sounds better in Swedish in this case. Ok?
|
||||
Description: "Beskrivning"
|
||||
ActiveShaders: "Inaktiva shaders"
|
||||
InExteriors: "Exteriörer"
|
||||
InInteriors: "Interiörer"
|
||||
KeyboardControls: |
|
||||
Tangentbordskontroller:
|
||||
|
||||
Shift+Högerpil > Aktivera shader
|
||||
Shift+Vänsterpil > Avaktivera shader
|
||||
Shift+Pil upp > Flytta shader upp
|
||||
Shift+Pil ner > Flytta shader ner
|
||||
PostProcessHUD: "Postprocess HUD"
|
||||
ResetShader: "Återställ shader to ursprungligt läge"
|
||||
ShaderLocked: "Låst"
|
||||
ShaderLockedDescription: "Kan ej aktiveras/inaktiveras eller flyttas. Kontrolleras av externt Lua-skript"
|
||||
ShaderResetUniform: "r"
|
||||
Underwater: "Under vatten"
|
||||
Version: "Version"
|
||||
|
@ -1,2 +0,0 @@
|
||||
SelectCharacter: "Charakterauswahl..."
|
||||
TimePlayed: "Spielzeit"
|
@ -1,2 +0,0 @@
|
||||
SelectCharacter: "Select Character..."
|
||||
TimePlayed: "Time played"
|
@ -1,2 +0,0 @@
|
||||
SelectCharacter: "Sélection du personnage..."
|
||||
TimePlayed: "Temps de jeu"
|
@ -1,2 +0,0 @@
|
||||
SelectCharacter: "Выберите персонажа..."
|
||||
TimePlayed: "Время в игре"
|
@ -1,2 +0,0 @@
|
||||
SelectCharacter: "Välj spelfigur..."
|
||||
TimePlayed: "Speltid"
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<MyGUI type="Layout">
|
||||
<Widget type="Window" skin="MW_Window" position="0 0 400 400" layer="Debug" name="_Main" align="Stretch">
|
||||
<Property key="Caption" value="#{DebugMenu:DebugWindow}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:DebugWindow}"/>
|
||||
<Property key="Visible" value="false"/>
|
||||
|
||||
<Widget type="Widget" skin="DialogBG" position_real="0 0 1 1" name="Background" align="Stretch">
|
||||
|
@ -2,7 +2,7 @@
|
||||
<MyGUI type="Layout">
|
||||
<Widget type="Window" skin="MW_Window" position="0 0 500 500" layer="Debug" name="_Main" align="Stretch">
|
||||
<Property key="Visible" value="false"/>
|
||||
<Property key="Caption" value="#{PostProcessing:PostProcessHUD}"/>
|
||||
<Property key="Caption" value="#{OMWShaders:PostProcessHUD}"/>
|
||||
<Property key="MinSize" value="600 600"/>
|
||||
|
||||
<Widget type="TabControl" skin="TabControl_NoBorder" position="8 8 468 450" align="Stretch" name="TabControl">
|
||||
@ -12,7 +12,7 @@
|
||||
<Property key="Caption" value="[?]"/>
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="TextToolTip"/>
|
||||
<UserString key="Caption_Text" value="#{PostProcessing:KeyboardControls}"/>
|
||||
<UserString key="Caption_Text" value="#{OMWShaders:KeyboardControls}"/>
|
||||
<Property key="Depth" value="-10"/>
|
||||
</Widget>
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
|
||||
<Widget type="VBox" position_real="0 0 1 1" align="Stretch">
|
||||
<Widget type="AutoSizedTextBox" skin="NormalText" position="0 0 50 50" align="Top Right">
|
||||
<Property key="Caption" value="#{PostProcessing:InactiveShaders}"/>
|
||||
<Property key="Caption" value="#{OMWShaders:InactiveShaders}"/>
|
||||
</Widget>
|
||||
|
||||
<Widget type="EditBox" skin="MW_TextBoxEditWithBorder" position="0 0 0 28" name="Filter">
|
||||
@ -80,7 +80,7 @@
|
||||
|
||||
<Widget type="VBox" position_real="0 0 1 1" align="Stretch">
|
||||
<Widget type="AutoSizedTextBox" skin="NormalText" position="0 0 50 50" align="Top Right">
|
||||
<Property key="Caption" value="#{PostProcessing:ActiveShaders}"/>
|
||||
<Property key="Caption" value="#{OMWShaders:ActiveShaders}"/>
|
||||
</Widget>
|
||||
|
||||
<Widget type="ListWrapper" skin="MW_List" name="ActiveList">
|
||||
|
@ -59,7 +59,7 @@
|
||||
<Widget type="AutoSizedButton" skin="MW_Button" position="0 0 22 22" name="Reset">
|
||||
<UserString key="HStretch" value="false"/>
|
||||
<UserString key="VStretch" value="false"/>
|
||||
<Property key="Caption" value="#{PostProcessing:ShaderResetUniform}"/>
|
||||
<Property key="Caption" value="#{OMWShaders:ShaderResetUniform}"/>
|
||||
</Widget>
|
||||
<Widget type="Widget" skin="BlackBG" position="0 0 225 22" name="Client">
|
||||
<UserString key="HStretch" value="false"/>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<Property key="Spacing" value="8"/>
|
||||
|
||||
<Widget type="ComboBox" skin="MW_ComboBox" position="0 0 0 24" name="SelectCharacter">
|
||||
<Property key="Caption" value="#{SavegameMenu:SelectCharacter}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:SelectCharacter}"/>
|
||||
<UserString key="HStretch" value="true"/>
|
||||
</Widget>
|
||||
|
||||
|
@ -75,7 +75,7 @@
|
||||
</Widget>
|
||||
<Widget type="Widget" position="4 184 400 54" align="Left Top HStretch">
|
||||
<Widget type="TextBox" skin="NormalText" position="0 0 400 16" align="Left Top" name="ActorProcessingText">
|
||||
<Property key="Caption" value="#{SettingsMenu:ActorsProcessingRange}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:ActorsProcessingRange}"/>
|
||||
</Widget>
|
||||
<Widget type="ScrollBar" skin="MW_HScroll" position="0 20 352 14" align="Left Top HStretch">
|
||||
<Property key="Range" value="3584"/>
|
||||
@ -87,7 +87,7 @@
|
||||
<UserString key="SettingMin" value="3584"/>
|
||||
<UserString key="SettingMax" value="7168"/>
|
||||
<UserString key="SettingLabelWidget" value="ActorProcessingText"/>
|
||||
<UserString key="SettingLabelCaption" value="#{SettingsMenu:ActorsProcessingRange} (%s)"/>
|
||||
<UserString key="SettingLabelCaption" value="#{OMWEngine:ActorsProcessingRange} (%s)"/>
|
||||
</Widget>
|
||||
<Widget type="TextBox" skin="SandText" position="0 38 352 16" align="Left Top">
|
||||
<Property key="Caption" value="#{sLow}"/>
|
||||
@ -204,10 +204,10 @@
|
||||
<Property key="Padding" value="0"/>
|
||||
<Property key="Spacing" value="4"/>
|
||||
<Widget type="AutoSizedButton" skin="MW_Button" name="KeyboardButton">
|
||||
<Property key="Caption" value="#{SettingsMenu:MouseAndKeyboard}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:MouseAndKeyboard}"/>
|
||||
</Widget>
|
||||
<Widget type="AutoSizedButton" skin="MW_Button" name="ControllerButton">
|
||||
<Property key="Caption" value="#{SettingsMenu:Controller}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:Controller}"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
@ -226,7 +226,7 @@
|
||||
<UserString key="SettingType" value="CheckButton"/>
|
||||
</Widget>
|
||||
<Widget type="AutoSizedTextBox" skin="SandText">
|
||||
<Property key="Caption" value="#{SettingsMenu:InvertXAxis} "/>
|
||||
<Property key="Caption" value="#{OMWEngine:InvertXAxis} "/>
|
||||
</Widget>
|
||||
<Widget type="AutoSizedButton" skin="MW_Button">
|
||||
<UserString key="SettingCategory" value="Input"/>
|
||||
@ -238,7 +238,7 @@
|
||||
</Widget>
|
||||
</Widget>
|
||||
<Widget type="TextBox" skin="NormalText" position="4 258 352 18" align="Left Bottom">
|
||||
<Property key="Caption" value="#{SettingsMenu:CameraSensitivity}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:CameraSensitivity}"/>
|
||||
</Widget>
|
||||
<Widget type="ScrollBar" skin="MW_HScroll" position="4 282 352 18" align="HStretch Bottom">
|
||||
<Property key="Range" value="10000"/>
|
||||
@ -277,13 +277,13 @@
|
||||
<Property key="Caption" value=" #{sVideo} "/>
|
||||
<Widget type="ListBox" skin="MW_List" position="0 4 185 225" align="Left Top" name="ResolutionList"/>
|
||||
<Widget type="TextBox" skin="NormalText" position="197 4 185 18" align="Left Top">
|
||||
<Property key="Caption" value="#{SettingsMenu:WindowMode}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:WindowMode}"/>
|
||||
</Widget>
|
||||
<Widget type="HBox" position="197 28 400 24">
|
||||
<Widget type="ComboBox" skin="MW_ComboBox" position="0 0 200 24" align="Left Top" name="WindowModeList">
|
||||
<Property key="AddItem" value="#{SettingsMenu:WindowModeFullscreen}"/>
|
||||
<Property key="AddItem" value="#{SettingsMenu:WindowModeWindowedFullscreen}"/>
|
||||
<Property key="AddItem" value="#{SettingsMenu:WindowModeWindowed}"/>
|
||||
<Property key="AddItem" value="#{OMWEngine:WindowModeFullscreen}"/>
|
||||
<Property key="AddItem" value="#{OMWEngine:WindowModeWindowedFullscreen}"/>
|
||||
<Property key="AddItem" value="#{OMWEngine:WindowModeWindowed}"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
<Widget type="HBox" position="197 58 400 28">
|
||||
@ -293,7 +293,7 @@
|
||||
<UserString key="SettingType" value="CheckButton"/>
|
||||
</Widget>
|
||||
<Widget type="AutoSizedTextBox" skin="SandText" position="28 4 48 16" align="Left Top">
|
||||
<Property key="Caption" value="#{SettingsMenu:VSync}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:VSync}"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
<Widget type="HBox" position="197 88 300 28">
|
||||
@ -303,7 +303,7 @@
|
||||
<UserString key="SettingType" value="CheckButton"/>
|
||||
</Widget>
|
||||
<Widget type="AutoSizedTextBox" skin="SandText" position="28 4 48 16" align="Left Top">
|
||||
<Property key="Caption" value="#{SettingsMenu:WindowBorder}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:WindowBorder}"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
<Widget type="HBox" position="197 118 300 28">
|
||||
@ -313,15 +313,15 @@
|
||||
<UserString key="SettingType" value="CheckButton"/>
|
||||
</Widget>
|
||||
<Widget type="AutoSizedTextBox" skin="SandText" position="28 4 48 16" align="Left Top">
|
||||
<Property key="Caption" value="#{SettingsMenu:PostProcessing}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:PostProcessing}"/>
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="TextToolTip"/>
|
||||
<UserString key="Caption_Text" value="#{SettingsMenu:PostProcessingTooltip}"/>
|
||||
<UserString key="Caption_Text" value="#{OMWEngine:PostProcessingTooltip}"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<Widget type="AutoSizedTextBox" skin="SandText" position="197 154 300 32" align="Left Top">
|
||||
<Property key="Caption" value="#{SettingsMenu:FrameRateHint}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:FrameRateHint}"/>
|
||||
</Widget>
|
||||
<Widget type="AutoSizedTextBox" skin="SandText" position="197 196 300 32" align="Left Top" name="WindowModeHint">
|
||||
<Property key="Caption" value="#{SettingsMenu:WindowModeHint}"/>
|
||||
@ -339,7 +339,7 @@
|
||||
<UserString key="SettingMin" value="30"/>
|
||||
<UserString key="SettingMax" value="110"/>
|
||||
<UserString key="SettingLabelWidget" value="FovText"/>
|
||||
<UserString key="SettingLabelCaption" value="#{SettingsMenu:FieldOfView} (%s)"/>
|
||||
<UserString key="SettingLabelCaption" value="#{OMWEngine:FieldOfView} (%s)"/>
|
||||
</Widget>
|
||||
<Widget type="TextBox" skin="SandText" position="0 286 352 18" align="Left Top">
|
||||
<Property key="Caption" value="#{sLow}"/>
|
||||
@ -375,17 +375,17 @@
|
||||
<Property key="Caption" value=" #{sDetail_Level} "/>
|
||||
|
||||
<Widget type="AutoSizedTextBox" skin="NormalText" align="Left Top">
|
||||
<Property key="Caption" value="#{SettingsMenu:TextureFiltering}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:TextureFiltering}"/>
|
||||
<UserString key="VStretch" value="false"/>
|
||||
<UserString key="HStretch" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="ComboBox" align="Left Top" skin="MW_ComboBox" position="0 28 200 24" name="TextureFilteringButton">
|
||||
<Property key="AddItem" value="#{SettingsMenu:TextureFilteringBilinear}"/>
|
||||
<Property key="AddItem" value="#{SettingsMenu:TextureFilteringTrilinear}"/>
|
||||
<Property key="AddItem" value="#{OMWEngine:TextureFilteringBilinear}"/>
|
||||
<Property key="AddItem" value="#{OMWEngine:TextureFilteringTrilinear}"/>
|
||||
</Widget>
|
||||
|
||||
<Widget type="AutoSizedTextBox" skin="NormalText" position="0 58 200 18" name="AnisotropyLabel">
|
||||
<Property key="Caption" value="#{SettingsMenu:Anisotropy}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:Anisotropy}"/>
|
||||
</Widget>
|
||||
<Widget type="ScrollBar" skin="MW_HScroll" position="0 80 352 18" align="HStretch Top">
|
||||
<Property key="Range" value="17"/>
|
||||
@ -394,7 +394,7 @@
|
||||
<UserString key="SettingCategory" value="General"/>
|
||||
<UserString key="SettingName" value="anisotropy"/>
|
||||
<UserString key="SettingLabelWidget" value="AnisotropyLabel"/>
|
||||
<UserString key="SettingLabelCaption" value="#{SettingsMenu:Anisotropy} (%s)"/>
|
||||
<UserString key="SettingLabelCaption" value="#{OMWEngine:Anisotropy} (%s)"/>
|
||||
</Widget>
|
||||
|
||||
<Widget type="AutoSizedTextBox" skin="NormalText" position="0 104 0 18" align="Left Top" name="RenderDistanceLabel">
|
||||
@ -435,7 +435,7 @@
|
||||
|
||||
</Widget>
|
||||
<Widget type="TabItem">
|
||||
<Property key="Caption" value=" #{SettingsMenu:Water} "/>
|
||||
<Property key="Caption" value=" #{OMWEngine:Water} "/>
|
||||
|
||||
<Widget type="VBox" position_real="0 0 1 1" align="Stretch">
|
||||
|
||||
@ -449,7 +449,7 @@
|
||||
<UserString key="SettingType" value="CheckButton"/>
|
||||
</Widget>
|
||||
<Widget type="AutoSizedTextBox" skin="SandText">
|
||||
<Property key="Caption" value="#{SettingsMenu:WaterShader}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:WaterShader}"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
@ -463,14 +463,14 @@
|
||||
<UserString key="SettingType" value="CheckButton"/>
|
||||
</Widget>
|
||||
<Widget type="AutoSizedTextBox" skin="SandText">
|
||||
<Property key="Caption" value="#{SettingsMenu:Refraction}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:Refraction}"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<Widget type="Widget" position="0 0 0 18" align="Top Left HStretch">
|
||||
<UserString key="HStretch" value="true"/>
|
||||
<Widget type="AutoSizedTextBox" skin="NormalText">
|
||||
<Property key="Caption" value="#{SettingsMenu:WaterShaderTextureQuality}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:WaterShaderTextureQuality}"/>
|
||||
</Widget>
|
||||
<Widget type="Spacer" />
|
||||
</Widget>
|
||||
@ -489,7 +489,7 @@
|
||||
<Widget type="Widget" position="0 0 0 18" align="Top Left HStretch">
|
||||
<UserString key="HStretch" value="true"/>
|
||||
<Widget type="AutoSizedTextBox" skin="NormalText">
|
||||
<Property key="Caption" value="#{SettingsMenu:ReflectionShaderDetail}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:ReflectionShaderDetail}"/>
|
||||
</Widget>
|
||||
<Widget type="Spacer" />
|
||||
</Widget>
|
||||
@ -498,12 +498,12 @@
|
||||
<UserString key="VStretch" value="false"/>
|
||||
|
||||
<Widget type="ComboBox" skin="MW_ComboBox" position="0 0 200 24" align="Left Top" name="WaterReflectionDetail">
|
||||
<Property key="AddItem" value="#{SettingsMenu:ReflectionShaderDetailSky}"/>
|
||||
<Property key="AddItem" value="#{SettingsMenu:ReflectionShaderDetailTerrain}"/>
|
||||
<Property key="AddItem" value="#{SettingsMenu:ReflectionShaderDetailWorld}"/>
|
||||
<Property key="AddItem" value="#{SettingsMenu:ReflectionShaderDetailObjects}"/>
|
||||
<Property key="AddItem" value="#{SettingsMenu:ReflectionShaderDetailActors}"/>
|
||||
<Property key="AddItem" value="#{SettingsMenu:ReflectionShaderDetailGroundcover}"/>
|
||||
<Property key="AddItem" value="#{OMWEngine:ReflectionShaderDetailSky}"/>
|
||||
<Property key="AddItem" value="#{OMWEngine:ReflectionShaderDetailTerrain}"/>
|
||||
<Property key="AddItem" value="#{OMWEngine:ReflectionShaderDetailWorld}"/>
|
||||
<Property key="AddItem" value="#{OMWEngine:ReflectionShaderDetailObjects}"/>
|
||||
<Property key="AddItem" value="#{OMWEngine:ReflectionShaderDetailActors}"/>
|
||||
<Property key="AddItem" value="#{OMWEngine:ReflectionShaderDetailGroundcover}"/>
|
||||
</Widget>
|
||||
<Widget type="Spacer" />
|
||||
</Widget>
|
||||
@ -511,7 +511,7 @@
|
||||
<Widget type="Widget" position="0 0 0 18" align="Top Left HStretch">
|
||||
<UserString key="HStretch" value="true"/>
|
||||
<Widget type="AutoSizedTextBox" skin="NormalText">
|
||||
<Property key="Caption" value="#{SettingsMenu:RainRippleDetail}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:RainRippleDetail}"/>
|
||||
</Widget>
|
||||
<Widget type="Spacer" />
|
||||
</Widget>
|
||||
@ -521,9 +521,9 @@
|
||||
<UserString key="VStretch" value="false"/>
|
||||
|
||||
<Widget type="ComboBox" skin="MW_ComboBox" position="0 0 200 24" align="Left Top" name="WaterRainRippleDetail">
|
||||
<Property key="AddItem" value="#{SettingsMenu:RainRippleDetailSimple}"/>
|
||||
<Property key="AddItem" value="#{SettingsMenu:RainRippleDetailSparse}"/>
|
||||
<Property key="AddItem" value="#{SettingsMenu:RainRippleDetailDense}"/>
|
||||
<Property key="AddItem" value="#{OMWEngine:RainRippleDetailSimple}"/>
|
||||
<Property key="AddItem" value="#{OMWEngine:RainRippleDetailSparse}"/>
|
||||
<Property key="AddItem" value="#{OMWEngine:RainRippleDetailDense}"/>
|
||||
</Widget>
|
||||
<Widget type="Spacer" />
|
||||
</Widget>
|
||||
@ -532,10 +532,10 @@
|
||||
|
||||
</Widget>
|
||||
<Widget type="TabItem">
|
||||
<Property key="Caption" value=" #{SettingsMenu:Lights} "/>
|
||||
<Property key="Caption" value=" #{OMWEngine:Lights} "/>
|
||||
<!-- Lighting Method -->
|
||||
<Widget type="TextBox" skin="NormalText" position="0 4 250 18" align="Left Top">
|
||||
<Property key="Caption" value="#{SettingsMenu:LightingMethod}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:LightingMethod}"/>
|
||||
</Widget>
|
||||
<Widget type="ComboBox" skin="MW_ComboBox" position="0 28 250 24" align="Left Top" name="LightingMethodButton">
|
||||
<Property key="AddItem" value="legacy"/>
|
||||
@ -546,7 +546,7 @@
|
||||
<Widget type="TextBox" skin="NormalText" position="258 4 350 18" align="Left Top" name="MaxLightsText">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="TextToolTip"/>
|
||||
<UserString key="Caption_Text" value="#{SettingsMenu:MaxLightsTooltip}"/>
|
||||
<UserString key="Caption_Text" value="#{OMWEngine:MaxLightsTooltip}"/>
|
||||
</Widget>
|
||||
<Widget type="ScrollBar" position="0 0 0 0">
|
||||
<UserString key="SettingType" value="Slider"/>
|
||||
@ -554,7 +554,7 @@
|
||||
<UserString key="SettingName" value="max lights"/>
|
||||
<UserString key="SettingValueType" value="Integer"/>
|
||||
<UserString key="SettingLabelWidget" value="MaxLightsText"/>
|
||||
<UserString key="SettingLabelCaption" value="#{SettingsMenu:MaxLights} (%s)"/>
|
||||
<UserString key="SettingLabelCaption" value="#{OMWEngine:MaxLights} (%s)"/>
|
||||
</Widget>
|
||||
<Widget type="ComboBox" skin="MW_ComboBox" position="258 28 250 24" align="Left Top" name="MaxLights">
|
||||
<Property key="AddItem" value="8"/>
|
||||
@ -567,7 +567,7 @@
|
||||
<Widget type="TextBox" skin="NormalText" position="0 78 500 18" align="Left Top" name="MaxLightDistanceText">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="TextToolTip"/>
|
||||
<UserString key="Caption_Text" value="#{SettingsMenu:LightsMaximumDistanceTooltip}"/>
|
||||
<UserString key="Caption_Text" value="#{OMWEngine:LightsMaximumDistanceTooltip}"/>
|
||||
</Widget>
|
||||
<Widget type="ScrollBar" skin="MW_HScroll" position="0 104 352 18" align="HStretch Top">
|
||||
<Property key="Range" value="8192"/>
|
||||
@ -579,13 +579,13 @@
|
||||
<UserString key="SettingName" value="maximum light distance"/>
|
||||
<UserString key="SettingValueType" value="Integer"/>
|
||||
<UserString key="SettingLabelWidget" value="MaxLightDistanceText"/>
|
||||
<UserString key="SettingLabelCaption" value="#{SettingsMenu:LightsMaximumDistance} (%s)"/>
|
||||
<UserString key="SettingLabelCaption" value="#{OMWEngine:LightsMaximumDistance} (%s)"/>
|
||||
</Widget>
|
||||
<!-- Light Fade Multiplier -->
|
||||
<Widget type="TextBox" skin="NormalText" position="0 128 500 18" align="Left Top" name="LightFadeMultiplierText">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="TextToolTip"/>
|
||||
<UserString key="Caption_Text" value="#{SettingsMenu:LightsFadeStartMultiplierTooltip}"/>
|
||||
<UserString key="Caption_Text" value="#{OMWEngine:LightsFadeStartMultiplierTooltip}"/>
|
||||
</Widget>
|
||||
<Widget type="ScrollBar" skin="MW_HScroll" position="0 152 352 18" align="HStretch Top">
|
||||
<Property key="Range" value="10000"/>
|
||||
@ -597,13 +597,13 @@
|
||||
<UserString key="SettingMin" value="0.0"/>
|
||||
<UserString key="SettingMax" value="1.0"/>
|
||||
<UserString key="SettingLabelWidget" value="LightFadeMultiplierText"/>
|
||||
<UserString key="SettingLabelCaption" value="#{SettingsMenu:LightsFadeStartMultiplier} (%s)"/>
|
||||
<UserString key="SettingLabelCaption" value="#{OMWEngine:LightsFadeStartMultiplier} (%s)"/>
|
||||
</Widget>
|
||||
<!-- Bounding Sphere Multiplier -->
|
||||
<Widget type="TextBox" skin="NormalText" position="0 176 500 18" align="Left Top" name="BoundingSphereMultText">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="TextToolTip"/>
|
||||
<UserString key="Caption_Text" value="#{SettingsMenu:LightsBoundingSphereMultiplierTooltip}"/>
|
||||
<UserString key="Caption_Text" value="#{OMWEngine:LightsBoundingSphereMultiplierTooltip}"/>
|
||||
</Widget>
|
||||
<Widget type="ScrollBar" skin="MW_HScroll" position="0 200 352 18" align="HStretch Top">
|
||||
<Property key="Range" value="500000"/>
|
||||
@ -615,13 +615,13 @@
|
||||
<UserString key="SettingName" value="light bounds multiplier"/>
|
||||
<UserString key="SettingValueType" value="Float"/>
|
||||
<UserString key="SettingLabelWidget" value="BoundingSphereMultText"/>
|
||||
<UserString key="SettingLabelCaption" value="#{SettingsMenu:LightsBoundingSphereMultiplier} (%s)"/>
|
||||
<UserString key="SettingLabelCaption" value="#{OMWEngine:LightsBoundingSphereMultiplier} (%s)"/>
|
||||
</Widget>
|
||||
<!-- Minimum Ambient Brightness -->
|
||||
<Widget type="TextBox" skin="NormalText" position="0 224 500 18" align="Left Top" name="MinimumBrightnessText">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="TextToolTip"/>
|
||||
<UserString key="Caption_Text" value="#{SettingsMenu:LightsMinimumInteriorBrightnessTooltip}"/>
|
||||
<UserString key="Caption_Text" value="#{OMWEngine:LightsMinimumInteriorBrightnessTooltip}"/>
|
||||
</Widget>
|
||||
<Widget type="ScrollBar" skin="MW_HScroll" position="0 248 352 18" align="HStretch Top">
|
||||
<Property key="Range" value="10000"/>
|
||||
@ -631,7 +631,7 @@
|
||||
<UserString key="SettingName" value="minimum interior brightness"/>
|
||||
<UserString key="SettingValueType" value="Float"/>
|
||||
<UserString key="SettingLabelWidget" value="MinimumBrightnessText"/>
|
||||
<UserString key="SettingLabelCaption" value="#{SettingsMenu:LightsMinimumInteriorBrightness} (%s)"/>
|
||||
<UserString key="SettingLabelCaption" value="#{OMWEngine:LightsMinimumInteriorBrightness} (%s)"/>
|
||||
</Widget>
|
||||
<Widget type="AutoSizedButton" skin="MW_Button" position="0 290 0 0" align="Top Left" name="LightsResetButton">
|
||||
<Property key="Caption" value="#{sControlsMenu1}"/>
|
||||
@ -640,10 +640,10 @@
|
||||
</Widget>
|
||||
</Widget>
|
||||
<Widget type="TabItem">
|
||||
<Property key="Caption" value=" #{SettingsMenu:Scripts} "/>
|
||||
<Property key="Caption" value=" #{OMWEngine:Scripts} "/>
|
||||
|
||||
<Widget name="ScriptDisabled" type="EditBox" skin="SandText" position_real="0 0 1 1" align="HStretch Top">
|
||||
<Property key="Caption" value="#{SettingsMenu:ScriptsDisabled}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:ScriptsDisabled}"/>
|
||||
<Property key="TextAlign" value="Center"/>
|
||||
<Property key="MultiLine" value="true"/>
|
||||
<Property key="WordWrap" value="true"/>
|
||||
@ -681,24 +681,24 @@
|
||||
|
||||
</Widget>
|
||||
<Widget type="TabItem">
|
||||
<Property key="Caption" value=" #{SettingsMenu:Language} "/>
|
||||
<Property key="Caption" value=" #{OMWEngine:Language} "/>
|
||||
<Widget type="AutoSizedTextBox" skin="SandText" position="4 4 300 32" align="Left Top">
|
||||
<Property key="Caption" value="#{SettingsMenu:LanguageNote}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:LanguageNote}"/>
|
||||
</Widget>
|
||||
<!-- Primary Language -->
|
||||
<Widget type="TextBox" skin="NormalText" position="4 28 250 18" align="Left Top">
|
||||
<Property key="Caption" value="#{SettingsMenu:PrimaryLanguage}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:PrimaryLanguage}"/>
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="TextToolTip"/>
|
||||
<UserString key="Caption_Text" value="#{SettingsMenu:PrimaryLanguageTooltip}"/>
|
||||
<UserString key="Caption_Text" value="#{OMWEngine:PrimaryLanguageTooltip}"/>
|
||||
</Widget>
|
||||
<Widget type="ComboBox" skin="MW_ComboBox" position="4 52 250 24" align="Left Top" name="PrimaryLanguage" />
|
||||
<!-- Secondary Language -->
|
||||
<Widget type="TextBox" skin="NormalText" position="262 28 250 18" align="Left Top">
|
||||
<Property key="Caption" value="#{SettingsMenu:SecondaryLanguage}"/>
|
||||
<Property key="Caption" value="#{OMWEngine:SecondaryLanguage}"/>
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="TextToolTip"/>
|
||||
<UserString key="Caption_Text" value="#{SettingsMenu:SecondaryLanguageTooltip}"/>
|
||||
<UserString key="Caption_Text" value="#{OMWEngine:SecondaryLanguageTooltip}"/>
|
||||
</Widget>
|
||||
<Widget type="ComboBox" skin="MW_ComboBox" position="262 52 250 24" align="Left Top" name="SecondaryLanguage" />
|
||||
</Widget>
|
||||
|
@ -3,8 +3,8 @@ uniform_float uGamma {
|
||||
step = 0.01;
|
||||
min = 0.0;
|
||||
max = 5.0;
|
||||
display_name = "#{BuiltInShaders:GammaLevelName}";
|
||||
description = "#{BuiltInShaders:GammaLevelDescription}";
|
||||
display_name = "#{OMWShaders:GammaLevelName}";
|
||||
description = "#{OMWShaders:GammaLevelDescription}";
|
||||
}
|
||||
|
||||
uniform_float uContrast {
|
||||
@ -12,8 +12,8 @@ uniform_float uContrast {
|
||||
step = 0.01;
|
||||
min = 0.0;
|
||||
max = 5.0;
|
||||
display_name = "#{BuiltInShaders:ContrastLevelName}";
|
||||
description = "#{BuiltInShaders:ContrastLevelDescription}";
|
||||
display_name = "#{OMWShaders:ContrastLevelName}";
|
||||
description = "#{OMWShaders:ContrastLevelDescription}";
|
||||
}
|
||||
|
||||
fragment main {
|
||||
@ -31,7 +31,7 @@ fragment main {
|
||||
}
|
||||
|
||||
technique {
|
||||
description = "#{BuiltInShaders:AdjustmentsDescription}";
|
||||
description = "#{OMWShaders:AdjustmentsDescription}";
|
||||
version = "1.0";
|
||||
author = "OpenMW";
|
||||
passes = main;
|
||||
|
@ -3,48 +3,48 @@ uniform_float uGamma {
|
||||
min = 0.1;
|
||||
max = 4.0;
|
||||
step = 0.01;
|
||||
display_name = "#{BuiltInShaders:GammaLevelName}";
|
||||
description = "#{BuiltInShaders:GammaLevelDescription}";
|
||||
display_name = "#{OMWShaders:GammaLevelName}";
|
||||
description = "#{OMWShaders:GammaLevelDescription}";
|
||||
}
|
||||
uniform_float uThreshold {
|
||||
default = 0.35;
|
||||
min = 0.0;
|
||||
max = 1.0;
|
||||
step = 0.01;
|
||||
display_name = "#{BuiltInShaders:BloomThresholdLevelName}";
|
||||
description = "#{BuiltInShaders:BloomThresholdLevelDescription}";
|
||||
display_name = "#{OMWShaders:BloomThresholdLevelName}";
|
||||
description = "#{OMWShaders:BloomThresholdLevelDescription}";
|
||||
}
|
||||
uniform_float uClamp {
|
||||
default = 1.0;
|
||||
min = 0.0;
|
||||
max = 1.0;
|
||||
step = 0.01;
|
||||
display_name = "#{BuiltInShaders:BloomClampLevelName}";
|
||||
description = "#{BuiltInShaders:BloomClampLevelDescription}";
|
||||
display_name = "#{OMWShaders:BloomClampLevelName}";
|
||||
description = "#{OMWShaders:BloomClampLevelDescription}";
|
||||
}
|
||||
uniform_float uSkyFactor {
|
||||
default = 0.5;
|
||||
min = 0.0;
|
||||
max = 2.0;
|
||||
step = 0.01;
|
||||
display_name = "#{BuiltInShaders:SkyFactorLevelName}";
|
||||
description = "#{BuiltInShaders:SkyFactorLevelDescription}";
|
||||
display_name = "#{OMWShaders:SkyFactorLevelName}";
|
||||
description = "#{OMWShaders:SkyFactorLevelDescription}";
|
||||
}
|
||||
uniform_float uRadius {
|
||||
default = 0.5;
|
||||
min = 0.0;
|
||||
max = 1.0;
|
||||
step = 0.01;
|
||||
display_name = "#{BuiltInShaders:RadiusLevelName}";
|
||||
description = "#{BuiltInShaders:RadiusLevelDescription}";
|
||||
display_name = "#{OMWShaders:RadiusLevelName}";
|
||||
description = "#{OMWShaders:RadiusLevelDescription}";
|
||||
}
|
||||
uniform_float uStrength {
|
||||
default = 0.25;
|
||||
min = 0.0;
|
||||
max = 1.0;
|
||||
step = 0.01;
|
||||
display_name = "#{BuiltInShaders:StrengthLevelName}";
|
||||
description = "#{BuiltInShaders:StrengthLevelDescription}";
|
||||
display_name = "#{OMWShaders:StrengthLevelName}";
|
||||
description = "#{OMWShaders:StrengthLevelDescription}";
|
||||
}
|
||||
|
||||
shared {
|
||||
@ -215,7 +215,7 @@ fragment final(rt1=RT_Vertical) {
|
||||
|
||||
technique {
|
||||
passes = nomipmap, horizontal, vertical, final;
|
||||
description = "#{BuiltInShaders:BloomDescription}";
|
||||
description = "#{OMWShaders:BloomDescription}";
|
||||
author = "OpenMW";
|
||||
version = "1.0";
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
uniform_bool uDisplayDepth {
|
||||
header = "#{BuiltInShaders:DebugHeaderDepth}";
|
||||
header = "#{OMWShaders:DebugHeaderDepth}";
|
||||
default = true;
|
||||
display_name = "#{BuiltInShaders:DisplayDepthName}";
|
||||
display_name = "#{OMWShaders:DisplayDepthName}";
|
||||
}
|
||||
|
||||
uniform_float uDepthFactor {
|
||||
@ -9,14 +9,14 @@ uniform_float uDepthFactor {
|
||||
min = 0.01;
|
||||
max = 20.0;
|
||||
default = 1.0;
|
||||
display_name = "#{BuiltInShaders:DisplayDepthFactorName}";
|
||||
description = "#{BuiltInShaders:DisplayDepthFactorDescription}";
|
||||
display_name = "#{OMWShaders:DisplayDepthFactorName}";
|
||||
description = "#{OMWShaders:DisplayDepthFactorDescription}";
|
||||
}
|
||||
|
||||
uniform_bool uDisplayNormals {
|
||||
header = "#{BuiltInShaders:DebugHeaderNormals}";
|
||||
header = "#{OMWShaders:DebugHeaderNormals}";
|
||||
default = true;
|
||||
display_name = "#{BuiltInShaders:DisplayNormalsName}";
|
||||
display_name = "#{OMWShaders:DisplayNormalsName}";
|
||||
}
|
||||
|
||||
fragment main {
|
||||
@ -38,7 +38,7 @@ fragment main {
|
||||
|
||||
technique {
|
||||
passes = main;
|
||||
description = "#{BuiltInShaders:DebugDescription}";
|
||||
description = "#{OMWShaders:DebugDescription}";
|
||||
author = "OpenMW";
|
||||
version = "1.0";
|
||||
pass_normals = true;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user