mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 21:45:33 +00:00
Merge branch 'master' into master
This commit is contained in:
commit
a55583a395
57 changed files with 421 additions and 151 deletions
|
@ -9,3 +9,8 @@ insert_final_newline = true
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.glsl]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
insert_final_newline = false
|
|
@ -173,6 +173,7 @@ Programmers
|
||||||
Documentation
|
Documentation
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
Adam Bowen (adamnbowen)
|
||||||
Alejandro Sanchez (HiPhish)
|
Alejandro Sanchez (HiPhish)
|
||||||
Bodillium
|
Bodillium
|
||||||
Bret Curtis (psi29a)
|
Bret Curtis (psi29a)
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
Bug #4327: Missing animations during spell/weapon stance switching
|
Bug #4327: Missing animations during spell/weapon stance switching
|
||||||
Bug #4368: Settings window ok button doesn't have key focus by default
|
Bug #4368: Settings window ok button doesn't have key focus by default
|
||||||
Bug #4393: NPCs walk back to where they were after using ResetActors
|
Bug #4393: NPCs walk back to where they were after using ResetActors
|
||||||
|
Bug #4416: Handle exception if we try to play non-music file
|
||||||
Bug #4419: MRK NiStringExtraData is handled incorrectly
|
Bug #4419: MRK NiStringExtraData is handled incorrectly
|
||||||
Bug #4426: RotateWorld behavior is incorrect
|
Bug #4426: RotateWorld behavior is incorrect
|
||||||
Bug #4429: [Windows] Error on build INSTALL.vcxproj project (debug) with cmake 3.7.2
|
Bug #4429: [Windows] Error on build INSTALL.vcxproj project (debug) with cmake 3.7.2
|
||||||
|
@ -39,18 +40,22 @@
|
||||||
Bug #4432: Guards behaviour is incorrect if they do not have AI packages
|
Bug #4432: Guards behaviour is incorrect if they do not have AI packages
|
||||||
Bug #4433: Guard behaviour is incorrect with Alarm = 0
|
Bug #4433: Guard behaviour is incorrect with Alarm = 0
|
||||||
Bug #4451: Script fails to compile when using "Begin, [ScriptName]" syntax
|
Bug #4451: Script fails to compile when using "Begin, [ScriptName]" syntax
|
||||||
|
Bug #4452: Default terrain texture bleeds through texture transitions
|
||||||
Bug #4453: Quick keys behaviour is invalid for equipment
|
Bug #4453: Quick keys behaviour is invalid for equipment
|
||||||
Bug #4454: AI opens doors too slow
|
Bug #4454: AI opens doors too slow
|
||||||
Bug #4457: Item without CanCarry flag prevents shield autoequipping in dark areas
|
Bug #4457: Item without CanCarry flag prevents shield autoequipping in dark areas
|
||||||
Bug #4458: AiWander console command handles idle chances incorrectly
|
Bug #4458: AiWander console command handles idle chances incorrectly
|
||||||
Bug #4459: NotCell dialogue condition doesn't support partial matches
|
Bug #4459: NotCell dialogue condition doesn't support partial matches
|
||||||
|
Bug #4461: "Open" spell from non-player caster isn't a crime
|
||||||
|
Bug #4469: Abot Silt Striders – Model turn 90 degrees on horizontal
|
||||||
Bug #4471: Retrieve SDL window settings instead of using magic numbers
|
Bug #4471: Retrieve SDL window settings instead of using magic numbers
|
||||||
Feature #4256: Implement ToggleBorders (TB) console command
|
|
||||||
Feature #3276: Editor: Search- Show number of (remaining) search results and indicate a search without any results
|
Feature #3276: Editor: Search- Show number of (remaining) search results and indicate a search without any results
|
||||||
Feature #4222: 360° screenshots
|
Feature #4222: 360° screenshots
|
||||||
|
Feature #4256: Implement ToggleBorders (TB) console command
|
||||||
Feature #4324: Add CFBundleIdentifier in Info.plist to allow for macOS function key shortcuts
|
Feature #4324: Add CFBundleIdentifier in Info.plist to allow for macOS function key shortcuts
|
||||||
Feature #4345: Add equivalents for the command line commands to Launcher
|
Feature #4345: Add equivalents for the command line commands to Launcher
|
||||||
Feature #4444: Per-group KF-animation files support
|
Feature #4444: Per-group KF-animation files support
|
||||||
|
Feature #4466: Editor: Add option to ignore "Base" records when running verifier
|
||||||
|
|
||||||
0.44.0
|
0.44.0
|
||||||
------
|
------
|
||||||
|
@ -136,6 +141,7 @@
|
||||||
Bug #4412: openmw-iniimporter ignores data paths from config
|
Bug #4412: openmw-iniimporter ignores data paths from config
|
||||||
Bug #4413: Moving with 0 strength uses all of your fatigue
|
Bug #4413: Moving with 0 strength uses all of your fatigue
|
||||||
Bug #4420: Camera flickering when I open up and close menus while sneaking
|
Bug #4420: Camera flickering when I open up and close menus while sneaking
|
||||||
|
Bug #4424: [macOS] Cursor is either empty or garbage when compiled against macOS 10.13 SDK
|
||||||
Bug #4435: Item health is considered a signed integer
|
Bug #4435: Item health is considered a signed integer
|
||||||
Bug #4441: Adding items to currently disabled weapon-wielding creatures crashes the game
|
Bug #4441: Adding items to currently disabled weapon-wielding creatures crashes the game
|
||||||
Feature #1786: Round up encumbrance value in the encumbrance bar
|
Feature #1786: Round up encumbrance value in the encumbrance bar
|
||||||
|
|
|
@ -18,7 +18,7 @@ Font Licenses:
|
||||||
Current Status
|
Current Status
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
The main quests in Morrowind, Tribunal and Bloodmoon are all completable. Some issues with side quests are to be expected (but rare). Check the [bug tracker](https://bugs.openmw.org/) for a list of issues we need to resolve before the "1.0" release. Even before the "1.0" release however, OpenMW boasts some new [features](https://wiki.openmw.org/index.php?title=Features), such as improved graphics and user interfaces.
|
The main quests in Morrowind, Tribunal and Bloodmoon are all completable. Some issues with side quests are to be expected (but rare). Check the [bug tracker](https://gitlab.com/OpenMW/openmw/issues?label_name%5B%5D=1.0) for a list of issues we need to resolve before the "1.0" release. Even before the "1.0" release however, OpenMW boasts some new [features](https://wiki.openmw.org/index.php?title=Features), such as improved graphics and user interfaces.
|
||||||
|
|
||||||
Pre-existing modifications created for the original Morrowind engine can be hit-and-miss. The OpenMW script compiler performs more thorough error-checking than Morrowind does, meaning that a mod created for Morrowind may not necessarily run in OpenMW. Some mods also rely on quirky behaviour or engine bugs in order to work. We are considering such compatibility issues on a case-by-case basis - in some cases adding a workaround to OpenMW may be feasible, in other cases fixing the mod will be the only option. If you know of any mods that work or don't work, feel free to add them to the [Mod status](https://wiki.openmw.org/index.php?title=Mod_status) wiki page.
|
Pre-existing modifications created for the original Morrowind engine can be hit-and-miss. The OpenMW script compiler performs more thorough error-checking than Morrowind does, meaning that a mod created for Morrowind may not necessarily run in OpenMW. Some mods also rely on quirky behaviour or engine bugs in order to work. We are considering such compatibility issues on a case-by-case basis - in some cases adding a workaround to OpenMW may be feasible, in other cases fixing the mod will be the only option. If you know of any mods that work or don't work, feel free to add them to the [Mod status](https://wiki.openmw.org/index.php?title=Mod_status) wiki page.
|
||||||
|
|
||||||
|
@ -30,8 +30,8 @@ Getting Started
|
||||||
* [Build from source](https://wiki.openmw.org/index.php?title=Development_Environment_Setup)
|
* [Build from source](https://wiki.openmw.org/index.php?title=Development_Environment_Setup)
|
||||||
* [Testing the game](https://wiki.openmw.org/index.php?title=Testing)
|
* [Testing the game](https://wiki.openmw.org/index.php?title=Testing)
|
||||||
* [How to contribute](https://wiki.openmw.org/index.php?title=Contribution_Wanted)
|
* [How to contribute](https://wiki.openmw.org/index.php?title=Contribution_Wanted)
|
||||||
* [Report a bug](https://bugs.openmw.org/projects/openmw) - read the [guidelines](https://wiki.openmw.org/index.php?title=Bug_Reporting_Guidelines) before submitting your first bug!
|
* [Report a bug](https://gitlab.com/OpenMW/openmw/issues) - read the [guidelines](https://wiki.openmw.org/index.php?title=Bug_Reporting_Guidelines) before submitting your first bug!
|
||||||
* [Known issues](https://bugs.openmw.org/projects/openmw/issues?utf8=%E2%9C%93&set_filter=1&f%5B%5D=status_id&op%5Bstatus_id%5D=%3D&v%5Bstatus_id%5D%5B%5D=7&f%5B%5D=tracker_id&op%5Btracker_id%5D=%3D&v%5Btracker_id%5D%5B%5D=1&f%5B%5D=&c%5B%5D=project&c%5B%5D=tracker&c%5B%5D=status&c%5B%5D=priority&c%5B%5D=subject&c%5B%5D=assigned_to&c%5B%5D=updated_on&group_by=tracker)
|
* [Known issues](https://gitlab.com/OpenMW/openmw/issues?label_name%5B%5D=Bug)
|
||||||
|
|
||||||
The data path
|
The data path
|
||||||
-------------
|
-------------
|
||||||
|
|
|
@ -123,6 +123,7 @@ void CSMPrefs::State::declare()
|
||||||
declareEnum ("double-s", "Shift Double Click", actionRemove).addValues (reportValues);
|
declareEnum ("double-s", "Shift Double Click", actionRemove).addValues (reportValues);
|
||||||
declareEnum ("double-c", "Control Double Click", actionEditAndRemove).addValues (reportValues);
|
declareEnum ("double-c", "Control Double Click", actionEditAndRemove).addValues (reportValues);
|
||||||
declareEnum ("double-sc", "Shift Control Double Click", actionNone).addValues (reportValues);
|
declareEnum ("double-sc", "Shift Control Double Click", actionNone).addValues (reportValues);
|
||||||
|
declareBool("ignore-base-records", "Ignore base records in verifier", false);
|
||||||
|
|
||||||
declareCategory ("Search & Replace");
|
declareCategory ("Search & Replace");
|
||||||
declareInt ("char-before", "Characters before search string", 10).
|
declareInt ("char-before", "Characters before search string", 10).
|
||||||
|
|
|
@ -5,14 +5,20 @@
|
||||||
|
|
||||||
#include <components/esm/loadbsgn.hpp>
|
#include <components/esm/loadbsgn.hpp>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
CSMTools::BirthsignCheckStage::BirthsignCheckStage (const CSMWorld::IdCollection<ESM::BirthSign>& birthsigns)
|
CSMTools::BirthsignCheckStage::BirthsignCheckStage (const CSMWorld::IdCollection<ESM::BirthSign>& birthsigns)
|
||||||
: mBirthsigns (birthsigns)
|
: mBirthsigns (birthsigns)
|
||||||
{}
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::BirthsignCheckStage::setup()
|
int CSMTools::BirthsignCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mBirthsigns.getSize();
|
return mBirthsigns.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +26,8 @@ void CSMTools::BirthsignCheckStage::perform (int stage, CSMDoc::Messages& messag
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::BirthSign>& record = mBirthsigns.getRecord (stage);
|
const CSMWorld::Record<ESM::BirthSign>& record = mBirthsigns.getRecord (stage);
|
||||||
|
|
||||||
if (record.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::BirthSign& birthsign = record.get();
|
const ESM::BirthSign& birthsign = record.get();
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace CSMTools
|
||||||
class BirthsignCheckStage : public CSMDoc::Stage
|
class BirthsignCheckStage : public CSMDoc::Stage
|
||||||
{
|
{
|
||||||
const CSMWorld::IdCollection<ESM::BirthSign>& mBirthsigns;
|
const CSMWorld::IdCollection<ESM::BirthSign>& mBirthsigns;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "bodypartcheck.hpp"
|
#include "bodypartcheck.hpp"
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
CSMTools::BodyPartCheckStage::BodyPartCheckStage(
|
CSMTools::BodyPartCheckStage::BodyPartCheckStage(
|
||||||
const CSMWorld::IdCollection<ESM::BodyPart> &bodyParts,
|
const CSMWorld::IdCollection<ESM::BodyPart> &bodyParts,
|
||||||
const CSMWorld::Resources &meshes,
|
const CSMWorld::Resources &meshes,
|
||||||
|
@ -7,10 +9,14 @@ CSMTools::BodyPartCheckStage::BodyPartCheckStage(
|
||||||
mBodyParts(bodyParts),
|
mBodyParts(bodyParts),
|
||||||
mMeshes(meshes),
|
mMeshes(meshes),
|
||||||
mRaces(races)
|
mRaces(races)
|
||||||
{ }
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::BodyPartCheckStage::setup()
|
int CSMTools::BodyPartCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mBodyParts.getSize();
|
return mBodyParts.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +24,8 @@ void CSMTools::BodyPartCheckStage::perform (int stage, CSMDoc::Messages &message
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::BodyPart> &record = mBodyParts.getRecord(stage);
|
const CSMWorld::Record<ESM::BodyPart> &record = mBodyParts.getRecord(stage);
|
||||||
|
|
||||||
if ( record.isDeleted() )
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::BodyPart &bodyPart = record.get();
|
const ESM::BodyPart &bodyPart = record.get();
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace CSMTools
|
||||||
const CSMWorld::IdCollection<ESM::BodyPart> &mBodyParts;
|
const CSMWorld::IdCollection<ESM::BodyPart> &mBodyParts;
|
||||||
const CSMWorld::Resources &mMeshes;
|
const CSMWorld::Resources &mMeshes;
|
||||||
const CSMWorld::IdCollection<ESM::Race> &mRaces;
|
const CSMWorld::IdCollection<ESM::Race> &mRaces;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BodyPartCheckStage(
|
BodyPartCheckStage(
|
||||||
|
|
|
@ -6,14 +6,20 @@
|
||||||
#include <components/esm/loadclas.hpp>
|
#include <components/esm/loadclas.hpp>
|
||||||
#include <components/esm/loadskil.hpp>
|
#include <components/esm/loadskil.hpp>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
CSMTools::ClassCheckStage::ClassCheckStage (const CSMWorld::IdCollection<ESM::Class>& classes)
|
CSMTools::ClassCheckStage::ClassCheckStage (const CSMWorld::IdCollection<ESM::Class>& classes)
|
||||||
: mClasses (classes)
|
: mClasses (classes)
|
||||||
{}
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::ClassCheckStage::setup()
|
int CSMTools::ClassCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mClasses.getSize();
|
return mClasses.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +27,8 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::Class>& record = mClasses.getRecord (stage);
|
const CSMWorld::Record<ESM::Class>& record = mClasses.getRecord (stage);
|
||||||
|
|
||||||
if (record.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Class& class_ = record.get();
|
const ESM::Class& class_ = record.get();
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace CSMTools
|
||||||
class ClassCheckStage : public CSMDoc::Stage
|
class ClassCheckStage : public CSMDoc::Stage
|
||||||
{
|
{
|
||||||
const CSMWorld::IdCollection<ESM::Class>& mClasses;
|
const CSMWorld::IdCollection<ESM::Class>& mClasses;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,20 @@
|
||||||
#include <components/esm/loadfact.hpp>
|
#include <components/esm/loadfact.hpp>
|
||||||
#include <components/esm/loadskil.hpp>
|
#include <components/esm/loadskil.hpp>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
CSMTools::FactionCheckStage::FactionCheckStage (const CSMWorld::IdCollection<ESM::Faction>& factions)
|
CSMTools::FactionCheckStage::FactionCheckStage (const CSMWorld::IdCollection<ESM::Faction>& factions)
|
||||||
: mFactions (factions)
|
: mFactions (factions)
|
||||||
{}
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::FactionCheckStage::setup()
|
int CSMTools::FactionCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mFactions.getSize();
|
return mFactions.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +27,8 @@ void CSMTools::FactionCheckStage::perform (int stage, CSMDoc::Messages& messages
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::Faction>& record = mFactions.getRecord (stage);
|
const CSMWorld::Record<ESM::Faction>& record = mFactions.getRecord (stage);
|
||||||
|
|
||||||
if (record.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Faction& faction = record.get();
|
const ESM::Faction& faction = record.get();
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace CSMTools
|
||||||
class FactionCheckStage : public CSMDoc::Stage
|
class FactionCheckStage : public CSMDoc::Stage
|
||||||
{
|
{
|
||||||
const CSMWorld::IdCollection<ESM::Faction>& mFactions;
|
const CSMWorld::IdCollection<ESM::Faction>& mFactions;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,20 @@
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include "../world/defaultgmsts.hpp"
|
#include "../world/defaultgmsts.hpp"
|
||||||
|
|
||||||
CSMTools::GmstCheckStage::GmstCheckStage(const CSMWorld::IdCollection<ESM::GameSetting>& gameSettings)
|
CSMTools::GmstCheckStage::GmstCheckStage(const CSMWorld::IdCollection<ESM::GameSetting>& gameSettings)
|
||||||
: mGameSettings(gameSettings)
|
: mGameSettings(gameSettings)
|
||||||
{}
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::GmstCheckStage::setup()
|
int CSMTools::GmstCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mGameSettings.getSize();
|
return mGameSettings.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +23,8 @@ void CSMTools::GmstCheckStage::perform(int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::GameSetting>& record = mGameSettings.getRecord (stage);
|
const CSMWorld::Record<ESM::GameSetting>& record = mGameSettings.getRecord (stage);
|
||||||
|
|
||||||
if (record.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::GameSetting& gmst = record.get();
|
const ESM::GameSetting& gmst = record.get();
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace CSMTools
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const CSMWorld::IdCollection<ESM::GameSetting>& mGameSettings;
|
const CSMWorld::IdCollection<ESM::GameSetting>& mGameSettings;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
std::string varTypeToString(ESM::VarType);
|
std::string varTypeToString(ESM::VarType);
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,19 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
CSMTools::JournalCheckStage::JournalCheckStage(const CSMWorld::IdCollection<ESM::Dialogue> &journals,
|
CSMTools::JournalCheckStage::JournalCheckStage(const CSMWorld::IdCollection<ESM::Dialogue> &journals,
|
||||||
const CSMWorld::InfoCollection& journalInfos)
|
const CSMWorld::InfoCollection& journalInfos)
|
||||||
: mJournals(journals), mJournalInfos(journalInfos)
|
: mJournals(journals), mJournalInfos(journalInfos)
|
||||||
{}
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::JournalCheckStage::setup()
|
int CSMTools::JournalCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mJournals.getSize();
|
return mJournals.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +23,8 @@ void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::Dialogue> &journalRecord = mJournals.getRecord(stage);
|
const CSMWorld::Record<ESM::Dialogue> &journalRecord = mJournals.getRecord(stage);
|
||||||
|
|
||||||
if (journalRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && journalRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || journalRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Dialogue &journal = journalRecord.get();
|
const ESM::Dialogue &journal = journalRecord.get();
|
||||||
|
@ -43,6 +50,10 @@ void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages)
|
||||||
statusNamedCount += 1;
|
statusNamedCount += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skip "Base" records (setting!)
|
||||||
|
if (mIgnoreBaseRecords && infoRecord.mState == CSMWorld::RecordBase::State_BaseOnly)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (journalInfo.mResponse.empty())
|
if (journalInfo.mResponse.empty())
|
||||||
{
|
{
|
||||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_JournalInfo, journalInfo.mId);
|
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_JournalInfo, journalInfo.mId);
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace CSMTools
|
||||||
|
|
||||||
const CSMWorld::IdCollection<ESM::Dialogue>& mJournals;
|
const CSMWorld::IdCollection<ESM::Dialogue>& mJournals;
|
||||||
const CSMWorld::InfoCollection& mJournalInfos;
|
const CSMWorld::InfoCollection& mJournalInfos;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include "../world/resources.hpp"
|
#include "../world/resources.hpp"
|
||||||
#include "../world/data.hpp"
|
#include "../world/data.hpp"
|
||||||
|
|
||||||
|
@ -77,16 +79,26 @@ CSMTools::MagicEffectCheckStage::MagicEffectCheckStage(const CSMWorld::IdCollect
|
||||||
mReferenceables(referenceables),
|
mReferenceables(referenceables),
|
||||||
mIcons(icons),
|
mIcons(icons),
|
||||||
mTextures(textures)
|
mTextures(textures)
|
||||||
{}
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::MagicEffectCheckStage::setup()
|
int CSMTools::MagicEffectCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mMagicEffects.getSize();
|
return mMagicEffects.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::MagicEffectCheckStage::perform(int stage, CSMDoc::Messages &messages)
|
void CSMTools::MagicEffectCheckStage::perform(int stage, CSMDoc::Messages &messages)
|
||||||
{
|
{
|
||||||
ESM::MagicEffect effect = mMagicEffects.getRecord(stage).get();
|
const CSMWorld::Record<ESM::MagicEffect> &record = mMagicEffects.getRecord(stage);
|
||||||
|
|
||||||
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ESM::MagicEffect effect = record.get();
|
||||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_MagicEffect, effect.mId);
|
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_MagicEffect, effect.mId);
|
||||||
|
|
||||||
if (effect.mData.mBaseCost < 0.0f)
|
if (effect.mData.mBaseCost < 0.0f)
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace CSMTools
|
||||||
const CSMWorld::RefIdCollection &mReferenceables;
|
const CSMWorld::RefIdCollection &mReferenceables;
|
||||||
const CSMWorld::Resources &mIcons;
|
const CSMWorld::Resources &mIcons;
|
||||||
const CSMWorld::Resources &mTextures;
|
const CSMWorld::Resources &mTextures;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isTextureExists(const std::string &texture, bool isIcon) const;
|
bool isTextureExists(const std::string &texture, bool isIcon) const;
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
#include "../world/idcollection.hpp"
|
#include "../world/idcollection.hpp"
|
||||||
#include "../world/subcellcollection.hpp"
|
#include "../world/subcellcollection.hpp"
|
||||||
|
@ -10,10 +12,14 @@
|
||||||
|
|
||||||
CSMTools::PathgridCheckStage::PathgridCheckStage (const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids)
|
CSMTools::PathgridCheckStage::PathgridCheckStage (const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids)
|
||||||
: mPathgrids (pathgrids)
|
: mPathgrids (pathgrids)
|
||||||
{}
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::PathgridCheckStage::setup()
|
int CSMTools::PathgridCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mPathgrids.getSize();
|
return mPathgrids.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +27,8 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<CSMWorld::Pathgrid>& record = mPathgrids.getRecord (stage);
|
const CSMWorld::Record<CSMWorld::Pathgrid>& record = mPathgrids.getRecord (stage);
|
||||||
|
|
||||||
if (record.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const CSMWorld::Pathgrid& pathgrid = record.get();
|
const CSMWorld::Pathgrid& pathgrid = record.get();
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace CSMTools
|
||||||
{
|
{
|
||||||
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid,
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid,
|
||||||
CSMWorld::IdAccessor<CSMWorld::Pathgrid> >& mPathgrids;
|
CSMWorld::IdAccessor<CSMWorld::Pathgrid> >& mPathgrids;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include <components/esm/loadrace.hpp>
|
#include <components/esm/loadrace.hpp>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
void CSMTools::RaceCheckStage::performPerRecord (int stage, CSMDoc::Messages& messages)
|
void CSMTools::RaceCheckStage::performPerRecord (int stage, CSMDoc::Messages& messages)
|
||||||
|
@ -15,6 +17,14 @@ void CSMTools::RaceCheckStage::performPerRecord (int stage, CSMDoc::Messages& me
|
||||||
|
|
||||||
const ESM::Race& race = record.get();
|
const ESM::Race& race = record.get();
|
||||||
|
|
||||||
|
// Consider mPlayable flag even when "Base" records are ignored
|
||||||
|
if (race.mData.mFlags & 0x1)
|
||||||
|
mPlayable = true;
|
||||||
|
|
||||||
|
// Skip "Base" records (setting!)
|
||||||
|
if (mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly)
|
||||||
|
return;
|
||||||
|
|
||||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Race, race.mId);
|
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Race, race.mId);
|
||||||
|
|
||||||
// test for empty name and description
|
// test for empty name and description
|
||||||
|
@ -38,10 +48,6 @@ void CSMTools::RaceCheckStage::performPerRecord (int stage, CSMDoc::Messages& me
|
||||||
if (race.mData.mWeight.mFemale<0)
|
if (race.mData.mWeight.mFemale<0)
|
||||||
messages.push_back (std::make_pair (id, "female " + race.mId + " has negative weight"));
|
messages.push_back (std::make_pair (id, "female " + race.mId + " has negative weight"));
|
||||||
|
|
||||||
// remember playable flag
|
|
||||||
if (race.mData.mFlags & 0x1)
|
|
||||||
mPlayable = true;
|
|
||||||
|
|
||||||
/// \todo check data members that can't be edited in the table view
|
/// \todo check data members that can't be edited in the table view
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,11 +61,15 @@ void CSMTools::RaceCheckStage::performFinal (CSMDoc::Messages& messages)
|
||||||
|
|
||||||
CSMTools::RaceCheckStage::RaceCheckStage (const CSMWorld::IdCollection<ESM::Race>& races)
|
CSMTools::RaceCheckStage::RaceCheckStage (const CSMWorld::IdCollection<ESM::Race>& races)
|
||||||
: mRaces (races), mPlayable (false)
|
: mRaces (races), mPlayable (false)
|
||||||
{}
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::RaceCheckStage::setup()
|
int CSMTools::RaceCheckStage::setup()
|
||||||
{
|
{
|
||||||
mPlayable = false;
|
mPlayable = false;
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mRaces.getSize()+1;
|
return mRaces.getSize()+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace CSMTools
|
||||||
{
|
{
|
||||||
const CSMWorld::IdCollection<ESM::Race>& mRaces;
|
const CSMWorld::IdCollection<ESM::Race>& mRaces;
|
||||||
bool mPlayable;
|
bool mPlayable;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
void performPerRecord (int stage, CSMDoc::Messages& messages);
|
void performPerRecord (int stage, CSMDoc::Messages& messages);
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include "../world/record.hpp"
|
#include "../world/record.hpp"
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
|
@ -18,6 +20,7 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(
|
||||||
mScripts(scripts),
|
mScripts(scripts),
|
||||||
mPlayerPresent(false)
|
mPlayerPresent(false)
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::ReferenceableCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
void CSMTools::ReferenceableCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
|
@ -228,6 +231,8 @@ void CSMTools::ReferenceableCheckStage::perform (int stage, CSMDoc::Messages& me
|
||||||
int CSMTools::ReferenceableCheckStage::setup()
|
int CSMTools::ReferenceableCheckStage::setup()
|
||||||
{
|
{
|
||||||
mPlayerPresent = false;
|
mPlayerPresent = false;
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mReferencables.getSize() + 1;
|
return mReferencables.getSize() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +243,8 @@ void CSMTools::ReferenceableCheckStage::bookCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Book& book = (dynamic_cast<const CSMWorld::Record<ESM::Book>& >(baseRecord)).get();
|
const ESM::Book& book = (dynamic_cast<const CSMWorld::Record<ESM::Book>& >(baseRecord)).get();
|
||||||
|
@ -257,7 +263,8 @@ void CSMTools::ReferenceableCheckStage::activatorCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Activator& activator = (dynamic_cast<const CSMWorld::Record<ESM::Activator>& >(baseRecord)).get();
|
const ESM::Activator& activator = (dynamic_cast<const CSMWorld::Record<ESM::Activator>& >(baseRecord)).get();
|
||||||
|
@ -278,7 +285,8 @@ void CSMTools::ReferenceableCheckStage::potionCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Potion& potion = (dynamic_cast<const CSMWorld::Record<ESM::Potion>& >(baseRecord)).get();
|
const ESM::Potion& potion = (dynamic_cast<const CSMWorld::Record<ESM::Potion>& >(baseRecord)).get();
|
||||||
|
@ -299,7 +307,8 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Apparatus& apparatus = (dynamic_cast<const CSMWorld::Record<ESM::Apparatus>& >(baseRecord)).get();
|
const ESM::Apparatus& apparatus = (dynamic_cast<const CSMWorld::Record<ESM::Apparatus>& >(baseRecord)).get();
|
||||||
|
@ -320,7 +329,8 @@ void CSMTools::ReferenceableCheckStage::armorCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Armor& armor = (dynamic_cast<const CSMWorld::Record<ESM::Armor>& >(baseRecord)).get();
|
const ESM::Armor& armor = (dynamic_cast<const CSMWorld::Record<ESM::Armor>& >(baseRecord)).get();
|
||||||
|
@ -347,7 +357,8 @@ void CSMTools::ReferenceableCheckStage::clothingCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Clothing& clothing = (dynamic_cast<const CSMWorld::Record<ESM::Clothing>& >(baseRecord)).get();
|
const ESM::Clothing& clothing = (dynamic_cast<const CSMWorld::Record<ESM::Clothing>& >(baseRecord)).get();
|
||||||
|
@ -365,7 +376,8 @@ void CSMTools::ReferenceableCheckStage::containerCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Container& container = (dynamic_cast<const CSMWorld::Record<ESM::Container>& >(baseRecord)).get();
|
const ESM::Container& container = (dynamic_cast<const CSMWorld::Record<ESM::Container>& >(baseRecord)).get();
|
||||||
|
@ -397,7 +409,8 @@ void CSMTools::ReferenceableCheckStage::creatureCheck (
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Creature& creature = (dynamic_cast<const CSMWorld::Record<ESM::Creature>&>(baseRecord)).get();
|
const ESM::Creature& creature = (dynamic_cast<const CSMWorld::Record<ESM::Creature>&>(baseRecord)).get();
|
||||||
|
@ -473,7 +486,8 @@ void CSMTools::ReferenceableCheckStage::doorCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Door& door = (dynamic_cast<const CSMWorld::Record<ESM::Door>&>(baseRecord)).get();
|
const ESM::Door& door = (dynamic_cast<const CSMWorld::Record<ESM::Door>&>(baseRecord)).get();
|
||||||
|
@ -497,7 +511,8 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Ingredient& ingredient = (dynamic_cast<const CSMWorld::Record<ESM::Ingredient>& >(baseRecord)).get();
|
const ESM::Ingredient& ingredient = (dynamic_cast<const CSMWorld::Record<ESM::Ingredient>& >(baseRecord)).get();
|
||||||
|
@ -516,10 +531,9 @@ void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
{
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
const ESM::CreatureLevList& CreatureLevList = (dynamic_cast<const CSMWorld::Record<ESM::CreatureLevList>& >(baseRecord)).get();
|
const ESM::CreatureLevList& CreatureLevList = (dynamic_cast<const CSMWorld::Record<ESM::CreatureLevList>& >(baseRecord)).get();
|
||||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_CreatureLevelledList, CreatureLevList.mId); //CreatureLevList but Type_CreatureLevelledList :/
|
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_CreatureLevelledList, CreatureLevList.mId); //CreatureLevList but Type_CreatureLevelledList :/
|
||||||
|
@ -534,10 +548,9 @@ void CSMTools::ReferenceableCheckStage::itemLevelledListCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
{
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
const ESM::ItemLevList& ItemLevList = (dynamic_cast<const CSMWorld::Record<ESM::ItemLevList>& >(baseRecord)).get();
|
const ESM::ItemLevList& ItemLevList = (dynamic_cast<const CSMWorld::Record<ESM::ItemLevList>& >(baseRecord)).get();
|
||||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_ItemLevelledList, ItemLevList.mId);
|
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_ItemLevelledList, ItemLevList.mId);
|
||||||
|
@ -551,7 +564,8 @@ void CSMTools::ReferenceableCheckStage::lightCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Light& light = (dynamic_cast<const CSMWorld::Record<ESM::Light>& >(baseRecord)).get();
|
const ESM::Light& light = (dynamic_cast<const CSMWorld::Record<ESM::Light>& >(baseRecord)).get();
|
||||||
|
@ -574,7 +588,8 @@ void CSMTools::ReferenceableCheckStage::lockpickCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Lockpick& lockpick = (dynamic_cast<const CSMWorld::Record<ESM::Lockpick>& >(baseRecord)).get();
|
const ESM::Lockpick& lockpick = (dynamic_cast<const CSMWorld::Record<ESM::Lockpick>& >(baseRecord)).get();
|
||||||
|
@ -595,7 +610,8 @@ void CSMTools::ReferenceableCheckStage::miscCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Miscellaneous& miscellaneous = (dynamic_cast<const CSMWorld::Record<ESM::Miscellaneous>& >(baseRecord)).get();
|
const ESM::Miscellaneous& miscellaneous = (dynamic_cast<const CSMWorld::Record<ESM::Miscellaneous>& >(baseRecord)).get();
|
||||||
|
@ -619,6 +635,14 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
|
||||||
const ESM::NPC& npc = (dynamic_cast<const CSMWorld::Record<ESM::NPC>& >(baseRecord)).get();
|
const ESM::NPC& npc = (dynamic_cast<const CSMWorld::Record<ESM::NPC>& >(baseRecord)).get();
|
||||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Npc, npc.mId);
|
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Npc, npc.mId);
|
||||||
|
|
||||||
|
//Detect if player is present
|
||||||
|
if (Misc::StringUtils::ciEqual(npc.mId, "player")) //Happy now, scrawl?
|
||||||
|
mPlayerPresent = true;
|
||||||
|
|
||||||
|
// Skip "Base" records (setting!)
|
||||||
|
if (mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly)
|
||||||
|
return;
|
||||||
|
|
||||||
short level(npc.mNpdt.mLevel);
|
short level(npc.mNpdt.mLevel);
|
||||||
char disposition(npc.mNpdt.mDisposition);
|
char disposition(npc.mNpdt.mDisposition);
|
||||||
char reputation(npc.mNpdt.mReputation);
|
char reputation(npc.mNpdt.mReputation);
|
||||||
|
@ -626,10 +650,6 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
|
||||||
//Don't know what unknown is for
|
//Don't know what unknown is for
|
||||||
int gold(npc.mNpdt.mGold);
|
int gold(npc.mNpdt.mGold);
|
||||||
|
|
||||||
//Detect if player is present
|
|
||||||
if (Misc::StringUtils::ciEqual(npc.mId, "player")) //Happy now, scrawl?
|
|
||||||
mPlayerPresent = true;
|
|
||||||
|
|
||||||
if (npc.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) //12 = autocalculated
|
if (npc.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) //12 = autocalculated
|
||||||
{
|
{
|
||||||
if ((npc.mFlags & ESM::NPC::Autocalc) == 0) //0x0010 = autocalculated flag
|
if ((npc.mFlags & ESM::NPC::Autocalc) == 0) //0x0010 = autocalculated flag
|
||||||
|
@ -728,7 +748,8 @@ void CSMTools::ReferenceableCheckStage::weaponCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Weapon& weapon = (dynamic_cast<const CSMWorld::Record<ESM::Weapon>& >(baseRecord)).get();
|
const ESM::Weapon& weapon = (dynamic_cast<const CSMWorld::Record<ESM::Weapon>& >(baseRecord)).get();
|
||||||
|
@ -808,7 +829,8 @@ void CSMTools::ReferenceableCheckStage::probeCheck(
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Probe& probe = (dynamic_cast<const CSMWorld::Record<ESM::Probe>& >(baseRecord)).get();
|
const ESM::Probe& probe = (dynamic_cast<const CSMWorld::Record<ESM::Probe>& >(baseRecord)).get();
|
||||||
|
@ -827,7 +849,8 @@ void CSMTools::ReferenceableCheckStage::repairCheck (
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Repair& repair = (dynamic_cast<const CSMWorld::Record<ESM::Repair>& >(baseRecord)).get();
|
const ESM::Repair& repair = (dynamic_cast<const CSMWorld::Record<ESM::Repair>& >(baseRecord)).get();
|
||||||
|
@ -846,7 +869,8 @@ void CSMTools::ReferenceableCheckStage::staticCheck (
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
|
||||||
|
|
||||||
if (baseRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Static& staticElement = (dynamic_cast<const CSMWorld::Record<ESM::Static>& >(baseRecord)).get();
|
const ESM::Static& staticElement = (dynamic_cast<const CSMWorld::Record<ESM::Static>& >(baseRecord)).get();
|
||||||
|
|
|
@ -82,6 +82,7 @@ namespace CSMTools
|
||||||
const CSMWorld::IdCollection<ESM::Faction>& mFactions;
|
const CSMWorld::IdCollection<ESM::Faction>& mFactions;
|
||||||
const CSMWorld::IdCollection<ESM::Script>& mScripts;
|
const CSMWorld::IdCollection<ESM::Script>& mScripts;
|
||||||
bool mPlayerPresent;
|
bool mPlayerPresent;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif // REFERENCEABLECHECKSTAGE_H
|
#endif // REFERENCEABLECHECKSTAGE_H
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "referencecheck.hpp"
|
#include "referencecheck.hpp"
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
CSMTools::ReferenceCheckStage::ReferenceCheckStage(
|
CSMTools::ReferenceCheckStage::ReferenceCheckStage(
|
||||||
const CSMWorld::RefCollection& references,
|
const CSMWorld::RefCollection& references,
|
||||||
const CSMWorld::RefIdCollection& referencables,
|
const CSMWorld::RefIdCollection& referencables,
|
||||||
|
@ -12,13 +14,15 @@ CSMTools::ReferenceCheckStage::ReferenceCheckStage(
|
||||||
mCells(cells),
|
mCells(cells),
|
||||||
mFactions(factions)
|
mFactions(factions)
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages &messages)
|
void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages &messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<CSMWorld::CellRef>& record = mReferences.getRecord(stage);
|
const CSMWorld::Record<CSMWorld::CellRef>& record = mReferences.getRecord(stage);
|
||||||
|
|
||||||
if (record.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const CSMWorld::CellRef& cellRef = record.get();
|
const CSMWorld::CellRef& cellRef = record.get();
|
||||||
|
@ -100,5 +104,7 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages &message
|
||||||
|
|
||||||
int CSMTools::ReferenceCheckStage::setup()
|
int CSMTools::ReferenceCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mReferences.getSize();
|
return mReferences.getSize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace CSMTools
|
||||||
const CSMWorld::RefIdData& mDataSet;
|
const CSMWorld::RefIdData& mDataSet;
|
||||||
const CSMWorld::IdCollection<CSMWorld::Cell>& mCells;
|
const CSMWorld::IdCollection<CSMWorld::Cell>& mCells;
|
||||||
const CSMWorld::IdCollection<ESM::Faction>& mFactions;
|
const CSMWorld::IdCollection<ESM::Faction>& mFactions;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,20 @@
|
||||||
|
|
||||||
#include <components/esm/loadregn.hpp>
|
#include <components/esm/loadregn.hpp>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
CSMTools::RegionCheckStage::RegionCheckStage (const CSMWorld::IdCollection<ESM::Region>& regions)
|
CSMTools::RegionCheckStage::RegionCheckStage (const CSMWorld::IdCollection<ESM::Region>& regions)
|
||||||
: mRegions (regions)
|
: mRegions (regions)
|
||||||
{}
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::RegionCheckStage::setup()
|
int CSMTools::RegionCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mRegions.getSize();
|
return mRegions.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +26,8 @@ void CSMTools::RegionCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::Region>& record = mRegions.getRecord (stage);
|
const CSMWorld::Record<ESM::Region>& record = mRegions.getRecord (stage);
|
||||||
|
|
||||||
if (record.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Region& region = record.get();
|
const ESM::Region& region = record.get();
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace CSMTools
|
||||||
class RegionCheckStage : public CSMDoc::Stage
|
class RegionCheckStage : public CSMDoc::Stage
|
||||||
{
|
{
|
||||||
const CSMWorld::IdCollection<ESM::Region>& mRegions;
|
const CSMWorld::IdCollection<ESM::Region>& mRegions;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,8 @@ CSMTools::ScriptCheckStage::ScriptCheckStage (const CSMDoc::Document& document)
|
||||||
|
|
||||||
Compiler::registerExtensions (mExtensions);
|
Compiler::registerExtensions (mExtensions);
|
||||||
mContext.setExtensions (&mExtensions);
|
mContext.setExtensions (&mExtensions);
|
||||||
|
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CSMTools::ScriptCheckStage::setup()
|
int CSMTools::ScriptCheckStage::setup()
|
||||||
|
@ -78,17 +80,25 @@ int CSMTools::ScriptCheckStage::setup()
|
||||||
mId.clear();
|
mId.clear();
|
||||||
Compiler::ErrorHandler::reset();
|
Compiler::ErrorHandler::reset();
|
||||||
|
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mDocument.getData().getScripts().getSize();
|
return mDocument.getData().getScripts().getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
|
const CSMWorld::Record<ESM::Script> &record = mDocument.getData().getScripts().getRecord(stage);
|
||||||
|
|
||||||
mId = mDocument.getData().getScripts().getId (stage);
|
mId = mDocument.getData().getScripts().getId (stage);
|
||||||
|
|
||||||
if (mDocument.isBlacklisted (
|
if (mDocument.isBlacklisted (
|
||||||
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Script, mId)))
|
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Script, mId)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
|
||||||
|
return;
|
||||||
|
|
||||||
mMessages = &messages;
|
mMessages = &messages;
|
||||||
|
|
||||||
switch (mWarningMode)
|
switch (mWarningMode)
|
||||||
|
@ -100,10 +110,8 @@ void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const CSMWorld::Data& data = mDocument.getData();
|
mFile = record.get().mId;
|
||||||
|
std::istringstream input (record.get().mScriptText);
|
||||||
mFile = data.getScripts().getRecord (stage).get().mId;
|
|
||||||
std::istringstream input (data.getScripts().getRecord (stage).get().mScriptText);
|
|
||||||
|
|
||||||
Compiler::Scanner scanner (*this, input, mContext.getExtensions());
|
Compiler::Scanner scanner (*this, input, mContext.getExtensions());
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace CSMTools
|
||||||
std::string mFile;
|
std::string mFile;
|
||||||
CSMDoc::Messages *mMessages;
|
CSMDoc::Messages *mMessages;
|
||||||
WarningMode mWarningMode;
|
WarningMode mWarningMode;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
CSMDoc::Message::Severity getSeverity (Type type);
|
CSMDoc::Message::Severity getSeverity (Type type);
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,20 @@
|
||||||
|
|
||||||
#include <components/esm/loadskil.hpp>
|
#include <components/esm/loadskil.hpp>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
CSMTools::SkillCheckStage::SkillCheckStage (const CSMWorld::IdCollection<ESM::Skill>& skills)
|
CSMTools::SkillCheckStage::SkillCheckStage (const CSMWorld::IdCollection<ESM::Skill>& skills)
|
||||||
: mSkills (skills)
|
: mSkills (skills)
|
||||||
{}
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::SkillCheckStage::setup()
|
int CSMTools::SkillCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mSkills.getSize();
|
return mSkills.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +25,8 @@ void CSMTools::SkillCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::Skill>& record = mSkills.getRecord (stage);
|
const CSMWorld::Record<ESM::Skill>& record = mSkills.getRecord (stage);
|
||||||
|
|
||||||
if (record.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Skill& skill = record.get();
|
const ESM::Skill& skill = record.get();
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace CSMTools
|
||||||
class SkillCheckStage : public CSMDoc::Stage
|
class SkillCheckStage : public CSMDoc::Stage
|
||||||
{
|
{
|
||||||
const CSMWorld::IdCollection<ESM::Skill>& mSkills;
|
const CSMWorld::IdCollection<ESM::Skill>& mSkills;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,20 @@
|
||||||
|
|
||||||
#include <components/esm/loadskil.hpp>
|
#include <components/esm/loadskil.hpp>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
CSMTools::SoundCheckStage::SoundCheckStage (const CSMWorld::IdCollection<ESM::Sound>& sounds)
|
CSMTools::SoundCheckStage::SoundCheckStage (const CSMWorld::IdCollection<ESM::Sound>& sounds)
|
||||||
: mSounds (sounds)
|
: mSounds (sounds)
|
||||||
{}
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::SoundCheckStage::setup()
|
int CSMTools::SoundCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mSounds.getSize();
|
return mSounds.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +25,8 @@ void CSMTools::SoundCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::Sound>& record = mSounds.getRecord (stage);
|
const CSMWorld::Record<ESM::Sound>& record = mSounds.getRecord (stage);
|
||||||
|
|
||||||
if (record.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Sound& sound = record.get();
|
const ESM::Sound& sound = record.get();
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace CSMTools
|
||||||
class SoundCheckStage : public CSMDoc::Stage
|
class SoundCheckStage : public CSMDoc::Stage
|
||||||
{
|
{
|
||||||
const CSMWorld::IdCollection<ESM::Sound>& mSounds;
|
const CSMWorld::IdCollection<ESM::Sound>& mSounds;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include "../world/refiddata.hpp"
|
#include "../world/refiddata.hpp"
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
|
@ -11,20 +13,24 @@ CSMTools::SoundGenCheckStage::SoundGenCheckStage(const CSMWorld::IdCollection<ES
|
||||||
: mSoundGens(soundGens),
|
: mSoundGens(soundGens),
|
||||||
mSounds(sounds),
|
mSounds(sounds),
|
||||||
mReferenceables(referenceables)
|
mReferenceables(referenceables)
|
||||||
{}
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::SoundGenCheckStage::setup()
|
int CSMTools::SoundGenCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mSoundGens.getSize();
|
return mSoundGens.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::SoundGenCheckStage::perform(int stage, CSMDoc::Messages &messages)
|
void CSMTools::SoundGenCheckStage::perform(int stage, CSMDoc::Messages &messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::SoundGenerator> &record = mSoundGens.getRecord(stage);
|
const CSMWorld::Record<ESM::SoundGenerator> &record = mSoundGens.getRecord(stage);
|
||||||
if (record.isDeleted())
|
|
||||||
{
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
const ESM::SoundGenerator& soundGen = record.get();
|
const ESM::SoundGenerator& soundGen = record.get();
|
||||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_SoundGen, soundGen.mId);
|
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_SoundGen, soundGen.mId);
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace CSMTools
|
||||||
const CSMWorld::IdCollection<ESM::SoundGenerator> &mSoundGens;
|
const CSMWorld::IdCollection<ESM::SoundGenerator> &mSoundGens;
|
||||||
const CSMWorld::IdCollection<ESM::Sound> &mSounds;
|
const CSMWorld::IdCollection<ESM::Sound> &mSounds;
|
||||||
const CSMWorld::RefIdCollection &mReferenceables;
|
const CSMWorld::RefIdCollection &mReferenceables;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SoundGenCheckStage(const CSMWorld::IdCollection<ESM::SoundGenerator> &soundGens,
|
SoundGenCheckStage(const CSMWorld::IdCollection<ESM::SoundGenerator> &soundGens,
|
||||||
|
|
|
@ -5,14 +5,20 @@
|
||||||
|
|
||||||
#include <components/esm/loadspel.hpp>
|
#include <components/esm/loadspel.hpp>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
CSMTools::SpellCheckStage::SpellCheckStage (const CSMWorld::IdCollection<ESM::Spell>& spells)
|
CSMTools::SpellCheckStage::SpellCheckStage (const CSMWorld::IdCollection<ESM::Spell>& spells)
|
||||||
: mSpells (spells)
|
: mSpells (spells)
|
||||||
{}
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::SpellCheckStage::setup()
|
int CSMTools::SpellCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mSpells.getSize();
|
return mSpells.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +26,8 @@ void CSMTools::SpellCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::Spell>& record = mSpells.getRecord (stage);
|
const CSMWorld::Record<ESM::Spell>& record = mSpells.getRecord (stage);
|
||||||
|
|
||||||
if (record.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ESM::Spell& spell = record.get();
|
const ESM::Spell& spell = record.get();
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace CSMTools
|
||||||
class SpellCheckStage : public CSMDoc::Stage
|
class SpellCheckStage : public CSMDoc::Stage
|
||||||
{
|
{
|
||||||
const CSMWorld::IdCollection<ESM::Spell>& mSpells;
|
const CSMWorld::IdCollection<ESM::Spell>& mSpells;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,23 @@
|
||||||
#include "startscriptcheck.hpp"
|
#include "startscriptcheck.hpp"
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
CSMTools::StartScriptCheckStage::StartScriptCheckStage (
|
CSMTools::StartScriptCheckStage::StartScriptCheckStage (
|
||||||
const CSMWorld::IdCollection<ESM::StartScript>& startScripts,
|
const CSMWorld::IdCollection<ESM::StartScript>& startScripts,
|
||||||
const CSMWorld::IdCollection<ESM::Script>& scripts)
|
const CSMWorld::IdCollection<ESM::Script>& scripts)
|
||||||
: mStartScripts (startScripts), mScripts (scripts)
|
: mStartScripts (startScripts), mScripts (scripts)
|
||||||
{}
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
void CSMTools::StartScriptCheckStage::perform(int stage, CSMDoc::Messages& messages)
|
void CSMTools::StartScriptCheckStage::perform(int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::StartScript>& record = mStartScripts.getRecord (stage);
|
const CSMWorld::Record<ESM::StartScript>& record = mStartScripts.getRecord (stage);
|
||||||
|
|
||||||
if (record.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::string scriptId = record.get().mId;
|
std::string scriptId = record.get().mId;
|
||||||
|
@ -26,5 +31,7 @@ void CSMTools::StartScriptCheckStage::perform(int stage, CSMDoc::Messages& messa
|
||||||
|
|
||||||
int CSMTools::StartScriptCheckStage::setup()
|
int CSMTools::StartScriptCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mStartScripts.getSize();
|
return mStartScripts.getSize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace CSMTools
|
||||||
{
|
{
|
||||||
const CSMWorld::IdCollection<ESM::StartScript>& mStartScripts;
|
const CSMWorld::IdCollection<ESM::StartScript>& mStartScripts;
|
||||||
const CSMWorld::IdCollection<ESM::Script>& mScripts;
|
const CSMWorld::IdCollection<ESM::Script>& mScripts;
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include "../world/infoselectwrapper.hpp"
|
#include "../world/infoselectwrapper.hpp"
|
||||||
|
|
||||||
CSMTools::TopicInfoCheckStage::TopicInfoCheckStage(
|
CSMTools::TopicInfoCheckStage::TopicInfoCheckStage(
|
||||||
|
@ -29,7 +31,9 @@ CSMTools::TopicInfoCheckStage::TopicInfoCheckStage(
|
||||||
mTopics(topics),
|
mTopics(topics),
|
||||||
mReferencables(referencables),
|
mReferencables(referencables),
|
||||||
mSoundFiles(soundFiles)
|
mSoundFiles(soundFiles)
|
||||||
{}
|
{
|
||||||
|
mIgnoreBaseRecords = false;
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::TopicInfoCheckStage::setup()
|
int CSMTools::TopicInfoCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
@ -67,6 +71,8 @@ int CSMTools::TopicInfoCheckStage::setup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
|
||||||
|
|
||||||
return mTopicInfos.getSize();
|
return mTopicInfos.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +80,8 @@ void CSMTools::TopicInfoCheckStage::perform(int stage, CSMDoc::Messages& message
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<CSMWorld::Info>& infoRecord = mTopicInfos.getRecord(stage);
|
const CSMWorld::Record<CSMWorld::Info>& infoRecord = mTopicInfos.getRecord(stage);
|
||||||
|
|
||||||
if (infoRecord.isDeleted())
|
// Skip "Base" records (setting!) and "Deleted" records
|
||||||
|
if ((mIgnoreBaseRecords && infoRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || infoRecord.isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const CSMWorld::Info& topicInfo = infoRecord.get();
|
const CSMWorld::Info& topicInfo = infoRecord.get();
|
||||||
|
|
|
@ -65,6 +65,8 @@ namespace CSMTools
|
||||||
|
|
||||||
std::set<std::string> mCellNames;
|
std::set<std::string> mCellNames;
|
||||||
|
|
||||||
|
bool mIgnoreBaseRecords;
|
||||||
|
|
||||||
// These return false when not successful and write an error
|
// These return false when not successful and write an error
|
||||||
bool verifyActor(const std::string& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
|
bool verifyActor(const std::string& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
|
||||||
bool verifyCell(const std::string& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
|
bool verifyCell(const std::string& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
|
||||||
|
|
|
@ -441,9 +441,8 @@ void OMW::Engine::setWindowIcon()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osg::Image> image = result.getImage();
|
osg::ref_ptr<osg::Image> image = result.getImage();
|
||||||
SDL_Surface* surface = SDLUtil::imageToSurface(image, true);
|
auto surface = SDLUtil::imageToSurface(image, true);
|
||||||
SDL_SetWindowIcon(mWindow, surface);
|
SDL_SetWindowIcon(mWindow, surface.get());
|
||||||
SDL_FreeSurface(surface);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2026,9 +2026,10 @@ void CharacterController::update(float duration)
|
||||||
{
|
{
|
||||||
// initial start of death animation for actors that started the game as dead
|
// initial start of death animation for actors that started the game as dead
|
||||||
// not done in constructor since we need to give scripts a chance to set the mSkipAnim flag
|
// not done in constructor since we need to give scripts a chance to set the mSkipAnim flag
|
||||||
if (!mSkipAnim && mDeathState != CharState_None && mCurrentDeath.empty() && cls.isPersistent(mPtr))
|
if (!mSkipAnim && mDeathState != CharState_None && mCurrentDeath.empty())
|
||||||
{
|
{
|
||||||
// Fast-forward death animation to end for persisting corpses
|
// Fast-forward death animation to end for persisting corpses or corpses after end of death animation
|
||||||
|
if (cls.isPersistent(mPtr) || cls.getCreatureStats(mPtr).isDeathAnimationFinished())
|
||||||
playDeath(1.f, mDeathState);
|
playDeath(1.f, mDeathState);
|
||||||
}
|
}
|
||||||
// We must always queue movement, even if there is none, to apply gravity.
|
// We must always queue movement, even if there is none, to apply gravity.
|
||||||
|
|
|
@ -645,6 +645,7 @@ namespace MWMechanics
|
||||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
const ESM::MagicEffect *magiceffect = store.get<ESM::MagicEffect>().find(effectId);
|
const ESM::MagicEffect *magiceffect = store.get<ESM::MagicEffect>().find(effectId);
|
||||||
MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(target);
|
MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(target);
|
||||||
|
if (animation)
|
||||||
animation->addSpellCastGlow(magiceffect);
|
animation->addSpellCastGlow(magiceffect);
|
||||||
if (target.getCellRef().getLockLevel() < magnitude) //If the door is not already locked to a higher value, lock it to spell magnitude
|
if (target.getCellRef().getLockLevel() < magnitude) //If the door is not already locked to a higher value, lock it to spell magnitude
|
||||||
{
|
{
|
||||||
|
@ -659,14 +660,16 @@ namespace MWMechanics
|
||||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
const ESM::MagicEffect *magiceffect = store.get<ESM::MagicEffect>().find(effectId);
|
const ESM::MagicEffect *magiceffect = store.get<ESM::MagicEffect>().find(effectId);
|
||||||
MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(target);
|
MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(target);
|
||||||
|
if (animation)
|
||||||
animation->addSpellCastGlow(magiceffect);
|
animation->addSpellCastGlow(magiceffect);
|
||||||
if (target.getCellRef().getLockLevel() <= magnitude)
|
if (target.getCellRef().getLockLevel() <= magnitude)
|
||||||
{
|
{
|
||||||
if (target.getCellRef().getLockLevel() > 0)
|
if (target.getCellRef().getLockLevel() > 0)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock", 1.f, 1.f);
|
MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock", 1.f, 1.f);
|
||||||
if (!caster.isEmpty() && caster.getClass().isActor())
|
if (!caster.isEmpty())
|
||||||
MWBase::Environment::get().getMechanicsManager()->objectOpened(caster, target);
|
MWBase::Environment::get().getMechanicsManager()->objectOpened(getPlayer(), target);
|
||||||
|
// Use the player instead of the caster for vanilla crime compatibility
|
||||||
|
|
||||||
if (caster == getPlayer())
|
if (caster == getPlayer())
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicOpenSuccess}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicOpenSuccess}");
|
||||||
|
|
|
@ -100,7 +100,13 @@ namespace
|
||||||
|
|
||||||
void apply(osg::MatrixTransform& trans)
|
void apply(osg::MatrixTransform& trans)
|
||||||
{
|
{
|
||||||
mMap[Misc::StringUtils::lowerCase(trans.getName())] = &trans;
|
// Take transformation for first found node in file
|
||||||
|
const std::string nodeName = Misc::StringUtils::lowerCase(trans.getName());
|
||||||
|
if (mMap.find(nodeName) == mMap.end())
|
||||||
|
{
|
||||||
|
mMap[nodeName] = &trans;
|
||||||
|
}
|
||||||
|
|
||||||
traverse(trans);
|
traverse(trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -251,11 +251,14 @@ void FFmpeg_Decoder::open(const std::string &fname)
|
||||||
if(mOutputChannelLayout == 0)
|
if(mOutputChannelLayout == 0)
|
||||||
mOutputChannelLayout = av_get_default_channel_layout((*mStream)->codec->channels);
|
mOutputChannelLayout = av_get_default_channel_layout((*mStream)->codec->channels);
|
||||||
}
|
}
|
||||||
catch(...) {
|
catch(...)
|
||||||
|
{
|
||||||
if(mStream)
|
if(mStream)
|
||||||
avcodec_close((*mStream)->codec);
|
avcodec_close((*mStream)->codec);
|
||||||
mStream = NULL;
|
mStream = NULL;
|
||||||
|
|
||||||
|
if (mFormatCtx != NULL)
|
||||||
|
{
|
||||||
if (mFormatCtx->pb->buffer != NULL)
|
if (mFormatCtx->pb->buffer != NULL)
|
||||||
{
|
{
|
||||||
av_free(mFormatCtx->pb->buffer);
|
av_free(mFormatCtx->pb->buffer);
|
||||||
|
@ -265,7 +268,7 @@ void FFmpeg_Decoder::open(const std::string &fname)
|
||||||
mFormatCtx->pb = NULL;
|
mFormatCtx->pb = NULL;
|
||||||
|
|
||||||
avformat_close_input(&mFormatCtx);
|
avformat_close_input(&mFormatCtx);
|
||||||
throw;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -361,6 +361,11 @@ namespace ESMTerrain
|
||||||
|
|
||||||
std::string Storage::getTextureName(UniqueTextureId id)
|
std::string Storage::getTextureName(UniqueTextureId id)
|
||||||
{
|
{
|
||||||
|
// Goes under used terrain blend transitions
|
||||||
|
static const std::string baseTexture = "textures\\tx_black_01.dds";
|
||||||
|
if (id.first == -1)
|
||||||
|
return baseTexture;
|
||||||
|
|
||||||
static const std::string defaultTexture = "textures\\_land_default.dds";
|
static const std::string defaultTexture = "textures\\_land_default.dds";
|
||||||
if (id.first == 0)
|
if (id.first == 0)
|
||||||
return defaultTexture; // Not sure if the default texture really is hardcoded?
|
return defaultTexture; // Not sure if the default texture really is hardcoded?
|
||||||
|
@ -396,11 +401,9 @@ namespace ESMTerrain
|
||||||
// Save the used texture indices so we know the total number of textures
|
// Save the used texture indices so we know the total number of textures
|
||||||
// and number of required blend maps
|
// and number of required blend maps
|
||||||
std::set<UniqueTextureId> textureIndices;
|
std::set<UniqueTextureId> textureIndices;
|
||||||
// Due to the way the blending works, the base layer will always shine through in between
|
// Due to the way the blending works, the base layer will bleed between texture transitions so we want it to be a black texture
|
||||||
// blend transitions (eg halfway between two texels, both blend values will be 0.5, so 25% of base layer visible).
|
// The subsequent passes are added instead of blended, so this gives the correct result
|
||||||
// To get a consistent look, we need to make sure to use the same base layer in all cells.
|
textureIndices.insert(std::make_pair(-1,0)); // -1 goes to tx_black_01
|
||||||
// So we're always adding _land_default.dds as the base layer here, even if it's not referenced in this cell.
|
|
||||||
textureIndices.insert(std::make_pair(0,0));
|
|
||||||
|
|
||||||
LandCache cache;
|
LandCache cache;
|
||||||
|
|
||||||
|
@ -618,15 +621,6 @@ namespace ESMTerrain
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
Terrain::LayerInfo Storage::getDefaultLayer()
|
|
||||||
{
|
|
||||||
Terrain::LayerInfo info;
|
|
||||||
info.mDiffuseMap = "textures\\_land_default.dds";
|
|
||||||
info.mParallax = false;
|
|
||||||
info.mSpecular = false;
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Storage::getCellWorldSize()
|
float Storage::getCellWorldSize()
|
||||||
{
|
{
|
||||||
return static_cast<float>(ESM::Land::REAL_SIZE);
|
return static_cast<float>(ESM::Land::REAL_SIZE);
|
||||||
|
|
|
@ -94,8 +94,6 @@ namespace ESMTerrain
|
||||||
|
|
||||||
virtual float getHeightAt (const osg::Vec3f& worldPos);
|
virtual float getHeightAt (const osg::Vec3f& worldPos);
|
||||||
|
|
||||||
virtual Terrain::LayerInfo getDefaultLayer();
|
|
||||||
|
|
||||||
/// Get the transformation factor for mapping cell units to world units.
|
/// Get the transformation factor for mapping cell units to world units.
|
||||||
virtual float getCellWorldSize();
|
virtual float getCellWorldSize();
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
namespace SDLUtil
|
namespace SDLUtil
|
||||||
{
|
{
|
||||||
|
|
||||||
SDL_Surface* imageToSurface(osg::Image *image, bool flip)
|
SurfaceUniquePtr imageToSurface(osg::Image *image, bool flip)
|
||||||
{
|
{
|
||||||
int width = image->s();
|
int width = image->s();
|
||||||
int height = image->t();
|
int height = image->t();
|
||||||
|
@ -22,7 +22,7 @@ SDL_Surface* imageToSurface(osg::Image *image, bool flip)
|
||||||
static_cast<Uint8>(clr.g() * 255), static_cast<Uint8>(clr.b() * 255), static_cast<Uint8>(clr.a() * 255));
|
static_cast<Uint8>(clr.g() * 255), static_cast<Uint8>(clr.b() * 255), static_cast<Uint8>(clr.a() * 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
return surface;
|
return SurfaceUniquePtr(surface, SDL_FreeSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef OPENMW_COMPONENTS_SDLUTIL_IMAGETOSURFACE_H
|
#ifndef OPENMW_COMPONENTS_SDLUTIL_IMAGETOSURFACE_H
|
||||||
#define OPENMW_COMPONENTS_SDLUTIL_IMAGETOSURFACE_H
|
#define OPENMW_COMPONENTS_SDLUTIL_IMAGETOSURFACE_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
struct SDL_Surface;
|
struct SDL_Surface;
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
|
@ -10,10 +12,10 @@ namespace osg
|
||||||
|
|
||||||
namespace SDLUtil
|
namespace SDLUtil
|
||||||
{
|
{
|
||||||
|
typedef std::unique_ptr<SDL_Surface, void (*)(SDL_Surface *)> SurfaceUniquePtr;
|
||||||
|
|
||||||
/// Convert an osg::Image to an SDL_Surface.
|
/// Convert an osg::Image to an SDL_Surface.
|
||||||
/// @note The returned surface must be freed using SDL_FreeSurface.
|
SurfaceUniquePtr imageToSurface(osg::Image* image, bool flip=false);
|
||||||
SDL_Surface* imageToSurface(osg::Image* image, bool flip=false);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,14 @@
|
||||||
|
|
||||||
#include <SDL_mouse.h>
|
#include <SDL_mouse.h>
|
||||||
#include <SDL_endian.h>
|
#include <SDL_endian.h>
|
||||||
|
#include <SDL_render.h>
|
||||||
|
#include <SDL_hints.h>
|
||||||
|
|
||||||
#include <osg/GraphicsContext>
|
#include <osg/GraphicsContext>
|
||||||
#include <osg/Geometry>
|
#include <osg/Geometry>
|
||||||
#include <osg/Texture2D>
|
#include <osg/Texture2D>
|
||||||
#include <osg/TexMat>
|
#include <osg/TexMat>
|
||||||
|
#include <osg/Version>
|
||||||
#include <osgViewer/GraphicsWindow>
|
#include <osgViewer/GraphicsWindow>
|
||||||
|
|
||||||
#include "imagetosurface.hpp"
|
#include "imagetosurface.hpp"
|
||||||
|
@ -22,8 +25,14 @@
|
||||||
USE_GRAPHICSWINDOW()
|
USE_GRAPHICSWINDOW()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace
|
namespace CursorDecompression
|
||||||
{
|
{
|
||||||
|
// macOS builds use the OSG fork that includes DXTC commit
|
||||||
|
#if OSG_VERSION_GREATER_OR_EQUAL(3, 5, 8) || defined(__APPLE__)
|
||||||
|
static const bool DXTCSupported = true;
|
||||||
|
#else
|
||||||
|
static const bool DXTCSupported = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
class MyGraphicsContext {
|
class MyGraphicsContext {
|
||||||
public:
|
public:
|
||||||
|
@ -80,10 +89,8 @@ namespace
|
||||||
osg::ref_ptr<osg::GraphicsContext> _gc;
|
osg::ref_ptr<osg::GraphicsContext> _gc;
|
||||||
};
|
};
|
||||||
|
|
||||||
osg::ref_ptr<osg::Image> decompress (osg::ref_ptr<osg::Image> source, float rotDegrees)
|
SDLUtil::SurfaceUniquePtr hardwareDecompress (osg::ref_ptr<osg::Image> source, float rotDegrees)
|
||||||
{
|
{
|
||||||
// TODO: use software decompression once S3TC patent expires
|
|
||||||
|
|
||||||
int width = source->s();
|
int width = source->s();
|
||||||
int height = source->t();
|
int height = source->t();
|
||||||
|
|
||||||
|
@ -132,17 +139,6 @@ namespace
|
||||||
|
|
||||||
osg::ref_ptr<osg::Geometry> geom;
|
osg::ref_ptr<osg::Geometry> geom;
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
// Extra flip needed on OS X systems due to a driver bug
|
|
||||||
const char* envval = getenv("OPENMW_CURSOR_WORKAROUND");
|
|
||||||
bool workaround = !envval || envval == std::string("1");
|
|
||||||
std::string vendorString = (const char*)glGetString(GL_VENDOR);
|
|
||||||
if (!envval)
|
|
||||||
workaround = vendorString.find("Intel") != std::string::npos || vendorString.find("ATI") != std::string::npos || vendorString.find("AMD") != std::string::npos;
|
|
||||||
if (workaround)
|
|
||||||
geom = osg::createTexturedQuadGeometry(osg::Vec3(-1,1,0), osg::Vec3(2,0,0), osg::Vec3(0,-2,0));
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
geom = osg::createTexturedQuadGeometry(osg::Vec3(-1,-1,0), osg::Vec3(2,0,0), osg::Vec3(0,2,0));
|
geom = osg::createTexturedQuadGeometry(osg::Vec3(-1,-1,0), osg::Vec3(2,0,0), osg::Vec3(0,2,0));
|
||||||
|
|
||||||
geom->drawImplementation(renderInfo);
|
geom->drawImplementation(renderInfo);
|
||||||
|
@ -153,7 +149,52 @@ namespace
|
||||||
source->releaseGLObjects();
|
source->releaseGLObjects();
|
||||||
texture->releaseGLObjects();
|
texture->releaseGLObjects();
|
||||||
|
|
||||||
return resultImage;
|
return SDLUtil::imageToSurface(resultImage, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDLUtil::SurfaceUniquePtr softwareDecompress (osg::ref_ptr<osg::Image> source, float rotDegrees)
|
||||||
|
{
|
||||||
|
int width = source->s();
|
||||||
|
int height = source->t();
|
||||||
|
bool useAlpha = source->isImageTranslucent();
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Image> decompressedImage = new osg::Image;
|
||||||
|
decompressedImage->setFileName(source->getFileName());
|
||||||
|
decompressedImage->allocateImage(width, height, 1, useAlpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE);
|
||||||
|
for (int s=0; s<width; ++s)
|
||||||
|
for (int t=0; t<height; ++t)
|
||||||
|
decompressedImage->setColor(source->getColor(s,t,0), s,t,0);
|
||||||
|
|
||||||
|
Uint32 redMask = 0x000000ff;
|
||||||
|
Uint32 greenMask = 0x0000ff00;
|
||||||
|
Uint32 blueMask = 0x00ff0000;
|
||||||
|
Uint32 alphaMask = useAlpha ? 0xff000000 : 0;
|
||||||
|
|
||||||
|
SDL_Surface *cursorSurface = SDL_CreateRGBSurfaceFrom(decompressedImage->data(),
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
decompressedImage->getPixelSizeInBits(),
|
||||||
|
decompressedImage->getRowSizeInBytes(),
|
||||||
|
redMask,
|
||||||
|
greenMask,
|
||||||
|
blueMask,
|
||||||
|
alphaMask);
|
||||||
|
|
||||||
|
SDL_Surface *targetSurface = SDL_CreateRGBSurface(0, width, height, 32, redMask, greenMask, blueMask, alphaMask);
|
||||||
|
SDL_Renderer *renderer = SDL_CreateSoftwareRenderer(targetSurface);
|
||||||
|
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
|
||||||
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
|
||||||
|
SDL_Texture *cursorTexture = SDL_CreateTextureFromSurface(renderer, cursorSurface);
|
||||||
|
|
||||||
|
SDL_RenderCopyEx(renderer, cursorTexture, NULL, NULL, -rotDegrees, NULL, SDL_FLIP_VERTICAL);
|
||||||
|
|
||||||
|
SDL_DestroyTexture(cursorTexture);
|
||||||
|
SDL_FreeSurface(cursorSurface);
|
||||||
|
SDL_DestroyRenderer(renderer);
|
||||||
|
|
||||||
|
return SDLUtil::SurfaceUniquePtr(targetSurface, SDL_FreeSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -222,27 +263,30 @@ namespace SDLUtil
|
||||||
|
|
||||||
void SDLCursorManager::_createCursorFromResource(const std::string& name, int rotDegrees, osg::Image* image, Uint8 hotspot_x, Uint8 hotspot_y)
|
void SDLCursorManager::_createCursorFromResource(const std::string& name, int rotDegrees, osg::Image* image, Uint8 hotspot_x, Uint8 hotspot_y)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osg::Image> decompressed;
|
|
||||||
|
|
||||||
if (mCursorMap.find(name) != mCursorMap.end())
|
if (mCursorMap.find(name) != mCursorMap.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
static bool forceSoftwareDecompression = (getenv("OPENMW_DECOMPRESS_TEXTURES") != 0);
|
||||||
|
|
||||||
|
SurfaceUniquePtr (*decompressionFunction)(osg::ref_ptr<osg::Image>, float);
|
||||||
|
if (forceSoftwareDecompression || CursorDecompression::DXTCSupported) {
|
||||||
|
decompressionFunction = CursorDecompression::softwareDecompress;
|
||||||
|
} else {
|
||||||
|
decompressionFunction = CursorDecompression::hardwareDecompress;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
decompressed = decompress(image, static_cast<float>(rotDegrees));
|
auto surface = decompressionFunction(image, static_cast<float>(rotDegrees));
|
||||||
|
|
||||||
|
//set the cursor and store it for later
|
||||||
|
SDL_Cursor* curs = SDL_CreateColorCursor(surface.get(), hotspot_x, hotspot_y);
|
||||||
|
|
||||||
|
mCursorMap.insert(CursorMap::value_type(std::string(name), curs));
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
std::cerr <<"Using default cursor."<<std::endl;
|
std::cerr <<"Using default cursor."<<std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Surface* surf = SDLUtil::imageToSurface(decompressed, true);
|
|
||||||
|
|
||||||
//set the cursor and store it for later
|
|
||||||
SDL_Cursor* curs = SDL_CreateColorCursor(surf, hotspot_x, hotspot_y);
|
|
||||||
mCursorMap.insert(CursorMap::value_type(std::string(name), curs));
|
|
||||||
|
|
||||||
//clean up
|
|
||||||
SDL_FreeSurface(surf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,13 @@
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <osg/Fog>
|
||||||
#include <osg/Depth>
|
#include <osg/Depth>
|
||||||
#include <osg/TexEnvCombine>
|
#include <osg/TexEnvCombine>
|
||||||
#include <osg/Texture2D>
|
#include <osg/Texture2D>
|
||||||
#include <osg/TexMat>
|
#include <osg/TexMat>
|
||||||
#include <osg/Material>
|
#include <osg/Material>
|
||||||
|
#include <osg/BlendFunc>
|
||||||
|
|
||||||
#include <components/shader/shadermanager.hpp>
|
#include <components/shader/shadermanager.hpp>
|
||||||
|
|
||||||
|
@ -59,24 +61,52 @@ namespace Terrain
|
||||||
}
|
}
|
||||||
return depth;
|
return depth;
|
||||||
}
|
}
|
||||||
|
osg::ref_ptr<osg::Depth> getLequalDepth()
|
||||||
|
{
|
||||||
|
static osg::ref_ptr<osg::Depth> depth;
|
||||||
|
if (!depth)
|
||||||
|
{
|
||||||
|
depth = new osg::Depth;
|
||||||
|
depth->setFunction(osg::Depth::LEQUAL);
|
||||||
|
}
|
||||||
|
return depth;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<osg::ref_ptr<osg::StateSet> > createPasses(bool useShaders, bool forcePerPixelLighting, bool clampLighting, Shader::ShaderManager* shaderManager, const std::vector<TextureLayer> &layers,
|
std::vector<osg::ref_ptr<osg::StateSet> > createPasses(bool useShaders, bool forcePerPixelLighting, bool clampLighting, Shader::ShaderManager* shaderManager, const std::vector<TextureLayer> &layers,
|
||||||
const std::vector<osg::ref_ptr<osg::Texture2D> > &blendmaps, int blendmapScale, float layerTileSize)
|
const std::vector<osg::ref_ptr<osg::Texture2D> > &blendmaps, int blendmapScale, float layerTileSize)
|
||||||
{
|
{
|
||||||
std::vector<osg::ref_ptr<osg::StateSet> > passes;
|
std::vector<osg::ref_ptr<osg::StateSet> > passes;
|
||||||
|
|
||||||
bool firstLayer = true;
|
|
||||||
unsigned int blendmapIndex = 0;
|
unsigned int blendmapIndex = 0;
|
||||||
unsigned int passIndex = 0;
|
unsigned int passIndex = 0;
|
||||||
for (std::vector<TextureLayer>::const_iterator it = layers.begin(); it != layers.end(); ++it)
|
for (std::vector<TextureLayer>::const_iterator it = layers.begin(); it != layers.end(); ++it)
|
||||||
{
|
{
|
||||||
|
bool firstLayer = (it == layers.begin());
|
||||||
|
|
||||||
osg::ref_ptr<osg::StateSet> stateset (new osg::StateSet);
|
osg::ref_ptr<osg::StateSet> stateset (new osg::StateSet);
|
||||||
|
|
||||||
if (!firstLayer)
|
if (!firstLayer)
|
||||||
{
|
{
|
||||||
|
static osg::ref_ptr<osg::BlendFunc> blendFunc;
|
||||||
|
if (!blendFunc)
|
||||||
|
{
|
||||||
|
blendFunc= new osg::BlendFunc();
|
||||||
|
blendFunc->setFunction(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE);
|
||||||
|
}
|
||||||
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
|
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||||
|
stateset->setAttributeAndModes(blendFunc, osg::StateAttribute::ON);
|
||||||
|
|
||||||
stateset->setAttributeAndModes(getEqualDepth(), osg::StateAttribute::ON);
|
stateset->setAttributeAndModes(getEqualDepth(), osg::StateAttribute::ON);
|
||||||
}
|
}
|
||||||
|
// disable fog if we're the first layer of several - supposed to be completely black
|
||||||
|
if (firstLayer && blendmaps.size() > 0)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Fog> fog (new osg::Fog);
|
||||||
|
fog->setStart(10000000);
|
||||||
|
fog->setEnd(10000000);
|
||||||
|
stateset->setAttributeAndModes(fog, osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
|
||||||
|
stateset->setAttributeAndModes(getLequalDepth(), osg::StateAttribute::ON);
|
||||||
|
}
|
||||||
|
|
||||||
int texunit = 0;
|
int texunit = 0;
|
||||||
|
|
||||||
|
@ -158,8 +188,6 @@ namespace Terrain
|
||||||
stateset->setTextureAttributeAndModes(texunit, getLayerTexMat(layerTileSize), osg::StateAttribute::ON);
|
stateset->setTextureAttributeAndModes(texunit, getLayerTexMat(layerTileSize), osg::StateAttribute::ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
firstLayer = false;
|
|
||||||
|
|
||||||
stateset->setRenderBinDetails(passIndex++, "RenderBin");
|
stateset->setRenderBinDetails(passIndex++, "RenderBin");
|
||||||
|
|
||||||
passes.push_back(stateset);
|
passes.push_back(stateset);
|
||||||
|
|
|
@ -72,8 +72,6 @@ namespace Terrain
|
||||||
|
|
||||||
virtual float getHeightAt (const osg::Vec3f& worldPos) = 0;
|
virtual float getHeightAt (const osg::Vec3f& worldPos) = 0;
|
||||||
|
|
||||||
virtual LayerInfo getDefaultLayer() = 0;
|
|
||||||
|
|
||||||
/// Get the transformation factor for mapping cell units to world units.
|
/// Get the transformation factor for mapping cell units to world units.
|
||||||
virtual float getCellWorldSize() = 0;
|
virtual float getCellWorldSize() = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue