1
0
Fork 1
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:
David Cernat 2019-12-20 15:43:50 +02:00
commit ca9cd90a4d
50 changed files with 277 additions and 165 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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;
}

View file

@ -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();
}

View file

@ -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" },

View file

@ -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,

View file

@ -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

View file

@ -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(

View file

@ -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());
}

View file

@ -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());
}

View file

@ -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)
{

View file

@ -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));
}

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;
}

View file

@ -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());

View file

@ -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)

View file

@ -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);

View file

@ -450,6 +450,11 @@ namespace MWMechanics
mFallHeight += height;
}
float CreatureStats::getFallHeight() const
{
return mFallHeight;
}
float CreatureStats::land(bool isPlayer)
{
if (isPlayer)

View file

@ -115,6 +115,7 @@ namespace MWMechanics
bool needToRecalcDynamicStats();
void setNeedRecalcDynamicStats(bool val);
float getFallHeight() const;
void addToFallHeight(float height);
/// Reset the fall height

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -1489,7 +1489,7 @@ OpenAL_Output::OpenAL_Output(SoundManager &mgr)
OpenAL_Output::~OpenAL_Output()
{
deinit();
OpenAL_Output::deinit();
}
}

View file

@ -1362,7 +1362,7 @@ namespace MWSound
void SoundManager::clear()
{
stopMusic();
SoundManager::stopMusic();
for(SoundMap::value_type &snd : mActiveSounds)
{

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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); });

View file

@ -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);

View file

@ -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())

View file

@ -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);

View file

@ -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)

View file

@ -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;
}

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -27,7 +27,7 @@ ParticleSystem::ParticleSystem(const ParticleSystem &copy, 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)

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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.