mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-07-04 13:21:35 +00:00
Add OpenMW commits up to 17 Jun 2021
This commit is contained in:
commit
62f0237376
11 changed files with 108 additions and 52 deletions
|
@ -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();
|
||||
|
||||
magnitude > 0 ? addBoundItem(item, ptr) : removeBoundItem(item, ptr);
|
||||
|
||||
if (it->first == ESM::MagicEffect::BoundGloves)
|
||||
bool found = creatureStats.mBoundItems.find(effect) != creatureStats.mBoundItems.end();
|
||||
float magnitude = effects.get(effect).getMagnitude();
|
||||
if (found != (magnitude > 0))
|
||||
{
|
||||
item = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
||||
"sMagicBoundRightGauntletID")->mValue.getString();
|
||||
if (magnitude > 0)
|
||||
creatureStats.mBoundItems.insert(effect);
|
||||
else
|
||||
creatureStats.mBoundItems.erase(effect);
|
||||
|
||||
std::string item = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
||||
itemGmst)->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…
Reference in a new issue