Add OpenMW commits up to 17 Jun 2021

pull/593/head
David Cernat 4 years ago
commit 62f0237376

@ -15,7 +15,7 @@ ccache --version
cmake --version
qmake --version
curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-8f5ef6e.zip -o ~/openmw-deps.zip
curl -fSL -R -J https://gitlab.com/OpenMW/openmw-deps/-/raw/main/macos/openmw-deps-20210617.zip -o ~/openmw-deps.zip
unzip -o ~/openmw-deps.zip -d /private/tmp/openmw-deps > /dev/null
# additional libraries

@ -381,7 +381,11 @@ if(NOT HAVE_STDINT_H)
endif()
if(OPENMW_USE_SYSTEM_OSG)
find_package(OpenSceneGraph 3.3.4 REQUIRED ${USED_OSG_COMPONENTS})
find_package(OpenSceneGraph 3.4.0 REQUIRED ${USED_OSG_COMPONENTS})
if (${OPENSCENEGRAPH_VERSION} VERSION_GREATER 3.6.2 AND ${OPENSCENEGRAPH_VERSION} VERSION_LESS 3.6.5)
message(FATAL_ERROR "OpenSceneGraph version ${OPENSCENEGRAPH_VERSION} has critical regressions which cause crashes. Please upgrade to 3.6.5 or later. We strongly recommend using the tip of the official 'OpenSceneGraph-3.6' branch or the tip of '3.6' OpenMW/osg (OSGoS).")
endif()
if(OSG_STATIC)
find_package(OSGPlugins REQUIRED COMPONENTS ${USED_OSG_PLUGINS})
endif()

@ -27,7 +27,9 @@
#include "../mwworld/class.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwmechanics/aipackage.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/summoning.hpp"
#include "../mwscript/interpretercontext.hpp"
@ -417,6 +419,23 @@ namespace MWGui
for (const auto& creature : creatureMap)
MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(ptr, creature.second);
creatureMap.clear();
// Check if we are a summon and inform our master we've bit the dust
for(const auto& package : creatureStats.getAiSequence())
{
if(package->followTargetThroughDoors() && !package->getTarget().isEmpty())
{
const auto& summoner = package->getTarget();
auto& summons = summoner.getClass().getCreatureStats(summoner).getSummonedCreatureMap();
auto it = std::find_if(summons.begin(), summons.end(), [&] (const auto& entry) { return entry.second == creatureStats.getActorId(); });
if(it != summons.end())
{
MWMechanics::purgeSummonEffect(summoner, *it);
summons.erase(it);
break;
}
}
}
}
MWBase::Environment::get().getWorld()->deleteObject(ptr);

@ -1303,7 +1303,7 @@ namespace MWMechanics
// Update bound effects
// Note: in vanilla MW multiple bound items of the same type can be created by different spells.
// As these extra copies are kinda useless this may or may not be important.
static std::map<int, std::string> boundItemsMap;
static std::map<ESM::MagicEffect::Effects, std::string> boundItemsMap;
if (boundItemsMap.empty())
{
boundItemsMap[ESM::MagicEffect::BoundBattleAxe] = "sMagicBoundBattleAxeID";
@ -1319,28 +1319,30 @@ namespace MWMechanics
boundItemsMap[ESM::MagicEffect::BoundSpear] = "sMagicBoundSpearID";
}
for (std::map<int, std::string>::iterator it = boundItemsMap.begin(); it != boundItemsMap.end(); ++it)
if(ptr.getClass().hasInventoryStore(ptr))
{
bool found = creatureStats.mBoundItems.find(it->first) != creatureStats.mBoundItems.end();
float magnitude = effects.get(it->first).getMagnitude();
if (found != (magnitude > 0))
for (const auto& [effect, itemGmst] : boundItemsMap)
{
if (magnitude > 0)
creatureStats.mBoundItems.insert(it->first);
else
creatureStats.mBoundItems.erase(it->first);
std::string itemGmst = it->second;
std::string item = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
itemGmst)->mValue.getString();
bool found = creatureStats.mBoundItems.find(effect) != creatureStats.mBoundItems.end();
float magnitude = effects.get(effect).getMagnitude();
if (found != (magnitude > 0))
{
if (magnitude > 0)
creatureStats.mBoundItems.insert(effect);
else
creatureStats.mBoundItems.erase(effect);
magnitude > 0 ? addBoundItem(item, ptr) : removeBoundItem(item, ptr);
std::string item = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
itemGmst)->mValue.getString();
if (it->first == ESM::MagicEffect::BoundGloves)
{
item = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
"sMagicBoundRightGauntletID")->mValue.getString();
magnitude > 0 ? addBoundItem(item, ptr) : removeBoundItem(item, ptr);
if (effect == ESM::MagicEffect::BoundGloves)
{
item = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
"sMagicBoundRightGauntletID")->mValue.getString();
magnitude > 0 ? addBoundItem(item, ptr) : removeBoundItem(item, ptr);
}
}
}
}

@ -625,6 +625,28 @@ namespace MWMechanics
mAiSequence.readState(state.mAiSequence);
mMagicEffects.readState(state.mMagicEffects);
// Rebuild the bound item cache
for(int effectId = ESM::MagicEffect::BoundDagger; effectId <= ESM::MagicEffect::BoundGloves; effectId++)
{
if(mMagicEffects.get(effectId).getMagnitude() > 0)
mBoundItems.insert(effectId);
else
{
// Check active spell effects
// We can't use mActiveSpells::getMagicEffects here because it doesn't include expired effects
auto spell = std::find_if(mActiveSpells.begin(), mActiveSpells.end(), [&] (const auto& spell)
{
const auto& effects = spell.second.mEffects;
return std::find_if(effects.begin(), effects.end(), [&] (const auto& effect)
{
return effect.mEffectId == effectId;
}) != effects.end();
});
if(spell != mActiveSpells.end())
mBoundItems.insert(effectId);
}
}
mSummonedCreatures = state.mSummonedCreatureMap;
mSummonGraveyard = state.mSummonGraveyard;

@ -77,10 +77,8 @@ namespace MWMechanics
void CastSpell::inflict(const MWWorld::Ptr &target, const MWWorld::Ptr &caster,
const ESM::EffectList &effects, ESM::RangeType range, bool reflected, bool exploded)
{
if (target.isEmpty())
return;
if (target.getClass().isActor())
const bool targetIsActor = !target.isEmpty() && target.getClass().isActor();
if (targetIsActor)
{
// Early-out for characters that have departed.
const auto& stats = target.getClass().getCreatureStats(target);
@ -102,7 +100,7 @@ namespace MWMechanics
return;
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search (mId);
if (spell && target.getClass().isActor() && (spell->mData.mType == ESM::Spell::ST_Disease || spell->mData.mType == ESM::Spell::ST_Blight))
if (spell && targetIsActor && (spell->mData.mType == ESM::Spell::ST_Disease || spell->mData.mType == ESM::Spell::ST_Blight))
{
int requiredResistance = (spell->mData.mType == ESM::Spell::ST_Disease) ?
ESM::MagicEffect::ResistCommonDisease
@ -125,13 +123,13 @@ namespace MWMechanics
// This is required for Weakness effects in a spell to apply to any subsequent effects in the spell.
// Otherwise, they'd only apply after the whole spell was added.
MagicEffects targetEffects;
if (target.getClass().isActor())
if (targetIsActor)
targetEffects += target.getClass().getCreatureStats(target).getMagicEffects();
bool castByPlayer = (!caster.isEmpty() && caster == getPlayer());
ActiveSpells targetSpells;
if (target.getClass().isActor())
if (targetIsActor)
targetSpells = target.getClass().getCreatureStats(target).getActiveSpells();
bool canCastAnEffect = false; // For bound equipment.If this remains false
@ -143,7 +141,7 @@ namespace MWMechanics
int currentEffectIndex = 0;
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt (effects.mList.begin());
effectIt != effects.mList.end(); ++effectIt, ++currentEffectIndex)
!target.isEmpty() && effectIt != effects.mList.end(); ++effectIt, ++currentEffectIndex)
{
if (effectIt->mRange != range)
continue;
@ -329,7 +327,7 @@ namespace MWMechanics
}
// Re-casting a summon effect will remove the creature from previous castings of that effect.
if (isSummoningEffect(effectIt->mEffectID) && target.getClass().isActor())
if (isSummoningEffect(effectIt->mEffectID) && targetIsActor)
{
CreatureStats& targetStats = target.getClass().getCreatureStats(target);
ESM::SummonKey key(effectIt->mEffectID, mId, currentEffectIndex);
@ -385,16 +383,19 @@ namespace MWMechanics
if (!exploded)
MWBase::Environment::get().getWorld()->explodeSpell(mHitPosition, effects, caster, target, range, mId, mSourceName, mFromProjectile);
if (!reflectedEffects.mList.empty())
inflict(caster, target, reflectedEffects, range, true, exploded);
if (!appliedLastingEffects.empty())
if (!target.isEmpty())
{
int casterActorId = -1;
if (!caster.isEmpty() && caster.getClass().isActor())
casterActorId = caster.getClass().getCreatureStats(caster).getActorId();
target.getClass().getCreatureStats(target).getActiveSpells().addSpell(mId, mStack, appliedLastingEffects,
mSourceName, casterActorId);
if (!reflectedEffects.mList.empty())
inflict(caster, target, reflectedEffects, range, true, exploded);
if (!appliedLastingEffects.empty())
{
int casterActorId = -1;
if (!caster.isEmpty() && caster.getClass().isActor())
casterActorId = caster.getClass().getCreatureStats(caster).getActorId();
target.getClass().getCreatureStats(target).getActiveSpells().addSpell(mId, mStack, appliedLastingEffects,
mSourceName, casterActorId);
}
}
}

@ -201,16 +201,10 @@ namespace MWMechanics
continue;
}
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->searchPtrViaActorId(it->second);
if (ptr.isEmpty() || (ptr.getClass().getCreatureStats(ptr).isDead() && ptr.getClass().getCreatureStats(ptr).isDeathAnimationFinished()))
if (!ptr.isEmpty() && ptr.getClass().getCreatureStats(ptr).isDead() && ptr.getClass().getCreatureStats(ptr).isDeathAnimationFinished())
{
// Purge the magic effect so a new creature can be summoned if desired
const ESM::SummonKey& key = it->first;
creatureStats.getActiveSpells().purgeEffect(key.mEffectId, key.mSourceId, key.mEffectIndex);
creatureStats.getSpells().purgeEffect(key.mEffectId, key.mSourceId);
if (mActor.getClass().hasInventoryStore(mActor))
mActor.getClass().getInventoryStore(mActor).purgeEffect(key.mEffectId, key.mSourceId, false, key.mEffectIndex);
MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(mActor, it->second);
purgeSummonEffect(mActor, *it);
creatureMap.erase(it++);
}
else
@ -218,4 +212,14 @@ namespace MWMechanics
}
}
void purgeSummonEffect(const MWWorld::Ptr& summoner, const std::pair<const ESM::SummonKey, int>& summon)
{
auto& creatureStats = summoner.getClass().getCreatureStats(summoner);
creatureStats.getActiveSpells().purgeEffect(summon.first.mEffectId, summon.first.mSourceId, summon.first.mEffectIndex);
creatureStats.getSpells().purgeEffect(summon.first.mEffectId, summon.first.mSourceId);
if (summoner.getClass().hasInventoryStore(summoner))
summoner.getClass().getInventoryStore(summoner).purgeEffect(summon.first.mEffectId, summon.first.mSourceId, false, summon.first.mEffectIndex);
MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(summoner, summon.second);
}
}

@ -17,6 +17,8 @@ namespace MWMechanics
std::string getSummonedCreature(int effectId);
void purgeSummonEffect(const MWWorld::Ptr& summoner, const std::pair<const ESM::SummonKey, int>& summon);
struct UpdateSummonedCreatures : public EffectSourceVisitor
{
UpdateSummonedCreatures(const MWWorld::Ptr& actor);

@ -477,6 +477,8 @@ namespace MWRender
constexpr auto copyMask = ~Mask_UpdateVisitor;
AnalyzeVisitor analyzeVisitor(copyMask);
osg::Vec3f center3 = { center.x(), center.y(), 0.f };
analyzeVisitor.mCurrentDistance = (viewPoint - center3).length2();
float minSize = mMinSize;
if (mMinSizeMergeFactor)
minSize *= mMinSizeMergeFactor;
@ -546,7 +548,6 @@ namespace MWRender
continue;
}
analyzeVisitor.mCurrentDistance = dSqr;
auto emplaced = nodes.emplace(cnode, InstanceList());
if (emplaced.second)
{

@ -158,7 +158,7 @@ namespace SceneUtil
static constexpr int queryBlockSize(int sz)
{
return 3 * osg::Vec4::num_components * sizeof(GL_FLOAT) * sz;
return 3 * osg::Vec4::num_components * sizeof(GLfloat) * sz;
}
void setCachedSunPos(const osg::Vec4& pos)
@ -215,9 +215,9 @@ namespace SceneUtil
}
Offsets(int offsetColors, int offsetPosition, int offsetAttenuationRadius, int stride)
: mStride((offsetAttenuationRadius + sizeof(GL_FLOAT) * osg::Vec4::num_components + stride) / 4)
: mStride((offsetAttenuationRadius + sizeof(GLfloat) * osg::Vec4::num_components + stride) / 4)
{
constexpr auto sizeofFloat = sizeof(GL_FLOAT);
constexpr auto sizeofFloat = sizeof(GLfloat);
const auto diffuseOffset = offsetColors / sizeofFloat;
mValues[Diffuse] = diffuseOffset;

@ -566,8 +566,9 @@ MWShadowTechnique::ShadowData::ShadowData(MWShadowTechnique::ViewDependentData*
_camera = new osg::Camera;
_camera->setName("ShadowCamera");
_camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT);
#ifndef __APPLE__ // workaround shadow issue on macOS, https://gitlab.com/OpenMW/openmw/-/issues/6057
_camera->setImplicitBufferAttachmentMask(0, 0);
#endif
//_camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
_camera->setClearColor(osg::Vec4(0.0f,0.0f,0.0f,0.0f));

Loading…
Cancel
Save