diff --git a/AUTHORS.md b/AUTHORS.md index b30168fd8f..d2de857477 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -4,7 +4,7 @@ Contributors The OpenMW project was started in 2008 by Nicolay Korslund. In the course of years many people have contributed to the project. -If you feel your name is missing from this list, please notify a developer. +If you feel your name is missing from this list, please add it to `AUTHORS.md`. Programmers @@ -24,7 +24,7 @@ Programmers Alex McKibben alexanderkjall Alexander Nadeau (wareya) - Alexander Olofsson (Ace) + Alexander Olofsson (Ananace) Alex Rice Alex S (docwest) Allofich @@ -235,7 +235,8 @@ Documentation Packagers --------- - Alexander Olofsson (Ace) - Windows + Alexander Olofsson (Ananace) - Windows and Flatpak + Alexey Sokolov (DarthGandalf) - Gentoo Linux Bret Curtis (psi29a) - Debian and Ubuntu Linux Edmondo Tommasina (edmondo) - Gentoo Linux Julian Ospald (hasufell) - Gentoo Linux diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 99f8632f3a..8c58fd943f 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -211,38 +211,48 @@ void CharacterController::refreshHitRecoilAnims(CharacterState& idle) if(mHitState == CharState_None) { if ((mPtr.getClass().getCreatureStats(mPtr).getFatigue().getCurrent() < 0 - || mPtr.getClass().getCreatureStats(mPtr).getFatigue().getBase() == 0) - && mAnimation->hasAnimation("knockout")) + || mPtr.getClass().getCreatureStats(mPtr).getFatigue().getBase() == 0)) { mTimeUntilWake = Misc::Rng::rollClosedProbability() * 2 + 1; // Wake up after 1 to 3 seconds if (isSwimming && mAnimation->hasAnimation("swimknockout")) { mHitState = CharState_SwimKnockOut; mCurrentHit = "swimknockout"; + mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, false, 1, "start", "stop", 0.0f, ~0ul); } - else + else if (!isSwimming && mAnimation->hasAnimation("knockout")) { mHitState = CharState_KnockOut; mCurrentHit = "knockout"; + mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, false, 1, "start", "stop", 0.0f, ~0ul); + } + else + { + // Knockout animations are missing. Fall back to idle animation, so target actor still can be killed via HtH. + mCurrentHit.erase(); } - mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, false, 1, "start", "stop", 0.0f, ~0ul); mPtr.getClass().getCreatureStats(mPtr).setKnockedDown(true); } - else if(knockdown && mAnimation->hasAnimation("knockdown")) + else if (knockdown) { if (isSwimming && mAnimation->hasAnimation("swimknockdown")) { mHitState = CharState_SwimKnockDown; mCurrentHit = "swimknockdown"; + mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, true, 1, "start", "stop", 0.0f, 0); } - else + else if (!isSwimming && mAnimation->hasAnimation("knockdown")) { mHitState = CharState_KnockDown; mCurrentHit = "knockdown"; + mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, true, 1, "start", "stop", 0.0f, 0); + } + else + { + // Knockdown animation is missing. Cancel knockdown state. + mPtr.getClass().getCreatureStats(mPtr).setKnockedDown(false); } - - mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, true, 1, "start", "stop", 0.0f, 0); } else if (recovery) { diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 905034cde5..a2454345bf 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -179,9 +179,9 @@ bool Actor::setPosition(const osg::Vec3f& position) if (mSkipSimulation) return false; bool hasChanged = mPosition != position || mPositionOffset.length() != 0 || mWorldPositionChanged; - mPreviousPosition = mPosition + mPositionOffset; - mPosition = position + mPositionOffset; - mPositionOffset = osg::Vec3f(); + applyOffsetChange(); + mPreviousPosition = mPosition; + mPosition = position; return hasChanged; } @@ -198,6 +198,7 @@ void Actor::applyOffsetChange() mWorldPosition += mPositionOffset; mPosition += mPositionOffset; mPreviousPosition += mPositionOffset; + mSimulationPosition += mPositionOffset; mPositionOffset = osg::Vec3f(); mWorldPositionChanged = true; } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index d6a4de71bd..5e0cdbb2b6 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -862,6 +862,19 @@ namespace MWWorld if (reference == getPlayerPtr()) throw std::runtime_error("can not disable player object"); + // A common pattern to teleport NPC in scripts is a sequence of SetPos/Disable/Enable + // Disable/Enable create a new physics actor, and so the SetPos call is lost + // Call moveObject so that the newly created physics actor will have up-to-date position + if (reference.getClass().isActor()) + { + auto* physactor = mPhysics->getActor(reference); + if (physactor) + { + physactor->applyOffsetChange(); + const auto position = physactor->getSimulationPosition(); + moveObject(reference, position.x(), position.y(), position.z(), true); + } + } reference.getRefData().disable(); if (reference.getCellRef().getRefNum().hasContentFile()) diff --git a/components/sceneutil/util.cpp b/components/sceneutil/util.cpp index fa3c7d26da..cc8a2f44b4 100644 --- a/components/sceneutil/util.cpp +++ b/components/sceneutil/util.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -263,6 +264,10 @@ osg::ref_ptr addEnchantedGlow(osg::ref_ptr node, Resourc bool attachAlphaToCoverageFriendlyFramebufferToCamera(osg::Camera* camera, osg::Camera::BufferComponent buffer, osg::Texture * texture, unsigned int level, unsigned int face, bool mipMapGeneration) { +#if OSG_VERSION_LESS_THAN(3, 6, 6) + // hack fix for https://github.com/openscenegraph/OpenSceneGraph/issues/1028 + osg::GLExtensions::Get(0, false)->glRenderbufferStorageMultisampleCoverageNV = nullptr; +#endif unsigned int samples = 0; unsigned int colourSamples = 0; bool addMSAAIntermediateTarget = Settings::Manager::getBool("antialias alpha test", "Shaders") && Settings::Manager::getInt("antialiasing", "Video") > 1; diff --git a/files/openmw.appdata.xml b/files/openmw.appdata.xml index f4bdb5c919..a9906aae66 100644 --- a/files/openmw.appdata.xml +++ b/files/openmw.appdata.xml @@ -5,8 +5,8 @@ Copyright 2020 Bret Curtis --> org.openmw.launcher.desktop - GPL-3+ - GPL-3+ + GPL-3.0-or-later + GPL-3.0-or-later OpenMW Unofficial open source engine re-implementation of the game Morrowind diff --git a/files/shaders/water_fragment.glsl b/files/shaders/water_fragment.glsl index 06a3213011..651aff6a1a 100644 --- a/files/shaders/water_fragment.glsl +++ b/files/shaders/water_fragment.glsl @@ -37,21 +37,20 @@ const float BUMP_RAIN = 2.5; const float REFL_BUMP = 0.10; // reflection distortion amount const float REFR_BUMP = 0.07; // refraction distortion amount +const float SCATTER_AMOUNT = 0.3; // amount of sunlight scattering +const vec3 SCATTER_COLOUR = vec3(0.0,1.0,0.95); // colour of sunlight scattering + const vec3 SUN_EXT = vec3(0.45, 0.55, 0.68); //sunlight extinction const float SPEC_HARDNESS = 256.0; // specular highlights hardness const float BUMP_SUPPRESS_DEPTH = 300.0; // at what water depth bumpmap will be suppressed for reflections and refractions (prevents artifacts at shores) -const float BUMP_SUPPRESS_DEPTH_SS = 1000.0; // modifier using screenspace depth (helps prevent same artifacts but at higher distances) const vec2 WIND_DIR = vec2(0.5f, -0.8f); const float WIND_SPEED = 0.2f; const vec3 WATER_COLOR = vec3(0.090195, 0.115685, 0.12745); -const float SCATTER_AMOUNT = 0.5; // amount of sunlight scattering -const vec3 SCATTER_COLOUR = WATER_COLOR * 8.0; // colour of sunlight scattering - // ---------------- rain ripples related stuff --------------------- const float RAIN_RIPPLE_GAPS = 5.0; @@ -230,10 +229,7 @@ void main(void) float depthSampleDistorted = linearizeDepth(texture2D(refractionDepthMap,screenCoords-screenCoordsOffset).x) * radialise; float surfaceDepth = linearizeDepth(gl_FragCoord.z) * radialise; float realWaterDepth = depthSample - surfaceDepth; // undistorted water depth in view direction, independent of frustum - screenCoordsOffset *= clamp( - realWaterDepth / (BUMP_SUPPRESS_DEPTH - * max(1, depthSample / BUMP_SUPPRESS_DEPTH_SS)) // suppress more at distance - ,0 ,1); + screenCoordsOffset *= clamp(realWaterDepth / BUMP_SUPPRESS_DEPTH,0,1); #endif // reflection vec3 reflection = texture2D(reflectionMap, screenCoords + screenCoordsOffset).rgb; @@ -257,11 +253,7 @@ void main(void) if (cameraPos.z < 0.0) refraction = clamp(refraction * 1.5, 0.0, 1.0); else - { - vec3 refractionA = mix(refraction, waterColor, clamp(depthSampleDistorted/VISIBILITY, 0.0, 1.0)); - vec3 refractionB = mix(refraction, waterColor, clamp(realWaterDepth/VISIBILITY, 0.0, 1.0)); - refraction = mix(refractionA, refractionB, 0.8); - } + refraction = mix(refraction, waterColor, clamp(depthSampleDistorted/VISIBILITY, 0.0, 1.0)); // sunlight scattering // normal for sunlight scattering