mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-20 18:39:39 +00:00
Add OpenMW commits up to 20 Dec 2019
# Conflicts: # apps/openmw/mwworld/scene.cpp
This commit is contained in:
commit
ca9cd90a4d
50 changed files with 277 additions and 165 deletions
|
@ -21,6 +21,7 @@
|
|||
Bug #3812: Wrong multiline tooltips width when word-wrapping is enabled
|
||||
Bug #3894: Hostile spell effects not detected/present on first frame of OnPCHitMe
|
||||
Bug #3977: Non-ASCII characters in object ID's are not supported
|
||||
Bug #4009: Launcher does not show data files on the first run after installing
|
||||
Bug #4077: Enchanted items are not recharged if they are not in the player's inventory
|
||||
Bug #4202: Open .omwaddon files without needing toopen openmw-cs first
|
||||
Bug #4240: Ash storm origin coordinates and hand shielding animation behavior are incorrect
|
||||
|
@ -62,6 +63,7 @@
|
|||
Bug #4787: Sneaking makes 1st person walking/bobbing animation super-slow
|
||||
Bug #4797: Player sneaking and running stances are not accounted for when in air
|
||||
Bug #4800: Standing collisions are not updated immediately when an object is teleported without a cell change
|
||||
Bug #4802: You can rest before taking falling damage from landing from a jump
|
||||
Bug #4803: Stray special characters before begin statement break script compilation
|
||||
Bug #4804: Particle system with the "Has Sizes = false" causes an exception
|
||||
Bug #4805: NPC movement speed calculations do not take race Weight into account
|
||||
|
@ -179,6 +181,10 @@
|
|||
Bug #5213: SameFaction script function is broken
|
||||
Bug #5218: Crash when disabling ToggleBorders
|
||||
Bug #5220: GetLOS crashes when actor isn't loaded
|
||||
Bug #5222: Empty cell name subrecords are not saved
|
||||
Bug #5223: Bow replacement during attack animation removes attached arrow
|
||||
Bug #5226: Reputation should be capped
|
||||
Bug #5229: Crash if mesh controller node has no data node
|
||||
Feature #1774: Handle AvoidNode
|
||||
Feature #2229: Improve pathfinding AI
|
||||
Feature #3025: Analogue gamepad movement controls
|
||||
|
@ -229,6 +235,7 @@
|
|||
Feature #5147: Show spell magicka cost in spell buying window
|
||||
Feature #5170: Editor: Land shape editing, land selection
|
||||
Feature #5193: Weapon sheathing
|
||||
Feature #5224: Handle NiKeyframeController for NiTriShape
|
||||
Task #4686: Upgrade media decoder to a more current FFmpeg API
|
||||
Task #4695: Optimize Distant Terrain memory consumption
|
||||
Task #4789: Optimize cell transitions
|
||||
|
|
|
@ -1032,14 +1032,6 @@ void Record<ESM::NPC>::print()
|
|||
std::cout << " Reputation: " << (int)mData.mNpdt.mReputation << std::endl;
|
||||
std::cout << " Disposition: " << (int)mData.mNpdt.mDisposition << std::endl;
|
||||
std::cout << " Rank: " << (int)mData.mNpdt.mRank << std::endl;
|
||||
//Why do we want to print these fields? They are padding in the struct and contain
|
||||
// nothing of real value. Now we don't deal with NPDTstruct12 in runtime either...
|
||||
//std::cout << " Unknown1: "
|
||||
// << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown1) << std::endl;
|
||||
//std::cout << " Unknown2: "
|
||||
// << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl;
|
||||
//std::cout << " Unknown3: "
|
||||
// << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl;
|
||||
std::cout << " Gold: " << mData.mNpdt.mGold << std::endl;
|
||||
}
|
||||
else {
|
||||
|
@ -1047,7 +1039,6 @@ void Record<ESM::NPC>::print()
|
|||
std::cout << " Reputation: " << (int)mData.mNpdt.mReputation << std::endl;
|
||||
std::cout << " Disposition: " << (int)mData.mNpdt.mDisposition << std::endl;
|
||||
std::cout << " Rank: " << (int)mData.mNpdt.mRank << std::endl;
|
||||
std::cout << " FactionID: " << (int)mData.mNpdt.mFactionID << std::endl;
|
||||
|
||||
std::cout << " Attributes:" << std::endl;
|
||||
std::cout << " Strength: " << (int)mData.mNpdt.mStrength << std::endl;
|
||||
|
@ -1067,7 +1058,6 @@ void Record<ESM::NPC>::print()
|
|||
std::cout << " Health: " << mData.mNpdt.mHealth << std::endl;
|
||||
std::cout << " Magicka: " << mData.mNpdt.mMana << std::endl;
|
||||
std::cout << " Fatigue: " << mData.mNpdt.mFatigue << std::endl;
|
||||
std::cout << " Unknown: " << (int)mData.mNpdt.mUnknown << std::endl;
|
||||
std::cout << " Gold: " << mData.mNpdt.mGold << std::endl;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace ESSImport
|
|||
|
||||
void convertSCPT(const SCPT &scpt, ESM::GlobalScript &out)
|
||||
{
|
||||
out.mId = Misc::StringUtils::lowerCase(scpt.mSCHD.mName);
|
||||
out.mId = Misc::StringUtils::lowerCase(scpt.mSCHD.mName.toString());
|
||||
out.mRunning = scpt.mRunning;
|
||||
convertSCRI(scpt.mSCRI, out.mLocals);
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@ namespace ESSImport
|
|||
{
|
||||
while (esm.isNextSub("NPCO"))
|
||||
{
|
||||
ESM::ContItem contItem;
|
||||
ContItem contItem;
|
||||
esm.getHT(contItem);
|
||||
|
||||
InventoryItem item;
|
||||
item.mId = contItem.mItem;
|
||||
item.mId = contItem.mItem.toString();
|
||||
item.mCount = contItem.mCount;
|
||||
item.mRelativeEquipmentSlot = -1;
|
||||
item.mLockLevel = 0;
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <string>
|
||||
|
||||
#include <components/esm/cellref.hpp>
|
||||
#include <components/esm/esmcommon.hpp>
|
||||
|
||||
#include "importscri.hpp"
|
||||
|
||||
namespace ESM
|
||||
|
@ -15,6 +17,12 @@ namespace ESM
|
|||
namespace ESSImport
|
||||
{
|
||||
|
||||
struct ContItem
|
||||
{
|
||||
int mCount;
|
||||
ESM::NAME32 mItem;
|
||||
};
|
||||
|
||||
struct Inventory
|
||||
{
|
||||
struct InventoryItem : public ESM::CellRef
|
||||
|
|
|
@ -13,10 +13,16 @@ namespace ESM
|
|||
namespace ESSImport
|
||||
{
|
||||
|
||||
struct SCHD
|
||||
{
|
||||
ESM::NAME32 mName;
|
||||
ESM::Script::SCHDstruct mData;
|
||||
};
|
||||
|
||||
// A running global script
|
||||
struct SCPT
|
||||
{
|
||||
ESM::Script::SCHD mSCHD;
|
||||
SCHD mSCHD;
|
||||
|
||||
// values of local variables
|
||||
SCRI mSCRI;
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
#include <QScreen>
|
||||
#endif
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
#undef MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
// We need to do this because of Qt: https://bugreports.qt-project.org/browse/QTBUG-22154
|
||||
|
@ -311,6 +315,17 @@ QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen)
|
|||
QRect Launcher::GraphicsPage::getMaximumResolution()
|
||||
{
|
||||
QRect max;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
for (QScreen* screen : QGuiApplication::screens())
|
||||
{
|
||||
QRect res = screen->geometry();
|
||||
if (res.width() > max.width())
|
||||
max.setWidth(res.width());
|
||||
if (res.height() > max.height())
|
||||
max.setHeight(res.height());
|
||||
}
|
||||
#else
|
||||
int screens = QApplication::desktop()->screenCount();
|
||||
for (int i = 0; i < screens; ++i)
|
||||
{
|
||||
|
@ -320,6 +335,7 @@ QRect Launcher::GraphicsPage::getMaximumResolution()
|
|||
if (res.height() > max.height())
|
||||
max.setHeight(res.height());
|
||||
}
|
||||
#endif
|
||||
return max;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,6 +116,10 @@ void Launcher::MainDialog::createIcons()
|
|||
|
||||
void Launcher::MainDialog::createPages()
|
||||
{
|
||||
// Avoid creating the widgets twice
|
||||
if (pagesWidget->count() != 0)
|
||||
return;
|
||||
|
||||
mPlayPage = new PlayPage(this);
|
||||
mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
|
||||
mGraphicsPage = new GraphicsPage(mCfgMgr, mEngineSettings, this);
|
||||
|
@ -166,18 +170,20 @@ Launcher::FirstRunDialogResult Launcher::MainDialog::showFirstRunDialog()
|
|||
QAbstractButton *skipButton =
|
||||
msgBox.addButton(tr("Skip"), QMessageBox::RejectRole);
|
||||
|
||||
Q_UNUSED(skipButton); // Surpress compiler unused warning
|
||||
|
||||
msgBox.exec();
|
||||
|
||||
if (msgBox.clickedButton() == wizardButton)
|
||||
{
|
||||
if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false)) {
|
||||
return FirstRunDialogResultFailure;
|
||||
} else {
|
||||
if (mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false))
|
||||
return FirstRunDialogResultWizard;
|
||||
}
|
||||
}
|
||||
else if (msgBox.clickedButton() == skipButton)
|
||||
{
|
||||
// Don't bother setting up absent game data.
|
||||
if (setup())
|
||||
return FirstRunDialogResultContinue;
|
||||
}
|
||||
return FirstRunDialogResultFailure;
|
||||
}
|
||||
|
||||
if (!setup() || !setupGameData()) {
|
||||
|
@ -384,22 +390,23 @@ bool Launcher::MainDialog::setupGameData()
|
|||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle(tr("Error detecting Morrowind installation"));
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setStandardButtons(QMessageBox::Cancel);
|
||||
msgBox.setStandardButtons(QMessageBox::NoButton);
|
||||
msgBox.setText(tr("<br><b>Could not find the Data Files location</b><br><br> \
|
||||
The directory containing the data files was not found."));
|
||||
|
||||
QAbstractButton *wizardButton =
|
||||
msgBox.addButton(tr("Run &Installation Wizard..."), QMessageBox::ActionRole);
|
||||
QAbstractButton *skipButton =
|
||||
msgBox.addButton(tr("Skip"), QMessageBox::RejectRole);
|
||||
|
||||
Q_UNUSED(skipButton); // Supress compiler unused warning
|
||||
|
||||
msgBox.exec();
|
||||
|
||||
if (msgBox.clickedButton() == wizardButton)
|
||||
{
|
||||
if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false)) {
|
||||
if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false))
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -582,7 +589,7 @@ void Launcher::MainDialog::wizardFinished(int exitCode, QProcess::ExitStatus exi
|
|||
// HACK: Ensure the pages are created, else segfault
|
||||
setup();
|
||||
|
||||
if (reloadSettings())
|
||||
if (setupGameData() && reloadSettings())
|
||||
show();
|
||||
}
|
||||
|
||||
|
|
|
@ -236,7 +236,6 @@ namespace CSMWorld
|
|||
|
||||
{ ColumnId_FactionReactions, "Reactions" },
|
||||
{ ColumnId_FactionRanks, "Ranks" },
|
||||
//{ ColumnId_FactionID, "Faction ID" },
|
||||
{ ColumnId_FactionReaction, "Reaction" },
|
||||
|
||||
{ ColumnId_FactionAttrib1, "Attrib 1" },
|
||||
|
@ -248,7 +247,6 @@ namespace CSMWorld
|
|||
|
||||
{ ColumnId_EffectList, "Effects" },
|
||||
{ ColumnId_EffectId, "Effect" },
|
||||
//{ ColumnId_EffectAttribute, "Attrib" },
|
||||
{ ColumnId_EffectRange, "Range" },
|
||||
{ ColumnId_EffectArea, "Area" },
|
||||
|
||||
|
@ -257,7 +255,6 @@ namespace CSMWorld
|
|||
{ ColumnId_AiWanderDist, "Wander Dist" },
|
||||
{ ColumnId_AiDuration, "Ai Duration" },
|
||||
{ ColumnId_AiWanderToD, "Wander ToD" },
|
||||
//{ ColumnId_AiWanderIdle, "Wander Idle" },
|
||||
{ ColumnId_AiWanderRepeat, "Wander Repeat" },
|
||||
{ ColumnId_AiActivateName, "Activate" },
|
||||
{ ColumnId_AiTargetId, "Target ID" },
|
||||
|
@ -291,7 +288,6 @@ namespace CSMWorld
|
|||
{ ColumnId_UChar, "Value [0..255]" },
|
||||
{ ColumnId_NpcMisc, "NPC Misc" },
|
||||
{ ColumnId_Level, "Level" },
|
||||
{ ColumnId_NpcFactionID, "Faction ID" },
|
||||
{ ColumnId_GenderNpc, "Gender"},
|
||||
{ ColumnId_Mana, "Mana" },
|
||||
{ ColumnId_Fatigue, "Fatigue" },
|
||||
|
|
|
@ -225,12 +225,10 @@ namespace CSMWorld
|
|||
ColumnId_SoundChance = 210,
|
||||
|
||||
ColumnId_FactionReactions = 211,
|
||||
//ColumnId_FactionID = 212,
|
||||
ColumnId_FactionReaction = 213,
|
||||
|
||||
ColumnId_EffectList = 214,
|
||||
ColumnId_EffectId = 215,
|
||||
//ColumnId_EffectAttribute = 216,
|
||||
ColumnId_EffectRange = 217,
|
||||
ColumnId_EffectArea = 218,
|
||||
|
||||
|
@ -275,7 +273,6 @@ namespace CSMWorld
|
|||
ColumnId_UChar = 250,
|
||||
ColumnId_NpcMisc = 251,
|
||||
ColumnId_Level = 252,
|
||||
ColumnId_NpcFactionID = 253,
|
||||
ColumnId_GenderNpc = 254,
|
||||
ColumnId_Mana = 255,
|
||||
ColumnId_Fatigue = 256,
|
||||
|
|
|
@ -1096,27 +1096,25 @@ QVariant CSMWorld::NpcMiscRefIdAdapter::getNestedData (const RefIdColumn *column
|
|||
case 1: return QVariant(QVariant::UserType);
|
||||
case 2: return QVariant(QVariant::UserType);
|
||||
case 3: return QVariant(QVariant::UserType);
|
||||
case 4: return QVariant(QVariant::UserType);
|
||||
case 5: return static_cast<int>(record.get().mNpdt.mDisposition);
|
||||
case 6: return static_cast<int>(record.get().mNpdt.mReputation);
|
||||
case 7: return static_cast<int>(record.get().mNpdt.mRank);
|
||||
case 8: return record.get().mNpdt.mGold;
|
||||
case 9: return record.get().mPersistent == true;
|
||||
case 4: return static_cast<int>(record.get().mNpdt.mDisposition);
|
||||
case 5: return static_cast<int>(record.get().mNpdt.mReputation);
|
||||
case 6: return static_cast<int>(record.get().mNpdt.mRank);
|
||||
case 7: return record.get().mNpdt.mGold;
|
||||
case 8: return record.get().mPersistent == true;
|
||||
default: return QVariant(); // throw an exception here?
|
||||
}
|
||||
else
|
||||
switch (subColIndex)
|
||||
{
|
||||
case 0: return static_cast<int>(record.get().mNpdt.mLevel);
|
||||
case 1: return static_cast<int>(record.get().mNpdt.mFactionID);
|
||||
case 2: return static_cast<int>(record.get().mNpdt.mHealth);
|
||||
case 3: return static_cast<int>(record.get().mNpdt.mMana);
|
||||
case 4: return static_cast<int>(record.get().mNpdt.mFatigue);
|
||||
case 5: return static_cast<int>(record.get().mNpdt.mDisposition);
|
||||
case 6: return static_cast<int>(record.get().mNpdt.mReputation);
|
||||
case 7: return static_cast<int>(record.get().mNpdt.mRank);
|
||||
case 8: return record.get().mNpdt.mGold;
|
||||
case 9: return record.get().mPersistent == true;
|
||||
case 1: return static_cast<int>(record.get().mNpdt.mHealth);
|
||||
case 2: return static_cast<int>(record.get().mNpdt.mMana);
|
||||
case 3: return static_cast<int>(record.get().mNpdt.mFatigue);
|
||||
case 4: return static_cast<int>(record.get().mNpdt.mDisposition);
|
||||
case 5: return static_cast<int>(record.get().mNpdt.mReputation);
|
||||
case 6: return static_cast<int>(record.get().mNpdt.mRank);
|
||||
case 7: return record.get().mNpdt.mGold;
|
||||
case 8: return record.get().mPersistent == true;
|
||||
default: return QVariant(); // throw an exception here?
|
||||
}
|
||||
}
|
||||
|
@ -1137,27 +1135,25 @@ void CSMWorld::NpcMiscRefIdAdapter::setNestedData (const RefIdColumn *column,
|
|||
case 1: return;
|
||||
case 2: return;
|
||||
case 3: return;
|
||||
case 4: return;
|
||||
case 5: npc.mNpdt.mDisposition = static_cast<signed char>(value.toInt()); break;
|
||||
case 6: npc.mNpdt.mReputation = static_cast<signed char>(value.toInt()); break;
|
||||
case 7: npc.mNpdt.mRank = static_cast<signed char>(value.toInt()); break;
|
||||
case 8: npc.mNpdt.mGold = value.toInt(); break;
|
||||
case 9: npc.mPersistent = value.toBool(); break;
|
||||
case 4: npc.mNpdt.mDisposition = static_cast<signed char>(value.toInt()); break;
|
||||
case 5: npc.mNpdt.mReputation = static_cast<signed char>(value.toInt()); break;
|
||||
case 6: npc.mNpdt.mRank = static_cast<signed char>(value.toInt()); break;
|
||||
case 7: npc.mNpdt.mGold = value.toInt(); break;
|
||||
case 8: npc.mPersistent = value.toBool(); break;
|
||||
default: return; // throw an exception here?
|
||||
}
|
||||
else
|
||||
switch(subColIndex)
|
||||
{
|
||||
case 0: npc.mNpdt.mLevel = static_cast<short>(value.toInt()); break;
|
||||
case 1: npc.mNpdt.mFactionID = static_cast<char>(value.toInt()); break;
|
||||
case 2: npc.mNpdt.mHealth = static_cast<unsigned short>(value.toInt()); break;
|
||||
case 3: npc.mNpdt.mMana = static_cast<unsigned short>(value.toInt()); break;
|
||||
case 4: npc.mNpdt.mFatigue = static_cast<unsigned short>(value.toInt()); break;
|
||||
case 5: npc.mNpdt.mDisposition = static_cast<signed char>(value.toInt()); break;
|
||||
case 6: npc.mNpdt.mReputation = static_cast<signed char>(value.toInt()); break;
|
||||
case 7: npc.mNpdt.mRank = static_cast<signed char>(value.toInt()); break;
|
||||
case 8: npc.mNpdt.mGold = value.toInt(); break;
|
||||
case 9: npc.mPersistent = value.toBool(); break;
|
||||
case 1: npc.mNpdt.mHealth = static_cast<unsigned short>(value.toInt()); break;
|
||||
case 2: npc.mNpdt.mMana = static_cast<unsigned short>(value.toInt()); break;
|
||||
case 3: npc.mNpdt.mFatigue = static_cast<unsigned short>(value.toInt()); break;
|
||||
case 4: npc.mNpdt.mDisposition = static_cast<signed char>(value.toInt()); break;
|
||||
case 5: npc.mNpdt.mReputation = static_cast<signed char>(value.toInt()); break;
|
||||
case 6: npc.mNpdt.mRank = static_cast<signed char>(value.toInt()); break;
|
||||
case 7: npc.mNpdt.mGold = value.toInt(); break;
|
||||
case 8: npc.mPersistent = value.toBool(); break;
|
||||
default: return; // throw an exception here?
|
||||
}
|
||||
|
||||
|
@ -1166,7 +1162,7 @@ void CSMWorld::NpcMiscRefIdAdapter::setNestedData (const RefIdColumn *column,
|
|||
|
||||
int CSMWorld::NpcMiscRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const
|
||||
{
|
||||
return 10; // Level, FactionID, Health, Mana, Fatigue, Disposition, Reputation, Rank, Gold, Persist
|
||||
return 9; // Level, Health, Mana, Fatigue, Disposition, Reputation, Rank, Gold, Persist
|
||||
}
|
||||
|
||||
int CSMWorld::NpcMiscRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const
|
||||
|
|
|
@ -535,8 +535,6 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), miscMap));
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_Level, CSMWorld::ColumnBase::Display_SignedInteger16));
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_NpcFactionID, CSMWorld::ColumnBase::Display_SignedInteger8));
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_Health, CSMWorld::ColumnBase::Display_UnsignedInteger16));
|
||||
mColumns.back().addColumn(
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
#include <QDialogButtonBox>
|
||||
#include <QPushButton>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
#include <QScreen>
|
||||
#endif
|
||||
|
||||
#include "filewidget.hpp"
|
||||
#include "adjusterwidget.hpp"
|
||||
|
||||
|
@ -46,7 +50,11 @@ CSVDoc::NewGameDialogue::NewGameDialogue()
|
|||
connect (mFileWidget, SIGNAL (nameChanged (const QString&, bool)),
|
||||
mAdjusterWidget, SLOT (setName (const QString&, bool)));
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
QRect scr = QGuiApplication::primaryScreen()->geometry();
|
||||
#else
|
||||
QRect scr = QApplication::desktop()->screenGeometry();
|
||||
#endif
|
||||
QRect rect = geometry();
|
||||
move (scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y());
|
||||
}
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
#include <QIcon>
|
||||
#include <QPushButton>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
#include <QScreen>
|
||||
#endif
|
||||
|
||||
QPushButton *CSVDoc::StartupDialogue::addButton (const QString& label, const QIcon& icon)
|
||||
{
|
||||
int column = mColumn--;
|
||||
|
@ -119,7 +123,12 @@ CSVDoc::StartupDialogue::StartupDialogue() : mWidth (0), mColumn (2)
|
|||
|
||||
setLayout (layout);
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
QRect scr = QGuiApplication::primaryScreen()->geometry();
|
||||
#else
|
||||
QRect scr = QApplication::desktop()->screenGeometry();
|
||||
#endif
|
||||
|
||||
QRect rect = geometry();
|
||||
move (scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y());
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
#include <QDesktopWidget>
|
||||
#include <QScrollBar>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
#include <QScreen>
|
||||
#endif
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
#include "../../model/prefs/state.hpp"
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
|
@ -1050,7 +1054,7 @@ void CSVDoc::View::updateWidth(bool isGrowLimit, int minSubViewWidth)
|
|||
if (isGrowLimit)
|
||||
rect = dw->screenGeometry(this);
|
||||
else
|
||||
rect = dw->screenGeometry(dw->screen(dw->screenNumber(this)));
|
||||
rect = QGuiApplication::screens().at(dw->screenNumber(this))->geometry();
|
||||
|
||||
if (!mScrollbarOnly && mScroll && mSubViews.size() > 1)
|
||||
{
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
#include <QStackedWidget>
|
||||
#include <QListWidgetItem>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
#include <QScreen>
|
||||
#endif
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
|
||||
#include "../../model/prefs/state.hpp"
|
||||
|
@ -34,7 +38,12 @@ void CSVPrefs::Dialogue::buildCategorySelector (QSplitter *main)
|
|||
++iter)
|
||||
{
|
||||
QString label = QString::fromUtf8 (iter->second.getKey().c_str());
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,11,0)
|
||||
maxWidth = std::max (maxWidth, metrics.horizontalAdvance (label));
|
||||
#else
|
||||
maxWidth = std::max (maxWidth, metrics.width (label));
|
||||
#endif
|
||||
|
||||
list->addItem (label);
|
||||
}
|
||||
|
@ -107,8 +116,15 @@ void CSVPrefs::Dialogue::show()
|
|||
}
|
||||
else
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
QRect scr = QGuiApplication::primaryScreen()->geometry();
|
||||
#else
|
||||
QRect scr = QApplication::desktop()->screenGeometry();
|
||||
#endif
|
||||
|
||||
// otherwise place at the centre of the screen
|
||||
QPoint screenCenter = QApplication::desktop()->screenGeometry().center();
|
||||
QPoint screenCenter = scr.center();
|
||||
|
||||
move (screenCenter - QPoint(frameGeometry().width()/2, frameGeometry().height()/2));
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ namespace CSVRender
|
|||
TerrainStorage(const CSMWorld::Data& data);
|
||||
void setAlteredHeight(int inCellX, int inCellY, float heightMap);
|
||||
void resetHeights();
|
||||
|
||||
virtual bool useAlteration() const { return true; }
|
||||
float getSumOfAlteredAndTrueHeight(int cellX, int cellY, int inCellX, int inCellY);
|
||||
float* getAlteredHeight(int inCellX, int inCellY);
|
||||
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
#include <QPainter>
|
||||
#include <QShowEvent>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
#include <QScreen>
|
||||
#endif
|
||||
|
||||
#include "colorpickerpopup.hpp"
|
||||
|
||||
CSVWidget::ColorEditor::ColorEditor(const QColor &color, QWidget *parent, const bool popupOnStart)
|
||||
|
@ -95,7 +99,11 @@ QPoint CSVWidget::ColorEditor::calculatePopupPosition()
|
|||
{
|
||||
QRect editorGeometry = geometry();
|
||||
QRect popupGeometry = mColorPicker->geometry();
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
QRect screenGeometry = QGuiApplication::primaryScreen()->geometry();
|
||||
#else
|
||||
QRect screenGeometry = QApplication::desktop()->screenGeometry();
|
||||
#endif
|
||||
|
||||
// Center the popup horizontally relative to the editor
|
||||
int localPopupX = (editorGeometry.width() - popupGeometry.width()) / 2;
|
||||
|
|
|
@ -134,7 +134,12 @@ QSize CSVWorld::EnumDelegate::sizeHint(const QStyleOptionViewItem &option, const
|
|||
itemOption.state = option.state;
|
||||
|
||||
const QString &valueText = mValues.at(valueIndex).second;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,11,0)
|
||||
QSize valueSize = QSize(itemOption.fontMetrics.horizontalAdvance(valueText), itemOption.fontMetrics.height());
|
||||
#else
|
||||
QSize valueSize = QSize(itemOption.fontMetrics.width(valueText), itemOption.fontMetrics.height());
|
||||
#endif
|
||||
|
||||
itemOption.currentText = valueText;
|
||||
return QApplication::style()->sizeFromContents(QStyle::CT_ComboBox, &itemOption, valueSize);
|
||||
|
|
|
@ -205,7 +205,12 @@ bool CSVWorld::ScriptEdit::stringNeedsQuote (const std::string& id) const
|
|||
void CSVWorld::ScriptEdit::setTabWidth()
|
||||
{
|
||||
// Set tab width to specified number of characters using current font.
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,11,0)
|
||||
setTabStopDistance(mTabCharCount * fontMetrics().horizontalAdvance(' '));
|
||||
#else
|
||||
setTabStopWidth(mTabCharCount * fontMetrics().width(' '));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptEdit::wrapLines(bool wrap)
|
||||
|
@ -285,7 +290,11 @@ int CSVWorld::ScriptEdit::lineNumberAreaWidth()
|
|||
++digits;
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,11,0)
|
||||
int space = 3 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits;
|
||||
#else
|
||||
int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;
|
||||
#endif
|
||||
|
||||
return space;
|
||||
}
|
||||
|
|
|
@ -253,7 +253,7 @@ namespace MWGui
|
|||
MyGUI::FactoryManager::getInstance().registerFactory<ResourceImageSetPointerFix>("Resource", "ResourceImageSetPointer");
|
||||
MyGUI::FactoryManager::getInstance().registerFactory<AutoSizedResourceSkin>("Resource", "AutoSizedResourceSkin");
|
||||
MyGUI::ResourceManager::getInstance().load("core.xml");
|
||||
loadUserFonts();
|
||||
WindowManager::loadUserFonts();
|
||||
|
||||
bool keyboardNav = Settings::Manager::getBool("keyboard navigation", "GUI");
|
||||
mKeyboardNavigation.reset(new KeyboardNavigation());
|
||||
|
|
|
@ -332,10 +332,10 @@ namespace MWMechanics
|
|||
|
||||
bool wasEquipped = currentItem != store.end() && Misc::StringUtils::ciEqual(currentItem->getCellRef().getRefId(), itemId);
|
||||
|
||||
store.remove(itemId, 1, actor);
|
||||
|
||||
if (actor != MWMechanics::getPlayer())
|
||||
{
|
||||
store.remove(itemId, 1, actor);
|
||||
|
||||
// Equip a replacement
|
||||
if (!wasEquipped)
|
||||
return;
|
||||
|
@ -362,17 +362,19 @@ namespace MWMechanics
|
|||
std::string prevItemId = player.getPreviousItem(itemId);
|
||||
player.erasePreviousItem(itemId);
|
||||
|
||||
if (prevItemId.empty())
|
||||
return;
|
||||
if (!prevItemId.empty())
|
||||
{
|
||||
// Find previous item (or its replacement) by id.
|
||||
// we should equip previous item only if expired bound item was equipped.
|
||||
MWWorld::Ptr item = store.findReplacement(prevItemId);
|
||||
if (!item.isEmpty() && wasEquipped)
|
||||
{
|
||||
MWWorld::ActionEquip action(item);
|
||||
action.execute(actor);
|
||||
}
|
||||
}
|
||||
|
||||
// Find previous item (or its replacement) by id.
|
||||
// we should equip previous item only if expired bound item was equipped.
|
||||
MWWorld::Ptr item = store.findReplacement(prevItemId);
|
||||
if (item.isEmpty() || !wasEquipped)
|
||||
return;
|
||||
|
||||
MWWorld::ActionEquip action(item);
|
||||
action.execute(actor);
|
||||
store.remove(itemId, 1, actor);
|
||||
}
|
||||
|
||||
void Actors::updateActor (const MWWorld::Ptr& ptr, float duration)
|
||||
|
|
|
@ -593,6 +593,13 @@ void CharacterController::refreshMovementAnims(const std::string& weapShortGroup
|
|||
mCurrentMovement = movementAnimName;
|
||||
if(!mCurrentMovement.empty())
|
||||
{
|
||||
if (resetIdle)
|
||||
{
|
||||
mAnimation->disable(mCurrentIdle);
|
||||
mIdleState = CharState_None;
|
||||
idle = CharState_None;
|
||||
}
|
||||
|
||||
// For non-flying creatures, MW uses the Walk animation to calculate the animation velocity
|
||||
// even if we are running. This must be replicated, otherwise the observed speed would differ drastically.
|
||||
std::string anim = mCurrentMovement;
|
||||
|
@ -632,9 +639,6 @@ void CharacterController::refreshMovementAnims(const std::string& weapShortGroup
|
|||
|
||||
mAnimation->play(mCurrentMovement, Priority_Movement, movemask, false,
|
||||
1.f, "start", "stop", startpoint, ~0ul, true);
|
||||
|
||||
if (resetIdle)
|
||||
mAnimation->disable(mCurrentIdle);
|
||||
}
|
||||
else
|
||||
mMovementState = CharState_None;
|
||||
|
@ -1814,6 +1818,7 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
|
|||
mIdleState != CharState_IdleSneak && mIdleState != CharState_IdleSwim)
|
||||
{
|
||||
mAnimation->disable(mCurrentIdle);
|
||||
mIdleState = CharState_None;
|
||||
}
|
||||
|
||||
animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete);
|
||||
|
|
|
@ -450,6 +450,11 @@ namespace MWMechanics
|
|||
mFallHeight += height;
|
||||
}
|
||||
|
||||
float CreatureStats::getFallHeight() const
|
||||
{
|
||||
return mFallHeight;
|
||||
}
|
||||
|
||||
float CreatureStats::land(bool isPlayer)
|
||||
{
|
||||
if (isPlayer)
|
||||
|
|
|
@ -115,6 +115,7 @@ namespace MWMechanics
|
|||
bool needToRecalcDynamicStats();
|
||||
void setNeedRecalcDynamicStats(bool val);
|
||||
|
||||
float getFallHeight() const;
|
||||
void addToFallHeight(float height);
|
||||
|
||||
/// Reset the fall height
|
||||
|
|
|
@ -431,7 +431,8 @@ int MWMechanics::NpcStats::getReputation() const
|
|||
|
||||
void MWMechanics::NpcStats::setReputation(int reputation)
|
||||
{
|
||||
mReputation = reputation;
|
||||
// Reputation is capped in original engine
|
||||
mReputation = std::min(255, std::max(0, reputation));
|
||||
}
|
||||
|
||||
int MWMechanics::NpcStats::getCrimeId() const
|
||||
|
|
|
@ -515,13 +515,11 @@ namespace MWRender
|
|||
protected:
|
||||
virtual void setDefaults(osg::StateSet* stateset)
|
||||
{
|
||||
osg::Material* material = static_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
|
||||
|
||||
osg::BlendFunc* blendfunc (new osg::BlendFunc);
|
||||
stateset->setAttributeAndModes(blendfunc, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
|
||||
|
||||
// FIXME: overriding diffuse/ambient/emissive colors
|
||||
material = new osg::Material;
|
||||
osg::Material* material = new osg::Material;
|
||||
material->setColorMode(osg::Material::OFF);
|
||||
material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,mAlpha));
|
||||
material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1));
|
||||
|
@ -635,7 +633,7 @@ namespace MWRender
|
|||
|
||||
Animation::~Animation()
|
||||
{
|
||||
setLightEffect(0.f);
|
||||
Animation::setLightEffect(0.f);
|
||||
|
||||
if (mObjectRoot)
|
||||
mInsert->removeChild(mObjectRoot);
|
||||
|
|
|
@ -409,6 +409,7 @@ void NpcAnimation::setRenderBin()
|
|||
void NpcAnimation::rebuild()
|
||||
{
|
||||
mScabbard.reset();
|
||||
mHolsteredShield.reset();
|
||||
updateNpcBase();
|
||||
|
||||
MWBase::Environment::get().getMechanicsManager()->forceStateUpdate(mPtr);
|
||||
|
@ -597,7 +598,7 @@ void NpcAnimation::updateParts()
|
|||
};
|
||||
static const size_t slotlistsize = sizeof(slotlist)/sizeof(slotlist[0]);
|
||||
|
||||
bool wasArrowAttached = (mAmmunition.get() != nullptr);
|
||||
bool wasArrowAttached = isArrowAttached();
|
||||
mAmmunition.reset();
|
||||
|
||||
const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr);
|
||||
|
|
|
@ -1489,7 +1489,7 @@ OpenAL_Output::OpenAL_Output(SoundManager &mgr)
|
|||
|
||||
OpenAL_Output::~OpenAL_Output()
|
||||
{
|
||||
deinit();
|
||||
OpenAL_Output::deinit();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1362,7 +1362,7 @@ namespace MWSound
|
|||
|
||||
void SoundManager::clear()
|
||||
{
|
||||
stopMusic();
|
||||
SoundManager::stopMusic();
|
||||
|
||||
for(SoundMap::value_type &snd : mActiveSounds)
|
||||
{
|
||||
|
|
|
@ -93,7 +93,7 @@ namespace MWWorld
|
|||
{
|
||||
for (slot=slots_.first.begin();slot!=slots_.first.end(); ++slot)
|
||||
{
|
||||
invStore.unequipSlot(*slot, actor);
|
||||
invStore.unequipSlot(*slot, actor, false);
|
||||
if (slot+1 != slots_.first.end())
|
||||
invStore.equip(*slot, invStore.getSlot(*(slot+1)), actor);
|
||||
else
|
||||
|
|
|
@ -832,7 +832,7 @@ int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor
|
|||
return retCount;
|
||||
}
|
||||
|
||||
MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipSlot(int slot, const MWWorld::Ptr& actor)
|
||||
MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipSlot(int slot, const MWWorld::Ptr& actor, bool fireEvent)
|
||||
{
|
||||
if (slot<0 || slot>=static_cast<int> (mSlots.size()))
|
||||
throw std::runtime_error ("slot number out of range");
|
||||
|
@ -864,7 +864,9 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipSlot(int slot, c
|
|||
}
|
||||
}
|
||||
|
||||
fireEquipmentChangedEvent(actor);
|
||||
if (fireEvent)
|
||||
fireEquipmentChangedEvent(actor);
|
||||
|
||||
updateMagicEffects(actor);
|
||||
|
||||
return retval;
|
||||
|
|
|
@ -173,7 +173,7 @@ namespace MWWorld
|
|||
///
|
||||
/// @return the number of items actually removed
|
||||
|
||||
ContainerStoreIterator unequipSlot(int slot, const Ptr& actor);
|
||||
ContainerStoreIterator unequipSlot(int slot, const Ptr& actor, bool fireEvent=true);
|
||||
///< Unequip \a slot.
|
||||
///
|
||||
/// @return an iterator to the item that was previously in the slot
|
||||
|
|
|
@ -215,12 +215,11 @@ namespace
|
|||
struct InsertVisitor
|
||||
{
|
||||
MWWorld::CellStore& mCell;
|
||||
bool mRescale;
|
||||
Loading::Listener& mLoadingListener;
|
||||
|
||||
std::vector<MWWorld::Ptr> mToInsert;
|
||||
|
||||
InsertVisitor (MWWorld::CellStore& cell, bool rescale, Loading::Listener& loadingListener);
|
||||
InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener);
|
||||
|
||||
bool operator() (const MWWorld::Ptr& ptr);
|
||||
|
||||
|
@ -228,8 +227,8 @@ namespace
|
|||
void insert(AddObject&& addObject);
|
||||
};
|
||||
|
||||
InsertVisitor::InsertVisitor (MWWorld::CellStore& cell, bool rescale, Loading::Listener& loadingListener)
|
||||
: mCell (cell), mRescale (rescale), mLoadingListener (loadingListener)
|
||||
InsertVisitor::InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener)
|
||||
: mCell (cell), mLoadingListener (loadingListener)
|
||||
{}
|
||||
|
||||
bool InsertVisitor::operator() (const MWWorld::Ptr& ptr)
|
||||
|
@ -245,14 +244,6 @@ namespace
|
|||
{
|
||||
for (MWWorld::Ptr& ptr : mToInsert)
|
||||
{
|
||||
if (mRescale)
|
||||
{
|
||||
if (ptr.getCellRef().getScale()<0.5)
|
||||
ptr.getCellRef().setScale(0.5);
|
||||
else if (ptr.getCellRef().getScale()>2)
|
||||
ptr.getCellRef().setScale(2);
|
||||
}
|
||||
|
||||
if (!ptr.getRefData().isDeleted() && ptr.getRefData().isEnabled())
|
||||
{
|
||||
try
|
||||
|
@ -459,19 +450,7 @@ namespace MWWorld
|
|||
cell->respawn();
|
||||
|
||||
// ... then references. This is important for adjustPosition to work correctly.
|
||||
/// \todo rescale depending on the state of a new GMST
|
||||
|
||||
/*
|
||||
Start of tes3mp change (major)
|
||||
|
||||
Instead of always rescaling objects as in the original code, never rescale them,
|
||||
so they can maintain their server-set scales when their cells are reloaded
|
||||
*/
|
||||
insertCell(*cell, false, loadingListener);
|
||||
/*
|
||||
End of tes3mp change (major)
|
||||
*/
|
||||
|
||||
insertCell (*cell, loadingListener);
|
||||
|
||||
mRendering.addCell(cell);
|
||||
MWBase::Environment::get().getWindowManager()->addCell(cell);
|
||||
|
@ -852,9 +831,9 @@ namespace MWWorld
|
|||
mCellChanged = false;
|
||||
}
|
||||
|
||||
void Scene::insertCell (CellStore &cell, bool rescale, Loading::Listener* loadingListener)
|
||||
void Scene::insertCell (CellStore &cell, Loading::Listener* loadingListener)
|
||||
{
|
||||
InsertVisitor insertVisitor (cell, rescale, *loadingListener);
|
||||
InsertVisitor insertVisitor (cell, *loadingListener);
|
||||
cell.forEach (insertVisitor);
|
||||
insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mRendering); });
|
||||
insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mNavigator); });
|
||||
|
|
|
@ -85,7 +85,7 @@ namespace MWWorld
|
|||
|
||||
osg::Vec3f mLastPlayerPos;
|
||||
|
||||
void insertCell (CellStore &cell, bool rescale, Loading::Listener* loadingListener);
|
||||
void insertCell (CellStore &cell, Loading::Listener* loadingListener);
|
||||
|
||||
// Load and unload cells as necessary to create a cell grid with "X" and "Y" in the center
|
||||
void changeCellGrid (int playerCellX, int playerCellY, bool changeEvent = true);
|
||||
|
|
|
@ -2806,7 +2806,9 @@ namespace MWWorld
|
|||
if (isUnderwater(currentCell, playerPos) || isWalkingOnWater(player))
|
||||
return Rest_PlayerIsUnderwater;
|
||||
|
||||
if ((actor->getCollisionMode() && !mPhysics->isOnSolidGround(player)) || isFlying(player))
|
||||
float fallHeight = player.getClass().getCreatureStats(player).getFallHeight();
|
||||
float epsilon = 1e-4;
|
||||
if ((actor->getCollisionMode() && (!mPhysics->isOnSolidGround(player) || fallHeight >= epsilon)) || isFlying(player))
|
||||
return Rest_PlayerIsInAir;
|
||||
|
||||
if((currentCell->getCell()->mData.mFlags&ESM::Cell::NoSleep) || player.getClass().getNpcStats(player).isWerewolf())
|
||||
|
|
|
@ -67,6 +67,10 @@ void ESM::CellRef::loadData(ESMReader &esm, bool &isDeleted)
|
|||
break;
|
||||
case ESM::FourCC<'X','S','C','L'>::value:
|
||||
esm.getHT(mScale);
|
||||
if (mScale < 0.5)
|
||||
mScale = 0.5;
|
||||
else if (mScale > 2)
|
||||
mScale = 2;
|
||||
break;
|
||||
case ESM::FourCC<'A','N','A','M'>::value:
|
||||
mOwner = esm.getHString();
|
||||
|
@ -141,7 +145,12 @@ void ESM::CellRef::save (ESMWriter &esm, bool wideRefNum, bool inInventory, bool
|
|||
}
|
||||
|
||||
if (mScale != 1.0) {
|
||||
esm.writeHNT("XSCL", mScale);
|
||||
float scale = mScale;
|
||||
if (scale < 0.5)
|
||||
scale = 0.5;
|
||||
else if (scale > 2)
|
||||
scale = 2;
|
||||
esm.writeHNT("XSCL", scale);
|
||||
}
|
||||
|
||||
esm.writeHNOCString("ANAM", mOwner);
|
||||
|
|
|
@ -160,7 +160,7 @@ namespace ESM
|
|||
|
||||
void Cell::save(ESMWriter &esm, bool isDeleted) const
|
||||
{
|
||||
esm.writeHNOCString("NAME", mName);
|
||||
esm.writeHNCString("NAME", mName);
|
||||
esm.writeHNT("DATA", mData, 12);
|
||||
|
||||
if (isDeleted)
|
||||
|
|
|
@ -216,9 +216,9 @@ namespace ESM
|
|||
mNpdt.mReputation = 0;
|
||||
mNpdt.mHealth = mNpdt.mMana = mNpdt.mFatigue = 0;
|
||||
mNpdt.mDisposition = 0;
|
||||
mNpdt.mFactionID = 0;
|
||||
mNpdt.mUnknown1 = 0;
|
||||
mNpdt.mRank = 0;
|
||||
mNpdt.mUnknown = 0;
|
||||
mNpdt.mUnknown2 = 0;
|
||||
mNpdt.mGold = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,10 +87,10 @@ struct NPC
|
|||
// mSkill can grow up to 200, it must be unsigned
|
||||
unsigned char mSkills[Skill::Length];
|
||||
|
||||
char mFactionID;
|
||||
char mUnknown1;
|
||||
unsigned short mHealth, mMana, mFatigue;
|
||||
unsigned char mDisposition, mReputation, mRank;
|
||||
char mUnknown;
|
||||
char mUnknown2;
|
||||
int mGold;
|
||||
}; // 52 bytes
|
||||
|
||||
|
|
|
@ -201,6 +201,8 @@ namespace ESMTerrain
|
|||
|
||||
LandCache cache;
|
||||
|
||||
bool alteration = useAlteration();
|
||||
|
||||
float vertY_ = 0; // of current cell corner
|
||||
for (int cellY = startCellY; cellY < startCellY + std::ceil(size); ++cellY)
|
||||
{
|
||||
|
@ -251,11 +253,12 @@ namespace ESMTerrain
|
|||
float height = defaultHeight;
|
||||
if (heightData)
|
||||
height = heightData->mHeights[col*ESM::Land::LAND_SIZE + row];
|
||||
|
||||
if (alteration)
|
||||
height += getAlteredHeight(col, row);
|
||||
(*positions)[static_cast<unsigned int>(vertX*numVerts + vertY)]
|
||||
= osg::Vec3f((vertX / float(numVerts - 1) - 0.5f) * size * Constants::CellSizeInUnits,
|
||||
(vertY / float(numVerts - 1) - 0.5f) * size * Constants::CellSizeInUnits,
|
||||
height + getAlteredHeight(col, row));
|
||||
height);
|
||||
|
||||
if (normalData)
|
||||
{
|
||||
|
@ -290,8 +293,8 @@ namespace ESMTerrain
|
|||
color.g() = 255;
|
||||
color.b() = 255;
|
||||
}
|
||||
|
||||
adjustColor(col, row, heightData, color); //Does nothing by default, override in OpenMW-CS
|
||||
if (alteration)
|
||||
adjustColor(col, row, heightData, color); //Does nothing by default, override in OpenMW-CS
|
||||
|
||||
// Unlike normals, colors mostly connect seamlessly between cells, but not always...
|
||||
if (col == ESM::Land::LAND_SIZE-1 || row == ESM::Land::LAND_SIZE-1)
|
||||
|
|
|
@ -125,6 +125,7 @@ namespace ESMTerrain
|
|||
|
||||
inline const LandObject* getLand(int cellX, int cellY, LandCache& cache);
|
||||
|
||||
virtual bool useAlteration() const { return false; }
|
||||
virtual void adjustColor(int col, int row, const ESM::Land::LandData *heightData, osg::Vec4ub& color) const;
|
||||
virtual float getAlteredHeight(int col, int row) const;
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@ namespace Interpreter
|
|||
|
||||
int Runtime::getIntegerLiteral (int index) const
|
||||
{
|
||||
assert (index>=0 && index<static_cast<int> (mCode[1]));
|
||||
if (index < 0 || index >= static_cast<int> (mCode[1]))
|
||||
throw std::out_of_range("out of range");
|
||||
|
||||
const Type_Code *literalBlock = mCode + 4 + mCode[0];
|
||||
|
||||
|
@ -24,7 +25,8 @@ namespace Interpreter
|
|||
|
||||
float Runtime::getFloatLiteral (int index) const
|
||||
{
|
||||
assert (index>=0 && index<static_cast<int> (mCode[2]));
|
||||
if (index < 0 || index >= static_cast<int> (mCode[2]))
|
||||
throw std::out_of_range("out of range");
|
||||
|
||||
const Type_Code *literalBlock = mCode + 4 + mCode[0] + mCode[1];
|
||||
|
||||
|
@ -33,7 +35,8 @@ namespace Interpreter
|
|||
|
||||
std::string Runtime::getStringLiteral (int index) const
|
||||
{
|
||||
assert (index>=0 && static_cast<int> (mCode[3])>0);
|
||||
if (index < 0 || static_cast<int> (mCode[3]) <= 0)
|
||||
throw std::out_of_range("out of range");
|
||||
|
||||
const char *literalBlock =
|
||||
reinterpret_cast<const char *> (mCode + 4 + mCode[0] + mCode[1] + mCode[2]);
|
||||
|
@ -43,7 +46,8 @@ namespace Interpreter
|
|||
for (; index; --index)
|
||||
{
|
||||
offset += std::strlen (literalBlock+offset) + 1;
|
||||
assert (offset/4<static_cast<int> (mCode[3]));
|
||||
if (offset / 4 >= static_cast<int> (mCode[3]))
|
||||
throw std::out_of_range("out of range");
|
||||
}
|
||||
|
||||
return literalBlock+offset;
|
||||
|
|
|
@ -614,8 +614,6 @@ namespace NifOsg
|
|||
if (composite->getNumControllers() > 0)
|
||||
node->addUpdateCallback(composite);
|
||||
|
||||
// Note: NiTriShapes are not allowed to have KeyframeControllers (the vanilla engine just crashes when there is one).
|
||||
// We can take advantage of this constraint for optimizations later.
|
||||
if (nifNode->recType != Nif::RC_NiTriShape && nifNode->recType != Nif::RC_NiTriStrips
|
||||
&& !nifNode->controller.empty() && node->getDataVariance() == osg::Object::DYNAMIC)
|
||||
handleNodeControllers(nifNode, static_cast<osg::MatrixTransform*>(node.get()), animflags);
|
||||
|
@ -663,6 +661,8 @@ namespace NifOsg
|
|||
if (ctrl->recType == Nif::RC_NiUVController)
|
||||
{
|
||||
const Nif::NiUVController *niuvctrl = static_cast<const Nif::NiUVController*>(ctrl.getPtr());
|
||||
if (niuvctrl->data.empty())
|
||||
continue;
|
||||
const unsigned int uvSet = niuvctrl->uvSet;
|
||||
std::set<int> texUnits;
|
||||
// UVController should work only for textures which use a given UV Set, usually 0.
|
||||
|
@ -676,6 +676,17 @@ namespace NifOsg
|
|||
setupController(niuvctrl, uvctrl, animflags);
|
||||
composite->addController(uvctrl);
|
||||
}
|
||||
else if (ctrl->recType == Nif::RC_NiKeyframeController)
|
||||
{
|
||||
const Nif::NiKeyframeController *key = static_cast<const Nif::NiKeyframeController*>(ctrl.getPtr());
|
||||
if(!key->data.empty())
|
||||
{
|
||||
osg::ref_ptr<KeyframeController> callback(new KeyframeController(key->data.getPtr()));
|
||||
|
||||
setupController(key, callback, animflags);
|
||||
node->addUpdateCallback(callback);
|
||||
}
|
||||
}
|
||||
else if (ctrl->recType == Nif::RC_NiVisController)
|
||||
{
|
||||
handleVisController(static_cast<const Nif::NiVisController*>(ctrl.getPtr()), node, animflags);
|
||||
|
@ -719,6 +730,8 @@ namespace NifOsg
|
|||
|
||||
void handleVisController(const Nif::NiVisController* visctrl, osg::Node* node, int animflags)
|
||||
{
|
||||
if (visctrl->data.empty())
|
||||
return;
|
||||
osg::ref_ptr<VisController> callback(new VisController(visctrl->data.getPtr()));
|
||||
setupController(visctrl, callback, animflags);
|
||||
node->addUpdateCallback(callback);
|
||||
|
@ -726,6 +739,8 @@ namespace NifOsg
|
|||
|
||||
void handleRollController(const Nif::NiRollController* rollctrl, osg::Node* node, int animflags)
|
||||
{
|
||||
if (rollctrl->data.empty())
|
||||
return;
|
||||
osg::ref_ptr<RollController> callback(new RollController(rollctrl->data.getPtr()));
|
||||
setupController(rollctrl, callback, animflags);
|
||||
node->addUpdateCallback(callback);
|
||||
|
@ -740,6 +755,8 @@ namespace NifOsg
|
|||
if (ctrl->recType == Nif::RC_NiAlphaController)
|
||||
{
|
||||
const Nif::NiAlphaController* alphactrl = static_cast<const Nif::NiAlphaController*>(ctrl.getPtr());
|
||||
if (alphactrl->data.empty())
|
||||
continue;
|
||||
osg::ref_ptr<AlphaController> osgctrl(new AlphaController(alphactrl->data.getPtr()));
|
||||
setupController(alphactrl, osgctrl, animflags);
|
||||
composite->addController(osgctrl);
|
||||
|
@ -747,6 +764,8 @@ namespace NifOsg
|
|||
else if (ctrl->recType == Nif::RC_NiMaterialColorController)
|
||||
{
|
||||
const Nif::NiMaterialColorController* matctrl = static_cast<const Nif::NiMaterialColorController*>(ctrl.getPtr());
|
||||
if (matctrl->data.empty())
|
||||
continue;
|
||||
// Two bits that correspond to the controlled material color.
|
||||
// 00: Ambient
|
||||
// 01: Diffuse
|
||||
|
@ -1133,10 +1152,12 @@ namespace NifOsg
|
|||
continue;
|
||||
if(ctrl->recType == Nif::RC_NiGeomMorpherController)
|
||||
{
|
||||
drawable = handleMorphGeometry(static_cast<const Nif::NiGeomMorpherController*>(ctrl.getPtr()), geom, parentNode, composite, boundTextures, animflags);
|
||||
const Nif::NiGeomMorpherController* nimorphctrl = static_cast<const Nif::NiGeomMorpherController*>(ctrl.getPtr());
|
||||
if (nimorphctrl->data.empty())
|
||||
continue;
|
||||
drawable = handleMorphGeometry(nimorphctrl, geom, parentNode, composite, boundTextures, animflags);
|
||||
|
||||
osg::ref_ptr<GeomMorpherController> morphctrl = new GeomMorpherController(
|
||||
static_cast<const Nif::NiGeomMorpherController*>(ctrl.getPtr())->data.getPtr());
|
||||
osg::ref_ptr<GeomMorpherController> morphctrl = new GeomMorpherController(nimorphctrl->data.getPtr());
|
||||
setupController(ctrl.getPtr(), morphctrl, animflags);
|
||||
drawable->setUpdateCallback(morphctrl);
|
||||
break;
|
||||
|
@ -1389,7 +1410,7 @@ namespace NifOsg
|
|||
return image;
|
||||
}
|
||||
|
||||
void handleTextureProperty(const Nif::NiTexturingProperty* texprop, osg::StateSet* stateset, SceneUtil::CompositeStateSetUpdater* composite, Resource::ImageManager* imageManager, std::vector<unsigned int>& boundTextures, int animflags)
|
||||
void handleTextureProperty(const Nif::NiTexturingProperty* texprop, const std::string& nodeName, osg::StateSet* stateset, SceneUtil::CompositeStateSetUpdater* composite, Resource::ImageManager* imageManager, std::vector<unsigned int>& boundTextures, int animflags)
|
||||
{
|
||||
if (!boundTextures.empty())
|
||||
{
|
||||
|
@ -1423,7 +1444,7 @@ namespace NifOsg
|
|||
}
|
||||
default:
|
||||
{
|
||||
Log(Debug::Info) << "Unhandled texture stage " << i << " in " << mFilename;
|
||||
Log(Debug::Info) << "Unhandled texture stage " << i << " on shape \"" << nodeName << "\" in " << mFilename;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -1431,7 +1452,8 @@ namespace NifOsg
|
|||
const Nif::NiTexturingProperty::Texture& tex = texprop->textures[i];
|
||||
if(tex.texture.empty() && texprop->controller.empty())
|
||||
{
|
||||
Log(Debug::Verbose) << "Texture layer " << i << " is in use but empty in " << mFilename;
|
||||
if (i == 0)
|
||||
Log(Debug::Warning) << "Base texture is in use but empty on shape \"" << nodeName << "\" in " << mFilename;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1619,7 +1641,7 @@ namespace NifOsg
|
|||
{
|
||||
const Nif::NiTexturingProperty* texprop = static_cast<const Nif::NiTexturingProperty*>(property);
|
||||
osg::StateSet* stateset = node->getOrCreateStateSet();
|
||||
handleTextureProperty(texprop, stateset, composite, imageManager, boundTextures, animflags);
|
||||
handleTextureProperty(texprop, node->getName(), stateset, composite, imageManager, boundTextures, animflags);
|
||||
break;
|
||||
}
|
||||
// unused by mw
|
||||
|
|
|
@ -27,7 +27,7 @@ ParticleSystem::ParticleSystem(const ParticleSystem ©, const osg::CopyOp &co
|
|||
{
|
||||
// For some reason the osgParticle constructor doesn't copy the particles
|
||||
for (int i=0;i<copy.numParticles()-copy.numDeadParticles();++i)
|
||||
createParticle(copy.getParticle(i));
|
||||
ParticleSystem::createParticle(copy.getParticle(i));
|
||||
}
|
||||
|
||||
void ParticleSystem::setQuota(int quota)
|
||||
|
|
|
@ -261,18 +261,18 @@ namespace SceneUtil {
|
|||
|
||||
float _shadowFadeStart = 0.0;
|
||||
|
||||
class DebugHUD : public osg::Referenced
|
||||
class DebugHUD final : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
DebugHUD(int numberOfShadowMapsPerLight);
|
||||
|
||||
virtual void draw(osg::ref_ptr<osg::Texture2D> texture, unsigned int shadowMapNumber, const osg::Matrixd &matrix, osgUtil::CullVisitor& cv);
|
||||
void draw(osg::ref_ptr<osg::Texture2D> texture, unsigned int shadowMapNumber, const osg::Matrixd &matrix, osgUtil::CullVisitor& cv);
|
||||
|
||||
virtual void releaseGLObjects(osg::State* state = 0) const;
|
||||
void releaseGLObjects(osg::State* state = 0) const;
|
||||
|
||||
virtual void setFrustumVertices(osg::ref_ptr<osg::Vec3Array> vertices, unsigned int traversalNumber);
|
||||
void setFrustumVertices(osg::ref_ptr<osg::Vec3Array> vertices, unsigned int traversalNumber);
|
||||
protected:
|
||||
virtual void addAnotherShadowMap();
|
||||
void addAnotherShadowMap();
|
||||
|
||||
static const int sDebugTextureUnit = 0;
|
||||
|
||||
|
|
|
@ -19,15 +19,13 @@ namespace SceneUtil
|
|||
|
||||
ShadowManager(osg::ref_ptr<osg::Group> sceneRoot, osg::ref_ptr<osg::Group> rootNode, unsigned int outdoorShadowCastingMask, unsigned int indoorShadowCastingMask, Shader::ShaderManager &shaderManager);
|
||||
|
||||
virtual ~ShadowManager() = default;
|
||||
void setupShadowSettings();
|
||||
|
||||
virtual void setupShadowSettings();
|
||||
Shader::ShaderManager::DefineMap getShadowDefines();
|
||||
|
||||
virtual Shader::ShaderManager::DefineMap getShadowDefines();
|
||||
void enableIndoorMode();
|
||||
|
||||
virtual void enableIndoorMode();
|
||||
|
||||
virtual void enableOutdoorMode();
|
||||
void enableOutdoorMode();
|
||||
protected:
|
||||
bool mEnableShadows;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ GraphicsWindowSDL2::GraphicsWindowSDL2(osg::GraphicsContext::Traits *traits)
|
|||
_traits = traits;
|
||||
|
||||
init();
|
||||
if(valid())
|
||||
if(GraphicsWindowSDL2::valid())
|
||||
{
|
||||
setState(new osg::State);
|
||||
getState()->setGraphicsContext(this);
|
||||
|
|
|
@ -28,7 +28,7 @@ TerrainGrid::~TerrainGrid()
|
|||
{
|
||||
while (!mGrid.empty())
|
||||
{
|
||||
unloadCell(mGrid.begin()->first.first, mGrid.begin()->first.second);
|
||||
TerrainGrid::unloadCell(mGrid.begin()->first.first, mGrid.begin()->first.second);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -306,9 +306,6 @@ struct dtMeshTile
|
|||
int dataSize; ///< Size of the tile data.
|
||||
int flags; ///< Tile flags. (See: #dtTileFlags)
|
||||
dtMeshTile* next; ///< The next free tile, or the next tile in the spatial grid.
|
||||
private:
|
||||
dtMeshTile(const dtMeshTile&);
|
||||
dtMeshTile& operator=(const dtMeshTile&);
|
||||
};
|
||||
|
||||
/// Get flags for edge in detail triangle.
|
||||
|
|
Loading…
Reference in a new issue