mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-19 16:39:41 +00:00
Add OpenMW commits up to 7 Nov 2019
# Conflicts: # apps/openmw/mwmechanics/aifollow.hpp
This commit is contained in:
commit
5762a36fc2
56 changed files with 1333 additions and 376 deletions
|
@ -13,8 +13,7 @@ Debian:
|
|||
before_script:
|
||||
- export APT_CACHE_DIR=`pwd`/apt-cache && mkdir -pv $APT_CACHE_DIR
|
||||
- apt-get update -yq
|
||||
- apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-iostreams-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt4-dev libopenal-dev libopenscenegraph-3.4-dev libunshield-dev libtinyxml-dev
|
||||
- apt-get install -y libmygui-dev libbullet-dev
|
||||
- apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-iostreams-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt4-dev libopenal-dev libopenscenegraph-3.4-dev libunshield-dev libtinyxml-dev libmygui-dev libbullet-dev
|
||||
stage: build
|
||||
script:
|
||||
- cores_to_use=$((`nproc`-2)); if (( $cores_to_use < 1 )); then cores_to_use=1; fi
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
Bug #1515: Opening console masks dialogue, inventory menu
|
||||
Bug #1933: Actors can have few stocks of the same item
|
||||
Bug #2395: Duplicated plugins in the launcher when multiple data directories provide the same plugin
|
||||
Bug #2679: Unable to map mouse wheel under control settings
|
||||
Bug #2969: Scripted items can stack
|
||||
Bug #2976: Data lines in global openmw.cfg take priority over user openmw.cfg
|
||||
Bug #2987: Editor: some chance and AI data fields can overflow
|
||||
|
@ -35,6 +36,7 @@
|
|||
Bug #4456: AiActivate should not be cancelled after target activation
|
||||
Bug #4540: Rain delay when exiting water
|
||||
Bug #4594: Actors without AI packages don't use Hello dialogue
|
||||
Bug #4598: Script parser does not support non-ASCII characters
|
||||
Bug #4600: Crash when no sound output is available or --no-sound is used.
|
||||
Bug #4639: Black screen after completing first mages guild mission + training
|
||||
Bug #4650: Focus is lost after pressing ESC in confirmation dialog inside savegame dialog
|
||||
|
@ -132,6 +134,7 @@
|
|||
Bug #5074: Paralyzed actors greet the player
|
||||
Bug #5075: Enchanting cast style can be changed if there's no object
|
||||
Bug #5078: DisablePlayerLooking is broken
|
||||
Bug #5081: OpenMW-CS: Apparatus type "Alembic" is erroneously named "Albemic"
|
||||
Bug #5082: Scrolling with controller in GUI mode is broken
|
||||
Bug #5087: Some valid script names can't be used as string arguments
|
||||
Bug #5089: Swimming/Underwater creatures only swim around ground level
|
||||
|
@ -152,6 +155,7 @@
|
|||
Bug #5134: Doors rotation by "Lock" console command is inconsistent
|
||||
Bug #5136: LegionUniform script: can not access local variables
|
||||
Bug #5137: Textures with Clamp Mode set to Clamp instead of Wrap are too dark outside the boundaries
|
||||
Bug #5138: Actors stuck in half closed door
|
||||
Bug #5149: Failing lock pick attempts isn't always a crime
|
||||
Bug #5155: Lock/unlock behavior differs from vanilla
|
||||
Bug #5158: Objects without a name don't fallback to their ID
|
||||
|
@ -182,6 +186,7 @@
|
|||
Feature #4255: Handle broken RepairedOnMe script function
|
||||
Feature #4316: Implement RaiseRank/LowerRank functions properly
|
||||
Feature #4360: Improve default controller bindings
|
||||
Feature #4544: Actors movement deceleration
|
||||
Feature #4673: Weapon sheathing
|
||||
Feature #4675: Support for NiRollController
|
||||
Feature #4730: Native animated containers support
|
||||
|
|
|
@ -44,6 +44,7 @@ New Editor Features:
|
|||
- Land heightmap/shape editing and vertex selection (#5170)
|
||||
|
||||
Bug Fixes:
|
||||
- The Mouse Wheel can now be used for key bindings (#2679)
|
||||
- Scripted Items cannot be stacked anymore to avoid multiple script execution (#2969)
|
||||
- Stray text after an "else" statement is now ignored, like in the original engine, to handle mods which erroneously use "else if" statements (#3006)
|
||||
- "SetPos" and "SetPosition" commands now more closely replicate the original engine's behaviour (#3109)
|
||||
|
|
|
@ -807,8 +807,10 @@ std::string magicEffectFlags(int flags)
|
|||
if (flags & ESM::MagicEffect::CastSelf) properties += "CastSelf ";
|
||||
if (flags & ESM::MagicEffect::CastTouch) properties += "CastTouch ";
|
||||
if (flags & ESM::MagicEffect::CastTarget) properties += "CastTarget ";
|
||||
if (flags & ESM::MagicEffect::UncappedDamage) properties += "UncappedDamage ";
|
||||
if (flags & ESM::MagicEffect::AppliedOnce) properties += "AppliedOnce ";
|
||||
if (flags & ESM::MagicEffect::Stealth) properties += "Stealth ";
|
||||
if (flags & ESM::MagicEffect::NonRecastable) properties += "NonRecastable ";
|
||||
if (flags & ESM::MagicEffect::IllegalDaedra) properties += "IllegalDaedra ";
|
||||
if (flags & ESM::MagicEffect::Unreflectable) properties += "Unreflectable ";
|
||||
if (flags & ESM::MagicEffect::CasterLinked) properties += "CasterLinked ";
|
||||
if (flags & ESM::MagicEffect::AllowSpellmaking) properties += "AllowSpellmaking ";
|
||||
|
|
|
@ -82,9 +82,15 @@ bool Launcher::AdvancedPage::loadSettings()
|
|||
loadSettingBool(requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game");
|
||||
loadSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game");
|
||||
loadSettingBool(normaliseRaceSpeedCheckBox, "normalise race speed", "Game");
|
||||
connect(animSourcesCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotAnimSourcesToggled(bool)));
|
||||
loadSettingBool(animSourcesCheckBox, "use additional anim sources", "Game");
|
||||
if (animSourcesCheckBox->checkState())
|
||||
{
|
||||
loadSettingBool(weaponSheathingCheckBox, "weapon sheathing", "Game");
|
||||
loadSettingBool(shieldSheathingCheckBox, "shield sheathing", "Game");
|
||||
}
|
||||
|
||||
// Input Settings
|
||||
loadSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input");
|
||||
loadSettingBool(grabCursorCheckBox, "grab cursor", "Input");
|
||||
loadSettingBool(toggleSneakCheckBox, "toggle sneak", "Input");
|
||||
|
||||
|
@ -143,9 +149,11 @@ void Launcher::AdvancedPage::saveSettings()
|
|||
saveSettingBool(requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game");
|
||||
saveSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game");
|
||||
saveSettingBool(normaliseRaceSpeedCheckBox, "normalise race speed", "Game");
|
||||
saveSettingBool(animSourcesCheckBox, "use additional anim sources", "Game");
|
||||
saveSettingBool(weaponSheathingCheckBox, "weapon sheathing", "Game");
|
||||
saveSettingBool(shieldSheathingCheckBox, "shield sheathing", "Game");
|
||||
|
||||
// Input Settings
|
||||
saveSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input");
|
||||
saveSettingBool(grabCursorCheckBox, "grab cursor", "Input");
|
||||
saveSettingBool(toggleSneakCheckBox, "toggle sneak", "Input");
|
||||
|
||||
|
@ -186,3 +194,14 @@ void Launcher::AdvancedPage::slotLoadedCellsChanged(QStringList cellNames)
|
|||
{
|
||||
loadCellsForAutocomplete(cellNames);
|
||||
}
|
||||
|
||||
void Launcher::AdvancedPage::slotAnimSourcesToggled(bool checked)
|
||||
{
|
||||
weaponSheathingCheckBox->setEnabled(checked);
|
||||
shieldSheathingCheckBox->setEnabled(checked);
|
||||
if (!checked)
|
||||
{
|
||||
weaponSheathingCheckBox->setCheckState(Qt::Unchecked);
|
||||
shieldSheathingCheckBox->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace Launcher
|
|||
private slots:
|
||||
void on_skipMenuCheckBox_stateChanged(int state);
|
||||
void on_runScriptAfterStartupBrowseButton_clicked();
|
||||
void slotAnimSourcesToggled(bool checked);
|
||||
|
||||
private:
|
||||
Files::ConfigurationManager &mCfgMgr;
|
||||
|
|
|
@ -45,6 +45,7 @@ Launcher::GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, Settings:
|
|||
connect(standardRadioButton, SIGNAL(toggled(bool)), this, SLOT(slotStandardToggled(bool)));
|
||||
connect(screenComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(screenChanged(int)));
|
||||
connect(framerateLimitCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotFramerateLimitToggled(bool)));
|
||||
connect(shadowDistanceCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotShadowDistLimitToggled(bool)));
|
||||
|
||||
}
|
||||
|
||||
|
@ -129,6 +130,33 @@ bool Launcher::GraphicsPage::loadSettings()
|
|||
framerateLimitSpinBox->setValue(fpsLimit);
|
||||
}
|
||||
|
||||
if (mEngineSettings.getBool("actor shadows", "Shadows"))
|
||||
actorShadowsCheckBox->setCheckState(Qt::Checked);
|
||||
if (mEngineSettings.getBool("player shadows", "Shadows"))
|
||||
playerShadowsCheckBox->setCheckState(Qt::Checked);
|
||||
if (mEngineSettings.getBool("terrain shadows", "Shadows"))
|
||||
objectShadowsCheckBox->setCheckState(Qt::Checked);
|
||||
if (mEngineSettings.getBool("object shadows", "Shadows"))
|
||||
objectShadowsCheckBox->setCheckState(Qt::Checked);
|
||||
if (mEngineSettings.getBool("enable indoor shadows", "Shadows"))
|
||||
indoorShadowsCheckBox->setCheckState(Qt::Checked);
|
||||
|
||||
int shadowDistLimit = mEngineSettings.getInt("maximum shadow map distance", "Shadows");
|
||||
if (shadowDistLimit > 0)
|
||||
{
|
||||
shadowDistanceCheckBox->setCheckState(Qt::Checked);
|
||||
shadowDistanceSpinBox->setValue(shadowDistLimit);
|
||||
}
|
||||
|
||||
float shadowFadeStart = mEngineSettings.getFloat("shadow fade start", "Shadows");
|
||||
if (shadowFadeStart != 0)
|
||||
fadeStartSpinBox->setValue(shadowFadeStart);
|
||||
|
||||
int shadowRes = mEngineSettings.getInt("shadow map resolution", "Shadows");
|
||||
int shadowResIndex = shadowResolutionComboBox->findText(QString::number(shadowRes));
|
||||
if (shadowResIndex != -1)
|
||||
shadowResolutionComboBox->setCurrentIndex(shadowResIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -185,6 +213,52 @@ void Launcher::GraphicsPage::saveSettings()
|
|||
{
|
||||
mEngineSettings.setFloat("framerate limit", "Video", 0);
|
||||
}
|
||||
|
||||
int cShadowDist = shadowDistanceCheckBox->checkState() ? shadowDistanceSpinBox->value() : 0;
|
||||
if (mEngineSettings.getInt("maximum shadow map distance", "Shadows") != cShadowDist)
|
||||
mEngineSettings.setInt("maximum shadow map distance", "Shadows", cShadowDist);
|
||||
float cFadeStart = fadeStartSpinBox->value();
|
||||
if (cShadowDist > 0 && mEngineSettings.getFloat("shadow fade start", "Shadows") != cFadeStart)
|
||||
mEngineSettings.setFloat("shadow fade start", "Shadows", cFadeStart);
|
||||
|
||||
bool cActorShadows = actorShadowsCheckBox->checkState();
|
||||
bool cObjectShadows = objectShadowsCheckBox->checkState();
|
||||
bool cTerrainShadows = terrainShadowsCheckBox->checkState();
|
||||
bool cPlayerShadows = playerShadowsCheckBox->checkState();
|
||||
if (cActorShadows || cObjectShadows || cTerrainShadows || cPlayerShadows)
|
||||
{
|
||||
if (mEngineSettings.getBool("enable shadows", "Shadows") != true)
|
||||
mEngineSettings.setBool("enable shadows", "Shadows", true);
|
||||
if (mEngineSettings.getBool("actor shadows", "Shadows") != cActorShadows)
|
||||
mEngineSettings.setBool("actor shadows", "Shadows", cActorShadows);
|
||||
if (mEngineSettings.getBool("player shadows", "Shadows") != cPlayerShadows)
|
||||
mEngineSettings.setBool("player shadows", "Shadows", cPlayerShadows);
|
||||
if (mEngineSettings.getBool("object shadows", "Shadows") != cObjectShadows)
|
||||
mEngineSettings.setBool("object shadows", "Shadows", cObjectShadows);
|
||||
if (mEngineSettings.getBool("terrain shadows", "Shadows") != cTerrainShadows)
|
||||
mEngineSettings.setBool("terrain shadows", "Shadows", cTerrainShadows);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mEngineSettings.getBool("enable shadows", "Shadows"))
|
||||
mEngineSettings.setBool("enable shadows", "Shadows", false);
|
||||
if (mEngineSettings.getBool("actor shadows", "Shadows"))
|
||||
mEngineSettings.setBool("actor shadows", "Shadows", false);
|
||||
if (mEngineSettings.getBool("player shadows", "Shadows"))
|
||||
mEngineSettings.setBool("player shadows", "Shadows", false);
|
||||
if (mEngineSettings.getBool("object shadows", "Shadows"))
|
||||
mEngineSettings.setBool("object shadows", "Shadows", false);
|
||||
if (mEngineSettings.getBool("terrain shadows", "Shadows"))
|
||||
mEngineSettings.setBool("terrain shadows", "Shadows", false);
|
||||
}
|
||||
|
||||
bool cIndoorShadows = indoorShadowsCheckBox->checkState();
|
||||
if (mEngineSettings.getBool("enable indoor shadows", "Shadows") != cIndoorShadows)
|
||||
mEngineSettings.setBool("enable indoor shadows", "Shadows", cIndoorShadows);
|
||||
|
||||
int cShadowRes = shadowResolutionComboBox->currentText().toInt();
|
||||
if (cShadowRes != mEngineSettings.getInt("shadow map resolution", "Shadows"))
|
||||
mEngineSettings.setInt("shadow map resolution", "Shadows", cShadowRes);
|
||||
}
|
||||
|
||||
QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen)
|
||||
|
@ -290,3 +364,9 @@ void Launcher::GraphicsPage::slotFramerateLimitToggled(bool checked)
|
|||
{
|
||||
framerateLimitSpinBox->setEnabled(checked);
|
||||
}
|
||||
|
||||
void Launcher::GraphicsPage::slotShadowDistLimitToggled(bool checked)
|
||||
{
|
||||
shadowDistanceSpinBox->setEnabled(checked);
|
||||
fadeStartSpinBox->setEnabled(checked);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace Launcher
|
|||
void slotFullScreenChanged(int state);
|
||||
void slotStandardToggled(bool checked);
|
||||
void slotFramerateLimitToggled(bool checked);
|
||||
void slotShadowDistLimitToggled(bool checked);
|
||||
|
||||
private:
|
||||
Files::ConfigurationManager &mCfgMgr;
|
||||
|
|
|
@ -52,5 +52,5 @@ void CSMTools::BodyPartCheckStage::perform (int stage, CSMDoc::Messages &message
|
|||
if ( bodyPart.mRace.empty() )
|
||||
messages.add(id, "Race is missing", "", CSMDoc::Message::Severity_Error);
|
||||
else if ( mRaces.searchId( bodyPart.mRace ) == -1 )
|
||||
messages.add(id, "Race '" + bodyPart.mRace + " does not exist", "", CSMDoc::Message::Severity_Error);
|
||||
messages.add(id, "Race '" + bodyPart.mRace + "' does not exist", "", CSMDoc::Message::Severity_Error);
|
||||
}
|
||||
|
|
|
@ -242,10 +242,37 @@ void CSVRender::TerrainSelection::drawTextureSelection(const osg::ref_ptr<osg::V
|
|||
}
|
||||
}
|
||||
|
||||
bool CSVRender::TerrainSelection::noCell(const std::string& cellId)
|
||||
{
|
||||
CSMDoc::Document& document = mWorldspaceWidget->getDocument();
|
||||
const CSMWorld::IdCollection<CSMWorld::Cell>& cellCollection = document.getData().getCells();
|
||||
return cellCollection.searchId (cellId) == -1;
|
||||
}
|
||||
|
||||
bool CSVRender::TerrainSelection::noLand(const std::string& cellId)
|
||||
{
|
||||
CSMDoc::Document& document = mWorldspaceWidget->getDocument();
|
||||
const CSMWorld::IdCollection<CSMWorld::Land>& landCollection = document.getData().getLand();
|
||||
return landCollection.searchId (cellId) == -1;
|
||||
}
|
||||
|
||||
bool CSVRender::TerrainSelection::noLandLoaded(const std::string& cellId)
|
||||
{
|
||||
CSMDoc::Document& document = mWorldspaceWidget->getDocument();
|
||||
const CSMWorld::IdCollection<CSMWorld::Land>& landCollection = document.getData().getLand();
|
||||
return !landCollection.getRecord(cellId).get().isDataLoaded(ESM::Land::DATA_VNML);
|
||||
}
|
||||
|
||||
bool CSVRender::TerrainSelection::isLandLoaded(const std::string& cellId)
|
||||
{
|
||||
if (!noCell(cellId) && !noLand(cellId) && !noLandLoaded(cellId)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int CSVRender::TerrainSelection::calculateLandHeight(int x, int y) // global vertex coordinates
|
||||
{
|
||||
int cellX = std::floor((1.0f*x / (ESM::Land::LAND_SIZE - 1)));
|
||||
int cellY = std::floor((1.0f*y / (ESM::Land::LAND_SIZE - 1)));
|
||||
int cellX = std::floor(static_cast<float>(x) / (ESM::Land::LAND_SIZE - 1));
|
||||
int cellY = std::floor(static_cast<float>(y) / (ESM::Land::LAND_SIZE - 1));
|
||||
int localX = x - cellX * (ESM::Land::LAND_SIZE - 1);
|
||||
int localY = y - cellY * (ESM::Land::LAND_SIZE - 1);
|
||||
|
||||
|
@ -253,7 +280,18 @@ int CSVRender::TerrainSelection::calculateLandHeight(int x, int y) // global ver
|
|||
|
||||
float landHeight = 0.f;
|
||||
if (CSVRender::Cell* cell = dynamic_cast<CSVRender::Cell*>(mWorldspaceWidget->getCell(coords)))
|
||||
{
|
||||
landHeight = cell->getSumOfAlteredAndTrueHeight(cellX, cellY, localX, localY);
|
||||
}
|
||||
else if (isLandLoaded(CSMWorld::CellCoordinates::generateId(cellX, cellY)))
|
||||
{
|
||||
CSMDoc::Document& document = mWorldspaceWidget->getDocument();
|
||||
CSMWorld::IdTable& landTable = dynamic_cast<CSMWorld::IdTable&> ( *document.getData().getTableModel (CSMWorld::UniversalId::Type_Land));
|
||||
std::string cellId = CSMWorld::CellCoordinates::generateId(cellX, cellY);
|
||||
int landshapeColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex);
|
||||
const CSMWorld::LandHeightsColumn::DataType mPointer = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value<CSMWorld::LandHeightsColumn::DataType>();
|
||||
return mPointer[localY*ESM::Land::LAND_SIZE + localX];
|
||||
}
|
||||
|
||||
return landHeight;
|
||||
}
|
||||
|
|
|
@ -44,10 +44,10 @@ namespace CSVRender
|
|||
|
||||
std::vector<std::pair<int, int>> getTerrainSelection() const;
|
||||
|
||||
protected:
|
||||
|
||||
void update();
|
||||
|
||||
protected:
|
||||
|
||||
void drawShapeSelection(const osg::ref_ptr<osg::Vec3Array> vertices);
|
||||
void drawTextureSelection(const osg::ref_ptr<osg::Vec3Array> vertices);
|
||||
|
||||
|
@ -55,6 +55,14 @@ namespace CSVRender
|
|||
|
||||
private:
|
||||
|
||||
bool noCell(const std::string& cellId);
|
||||
|
||||
bool noLand(const std::string& cellId);
|
||||
|
||||
bool noLandLoaded(const std::string& cellId);
|
||||
|
||||
bool isLandLoaded(const std::string& cellId);
|
||||
|
||||
osg::Group* mParentNode;
|
||||
WorldspaceWidget *mWorldspaceWidget;
|
||||
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
|
||||
|
|
|
@ -112,12 +112,7 @@ void CSVRender::TerrainShapeMode::primaryEditPressed(const WorldspaceHitResult&
|
|||
selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1, true);
|
||||
}
|
||||
}
|
||||
if (CSVRender::PagedWorldspaceWidget *paged =
|
||||
dynamic_cast<CSVRender::PagedWorldspaceWidget *> (&getWorldspaceWidget()))
|
||||
{
|
||||
paged->resetAllAlteredHeights();
|
||||
mTotalDiffY = 0;
|
||||
}
|
||||
clearTransientEdits();
|
||||
}
|
||||
|
||||
void CSVRender::TerrainShapeMode::primarySelectPressed(const WorldspaceHitResult& hit)
|
||||
|
@ -214,28 +209,15 @@ void CSVRender::TerrainShapeMode::dragCompleted(const QPoint& pos)
|
|||
{
|
||||
if (mDragMode == InteractionType_PrimaryEdit)
|
||||
{
|
||||
if (mIsEditing)
|
||||
{
|
||||
mTotalDiffY = 0;
|
||||
mIsEditing = false;
|
||||
}
|
||||
|
||||
applyTerrainEditChanges();
|
||||
|
||||
if (CSVRender::PagedWorldspaceWidget *paged = dynamic_cast<CSVRender::PagedWorldspaceWidget *> (&getWorldspaceWidget()))
|
||||
paged->resetAllAlteredHeights();
|
||||
clearTransientEdits();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CSVRender::TerrainShapeMode::dragAborted()
|
||||
{
|
||||
if (CSVRender::PagedWorldspaceWidget *paged =
|
||||
dynamic_cast<CSVRender::PagedWorldspaceWidget *> (&getWorldspaceWidget()))
|
||||
{
|
||||
paged->resetAllAlteredHeights();
|
||||
mTotalDiffY = 0;
|
||||
}
|
||||
clearTransientEdits();
|
||||
}
|
||||
|
||||
void CSVRender::TerrainShapeMode::dragWheel (int diff, double speedFactor)
|
||||
|
@ -266,17 +248,22 @@ void CSVRender::TerrainShapeMode::sortAndLimitAlteredCells()
|
|||
if (passes > 2)
|
||||
{
|
||||
Log(Debug::Warning) << "Warning: User edit exceeds accepted slope steepness. Automatic limiting has failed, edit has been discarded.";
|
||||
if (CSVRender::PagedWorldspaceWidget *paged =
|
||||
dynamic_cast<CSVRender::PagedWorldspaceWidget *> (&getWorldspaceWidget()))
|
||||
{
|
||||
paged->resetAllAlteredHeights();
|
||||
mAlteredCells.clear();
|
||||
return;
|
||||
}
|
||||
clearTransientEdits();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::TerrainShapeMode::clearTransientEdits()
|
||||
{
|
||||
mTotalDiffY = 0;
|
||||
mIsEditing = false;
|
||||
mAlteredCells.clear();
|
||||
if (CSVRender::PagedWorldspaceWidget *paged = dynamic_cast<CSVRender::PagedWorldspaceWidget *> (&getWorldspaceWidget()))
|
||||
paged->resetAllAlteredHeights();
|
||||
mTerrainShapeSelection->update();
|
||||
}
|
||||
|
||||
void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
|
||||
{
|
||||
CSMDoc::Document& document = getWorldspaceWidget().getDocument();
|
||||
|
@ -385,7 +372,7 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
|
|||
pushNormalsEditToCommand(landNormalsNew, document, landTable, cellId);
|
||||
}
|
||||
undoStack.endMacro();
|
||||
mAlteredCells.clear();
|
||||
clearTransientEdits();
|
||||
}
|
||||
|
||||
float CSVRender::TerrainShapeMode::calculateBumpShape(float distance, int radius, float height)
|
||||
|
@ -498,6 +485,7 @@ void CSVRender::TerrainShapeMode::editTerrainShapeGrid(const std::pair<int, int>
|
|||
}
|
||||
}
|
||||
}
|
||||
mTerrainShapeSelection->update();
|
||||
}
|
||||
|
||||
void CSVRender::TerrainShapeMode::setFlattenToolTargetHeight(const WorldspaceHitResult& hit)
|
||||
|
@ -1039,6 +1027,17 @@ bool CSVRender::TerrainShapeMode::limitAlteredHeights(const CSMWorld::CellCoordi
|
|||
return steepnessIsWithinLimits;
|
||||
}
|
||||
|
||||
bool CSVRender::TerrainShapeMode::isInCellSelection(int globalSelectionX, int globalSelectionY)
|
||||
{
|
||||
if (CSVRender::PagedWorldspaceWidget *paged = dynamic_cast<CSVRender::PagedWorldspaceWidget *> (&getWorldspaceWidget()))
|
||||
{
|
||||
std::pair<int, int> vertexCoords = std::make_pair(globalSelectionX, globalSelectionY);
|
||||
std::string cellId = CSMWorld::CellCoordinates::vertexGlobalToCellId(vertexCoords);
|
||||
return paged->getCellSelection().has(CSMWorld::CellCoordinates::fromId(cellId).first) && isLandLoaded(cellId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair<int, int>& vertexCoords, unsigned char selectMode, bool dragOperation)
|
||||
{
|
||||
int r = mBrushSize / 2;
|
||||
|
@ -1046,7 +1045,7 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair<int, int>&
|
|||
|
||||
if (mBrushShape == CSVWidget::BrushShape_Point)
|
||||
{
|
||||
selections.emplace_back(vertexCoords);
|
||||
if (isInCellSelection(vertexCoords.first, vertexCoords.second)) selections.emplace_back(vertexCoords.first, vertexCoords.second);
|
||||
}
|
||||
|
||||
if (mBrushShape == CSVWidget::BrushShape_Square)
|
||||
|
@ -1055,7 +1054,7 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair<int, int>&
|
|||
{
|
||||
for(int j = vertexCoords.second - r; j <= vertexCoords.second + r; ++j)
|
||||
{
|
||||
selections.emplace_back(std::make_pair(i, j));
|
||||
if (isInCellSelection(i, j)) selections.emplace_back(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1069,7 +1068,7 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair<int, int>&
|
|||
int distanceX = abs(i - vertexCoords.first);
|
||||
int distanceY = abs(j - vertexCoords.second);
|
||||
int distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2)));
|
||||
if (distance <= r) selections.emplace_back(std::make_pair(i, j));
|
||||
if (isInCellSelection(i, j) && distance <= r) selections.emplace_back(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1080,7 +1079,9 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair<int, int>&
|
|||
{
|
||||
for(auto const& value: mCustomBrushShape)
|
||||
{
|
||||
selections.emplace_back(std::make_pair(vertexCoords.first + value.first, vertexCoords.second + value.second));
|
||||
std::pair<int, int> localVertexCoords (vertexCoords.first + value.first, vertexCoords.second + value.second);
|
||||
std::string cellId (CSMWorld::CellCoordinates::vertexGlobalToCellId(localVertexCoords));
|
||||
if (isInCellSelection(localVertexCoords.first, localVertexCoords.second)) selections.emplace_back(localVertexCoords);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,6 +95,9 @@ namespace CSVRender
|
|||
/// Remove duplicates and sort mAlteredCells, then limitAlteredHeights forward and reverse
|
||||
void sortAndLimitAlteredCells();
|
||||
|
||||
/// Reset everything in the current edit
|
||||
void clearTransientEdits();
|
||||
|
||||
/// Move pending alteredHeights changes to omwgame/omwaddon -data
|
||||
void applyTerrainEditChanges();
|
||||
|
||||
|
@ -128,6 +131,9 @@ namespace CSVRender
|
|||
/// Check that the edit doesn't break save format limits, fix if necessary, return true if slope steepness is within limits
|
||||
bool limitAlteredHeights(const CSMWorld::CellCoordinates& cellCoords, bool reverseMode = false);
|
||||
|
||||
/// Check if global selection coordinate belongs to cell in view
|
||||
bool isInCellSelection(int globalSelectionX, int globalSelectionY);
|
||||
|
||||
/// Handle brush mechanics for terrain shape selection
|
||||
void selectTerrainShapes (const std::pair<int, int>& vertexCoords, unsigned char selectMode, bool dragOperation);
|
||||
|
||||
|
|
|
@ -65,7 +65,10 @@ void CSVWorld::ScriptHighlighter::parseEOF (Compiler::Scanner& scanner)
|
|||
|
||||
void CSVWorld::ScriptHighlighter::highlight (const Compiler::TokenLoc& loc, Type type)
|
||||
{
|
||||
int length = static_cast<int> (loc.mLiteral.size());
|
||||
// We should take in account multibyte characters
|
||||
int length = 0;
|
||||
const char* token = loc.mLiteral.c_str();
|
||||
while (*token) length += (*token++ & 0xc0) != 0x80;
|
||||
|
||||
int index = loc.mColumn;
|
||||
|
||||
|
|
|
@ -621,8 +621,11 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||
if(boost::filesystem::exists(input2)) {
|
||||
boost::filesystem::copy_file(input2, keybinderUser);
|
||||
keybinderUserExists = boost::filesystem::exists(keybinderUser);
|
||||
Log(Debug::Info) << "Loading keybindings file: " << keybinderUser;
|
||||
}
|
||||
}
|
||||
else
|
||||
Log(Debug::Info) << "Loading keybindings file: " << keybinderUser;
|
||||
|
||||
// find correct path to the game controller bindings
|
||||
// File format for controller mappings is different for SDL <= 2.0.4, 2.0.5, and >= 2.0.6
|
||||
|
|
|
@ -706,6 +706,8 @@ namespace MWClass
|
|||
if(getMovementSettings(ptr).mPosition[0] != 0 && getMovementSettings(ptr).mPosition[1] == 0)
|
||||
moveSpeed *= 0.75f;
|
||||
|
||||
moveSpeed *= ptr.getClass().getMovementSettings(ptr).mSpeedFactor;
|
||||
|
||||
return moveSpeed;
|
||||
}
|
||||
|
||||
|
|
|
@ -1175,6 +1175,8 @@ namespace MWClass
|
|||
if(npcdata->mNpcStats.isWerewolf() && running && npcdata->mNpcStats.getDrawState() == MWMechanics::DrawState_Nothing)
|
||||
moveSpeed *= gmst.fWereWolfRunMult->mValue.getFloat();
|
||||
|
||||
moveSpeed *= ptr.getClass().getMovementSettings(ptr).mSpeedFactor;
|
||||
|
||||
return moveSpeed;
|
||||
}
|
||||
|
||||
|
|
|
@ -477,6 +477,14 @@ namespace MWInput
|
|||
case A_ToggleDebug:
|
||||
MWBase::Environment::get().getWindowManager()->toggleDebugWindow();
|
||||
break;
|
||||
case A_ZoomIn:
|
||||
if (mControlSwitch["playerviewswitch"] && mControlSwitch["playercontrols"] && !MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
MWBase::Environment::get().getWorld()->setCameraDistance(ZOOM_SCALE, true, true);
|
||||
break;
|
||||
case A_ZoomOut:
|
||||
if (mControlSwitch["playerviewswitch"] && mControlSwitch["playercontrols"] && !MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
MWBase::Environment::get().getWorld()->setCameraDistance(-ZOOM_SCALE, true, true);
|
||||
break;
|
||||
case A_QuickSave:
|
||||
quickSave();
|
||||
break;
|
||||
|
@ -763,7 +771,9 @@ namespace MWInput
|
|||
actionIsActive(A_MoveRight) ||
|
||||
actionIsActive(A_Jump) ||
|
||||
actionIsActive(A_Sneak) ||
|
||||
actionIsActive(A_TogglePOV))
|
||||
actionIsActive(A_TogglePOV) ||
|
||||
actionIsActive(A_ZoomIn) ||
|
||||
actionIsActive(A_ZoomOut) )
|
||||
{
|
||||
resetIdleTime();
|
||||
} else {
|
||||
|
@ -961,6 +971,14 @@ namespace MWInput
|
|||
}
|
||||
}
|
||||
|
||||
void InputManager::mouseWheelMoved(const SDL_MouseWheelEvent &arg)
|
||||
{
|
||||
if (mInputBinder->detectingBindingState() || !mControlsDisabled)
|
||||
mInputBinder->mouseWheelMoved(arg);
|
||||
|
||||
mJoystickLastUsed = false;
|
||||
}
|
||||
|
||||
void InputManager::mouseMoved(const SDLUtil::MouseMotionEvent &arg )
|
||||
{
|
||||
mInputBinder->mouseMoved (arg);
|
||||
|
@ -1008,9 +1026,6 @@ namespace MWInput
|
|||
if (arg.zrel && mControlSwitch["playerviewswitch"] && mControlSwitch["playercontrols"]) //Check to make sure you are allowed to zoomout and there is a change
|
||||
{
|
||||
MWBase::Environment::get().getWorld()->changeVanityModeScale(static_cast<float>(arg.zrel));
|
||||
|
||||
if (Settings::Manager::getBool("allow third person zoom", "Input"))
|
||||
MWBase::Environment::get().getWorld()->setCameraDistance(static_cast<float>(arg.zrel), true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1105,13 +1120,13 @@ namespace MWInput
|
|||
{
|
||||
if(arg.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT)
|
||||
{
|
||||
mGamepadZoom = static_cast<float>(arg.value / 10000 * 8.5f);
|
||||
return; // Do not propogate event.
|
||||
mGamepadZoom = arg.value * 0.85f / 1000.f;
|
||||
return; // Do not propagate event.
|
||||
}
|
||||
else if(arg.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT)
|
||||
{
|
||||
mGamepadZoom = static_cast<float>(-(arg.value / 10000 * 8.5f));
|
||||
return; // Do not propogate event.
|
||||
mGamepadZoom = -arg.value * 0.85f / 1000.f;
|
||||
return; // Do not propagate event.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1527,6 +1542,10 @@ namespace MWInput
|
|||
defaultMouseButtonBindings[A_Inventory] = SDL_BUTTON_RIGHT;
|
||||
defaultMouseButtonBindings[A_Use] = SDL_BUTTON_LEFT;
|
||||
|
||||
std::map<int, ICS::InputControlSystem::MouseWheelClick> defaultMouseWheelBindings;
|
||||
defaultMouseWheelBindings[A_ZoomIn] = ICS::InputControlSystem::MouseWheelClick::UP;
|
||||
defaultMouseWheelBindings[A_ZoomOut] = ICS::InputControlSystem::MouseWheelClick::DOWN;
|
||||
|
||||
for (int i = 0; i < A_Last; ++i)
|
||||
{
|
||||
ICS::Control* control;
|
||||
|
@ -1545,6 +1564,7 @@ namespace MWInput
|
|||
if (!controlExists || force ||
|
||||
( mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) == SDL_SCANCODE_UNKNOWN
|
||||
&& mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS
|
||||
&& mInputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE) == ICS::InputControlSystem::MouseWheelClick::UNASSIGNED
|
||||
))
|
||||
{
|
||||
clearAllKeyBindings(control);
|
||||
|
@ -1561,6 +1581,12 @@ namespace MWInput
|
|||
control->setInitialValue(0.0f);
|
||||
mInputBinder->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE);
|
||||
}
|
||||
else if (defaultMouseWheelBindings.find(i) != defaultMouseWheelBindings.end()
|
||||
&& (force || !mInputBinder->isMouseWheelBound(defaultMouseWheelBindings[i])))
|
||||
{
|
||||
control->setInitialValue(0.f);
|
||||
mInputBinder->addMouseWheelBinding(control, defaultMouseWheelBindings[i], ICS::Control::INCREASE);
|
||||
}
|
||||
|
||||
if (i == A_LookLeftRight && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_4) && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_6))
|
||||
{
|
||||
|
@ -1651,6 +1677,10 @@ namespace MWInput
|
|||
|
||||
if (action == A_Screenshot)
|
||||
return "Screenshot";
|
||||
else if (action == A_ZoomIn)
|
||||
return "Zoom In";
|
||||
else if (action == A_ZoomOut)
|
||||
return "Zoom Out";
|
||||
|
||||
descriptions[A_Use] = "sUse";
|
||||
descriptions[A_Activate] = "sActivate";
|
||||
|
@ -1703,10 +1733,25 @@ namespace MWInput
|
|||
|
||||
SDL_Scancode key = mInputBinder->getKeyBinding (c, ICS::Control::INCREASE);
|
||||
unsigned int mouse = mInputBinder->getMouseButtonBinding (c, ICS::Control::INCREASE);
|
||||
ICS::InputControlSystem::MouseWheelClick wheel = mInputBinder->getMouseWheelBinding(c, ICS::Control::INCREASE);
|
||||
if (key != SDL_SCANCODE_UNKNOWN)
|
||||
return MyGUI::TextIterator::toTagsString(mInputBinder->scancodeToString (key));
|
||||
else if (mouse != ICS_MAX_DEVICE_BUTTONS)
|
||||
return "#{sMouse} " + std::to_string(mouse);
|
||||
else if (wheel != ICS::InputControlSystem::MouseWheelClick::UNASSIGNED)
|
||||
switch (wheel)
|
||||
{
|
||||
case ICS::InputControlSystem::MouseWheelClick::UP:
|
||||
return "Mouse Wheel Up";
|
||||
case ICS::InputControlSystem::MouseWheelClick::DOWN:
|
||||
return "Mouse Wheel Down";
|
||||
case ICS::InputControlSystem::MouseWheelClick::RIGHT:
|
||||
return "Mouse Wheel Right";
|
||||
case ICS::InputControlSystem::MouseWheelClick::LEFT:
|
||||
return "Mouse Wheel Left";
|
||||
default:
|
||||
return "#{sNone}";
|
||||
}
|
||||
else
|
||||
return "#{sNone}";
|
||||
}
|
||||
|
@ -1793,6 +1838,8 @@ namespace MWInput
|
|||
ret.push_back(A_MoveLeft);
|
||||
ret.push_back(A_MoveRight);
|
||||
ret.push_back(A_TogglePOV);
|
||||
ret.push_back(A_ZoomIn);
|
||||
ret.push_back(A_ZoomOut);
|
||||
ret.push_back(A_Run);
|
||||
ret.push_back(A_AlwaysRun);
|
||||
ret.push_back(A_Sneak);
|
||||
|
@ -1831,6 +1878,8 @@ namespace MWInput
|
|||
{
|
||||
std::vector<int> ret;
|
||||
ret.push_back(A_TogglePOV);
|
||||
ret.push_back(A_ZoomIn);
|
||||
ret.push_back(A_ZoomOut);
|
||||
ret.push_back(A_Sneak);
|
||||
ret.push_back(A_Activate);
|
||||
ret.push_back(A_Use);
|
||||
|
@ -1870,13 +1919,6 @@ namespace MWInput
|
|||
mInputBinder->enableDetectingBindingState (c, ICS::Control::INCREASE);
|
||||
}
|
||||
|
||||
void InputManager::mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
|
||||
, ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction)
|
||||
{
|
||||
// we don't want mouse movement bindings
|
||||
return;
|
||||
}
|
||||
|
||||
void InputManager::keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
|
||||
, SDL_Scancode key, ICS::Control::ControlChangingDirection direction)
|
||||
{
|
||||
|
@ -1908,6 +1950,13 @@ namespace MWInput
|
|||
MWBase::Environment::get().getWindowManager ()->notifyInputActionBound ();
|
||||
}
|
||||
|
||||
void InputManager::mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
|
||||
, ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction)
|
||||
{
|
||||
// we don't want mouse movement bindings
|
||||
return;
|
||||
}
|
||||
|
||||
void InputManager::mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
|
||||
, unsigned int button, ICS::Control::ControlChangingDirection direction)
|
||||
{
|
||||
|
@ -1919,6 +1968,17 @@ namespace MWInput
|
|||
MWBase::Environment::get().getWindowManager ()->notifyInputActionBound ();
|
||||
}
|
||||
|
||||
void InputManager::mouseWheelBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
|
||||
, ICS::InputControlSystem::MouseWheelClick click, ICS::Control::ControlChangingDirection direction)
|
||||
{
|
||||
if(!mDetectingKeyboard)
|
||||
return;
|
||||
clearAllKeyBindings(control);
|
||||
control->setInitialValue(0.0f);
|
||||
ICS::DetectingBindingListener::mouseWheelBindingDetected(ICS, control, click, direction);
|
||||
MWBase::Environment::get().getWindowManager()->notifyInputActionBound();
|
||||
}
|
||||
|
||||
void InputManager::joystickAxisBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control
|
||||
, int axis, ICS::Control::ControlChangingDirection direction)
|
||||
{
|
||||
|
@ -1953,6 +2013,8 @@ namespace MWInput
|
|||
mInputBinder->removeKeyBinding (mInputBinder->getKeyBinding (control, ICS::Control::INCREASE));
|
||||
if (mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS)
|
||||
mInputBinder->removeMouseButtonBinding (mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE));
|
||||
if (mInputBinder->getMouseWheelBinding (control, ICS::Control::INCREASE) != ICS::InputControlSystem::MouseWheelClick::UNASSIGNED)
|
||||
mInputBinder->removeMouseWheelBinding (mInputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE));
|
||||
}
|
||||
|
||||
void InputManager::clearAllControllerBindings (ICS::Control* control)
|
||||
|
|
|
@ -56,6 +56,7 @@ struct SDL_Window;
|
|||
|
||||
namespace MWInput
|
||||
{
|
||||
const float ZOOM_SCALE = 120.f; /// Used for scrolling camera in and out
|
||||
|
||||
/**
|
||||
* @brief Class that handles all input and key bindings for OpenMW.
|
||||
|
@ -120,6 +121,8 @@ namespace MWInput
|
|||
virtual void mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id );
|
||||
virtual void mouseMoved( const SDLUtil::MouseMotionEvent &arg );
|
||||
|
||||
virtual void mouseWheelMoved( const SDL_MouseWheelEvent &arg);
|
||||
|
||||
virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg);
|
||||
virtual void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg);
|
||||
virtual void axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg);
|
||||
|
@ -133,15 +136,18 @@ namespace MWInput
|
|||
|
||||
virtual void channelChanged(ICS::Channel* channel, float currentValue, float previousValue);
|
||||
|
||||
virtual void mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
|
||||
, ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction);
|
||||
|
||||
virtual void keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
|
||||
, SDL_Scancode key, ICS::Control::ControlChangingDirection direction);
|
||||
|
||||
virtual void mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
|
||||
, ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction);
|
||||
|
||||
virtual void mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
|
||||
, unsigned int button, ICS::Control::ControlChangingDirection direction);
|
||||
|
||||
virtual void mouseWheelBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
|
||||
, ICS::InputControlSystem::MouseWheelClick click, ICS::Control::ControlChangingDirection direction);
|
||||
|
||||
virtual void joystickAxisBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control
|
||||
, int axis, ICS::Control::ControlChangingDirection direction);
|
||||
|
||||
|
@ -268,33 +274,33 @@ namespace MWInput
|
|||
|
||||
A_Unused,
|
||||
|
||||
A_Screenshot, // Take a screenshot
|
||||
A_Screenshot, // Take a screenshot
|
||||
|
||||
A_Inventory, // Toggle inventory screen
|
||||
A_Inventory, // Toggle inventory screen
|
||||
|
||||
A_Console, // Toggle console screen
|
||||
A_Console, // Toggle console screen
|
||||
|
||||
A_MoveLeft, // Move player left / right
|
||||
A_MoveLeft, // Move player left / right
|
||||
A_MoveRight,
|
||||
A_MoveForward, // Forward / Backward
|
||||
A_MoveForward, // Forward / Backward
|
||||
A_MoveBackward,
|
||||
|
||||
A_Activate,
|
||||
|
||||
A_Use, //Use weapon, spell, etc.
|
||||
A_Use, //Use weapon, spell, etc.
|
||||
A_Jump,
|
||||
A_AutoMove, //Toggle Auto-move forward
|
||||
A_Rest, //Rest
|
||||
A_Journal, //Journal
|
||||
A_Weapon, //Draw/Sheath weapon
|
||||
A_Spell, //Ready/Unready Casting
|
||||
A_Run, //Run when held
|
||||
A_CycleSpellLeft, //cycling through spells
|
||||
A_AutoMove, //Toggle Auto-move forward
|
||||
A_Rest, //Rest
|
||||
A_Journal, //Journal
|
||||
A_Weapon, //Draw/Sheath weapon
|
||||
A_Spell, //Ready/Unready Casting
|
||||
A_Run, //Run when held
|
||||
A_CycleSpellLeft, //cycling through spells
|
||||
A_CycleSpellRight,
|
||||
A_CycleWeaponLeft,//Cycling through weapons
|
||||
A_CycleWeaponLeft, //Cycling through weapons
|
||||
A_CycleWeaponRight,
|
||||
A_ToggleSneak, //Toggles Sneak
|
||||
A_AlwaysRun, //Toggle Walking/Running
|
||||
A_ToggleSneak, //Toggles Sneak
|
||||
A_AlwaysRun, //Toggle Walking/Running
|
||||
A_Sneak,
|
||||
|
||||
A_QuickSave,
|
||||
|
@ -322,12 +328,15 @@ namespace MWInput
|
|||
|
||||
A_ToggleDebug,
|
||||
|
||||
A_LookUpDown, //Joystick look
|
||||
A_LookUpDown, //Joystick look
|
||||
A_LookLeftRight,
|
||||
A_MoveForwardBackward,
|
||||
A_MoveLeftRight,
|
||||
|
||||
A_Last // Marker for the last item
|
||||
A_ZoomIn,
|
||||
A_ZoomOut,
|
||||
|
||||
A_Last // Marker for the last item
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -161,6 +161,7 @@ namespace MWMechanics
|
|||
{
|
||||
static const int GREETING_SHOULD_START = 4; //how many updates should pass before NPC can greet player
|
||||
static const int GREETING_SHOULD_END = 10;
|
||||
static const float DECELERATE_DISTANCE = 512.f;
|
||||
|
||||
class GetStuntedMagickaDuration : public MWMechanics::EffectSourceVisitor
|
||||
{
|
||||
|
@ -453,6 +454,26 @@ namespace MWMechanics
|
|||
MWBase::Environment::get().getDialogueManager()->say(actor, "idle");
|
||||
}
|
||||
|
||||
void Actors::updateMovementSpeed(const MWWorld::Ptr& actor)
|
||||
{
|
||||
float previousSpeedFactor = actor.getClass().getMovementSettings(actor).mSpeedFactor;
|
||||
float newSpeedFactor = 1.f;
|
||||
|
||||
CreatureStats &stats = actor.getClass().getCreatureStats(actor);
|
||||
MWMechanics::AiSequence& seq = stats.getAiSequence();
|
||||
|
||||
if (!seq.isEmpty() && seq.getActivePackage()->useVariableSpeed())
|
||||
{
|
||||
osg::Vec3f targetPos = seq.getActivePackage()->getDestination();
|
||||
osg::Vec3f actorPos = actor.getRefData().getPosition().asVec3();
|
||||
float distance = (targetPos - actorPos).length();
|
||||
if (distance < DECELERATE_DISTANCE)
|
||||
newSpeedFactor = std::max(0.7f, 0.1f * previousSpeedFactor * (distance/64.f + 2.f));
|
||||
}
|
||||
|
||||
actor.getClass().getMovementSettings(actor).mSpeedFactor = newSpeedFactor;
|
||||
}
|
||||
|
||||
void Actors::updateGreetingState(const MWWorld::Ptr& actor, bool turnOnly)
|
||||
{
|
||||
if (!actor.getClass().isActor() || actor == getPlayer())
|
||||
|
@ -1865,6 +1886,7 @@ namespace MWMechanics
|
|||
stats.getAiSequence().execute(iter->first, *ctrl, duration);
|
||||
updateGreetingState(iter->first, timerUpdateHello > 0);
|
||||
playIdleDialogue(iter->first);
|
||||
updateMovementSpeed(iter->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,6 +121,7 @@ namespace MWMechanics
|
|||
void engageCombat(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr> >& cachedAllies, bool againstPlayer);
|
||||
|
||||
void playIdleDialogue(const MWWorld::Ptr& actor);
|
||||
void updateMovementSpeed(const MWWorld::Ptr& actor);
|
||||
void updateGreetingState(const MWWorld::Ptr& actor, bool turnOnly);
|
||||
void turnActorToFacePlayer(const MWWorld::Ptr& actor, const osg::Vec3f& dir);
|
||||
|
||||
|
|
|
@ -36,12 +36,16 @@ namespace MWMechanics
|
|||
|
||||
virtual int getTypeId() const;
|
||||
|
||||
virtual bool useVariableSpeed() const { return true;}
|
||||
|
||||
virtual bool sideWithTarget() const { return true; }
|
||||
|
||||
void writeState(ESM::AiSequence::AiSequence &sequence) const;
|
||||
|
||||
void fastForward(const MWWorld::Ptr& actor, AiState& state);
|
||||
|
||||
virtual osg::Vec3f getDestination() { return osg::Vec3f(mX, mY, mZ); }
|
||||
|
||||
private:
|
||||
std::string mCellId;
|
||||
float mX;
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include <components/esm/defs.hpp>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
#include "pathfinding.hpp"
|
||||
|
||||
namespace ESM
|
||||
|
@ -61,6 +63,8 @@ namespace MWMechanics
|
|||
|
||||
virtual int getTypeId() const;
|
||||
|
||||
virtual bool useVariableSpeed() const { return true;}
|
||||
|
||||
/// Returns the actor being followed
|
||||
std::string getFollowedActor();
|
||||
|
||||
|
@ -72,6 +76,15 @@ namespace MWMechanics
|
|||
|
||||
void fastForward(const MWWorld::Ptr& actor, AiState& state);
|
||||
|
||||
virtual osg::Vec3f getDestination()
|
||||
{
|
||||
MWWorld::Ptr target = getTarget();
|
||||
if (target.isEmpty())
|
||||
return osg::Vec3f(0, 0, 0);
|
||||
|
||||
return target.getRefData().getPosition().asVec3();
|
||||
}
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
|
|
|
@ -73,6 +73,9 @@ namespace MWMechanics
|
|||
/// Higher number is higher priority (0 being the lowest)
|
||||
virtual unsigned int getPriority() const {return 0;}
|
||||
|
||||
/// Check if package use movement with variable speed
|
||||
virtual bool useVariableSpeed() const { return false;}
|
||||
|
||||
virtual void writeState (ESM::AiSequence::AiSequence& sequence) const {}
|
||||
|
||||
/// Simulates the passing of time
|
||||
|
@ -99,6 +102,8 @@ namespace MWMechanics
|
|||
/// Return true if this package should repeat. Currently only used for Wander packages.
|
||||
virtual bool getRepeat() const;
|
||||
|
||||
virtual osg::Vec3f getDestination() { return osg::Vec3f(0, 0, 0); }
|
||||
|
||||
/// Reset pathfinding state
|
||||
void reset();
|
||||
|
||||
|
|
|
@ -388,6 +388,11 @@ void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor, boo
|
|||
}
|
||||
}
|
||||
|
||||
bool MWMechanics::AiSequence::isEmpty() const
|
||||
{
|
||||
return mPackages.empty();
|
||||
}
|
||||
|
||||
AiPackage* MWMechanics::AiSequence::getActivePackage()
|
||||
{
|
||||
if(mPackages.empty())
|
||||
|
|
|
@ -132,6 +132,8 @@ namespace MWMechanics
|
|||
\see ESM::AIPackageList **/
|
||||
void fill (const ESM::AIPackageList& list);
|
||||
|
||||
bool isEmpty() const;
|
||||
|
||||
void writeState (ESM::AiSequence::AiSequence& sequence) const;
|
||||
void readState (const ESM::AiSequence::AiSequence& sequence);
|
||||
};
|
||||
|
|
|
@ -32,6 +32,10 @@ namespace MWMechanics
|
|||
|
||||
virtual int getTypeId() const;
|
||||
|
||||
virtual bool useVariableSpeed() const { return true;}
|
||||
|
||||
virtual osg::Vec3f getDestination() { return osg::Vec3f(mX, mY, mZ); }
|
||||
|
||||
private:
|
||||
float mX;
|
||||
float mY;
|
||||
|
|
|
@ -10,11 +10,13 @@ namespace MWMechanics
|
|||
{
|
||||
float mPosition[3];
|
||||
float mRotation[3];
|
||||
float mSpeedFactor;
|
||||
|
||||
Movement()
|
||||
{
|
||||
mPosition[0] = mPosition[1] = mPosition[2] = 0.0f;
|
||||
mRotation[0] = mRotation[1] = mRotation[2] = 0.0f;
|
||||
mSpeedFactor = 1.f;
|
||||
}
|
||||
|
||||
osg::Vec3f asVec3()
|
||||
|
|
|
@ -107,7 +107,7 @@ namespace MWMechanics
|
|||
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(
|
||||
it->mEffectID);
|
||||
|
||||
if (!(magicEffect->mData.mFlags & ESM::MagicEffect::UncappedDamage))
|
||||
if (!(magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce))
|
||||
x = std::max(1.f, x);
|
||||
|
||||
x *= 0.1f * magicEffect->mData.mBaseCost;
|
||||
|
|
|
@ -331,7 +331,7 @@ namespace MWMechanics
|
|||
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = spell->mEffects.mList.begin(); effectIt != spell->mEffects.mList.end(); ++effectIt, ++i)
|
||||
{
|
||||
const ESM::MagicEffect * magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effectIt->mEffectID);
|
||||
if ((effectIt->mEffectID != ESM::MagicEffect::Corprus) && (magicEffect->mData.mFlags & ESM::MagicEffect::UncappedDamage)) // APPLIED_ONCE
|
||||
if ((effectIt->mEffectID != ESM::MagicEffect::Corprus) && (magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce))
|
||||
{
|
||||
float random = 1.f;
|
||||
if (mSpells[spell].mEffectRands.find(i) != mSpells[spell].mEffectRands.end())
|
||||
|
|
|
@ -361,7 +361,7 @@ namespace Compiler
|
|||
opcodePlayLoopSound3DExplicit);
|
||||
extensions.registerInstruction ("playloopsound3dvp", "cff", opcodePlayLoopSound3DVP,
|
||||
opcodePlayLoopSound3DVPExplicit);
|
||||
extensions.registerInstruction ("stopsound", "c", opcodeStopSound,
|
||||
extensions.registerInstruction ("stopsound", "cXX", opcodeStopSound,
|
||||
opcodeStopSoundExplicit);
|
||||
extensions.registerFunction ("getsoundplaying", 'l', "c", opcodeGetSoundPlaying,
|
||||
opcodeGetSoundPlayingExplicit);
|
||||
|
@ -537,7 +537,7 @@ namespace Compiler
|
|||
extensions.registerInstruction("setpos","cf",opcodeSetPos,opcodeSetPosExplicit);
|
||||
extensions.registerFunction("getpos",'f',"c",opcodeGetPos,opcodeGetPosExplicit);
|
||||
extensions.registerFunction("getstartingpos",'f',"c",opcodeGetStartingPos,opcodeGetStartingPosExplicit);
|
||||
extensions.registerInstruction("position","ffffX",opcodePosition,opcodePositionExplicit);
|
||||
extensions.registerInstruction("position","ffffz",opcodePosition,opcodePositionExplicit);
|
||||
extensions.registerInstruction("positioncell","ffffcX",opcodePositionCell,opcodePositionCellExplicit);
|
||||
extensions.registerInstruction("placeitemcell","ccffffX",opcodePlaceItemCell);
|
||||
extensions.registerInstruction("placeitem","cffffX",opcodePlaceItem);
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#include "scanner.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <sstream>
|
||||
#include <iterator>
|
||||
|
||||
#include "exception.hpp"
|
||||
|
@ -14,14 +12,12 @@
|
|||
|
||||
namespace Compiler
|
||||
{
|
||||
bool Scanner::get (char& c)
|
||||
bool Scanner::get (MultiChar& c)
|
||||
{
|
||||
mStream.get (c);
|
||||
|
||||
if (!mStream.good())
|
||||
if (!c.getFrom(mStream))
|
||||
return false;
|
||||
|
||||
mPrevLoc =mLoc;
|
||||
mPrevLoc = mLoc;
|
||||
|
||||
if (c=='\n')
|
||||
{
|
||||
|
@ -34,15 +30,15 @@ namespace Compiler
|
|||
else
|
||||
{
|
||||
++mLoc.mColumn;
|
||||
mLoc.mLiteral += c;
|
||||
c.appendTo(mLoc.mLiteral);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Scanner::putback (char c)
|
||||
void Scanner::putback (MultiChar& c)
|
||||
{
|
||||
mStream.putback (c);
|
||||
c.putback(mStream);
|
||||
mLoc = mPrevLoc;
|
||||
}
|
||||
|
||||
|
@ -80,7 +76,7 @@ namespace Compiler
|
|||
break;
|
||||
}
|
||||
|
||||
char c;
|
||||
MultiChar c;
|
||||
|
||||
if (!get (c))
|
||||
{
|
||||
|
@ -91,7 +87,7 @@ namespace Compiler
|
|||
{
|
||||
std::string comment;
|
||||
|
||||
comment += c;
|
||||
c.appendTo(comment);
|
||||
|
||||
while (get (c))
|
||||
{
|
||||
|
@ -101,7 +97,7 @@ namespace Compiler
|
|||
break;
|
||||
}
|
||||
else
|
||||
comment += c;
|
||||
c.appendTo(comment);
|
||||
}
|
||||
|
||||
TokenLoc loc (mLoc);
|
||||
|
@ -109,7 +105,7 @@ namespace Compiler
|
|||
|
||||
return parser.parseComment (comment, loc, *this);
|
||||
}
|
||||
else if (isWhitespace (c))
|
||||
else if (c.isWhitespace())
|
||||
{
|
||||
mLoc.mLiteral.clear();
|
||||
return true;
|
||||
|
@ -120,7 +116,7 @@ namespace Compiler
|
|||
mLoc.mLiteral.clear();
|
||||
return true;
|
||||
}
|
||||
else if (std::isalpha (c) || c=='_' || c=='"')
|
||||
else if (c.isAlpha() || c=='_' || c=='"')
|
||||
{
|
||||
bool cont = false;
|
||||
|
||||
|
@ -130,7 +126,7 @@ namespace Compiler
|
|||
return cont;
|
||||
}
|
||||
}
|
||||
else if (std::isdigit (c))
|
||||
else if (c.isDigit())
|
||||
{
|
||||
bool cont = false;
|
||||
|
||||
|
@ -162,24 +158,24 @@ namespace Compiler
|
|||
throw SourceException();
|
||||
}
|
||||
|
||||
bool Scanner::scanInt (char c, Parser& parser, bool& cont)
|
||||
bool Scanner::scanInt (MultiChar& c, Parser& parser, bool& cont)
|
||||
{
|
||||
assert(c != '\0');
|
||||
std::string value;
|
||||
value += c;
|
||||
c.appendTo(value);
|
||||
|
||||
bool error = false;
|
||||
|
||||
while (get (c))
|
||||
{
|
||||
if (std::isdigit (c))
|
||||
if (c.isDigit())
|
||||
{
|
||||
value += c;
|
||||
c.appendTo(value);
|
||||
}
|
||||
else if (c!='-' && isStringCharacter (c))
|
||||
else if (!c.isMinusSign() && isStringCharacter (c))
|
||||
{
|
||||
error = true;
|
||||
value += c;
|
||||
c.appendTo(value);
|
||||
}
|
||||
else if (c=='.')
|
||||
{
|
||||
|
@ -224,19 +220,19 @@ namespace Compiler
|
|||
{
|
||||
std::string value = intValue + ".";
|
||||
|
||||
char c;
|
||||
MultiChar c;
|
||||
|
||||
bool empty = intValue.empty() || intValue=="-";
|
||||
bool error = false;
|
||||
|
||||
while (get (c))
|
||||
{
|
||||
if (std::isdigit (c))
|
||||
if (c.isDigit())
|
||||
{
|
||||
value += c;
|
||||
c.appendTo(value);
|
||||
empty = false;
|
||||
}
|
||||
else if (std::isalpha (c) || c=='_')
|
||||
else if (c.isAlpha() || c=='_')
|
||||
error = true;
|
||||
else
|
||||
{
|
||||
|
@ -279,10 +275,10 @@ namespace Compiler
|
|||
0
|
||||
};
|
||||
|
||||
bool Scanner::scanName (char c, Parser& parser, bool& cont)
|
||||
bool Scanner::scanName (MultiChar& c, Parser& parser, bool& cont)
|
||||
{
|
||||
std::string name;
|
||||
name += c;
|
||||
c.appendTo(name);
|
||||
|
||||
if (!scanName (name))
|
||||
return false;
|
||||
|
@ -315,8 +311,8 @@ namespace Compiler
|
|||
|
||||
// Russian localization and some mods use a quirk - add newline character directly
|
||||
// to compiled bytecode via HEX-editor to implement multiline messageboxes.
|
||||
// Of course, original editor will not compile such script.
|
||||
// Allow messageboxes to bybass the "incomplete string or name" error.
|
||||
// Of course, original editor can not compile such script.
|
||||
// Allow messageboxes to bypass the "incomplete string or name" error.
|
||||
if (lowerCase == "messagebox")
|
||||
enableIgnoreNewlines();
|
||||
else if (isKeyword)
|
||||
|
@ -344,7 +340,7 @@ namespace Compiler
|
|||
|
||||
bool Scanner::scanName (std::string& name)
|
||||
{
|
||||
char c;
|
||||
MultiChar c;
|
||||
bool error = false;
|
||||
|
||||
while (get (c))
|
||||
|
@ -353,7 +349,7 @@ namespace Compiler
|
|||
{
|
||||
if (c=='"')
|
||||
{
|
||||
name += c;
|
||||
c.appendTo(name);
|
||||
break;
|
||||
}
|
||||
// ignoring escape sequences for now, because they are messing up stupid Windows path names.
|
||||
|
@ -380,20 +376,20 @@ namespace Compiler
|
|||
}
|
||||
else if (!(c=='"' && name.empty()))
|
||||
{
|
||||
if (!isStringCharacter (c) && !(mTolerantNames && (c=='.' || c=='-')))
|
||||
if (!isStringCharacter (c) && !(mTolerantNames && (c=='.' || c == '-')))
|
||||
{
|
||||
putback (c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
name += c;
|
||||
c.appendTo(name);
|
||||
}
|
||||
|
||||
return !error;
|
||||
}
|
||||
|
||||
bool Scanner::scanSpecial (char c, Parser& parser, bool& cont)
|
||||
bool Scanner::scanSpecial (MultiChar& c, Parser& parser, bool& cont)
|
||||
{
|
||||
int special = -1;
|
||||
|
||||
|
@ -410,7 +406,7 @@ namespace Compiler
|
|||
{
|
||||
putback (c);
|
||||
|
||||
if (std::isdigit (c))
|
||||
if (c.isDigit())
|
||||
return scanFloat ("", parser, cont);
|
||||
}
|
||||
|
||||
|
@ -428,7 +424,7 @@ namespace Compiler
|
|||
else if (c == '>' || c == '<') // Treat => and =< as ==
|
||||
{
|
||||
special = S_cmpEQ;
|
||||
mErrorHandler.warning (std::string("invalid operator =") + c + ", treating it as ==", mLoc);
|
||||
mErrorHandler.warning (std::string("invalid operator =") + c.data() + ", treating it as ==", mLoc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -463,7 +459,7 @@ namespace Compiler
|
|||
else
|
||||
return false;
|
||||
}
|
||||
else if (c=='-')
|
||||
else if (c.isMinusSign())
|
||||
{
|
||||
if (get (c))
|
||||
{
|
||||
|
@ -478,32 +474,6 @@ namespace Compiler
|
|||
else
|
||||
special = S_minus;
|
||||
}
|
||||
else if (static_cast<unsigned char> (c)==0xe2)
|
||||
{
|
||||
/// Workaround for some translator who apparently can't keep his minus in order
|
||||
/// \todo disable for later script formats
|
||||
if (get (c) && static_cast<unsigned char> (c)==0x80 &&
|
||||
get (c) && static_cast<unsigned char> (c)==0x93)
|
||||
{
|
||||
if (get (c))
|
||||
{
|
||||
if (c=='>')
|
||||
special = S_ref;
|
||||
else
|
||||
{
|
||||
putback (c);
|
||||
special = S_minus;
|
||||
}
|
||||
}
|
||||
else
|
||||
special = S_minus;
|
||||
}
|
||||
else
|
||||
{
|
||||
mErrorHandler.error ("Invalid character", mLoc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (c=='<')
|
||||
{
|
||||
if (get (c))
|
||||
|
@ -582,20 +552,21 @@ namespace Compiler
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Scanner::isStringCharacter (char c, bool lookAhead)
|
||||
bool Scanner::isStringCharacter (MultiChar& c, bool lookAhead)
|
||||
{
|
||||
return std::isalpha (c) || std::isdigit (c) || c=='_' ||
|
||||
/// \todo disable this when doing more stricter compiling
|
||||
c=='`' || c=='\'' ||
|
||||
if (lookAhead && c.isMinusSign())
|
||||
{
|
||||
/// \todo disable this when doing more stricter compiling. Also, find out who is
|
||||
/// responsible for allowing it in the first place and meet up with that person in
|
||||
/// a dark alley.
|
||||
(c=='-' && (!lookAhead || isStringCharacter (mStream.peek(), false)));
|
||||
}
|
||||
MultiChar next;
|
||||
if (next.peek(mStream) && isStringCharacter (next, false))
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Scanner::isWhitespace (char c)
|
||||
{
|
||||
return c==' ' || c=='\t';
|
||||
return c.isAlpha() || c.isDigit() || c=='_' ||
|
||||
/// \todo disable this when doing more stricter compiling
|
||||
c=='`' || c=='\'';
|
||||
}
|
||||
|
||||
// constructor
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
#ifndef COMPILER_SCANNER_H_INCLUDED
|
||||
#define COMPILER_SCANNER_H_INCLUDED
|
||||
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#include "tokenloc.hpp"
|
||||
|
||||
|
@ -18,6 +20,160 @@ namespace Compiler
|
|||
/// This class translate a char-stream to a token stream (delivered via
|
||||
/// parser-callbacks).
|
||||
|
||||
class MultiChar
|
||||
{
|
||||
public:
|
||||
MultiChar()
|
||||
{
|
||||
blank();
|
||||
}
|
||||
|
||||
MultiChar(const char ch)
|
||||
{
|
||||
blank();
|
||||
mData[0] = ch;
|
||||
|
||||
mLength = getCharLength(ch);
|
||||
}
|
||||
|
||||
int getCharLength(const char ch)
|
||||
{
|
||||
unsigned char c = ch;
|
||||
if (c<=127) return 0;
|
||||
else if ((c & 0xE0) == 0xC0) return 1;
|
||||
else if ((c & 0xF0) == 0xE0) return 2;
|
||||
else if ((c & 0xF8) == 0xF0) return 3;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
bool operator== (const char ch)
|
||||
{
|
||||
return mData[0]==ch && mData[1]==0 && mData[2]==0 && mData[3]==0;
|
||||
}
|
||||
|
||||
bool operator== (const MultiChar& ch)
|
||||
{
|
||||
return mData[0]==ch.mData[0] && mData[1]==ch.mData[1] && mData[2]==ch.mData[2] && mData[3]==ch.mData[3];
|
||||
}
|
||||
|
||||
bool operator!= (const char ch)
|
||||
{
|
||||
return mData[0]!=ch || mData[1]!=0 || mData[2]!=0 || mData[3]!=0;
|
||||
}
|
||||
|
||||
bool isWhitespace()
|
||||
{
|
||||
return (mData[0]==' ' || mData[0]=='\t') && mData[1]==0 && mData[2]==0 && mData[3]==0;
|
||||
}
|
||||
|
||||
bool isDigit()
|
||||
{
|
||||
return std::isdigit(mData[0]) && mData[1]==0 && mData[2]==0 && mData[3]==0;
|
||||
}
|
||||
|
||||
bool isMinusSign()
|
||||
{
|
||||
if (mData[0] == '-' && mData[1] == 0 && mData[2] == 0 && mData[3] == 0)
|
||||
return true;
|
||||
|
||||
return mData[0] == '\xe2' && mData[1] == '\x80' && mData[2] == '\x93' && mData[3] == 0;
|
||||
}
|
||||
|
||||
bool isAlpha()
|
||||
{
|
||||
if (isMinusSign())
|
||||
return false;
|
||||
|
||||
return std::isalpha(mData[0]) || mData[1]!=0 || mData[2]!=0 || mData[3]!=0;
|
||||
}
|
||||
|
||||
void appendTo(std::string& str)
|
||||
{
|
||||
for (int i = 0; i <= mLength; i++)
|
||||
str += mData[i];
|
||||
}
|
||||
|
||||
void putback (std::istream& in)
|
||||
{
|
||||
for (int i = mLength; i >= 0; i--)
|
||||
in.putback (mData[i]);
|
||||
}
|
||||
|
||||
bool getFrom(std::istream& in)
|
||||
{
|
||||
blank();
|
||||
|
||||
char ch = in.peek();
|
||||
|
||||
if (!in.good())
|
||||
return false;
|
||||
|
||||
int length = getCharLength(ch);
|
||||
if (length < 0) return false;
|
||||
|
||||
for (int i = 0; i <= length; i++)
|
||||
{
|
||||
in.get (ch);
|
||||
|
||||
if (!in.good())
|
||||
return false;
|
||||
|
||||
mData[i] = ch;
|
||||
}
|
||||
|
||||
mLength = length;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool peek(std::istream& in)
|
||||
{
|
||||
std::streampos p_orig = in.tellg();
|
||||
|
||||
char ch = in.peek();
|
||||
|
||||
if (!in.good())
|
||||
return false;
|
||||
|
||||
int length = getCharLength(ch);
|
||||
if (length < 0) return false;
|
||||
|
||||
for (int i = 0; i <= length; i++)
|
||||
{
|
||||
if (length >= i)
|
||||
{
|
||||
in.get (ch);
|
||||
|
||||
if (!in.good())
|
||||
return false;
|
||||
|
||||
mData[i] = ch;
|
||||
}
|
||||
}
|
||||
|
||||
mLength = length;
|
||||
|
||||
in.seekg(p_orig);
|
||||
return true;
|
||||
};
|
||||
|
||||
void blank()
|
||||
{
|
||||
std::fill(mData, mData + sizeof(mData), 0);
|
||||
mLength = -1;
|
||||
}
|
||||
|
||||
std::string data()
|
||||
{
|
||||
// NB: mLength is the number of the last element in the array
|
||||
return std::string(mData, mLength + 1);
|
||||
}
|
||||
|
||||
private:
|
||||
char mData[4];
|
||||
int mLength;
|
||||
};
|
||||
|
||||
class Scanner
|
||||
{
|
||||
enum putback_type
|
||||
|
@ -79,26 +235,24 @@ namespace Compiler
|
|||
Scanner (const Scanner&);
|
||||
Scanner& operator= (const Scanner&);
|
||||
|
||||
bool get (char& c);
|
||||
bool get (MultiChar& c);
|
||||
|
||||
void putback (char c);
|
||||
void putback (MultiChar& c);
|
||||
|
||||
bool scanToken (Parser& parser);
|
||||
|
||||
bool scanInt (char c, Parser& parser, bool& cont);
|
||||
bool scanInt (MultiChar& c, Parser& parser, bool& cont);
|
||||
|
||||
bool scanFloat (const std::string& intValue, Parser& parser, bool& cont);
|
||||
|
||||
bool scanName (char c, Parser& parser, bool& cont);
|
||||
bool scanName (MultiChar& c, Parser& parser, bool& cont);
|
||||
|
||||
/// \param name May contain the start of the name (one or more characters)
|
||||
bool scanName (std::string& name);
|
||||
|
||||
bool scanSpecial (char c, Parser& parser, bool& cont);
|
||||
bool scanSpecial (MultiChar& c, Parser& parser, bool& cont);
|
||||
|
||||
bool isStringCharacter (char c, bool lookAhead = true);
|
||||
|
||||
static bool isWhitespace (char c);
|
||||
bool isStringCharacter (MultiChar& c, bool lookAhead = true);
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -30,15 +30,17 @@ struct MagicEffect
|
|||
CastSelf = 0x40, // Allows range - cast on self.
|
||||
CastTouch = 0x80, // Allows range - cast on touch.
|
||||
CastTarget = 0x100, // Allows range - cast on target.
|
||||
UncappedDamage = 0x1000, // Negates multiple cap behaviours. Allows an effect to reduce an attribute below zero; removes the normal minimum effect duration of 1 second.
|
||||
AppliedOnce = 0x1000, // An effect that is applied once it lands, instead of continuously. Allows an effect to reduce an attribute below zero; removes the normal minimum effect duration of 1 second.
|
||||
Stealth = 0x2000, // Unused
|
||||
NonRecastable = 0x4000, // Does not land if parent spell is already affecting target. Shows "you cannot re-cast" message for self target.
|
||||
IllegalDaedra = 0x8000, // Unused
|
||||
Unreflectable = 0x10000, // Cannot be reflected, the effect always lands normally.
|
||||
CasterLinked = 0x20000, // Must quench if caster is dead, or not an NPC/creature. Not allowed in containter/door trap spells.
|
||||
|
||||
// Originally modifiable flags
|
||||
AllowSpellmaking = 0x200, // Can be used for spellmaking
|
||||
AllowEnchanting = 0x400, // Can be used for enchanting
|
||||
NegativeLight = 0x800 // Negative light source
|
||||
NegativeLight = 0x800 // Unused
|
||||
};
|
||||
|
||||
enum MagnitudeDisplayType
|
||||
|
|
|
@ -843,6 +843,11 @@ void SceneUtil::MWShadowTechnique::setPolygonOffset(float factor, float units)
|
|||
}
|
||||
}
|
||||
|
||||
void SceneUtil::MWShadowTechnique::setShadowFadeStart(float shadowFadeStart)
|
||||
{
|
||||
_shadowFadeStart = shadowFadeStart;
|
||||
}
|
||||
|
||||
void SceneUtil::MWShadowTechnique::enableFrontFaceCulling()
|
||||
{
|
||||
_useFrontFaceCulling = true;
|
||||
|
@ -1493,6 +1498,9 @@ void MWShadowTechnique::createShaders()
|
|||
osg::ref_ptr<osg::Uniform> baseTextureUnit = new osg::Uniform("baseTextureUnit",(int)_baseTextureUnit);
|
||||
_uniforms.push_back(baseTextureUnit.get());
|
||||
|
||||
_uniforms.push_back(new osg::Uniform("maximumShadowMapDistance", (float)settings->getMaximumShadowMapDistance()));
|
||||
_uniforms.push_back(new osg::Uniform("shadowFadeStart", (float)_shadowFadeStart));
|
||||
|
||||
for(unsigned int sm_i=0; sm_i<settings->getNumShadowMapsPerLight(); ++sm_i)
|
||||
{
|
||||
{
|
||||
|
|
|
@ -76,6 +76,8 @@ namespace SceneUtil {
|
|||
|
||||
virtual void setPolygonOffset(float factor, float units);
|
||||
|
||||
virtual void setShadowFadeStart(float shadowFadeStart);
|
||||
|
||||
virtual void enableFrontFaceCulling();
|
||||
|
||||
virtual void disableFrontFaceCulling();
|
||||
|
@ -257,6 +259,8 @@ namespace SceneUtil {
|
|||
|
||||
bool _useFrontFaceCulling = true;
|
||||
|
||||
float _shadowFadeStart = 0.0;
|
||||
|
||||
class DebugHUD : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -27,6 +27,14 @@ namespace SceneUtil
|
|||
mShadowSettings->setNumShadowMapsPerLight(numberOfShadowMapsPerLight);
|
||||
mShadowSettings->setBaseShadowTextureUnit(8 - numberOfShadowMapsPerLight);
|
||||
|
||||
const float maximumShadowMapDistance = Settings::Manager::getFloat("maximum shadow map distance", "Shadows");
|
||||
if (maximumShadowMapDistance > 0)
|
||||
{
|
||||
const float shadowFadeStart = std::min(std::max(0.f, Settings::Manager::getFloat("shadow fade start", "Shadows")), 1.f);
|
||||
mShadowSettings->setMaximumShadowMapDistance(maximumShadowMapDistance);
|
||||
mShadowTechnique->setShadowFadeStart(maximumShadowMapDistance * shadowFadeStart);
|
||||
}
|
||||
|
||||
mShadowSettings->setMinimumShadowMapNearFarRatio(Settings::Manager::getFloat("minimum lispsm near far ratio", "Shadows"));
|
||||
if (Settings::Manager::getBool("compute tight scene bounds", "Shadows"))
|
||||
mShadowSettings->setComputeNearFarModeOverride(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES);
|
||||
|
@ -117,6 +125,8 @@ namespace SceneUtil
|
|||
|
||||
definesWithShadows["shadowNormalOffset"] = std::to_string(Settings::Manager::getFloat("normal offset distance", "Shadows"));
|
||||
|
||||
definesWithShadows["limitShadowMapDistance"] = Settings::Manager::getFloat("maximum shadow map distance", "Shadows") > 0 ? "1" : "0";
|
||||
|
||||
return definesWithShadows;
|
||||
}
|
||||
|
||||
|
@ -138,6 +148,8 @@ namespace SceneUtil
|
|||
|
||||
definesWithoutShadows["shadowNormalOffset"] = "0.0";
|
||||
|
||||
definesWithoutShadows["limitShadowMapDistance"] = "0";
|
||||
|
||||
return definesWithoutShadows;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ public:
|
|||
virtual void mouseMoved( const MouseMotionEvent &arg ) = 0;
|
||||
virtual void mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ) = 0;
|
||||
virtual void mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ) = 0;
|
||||
virtual void mouseWheelMoved( const SDL_MouseWheelEvent &arg) = 0;
|
||||
};
|
||||
|
||||
class KeyListener
|
||||
|
|
|
@ -77,6 +77,7 @@ InputWrapper::InputWrapper(SDL_Window* window, osg::ref_ptr<osgViewer::Viewer> v
|
|||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
mMouseListener->mouseMoved(_packageMouseMotion(evt));
|
||||
mMouseListener->mouseWheelMoved(evt.wheel);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
mMouseListener->mousePressed(evt.button, evt.button.button);
|
||||
|
|
|
@ -108,7 +108,7 @@ void QuadTreeNode::initNeighbours()
|
|||
getChild(i)->initNeighbours();
|
||||
}
|
||||
|
||||
void QuadTreeNode::traverse(ViewData* vd, const osg::Vec3f& viewPoint, LodCallback* lodCallback, float maxDist)
|
||||
void QuadTreeNode::traverseNodes(ViewData* vd, const osg::Vec3f& viewPoint, LodCallback* lodCallback, float maxDist)
|
||||
{
|
||||
if (!hasValidBounds())
|
||||
return;
|
||||
|
@ -124,7 +124,7 @@ void QuadTreeNode::traverse(ViewData* vd, const osg::Vec3f& viewPoint, LodCallba
|
|||
else
|
||||
{
|
||||
for (unsigned int i=0; i<getNumChildren(); ++i)
|
||||
getChild(i)->traverse(vd, viewPoint, lodCallback, maxDist);
|
||||
getChild(i)->traverseNodes(vd, viewPoint, lodCallback, maxDist);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ namespace Terrain
|
|||
const osg::Vec2f& getCenter() const;
|
||||
|
||||
/// Traverse nodes according to LOD selection.
|
||||
void traverse(ViewData* vd, const osg::Vec3f& viewPoint, LodCallback* lodCallback, float maxDist);
|
||||
void traverseNodes(ViewData* vd, const osg::Vec3f& viewPoint, LodCallback* lodCallback, float maxDist);
|
||||
|
||||
/// Traverse to a specific node and add only that node.
|
||||
void traverseTo(ViewData* vd, float size, const osg::Vec2f& center);
|
||||
|
|
|
@ -353,7 +353,7 @@ void QuadTreeWorld::accept(osg::NodeVisitor &nv)
|
|||
mRootNode->traverseTo(vd, 1, osg::Vec2f(x+0.5,y+0.5));
|
||||
}
|
||||
else
|
||||
mRootNode->traverse(vd, cv->getViewPoint(), mLodCallback, mViewDistance);
|
||||
mRootNode->traverseNodes(vd, cv->getViewPoint(), mLodCallback, mViewDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -446,7 +446,7 @@ void QuadTreeWorld::preload(View *view, const osg::Vec3f &viewPoint, std::atomic
|
|||
|
||||
ViewData* vd = static_cast<ViewData*>(view);
|
||||
vd->setViewPoint(viewPoint);
|
||||
mRootNode->traverse(vd, viewPoint, mLodCallback, mViewDistance);
|
||||
mRootNode->traverseNodes(vd, viewPoint, mLodCallback, mViewDistance);
|
||||
|
||||
for (unsigned int i=0; i<vd->getNumEntries() && !abort; ++i)
|
||||
{
|
||||
|
|
|
@ -197,10 +197,6 @@ The appearance and count of shown ammunition depends on type and count of equipp
|
|||
|
||||
It is important to make sure the names of empty nodes start with ``"Bip01 "``, or the engine will optimize them out.
|
||||
|
||||
4. Shields
|
||||
|
||||
Shield holstering is not supported at the moment since it conflicts with any mods which use pseudo-shields as held items (such as Animated Morrowind and Hold It).
|
||||
|
||||
An example of a mod which uses this feature is `Weapon Sheathing`_.
|
||||
|
||||
|
||||
|
|
|
@ -54,18 +54,6 @@ based on whether the caps lock key was on or off at the time you exited.
|
|||
|
||||
This settings can be toggled in game by pressing the CapsLock key and exiting.
|
||||
|
||||
allow third person zoom
|
||||
-----------------------
|
||||
|
||||
:Type: boolean
|
||||
:Range: True/False
|
||||
:Default: False
|
||||
|
||||
Allow zooming in and out using the middle mouse wheel in third person view.
|
||||
This feature may not work correctly if the mouse wheel is bound to other actions,
|
||||
and may be triggered accidentally in some cases, so is disabled by default.
|
||||
This setting can only be configured by editing the settings configuration file.
|
||||
|
||||
camera sensitivity
|
||||
------------------
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ Unlike in the original Morrowind engine, 'Shadow Mapping' is used, which can hav
|
|||
Bear in mind that this will force OpenMW to use shaders as if :ref:`force shaders` was enabled.
|
||||
A keen developer may be able to implement compatibility with fixed-function mode using the advice of `this post <https://github.com/OpenMW/openmw/pull/1547#issuecomment-369657381>`_, but it may be more difficult than it seems.
|
||||
|
||||
|
||||
number of shadow maps
|
||||
---------------------
|
||||
|
||||
|
@ -28,6 +27,28 @@ Control how many shadow maps to use - more of these means each shadow map texel
|
|||
Using too many shadow maps will lead to them overriding texture slots used for other effects, producing unpleasant artefacts.
|
||||
A value of three is recommended in most cases, but other values may produce better results or performance.
|
||||
|
||||
maximum shadow map distance
|
||||
---------------------------
|
||||
|
||||
:Type: float
|
||||
:Range: The whole range of 32-bit floating point
|
||||
:Default: 8192
|
||||
|
||||
The maximum distance from the camera shadows cover, limiting their overall area coverage
|
||||
and improving their quality and performance at the cost of removing shadows of distant objects or terrain.
|
||||
Set this to a non-positive value to remove the limit.
|
||||
|
||||
shadow fade start
|
||||
-------------------
|
||||
|
||||
:Type: float
|
||||
:Range: 0.0-1.0
|
||||
:Default: 0.9
|
||||
|
||||
The fraction of the maximum shadow map distance at which the shadows will begin to fade away.
|
||||
Tweaking it will make the transition proportionally more or less smooth.
|
||||
This setting has no effect if the maximum shadow map distance is non-positive (infinite).
|
||||
|
||||
allow shadow map overlap
|
||||
------------------------
|
||||
|
||||
|
@ -213,4 +234,4 @@ minimum lispsm near far ratio
|
|||
|
||||
Controls the minimum near/far ratio for the Light Space Perspective Shadow Map transformation.
|
||||
Helps prevent too much detail being brought towards the camera at the expense of detail further from the camera.
|
||||
Increasing this pushes detail further away by moving the frustum apex further from the near plane.
|
||||
Increasing this pushes detail further away by moving the frustum apex further from the near plane.
|
||||
|
|
79
extern/oics/ICSInputControlSystem.cpp
vendored
79
extern/oics/ICSInputControlSystem.cpp
vendored
|
@ -226,6 +226,15 @@ namespace ICS
|
|||
|
||||
loadJoystickButtonBinders(xmlControl);
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* OPENMW CODE STARTS HERE
|
||||
* Mouse Wheel support added by Michael Stopa (Stomy) */
|
||||
|
||||
loadMouseWheelBinders(xmlControl);
|
||||
|
||||
/* OPENMW CODE ENDS HERE
|
||||
* ------------------------------------------------------------------------------------- */
|
||||
|
||||
// Attach controls to channels
|
||||
TiXmlElement* xmlChannel = xmlControl->FirstChildElement("Channel");
|
||||
while(xmlChannel)
|
||||
|
@ -307,6 +316,15 @@ namespace ICS
|
|||
mControlsMouseButtonBinderMap.clear();
|
||||
mControlsJoystickButtonBinderMap.clear();
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* OPENMW CODE STARTS HERE
|
||||
* Mouse Wheel support added by Michael Stopa (Stomy) */
|
||||
|
||||
mControlsMouseWheelBinderMap.clear();
|
||||
|
||||
/* OPENMW CODE ENDS HERE
|
||||
* ------------------------------------------------------------------------------------- */
|
||||
|
||||
ICS_LOG(" - InputControlSystem deleted - ");
|
||||
}
|
||||
|
||||
|
@ -491,6 +509,67 @@ namespace ICS
|
|||
control.InsertEndChild(binder);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* OPENMW CODE STARTS HERE
|
||||
* Mouse Wheel support added by Stomy */
|
||||
|
||||
if(getMouseWheelBinding(*o, Control::INCREASE) != MouseWheelClick::UNASSIGNED)
|
||||
{
|
||||
TiXmlElement binder( "MouseWheelBinder" );
|
||||
MouseWheelClick click = getMouseWheelBinding(*o, Control::INCREASE);
|
||||
bool skip = false;
|
||||
switch (click) {
|
||||
case MouseWheelClick::UP: {
|
||||
binder.SetAttribute("button", "UP");
|
||||
} break;
|
||||
case MouseWheelClick::DOWN: {
|
||||
binder.SetAttribute("button", "DOWN");
|
||||
} break;
|
||||
case MouseWheelClick::RIGHT: {
|
||||
binder.SetAttribute("button", "RIGHT");
|
||||
} break;
|
||||
case MouseWheelClick::LEFT: {
|
||||
binder.SetAttribute("button", "LEFT");
|
||||
} break;
|
||||
default: {
|
||||
skip = true;
|
||||
} break;
|
||||
}
|
||||
binder.SetAttribute( "direction", "INCREASE" );
|
||||
if (!skip)
|
||||
control.InsertEndChild(binder);
|
||||
}
|
||||
|
||||
if(getMouseWheelBinding(*o, Control::DECREASE) != MouseWheelClick::UNASSIGNED)
|
||||
{
|
||||
TiXmlElement binder( "MouseWheelBinder" );
|
||||
MouseWheelClick click = getMouseWheelBinding(*o, Control::INCREASE);
|
||||
bool skip = false;
|
||||
switch (click) {
|
||||
case MouseWheelClick::UP: {
|
||||
binder.SetAttribute("button", "UP");
|
||||
} break;
|
||||
case MouseWheelClick::DOWN: {
|
||||
binder.SetAttribute("button", "DOWN");
|
||||
} break;
|
||||
case MouseWheelClick::RIGHT: {
|
||||
binder.SetAttribute("button", "RIGHT");
|
||||
} break;
|
||||
case MouseWheelClick::LEFT: {
|
||||
binder.SetAttribute("button", "LEFT");
|
||||
} break;
|
||||
default: {
|
||||
skip = true;
|
||||
} break;
|
||||
}
|
||||
binder.SetAttribute( "direction", "DECREASE" );
|
||||
if (!skip)
|
||||
control.InsertEndChild(binder);
|
||||
}
|
||||
|
||||
/* OPENMW CODE ENDS HERE
|
||||
* ------------------------------------------------------------------------------------- */
|
||||
|
||||
if(getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::INCREASE)
|
||||
!= ICS_MAX_DEVICE_BUTTONS)
|
||||
{
|
||||
|
|
30
extern/oics/ICSInputControlSystem.h
vendored
30
extern/oics/ICSInputControlSystem.h
vendored
|
@ -214,6 +214,26 @@ namespace ICS
|
|||
|
||||
Uint16 mClientWidth;
|
||||
Uint16 mClientHeight;
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* OPENMW CODE STARTS HERE
|
||||
* Mouse Wheel support added by Michael Stopa (Stomy) */
|
||||
|
||||
public:
|
||||
enum class MouseWheelClick : int { UNASSIGNED = 0, UP = 1, DOWN = 2, LEFT = 3, RIGHT = 4};
|
||||
|
||||
void mouseWheelMoved(const SDL_MouseWheelEvent &evt);
|
||||
void addMouseWheelBinding(Control* control, MouseWheelClick click, Control::ControlChangingDirection direction);
|
||||
void removeMouseWheelBinding(MouseWheelClick click);
|
||||
MouseWheelClick getMouseWheelBinding(Control* control, ICS::Control::ControlChangingDirection direction);
|
||||
bool isMouseWheelBound(MouseWheelClick button) const;
|
||||
|
||||
protected:
|
||||
void loadMouseWheelBinders(TiXmlElement* xmlControlNode);
|
||||
ControlsButtonBinderMapType mControlsMouseWheelBinderMap;
|
||||
|
||||
/* OPENMW CODE ENDS HERE
|
||||
* ------------------------------------------------------------------------------------- */
|
||||
};
|
||||
|
||||
class DllExport DetectingBindingListener
|
||||
|
@ -234,6 +254,16 @@ namespace ICS
|
|||
virtual void joystickButtonBindingDetected(InputControlSystem* ICS, int deviceID, Control* control
|
||||
, unsigned int button, Control::ControlChangingDirection direction);
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* OPENMW CODE STARTS HERE
|
||||
* Mouse Wheel support added by Michael Stopa (Stomy) */
|
||||
|
||||
virtual void mouseWheelBindingDetected(InputControlSystem* ICS, Control* control,
|
||||
InputControlSystem::MouseWheelClick click,
|
||||
Control::ControlChangingDirection direction);
|
||||
|
||||
/* OPENMW CODE ENDS HERE
|
||||
* ------------------------------------------------------------------------------------- */
|
||||
};
|
||||
|
||||
extern const float ICS_MAX;
|
||||
|
|
167
extern/oics/ICSInputControlSystem_mouse.cpp
vendored
167
extern/oics/ICSInputControlSystem_mouse.cpp
vendored
|
@ -396,4 +396,171 @@ namespace ICS
|
|||
ICS->cancelDetectingBindingState();
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* OPENMW CODE STARTS HERE
|
||||
* Mouse Wheel support added by Michael Stopa (Stomy) */
|
||||
|
||||
void InputControlSystem::loadMouseWheelBinders(TiXmlElement* xmlControlNode)
|
||||
{
|
||||
TiXmlElement* xmlMouseWheelBinder = xmlControlNode->FirstChildElement("MouseWheelBinder");
|
||||
while (xmlMouseWheelBinder)
|
||||
{
|
||||
Control::ControlChangingDirection dir = Control::STOP;
|
||||
if (std::string(xmlMouseWheelBinder->Attribute("direction")) == "INCREASE")
|
||||
{
|
||||
dir = Control::INCREASE;
|
||||
}
|
||||
else if (std::string(xmlMouseWheelBinder->Attribute("direction")) == "DECREASE")
|
||||
{
|
||||
dir = Control::DECREASE;
|
||||
}
|
||||
|
||||
MouseWheelClick click = MouseWheelClick::UNASSIGNED;
|
||||
if (std::string(xmlMouseWheelBinder->Attribute("button")) == "UP")
|
||||
{
|
||||
click = MouseWheelClick::UP;
|
||||
}
|
||||
else if (std::string(xmlMouseWheelBinder->Attribute("button")) == "DOWN")
|
||||
{
|
||||
click = MouseWheelClick::DOWN;
|
||||
}
|
||||
else if (std::string(xmlMouseWheelBinder->Attribute("button")) == "DOWN")
|
||||
{
|
||||
click = MouseWheelClick::RIGHT;
|
||||
}
|
||||
else if (std::string(xmlMouseWheelBinder->Attribute("button")) == "DOWN")
|
||||
{
|
||||
click = MouseWheelClick::LEFT;
|
||||
}
|
||||
|
||||
addMouseWheelBinding(mControls.back(), click, dir);
|
||||
xmlMouseWheelBinder = xmlMouseWheelBinder->NextSiblingElement("MouseWheelBinder");
|
||||
}
|
||||
}
|
||||
|
||||
void InputControlSystem::addMouseWheelBinding(
|
||||
Control* control,
|
||||
MouseWheelClick click,
|
||||
Control::ControlChangingDirection direction)
|
||||
{
|
||||
ICS_LOG("\tAdding MouseWheelBinder [button="
|
||||
+ ToString<int>(static_cast<int>(click)) + ", direction="
|
||||
+ ToString<int>(direction) + "]");
|
||||
|
||||
ControlButtonBinderItem controlButtonBinderItem;
|
||||
controlButtonBinderItem.control = control;
|
||||
controlButtonBinderItem.direction = direction;
|
||||
mControlsMouseWheelBinderMap[static_cast<int>(click)] = controlButtonBinderItem;
|
||||
}
|
||||
|
||||
void InputControlSystem::removeMouseWheelBinding(MouseWheelClick click)
|
||||
{
|
||||
ControlsAxisBinderMapType::iterator it = mControlsMouseWheelBinderMap.find(static_cast<int>(click));
|
||||
if (it != mControlsMouseWheelBinderMap.end())
|
||||
{
|
||||
mControlsMouseWheelBinderMap.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
InputControlSystem::MouseWheelClick InputControlSystem::getMouseWheelBinding(
|
||||
Control* control,
|
||||
ICS::Control::ControlChangingDirection direction)
|
||||
{
|
||||
ControlsAxisBinderMapType::iterator it = mControlsMouseWheelBinderMap.begin();
|
||||
while (it != mControlsMouseWheelBinderMap.end())
|
||||
{
|
||||
if (it->first > 0 && it->second.control == control && it->second.direction == direction)
|
||||
{
|
||||
return (MouseWheelClick)(it->first);
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
return MouseWheelClick::UNASSIGNED;
|
||||
}
|
||||
|
||||
bool InputControlSystem::isMouseWheelBound(MouseWheelClick button) const
|
||||
{
|
||||
return mControlsMouseWheelBinderMap.find(static_cast<int>(button)) != mControlsMouseWheelBinderMap.end();
|
||||
}
|
||||
|
||||
void InputControlSystem::mouseWheelMoved(const SDL_MouseWheelEvent &evt)
|
||||
{
|
||||
if (mActive)
|
||||
{
|
||||
MouseWheelClick click = MouseWheelClick::UNASSIGNED;
|
||||
int value;
|
||||
if (evt.y != 0)
|
||||
{
|
||||
value = evt.y;
|
||||
if (evt.direction == SDL_MOUSEWHEEL_FLIPPED)
|
||||
value *= -1;
|
||||
if (value > 0)
|
||||
click = MouseWheelClick::UP;
|
||||
else
|
||||
click = MouseWheelClick::DOWN;
|
||||
}
|
||||
else if (evt.x != 0)
|
||||
{
|
||||
value = evt.x;
|
||||
if (evt.direction == SDL_MOUSEWHEEL_FLIPPED)
|
||||
value *= -1;
|
||||
if (value > 0)
|
||||
click = MouseWheelClick::RIGHT;
|
||||
else
|
||||
click = MouseWheelClick::LEFT;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
if(!mDetectingBindingControl)
|
||||
{
|
||||
// This assumes a single event is sent for every single mouse wheel direction, if they are
|
||||
// buffered up then all bindings will have to be resolved on every invocation of this function
|
||||
|
||||
ControlButtonBinderItem wheelBinderItem = mControlsMouseWheelBinderMap[static_cast<int>(click)];
|
||||
Control* control = wheelBinderItem.control;
|
||||
if (control)
|
||||
{
|
||||
control->setIgnoreAutoReverse(false);
|
||||
if (wheelBinderItem.direction == Control::INCREASE)
|
||||
{
|
||||
control->setValue(static_cast<float>(std::abs(value)));
|
||||
control->setChangingDirection(Control::STOP);
|
||||
}
|
||||
else if (wheelBinderItem.direction == Control::DECREASE)
|
||||
{
|
||||
control->setValue(static_cast<float>(std::abs(value)));
|
||||
control->setChangingDirection(Control::STOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(mDetectingBindingListener)
|
||||
{
|
||||
mDetectingBindingListener->mouseWheelBindingDetected(this,
|
||||
mDetectingBindingControl, click, mDetectingBindingDirection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DetectingBindingListener::mouseWheelBindingDetected(
|
||||
InputControlSystem* ICS,
|
||||
Control* control,
|
||||
InputControlSystem::MouseWheelClick click,
|
||||
Control::ControlChangingDirection direction)
|
||||
{
|
||||
ICS->removeMouseWheelBinding(click);
|
||||
|
||||
InputControlSystem::MouseWheelClick oldClick = ICS->getMouseWheelBinding(control, direction);
|
||||
if (oldClick != InputControlSystem::MouseWheelClick::UNASSIGNED)
|
||||
{
|
||||
ICS->removeMouseWheelBinding(oldClick);
|
||||
}
|
||||
|
||||
ICS->addMouseWheelBinding(control, click, direction);
|
||||
ICS->cancelDetectingBindingState();
|
||||
}
|
||||
|
||||
/* OPENMW CODE ENDS HERE
|
||||
* ------------------------------------------------------------------------------------- */
|
||||
}
|
||||
|
|
|
@ -48,4 +48,5 @@ Copyright 2018 Bret Curtis <psi29a@gmail.com>
|
|||
<url type="homepage">https://openmw.org</url>
|
||||
<url type="bugtracker">https://gitlab.com/OpenMW/openmw/issues</url>
|
||||
<url type="faq">https://openmw.org/faq/</url>
|
||||
<content_rating type="oars-1.1" />
|
||||
</component>
|
||||
|
|
|
@ -348,9 +348,6 @@ toggle sneak = false
|
|||
# Player is running by default.
|
||||
always run = false
|
||||
|
||||
# Zoom in and out from player in third person view with mouse wheel.
|
||||
allow third person zoom = false
|
||||
|
||||
# Camera sensitivity when not in GUI mode. (>0.0, e.g. 0.1 to 5.0).
|
||||
camera sensitivity = 1.0
|
||||
|
||||
|
@ -749,6 +746,12 @@ enable shadows = false
|
|||
# How many shadow maps to use - more of these means each shadow map texel covers less area, producing better looking shadows, but may decrease performance.
|
||||
number of shadow maps = 3
|
||||
|
||||
# The distance from the camera at which shadows fade away completely. Set to 0 to make the distance infinite.
|
||||
maximum shadow map distance = 8192
|
||||
|
||||
# Fraction of the maximum distance at which shadows begin to gradually fade away.
|
||||
shadow fade start = 0.9
|
||||
|
||||
# If true, allow shadow maps to overlap. Counter-intuitively, will produce better results when the light is behind the camera. When enabled, OpenMW uses Cascaded Shadow Maps and when disabled, it uses Parallel Split Shadow Maps.
|
||||
allow shadow map overlap = true
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ void main()
|
|||
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, decalTex.xyz, decalTex.a);
|
||||
#endif
|
||||
|
||||
float shadowing = unshadowedLightRatio();
|
||||
float shadowing = unshadowedLightRatio(depth);
|
||||
|
||||
#if !PER_PIXEL_LIGHTING
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#define SHADOWS @shadows_enabled
|
||||
|
||||
#if SHADOWS
|
||||
uniform float maximumShadowMapDistance;
|
||||
uniform float shadowFadeStart;
|
||||
@foreach shadow_texture_unit_index @shadow_texture_unit_list
|
||||
uniform sampler2DShadow shadowTexture@shadow_texture_unit_index;
|
||||
varying vec4 shadowSpaceCoords@shadow_texture_unit_index;
|
||||
|
@ -11,10 +13,15 @@
|
|||
@endforeach
|
||||
#endif // SHADOWS
|
||||
|
||||
float unshadowedLightRatio()
|
||||
float unshadowedLightRatio(float distance)
|
||||
{
|
||||
float shadowing = 1.0;
|
||||
#if SHADOWS
|
||||
#if @limitShadowMapDistance
|
||||
float fade = clamp((distance - shadowFadeStart) / (maximumShadowMapDistance - shadowFadeStart), 0.0, 1.0);
|
||||
if (fade == 1.0)
|
||||
return shadowing;
|
||||
#endif
|
||||
#if @shadowMapsOverlap
|
||||
bool doneShadows = false;
|
||||
@foreach shadow_texture_unit_index @shadow_texture_unit_list
|
||||
|
@ -41,6 +48,9 @@ float unshadowedLightRatio()
|
|||
shadowing = min(shadow2DProj(shadowTexture@shadow_texture_unit_index, shadowSpaceCoords@shadow_texture_unit_index).r, shadowing);
|
||||
@endforeach
|
||||
#endif
|
||||
#if @limitShadowMapDistance
|
||||
shadowing = mix(shadowing, 1.0, fade);
|
||||
#endif
|
||||
#endif // SHADOWS
|
||||
return shadowing;
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ void main()
|
|||
gl_FragData[0].a *= texture2D(blendMap, blendMapUV).a;
|
||||
#endif
|
||||
|
||||
float shadowing = unshadowedLightRatio();
|
||||
float shadowing = unshadowedLightRatio(depth);
|
||||
|
||||
#if !PER_PIXEL_LIGHTING
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ void main(void)
|
|||
vec2 UV = worldPos.xy / (8192.0*5.0) * 3.0;
|
||||
UV.y *= -1.0;
|
||||
|
||||
float shadow = unshadowedLightRatio();
|
||||
float shadow = unshadowedLightRatio(depthPassthrough);
|
||||
|
||||
vec2 screenCoords = screenCoordsPassthrough.xy / screenCoordsPassthrough.z;
|
||||
screenCoords.y = (1.0-screenCoords.y);
|
||||
|
|
|
@ -169,6 +169,63 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="animSourcesCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Load per-group KF-files and skeleton files from Animations folder</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use additional animation sources</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="sheathingGroup" native="true">
|
||||
<layout class="QVBoxLayout" name="sheathingLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="weaponSheathingCheckBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Render holstered weapons (with quivers and scabbards), requires modded assets.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Weapon sheathing</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="shieldSheathingCheckBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Render holstered shield, requires modded assets.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Shield sheathing</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -178,16 +235,6 @@
|
|||
<string>Input</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="inputGroupVerticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="allowThirdPersonZoomCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Allow zooming in and out using the middle mouse wheel in third person view. This feature may not work correctly if the mouse wheel is bound to other actions, and may be triggered accidentally in some cases, so is disabled by default.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Allow third person zoom</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="grabCursorCheckBox">
|
||||
<property name="toolTip">
|
||||
|
|
|
@ -6,191 +6,353 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>437</width>
|
||||
<height>343</height>
|
||||
<width>650</width>
|
||||
<height>340</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="displayGroup">
|
||||
<property name="title">
|
||||
<string>Display</string>
|
||||
<widget class="QTabWidget" name="DisplayTabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4" columnstretch="1,1">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="vSyncCheckBox">
|
||||
<property name="text">
|
||||
<string>Vertical Sync</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="fullScreenCheckBox">
|
||||
<property name="text">
|
||||
<string>Full Screen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="windowBorderCheckBox">
|
||||
<property name="text">
|
||||
<string>Window Border</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="antiAliasingLabel">
|
||||
<property name="text">
|
||||
<string>Anti-aliasing:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="screenLabel">
|
||||
<property name="text">
|
||||
<string>Screen:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="resolutionLabel">
|
||||
<property name="text">
|
||||
<string>Resolution:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QCheckBox" name="framerateLimitCheckBox">
|
||||
<property name="text">
|
||||
<string>Framerate Limit:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="antiAliasingComboBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>8</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>16</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="screenComboBox"/>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<layout class="QGridLayout" name="resolutionLayout">
|
||||
<item row="1" column="2">
|
||||
<layout class="QHBoxLayout" name="customResolutionLayout" stretch="1,0,1">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="customWidthSpinBox">
|
||||
<property name="minimum">
|
||||
<number>800</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="multiplyLabel">
|
||||
<widget class="QWidget" name="DisplayWrapper">
|
||||
<attribute name="title">
|
||||
<string>Display</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QWidget" name="DisplayWidget">
|
||||
<layout class="QGridLayout" name="gridLayout_4" columnstretch="1,0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="antiAliasingLabel">
|
||||
<property name="text">
|
||||
<string> x </string>
|
||||
<string>Anti-aliasing:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="customHeightSpinBox">
|
||||
<item row="6" column="0">
|
||||
<widget class="QCheckBox" name="framerateLimitCheckBox">
|
||||
<property name="text">
|
||||
<string>Framerate Limit:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<layout class="QGridLayout" name="resolutionLayout">
|
||||
<item row="1" column="2">
|
||||
<layout class="QHBoxLayout" name="customResolutionLayout" stretch="1,0,1">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="customWidthSpinBox">
|
||||
<property name="minimum">
|
||||
<number>800</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="multiplyLabel">
|
||||
<property name="text">
|
||||
<string> x </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="customHeightSpinBox">
|
||||
<property name="minimum">
|
||||
<number>600</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QRadioButton" name="customRadioButton">
|
||||
<property name="text">
|
||||
<string>Custom:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="standardRadioButton">
|
||||
<property name="text">
|
||||
<string>Standard:</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QComboBox" name="resolutionComboBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QDoubleSpinBox" name="framerateLimitSpinBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> FPS</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>600</number>
|
||||
<double>1</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>15</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>300</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="windowBorderCheckBox">
|
||||
<property name="text">
|
||||
<string>Window Border</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="fullScreenCheckBox">
|
||||
<property name="text">
|
||||
<string>Full Screen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="resolutionLabel">
|
||||
<property name="text">
|
||||
<string>Resolution:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="screenComboBox"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="screenLabel">
|
||||
<property name="text">
|
||||
<string>Screen:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="antiAliasingComboBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>8</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>16</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="vSyncCheckBox">
|
||||
<property name="text">
|
||||
<string>Vertical Sync</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QRadioButton" name="customRadioButton">
|
||||
<property name="text">
|
||||
<string>Custom:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="standardRadioButton">
|
||||
<property name="text">
|
||||
<string>Standard:</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QComboBox" name="resolutionComboBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QDoubleSpinBox" name="framerateLimitSpinBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> FPS</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>1</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>15</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>300</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="ShadowWrapper">
|
||||
<attribute name="title">
|
||||
<string>Shadows</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="ShadowWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="shadowsLayout" columnstretch="0,0">
|
||||
<item row="6" column="0">
|
||||
<widget class="QCheckBox" name="shadowDistanceCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The distance from the camera at which shadows completely disappear.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Shadow Distance Limit:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QSpinBox" name="shadowDistanceSpinBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>64 game units is 1 real life yard or about 0.9 m</p></body></html></string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> unit(s)</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>512</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>81920</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>8192</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="fadeStartLabel">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The fraction of the limit above at which shadows begin to gradually fade away.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Fade Start Multiplier:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="shadowResolutionComboBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>512</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1024</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2048</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4096</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="actorShadowsCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enable shadows for NPCs and creatures besides the player character. May have a minor performance impact.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Actor Shadows</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" alignment="Qt::AlignLeft">
|
||||
<widget class="QCheckBox" name="terrainShadowsCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enable shadows for the terrain including distant terrain. May have a significant performance and shadow quality impact.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Terrain Shadows</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QDoubleSpinBox" name="fadeStartSpinBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.90</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="playerShadowsCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enable shadows exclusively for the player character. May have a very minor performance impact.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Player Shadows</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" alignment="Qt::AlignLeft">
|
||||
<widget class="QLabel" name="shadowResolutionLabel">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The resolution of each individual shadow map. Increasing it significantly improves shadow quality but may have a minor performance impact.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Shadow Map Resolution:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="objectShadowsCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enable shadows for primarily inanimate objects. May have a significant performance impact.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Object Shadows</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="indoorShadowsCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Due to limitations with Morrowind's data, only actors can cast shadows indoors, which some might feel is distracting.</p><p>Has no effect if actor/player shadows are not enabled.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Indoor Shadows</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>61</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
|
Loading…
Reference in a new issue