forked from teamnwah/openmw-tes3coop
ESS-Importer: Convert magic projectiles (Closes #2320)
This commit is contained in:
parent
5ebb43a422
commit
f15de6d3ca
16 changed files with 238 additions and 63 deletions
|
@ -17,6 +17,7 @@ set(ESSIMPORTER_FILES
|
|||
importscri.cpp
|
||||
importscpt.cpp
|
||||
importproj.cpp
|
||||
importsplm.cpp
|
||||
importercontext.cpp
|
||||
converter.cpp
|
||||
convertacdt.cpp
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#include "converter.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#include <osgDB/WriteFile>
|
||||
|
||||
#include <components/esm/creaturestate.hpp>
|
||||
#include <components/esm/containerstate.hpp>
|
||||
#include <components/esm/projectilestate.hpp>
|
||||
|
||||
#include "convertcrec.hpp"
|
||||
#include "convertcntc.hpp"
|
||||
|
@ -461,11 +461,7 @@ namespace ESSImport
|
|||
if (!pnam.isMagic())
|
||||
{
|
||||
ESM::ProjectileState out;
|
||||
out.mId = pnam.mArrowId.toString();
|
||||
out.mPosition = pnam.mPosition;
|
||||
out.mOrientation.mValues[0] = out.mOrientation.mValues[1] = out.mOrientation.mValues[2] = 0.0f;
|
||||
out.mOrientation.mValues[3] = 1.0f;
|
||||
out.mActorId = convertActorId(pnam.mActorId.toString(), *mContext);
|
||||
convertBaseState(out, pnam);
|
||||
|
||||
out.mBowId = pnam.mBowId.toString();
|
||||
out.mVelocity = pnam.mVelocity;
|
||||
|
@ -477,16 +473,49 @@ namespace ESSImport
|
|||
}
|
||||
else
|
||||
{
|
||||
// TODO: Implement magic projectile conversion.
|
||||
ESM::MagicBoltState out;
|
||||
convertBaseState(out, pnam);
|
||||
|
||||
/*esm.startRecord(ESM::REC_MPRJ);
|
||||
auto it = std::find_if(mContext->mActiveSpells.begin(), mContext->mActiveSpells.end(),
|
||||
[&pnam](const SPLM::ActiveSpell& spell) -> bool { return spell.mIndex == pnam.mSplmIndex; });
|
||||
|
||||
if (it == mContext->mActiveSpells.end())
|
||||
{
|
||||
std::cerr << "Warning: Skipped conversion for magic projectile \"" << pnam.mArrowId.toString() << "\" (invalid spell link)" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
out.mSpellId = it->mSPDT.mId.toString();
|
||||
out.mSpeed = pnam.mSpeed * 0.001f; // not sure where this factor comes from
|
||||
|
||||
esm.startRecord(ESM::REC_MPRJ);
|
||||
out.save(esm);
|
||||
esm.endRecord(ESM::REC_MPRJ);*/
|
||||
|
||||
std::cerr << "Warning: Skipped conversion for magic projectile \"" << pnam.mArrowId.toString() << "\" (not implemented)" << std::endl;
|
||||
continue;
|
||||
esm.endRecord(ESM::REC_MPRJ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertPROJ::convertBaseState(ESM::BaseProjectileState& base, const PROJ::PNAM& pnam)
|
||||
{
|
||||
base.mId = pnam.mArrowId.toString();
|
||||
base.mPosition = pnam.mPosition;
|
||||
|
||||
osg::Quat orient;
|
||||
orient.makeRotate(osg::Vec3f(0,1,0), pnam.mVelocity);
|
||||
base.mOrientation = orient;
|
||||
|
||||
base.mActorId = convertActorId(pnam.mActorId.toString(), *mContext);
|
||||
}
|
||||
|
||||
void ConvertSPLM::read(ESM::ESMReader& esm)
|
||||
{
|
||||
mSPLM.load(esm);
|
||||
mContext->mActiveSpells = mSPLM.mActiveSpells;
|
||||
}
|
||||
|
||||
void ConvertSPLM::write(ESM::ESMWriter& esm)
|
||||
{
|
||||
std::cerr << "Warning: Skipped active spell conversion (not implemented)" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <components/esm/globalscript.hpp>
|
||||
#include <components/esm/queststate.hpp>
|
||||
#include <components/esm/stolenitems.hpp>
|
||||
#include <components/esm/projectilestate.hpp>
|
||||
|
||||
#include "importcrec.hpp"
|
||||
#include "importcntc.hpp"
|
||||
|
@ -36,6 +37,7 @@
|
|||
#include "importjour.hpp"
|
||||
#include "importscpt.hpp"
|
||||
#include "importproj.h"
|
||||
#include "importsplm.h"
|
||||
|
||||
#include "convertacdt.hpp"
|
||||
#include "convertnpcc.hpp"
|
||||
|
@ -602,9 +604,19 @@ public:
|
|||
virtual void read(ESM::ESMReader& esm) override;
|
||||
virtual void write(ESM::ESMWriter& esm) override;
|
||||
private:
|
||||
void convertBaseState(ESM::BaseProjectileState& base, const PROJ::PNAM& pnam);
|
||||
PROJ mProj;
|
||||
};
|
||||
|
||||
class ConvertSPLM : public Converter
|
||||
{
|
||||
public:
|
||||
virtual void read(ESM::ESMReader& esm) override;
|
||||
virtual void write(ESM::ESMWriter& esm) override;
|
||||
private:
|
||||
SPLM mSPLM;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -271,6 +271,7 @@ namespace ESSImport
|
|||
const unsigned int recSTLN = ESM::FourCC<'S','T','L','N'>::value;
|
||||
const unsigned int recGAME = ESM::FourCC<'G','A','M','E'>::value;
|
||||
const unsigned int recJOUR = ESM::FourCC<'J','O','U','R'>::value;
|
||||
const unsigned int recSPLM = ESM::FourCC<'S','P','L','M'>::value;
|
||||
|
||||
std::map<unsigned int, std::shared_ptr<Converter> > converters;
|
||||
converters[ESM::REC_GLOB] = std::shared_ptr<Converter>(new ConvertGlobal());
|
||||
|
@ -304,12 +305,12 @@ namespace ESSImport
|
|||
converters[recJOUR ] = std::shared_ptr<Converter>(new ConvertJOUR());
|
||||
converters[ESM::REC_SCPT] = std::shared_ptr<Converter>(new ConvertSCPT());
|
||||
converters[ESM::REC_PROJ] = std::shared_ptr<Converter>(new ConvertPROJ());
|
||||
converters[recSPLM] = std::shared_ptr<Converter>(new ConvertSPLM());
|
||||
|
||||
// TODO:
|
||||
// - REGN (weather in certain regions?)
|
||||
// - VFXM
|
||||
// - SPLM (active spell effects)
|
||||
// - PROJ (magic projectiles in air)
|
||||
|
||||
std::set<unsigned int> unknownRecords;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "importcrec.hpp"
|
||||
#include "importcntc.hpp"
|
||||
#include "importplayer.hpp"
|
||||
|
||||
#include "importsplm.h"
|
||||
|
||||
|
||||
|
||||
|
@ -54,6 +54,8 @@ namespace ESSImport
|
|||
std::map<std::string, ESM::Creature> mCreatures;
|
||||
std::map<std::string, ESM::NPC> mNpcs;
|
||||
|
||||
std::vector<SPLM::ActiveSpell> mActiveSpells;
|
||||
|
||||
Context()
|
||||
: mDay(0)
|
||||
, mMonth(0)
|
||||
|
|
43
apps/essimporter/importsplm.cpp
Normal file
43
apps/essimporter/importsplm.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include "importsplm.h"
|
||||
|
||||
#include <components/esm/esmreader.hpp>
|
||||
|
||||
namespace ESSImport
|
||||
{
|
||||
|
||||
void SPLM::load(ESM::ESMReader& esm)
|
||||
{
|
||||
while (esm.isNextSub("NAME"))
|
||||
{
|
||||
ActiveSpell spell;
|
||||
esm.getHT(spell.mIndex);
|
||||
esm.getHNT(spell.mSPDT, "SPDT");
|
||||
spell.mTarget = esm.getHNOString("TNAM");
|
||||
|
||||
while (esm.isNextSub("NPDT"))
|
||||
{
|
||||
ActiveEffect effect;
|
||||
esm.getHT(effect.mNPDT);
|
||||
|
||||
// Effect-specific subrecords can follow:
|
||||
// - INAM for disintegration and bound effects
|
||||
// - CNAM for summoning and command effects
|
||||
// - VNAM for vampirism
|
||||
// NOTE: There can be multiple INAMs per effect.
|
||||
// TODO: Needs more research.
|
||||
|
||||
esm.skipHSubUntil("NAM0"); // sentinel
|
||||
esm.getSubName();
|
||||
esm.skipHSub();
|
||||
|
||||
spell.mActiveEffects.push_back(effect);
|
||||
}
|
||||
|
||||
unsigned char xnam; // sentinel
|
||||
esm.getHNT(xnam, "XNAM");
|
||||
|
||||
mActiveSpells.push_back(spell);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
81
apps/essimporter/importsplm.h
Normal file
81
apps/essimporter/importsplm.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
#ifndef OPENMW_ESSIMPORT_IMPORTSPLM_H
|
||||
#define OPENMW_ESSIMPORT_IMPORTSPLM_H
|
||||
|
||||
#include <vector>
|
||||
#include <components/esm/esmcommon.hpp>
|
||||
#include <components/esm/util.hpp>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
class ESMReader;
|
||||
}
|
||||
|
||||
namespace ESSImport
|
||||
{
|
||||
|
||||
struct SPLM
|
||||
{
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct SPDT // 160 bytes
|
||||
{
|
||||
int mType; // 1 = spell, 2 = enchantment, 3 = potion
|
||||
ESM::NAME32 mId; // base ID of a spell/enchantment/potion
|
||||
unsigned char mUnknown[4*4];
|
||||
ESM::NAME32 mCasterId;
|
||||
ESM::NAME32 mSourceId; // empty for spells
|
||||
unsigned char mUnknown2[4*11];
|
||||
};
|
||||
|
||||
struct NPDT // 56 bytes
|
||||
{
|
||||
ESM::NAME32 mAffectedActorId;
|
||||
unsigned char mUnknown[4*2];
|
||||
int mMagnitude;
|
||||
float mSecondsActive;
|
||||
unsigned char mUnknown2[4*2];
|
||||
};
|
||||
|
||||
struct INAM // 40 bytes
|
||||
{
|
||||
int mUnknown;
|
||||
unsigned char mUnknown2;
|
||||
ESM::FIXED_STRING<35> mItemId; // disintegrated item / bound item / item to re-equip after expiration
|
||||
};
|
||||
|
||||
struct CNAM // 36 bytes
|
||||
{
|
||||
int mUnknown; // seems to always be 0
|
||||
ESM::NAME32 mSummonedOrCommandedActor[32];
|
||||
};
|
||||
|
||||
struct VNAM // 4 bytes
|
||||
{
|
||||
int mUnknown;
|
||||
};
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
struct ActiveEffect
|
||||
{
|
||||
NPDT mNPDT;
|
||||
};
|
||||
|
||||
struct ActiveSpell
|
||||
{
|
||||
int mIndex;
|
||||
SPDT mSPDT;
|
||||
std::string mTarget;
|
||||
std::vector<ActiveEffect> mActiveEffects;
|
||||
};
|
||||
|
||||
std::vector<ActiveSpell> mActiveSpells;
|
||||
|
||||
void load(ESM::ESMReader& esm);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -487,8 +487,7 @@ namespace MWBase
|
|||
|
||||
virtual void castSpell (const MWWorld::Ptr& actor) = 0;
|
||||
|
||||
virtual void launchMagicBolt (const std::string& spellId, bool stack, const ESM::EffectList& effects,
|
||||
const MWWorld::Ptr& caster, const std::string& sourceName, const osg::Vec3f& fallbackDirection) = 0;
|
||||
virtual void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) = 0;
|
||||
virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
|
||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength) = 0;
|
||||
|
||||
|
|
|
@ -329,7 +329,7 @@ namespace MWMechanics
|
|||
{
|
||||
}
|
||||
|
||||
void CastSpell::launchMagicBolt (const ESM::EffectList& effects)
|
||||
void CastSpell::launchMagicBolt ()
|
||||
{
|
||||
osg::Vec3f fallbackDirection (0,1,0);
|
||||
|
||||
|
@ -340,8 +340,7 @@ namespace MWMechanics
|
|||
osg::Vec3f(mTarget.getRefData().getPosition().asVec3())-
|
||||
osg::Vec3f(mCaster.getRefData().getPosition().asVec3());
|
||||
|
||||
MWBase::Environment::get().getWorld()->launchMagicBolt(mId, false, effects,
|
||||
mCaster, mSourceName, fallbackDirection);
|
||||
MWBase::Environment::get().getWorld()->launchMagicBolt(mId, mCaster, fallbackDirection);
|
||||
}
|
||||
|
||||
void CastSpell::inflict(const MWWorld::Ptr &target, const MWWorld::Ptr &caster,
|
||||
|
@ -823,7 +822,7 @@ namespace MWMechanics
|
|||
inflict(mTarget, mCaster, enchantment->mEffects, ESM::RT_Touch);
|
||||
|
||||
if (launchProjectile)
|
||||
launchMagicBolt(enchantment->mEffects);
|
||||
launchMagicBolt();
|
||||
else if (isProjectile || !mTarget.isEmpty())
|
||||
inflict(mTarget, mCaster, enchantment->mEffects, ESM::RT_Target);
|
||||
|
||||
|
@ -915,7 +914,7 @@ namespace MWMechanics
|
|||
if (!mTarget.isEmpty())
|
||||
inflict(mTarget, mCaster, spell->mEffects, ESM::RT_Touch);
|
||||
|
||||
launchMagicBolt(spell->mEffects);
|
||||
launchMagicBolt();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ namespace MWMechanics
|
|||
void playSpellCastingEffects(const std::string &spellid);
|
||||
|
||||
/// Launch a bolt with the given effects.
|
||||
void launchMagicBolt (const ESM::EffectList& effects);
|
||||
void launchMagicBolt ();
|
||||
|
||||
/// @note \a target can be any type of object, not just actors.
|
||||
/// @note \a caster can be any type of object, or even an empty object.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "projectilemanager.hpp"
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
|
||||
|
@ -41,13 +42,29 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
ESM::EffectList getMagicBoltData(std::vector<std::string>& projectileIDs, std::vector<std::string>& sounds, float& speed, std::string& texture, const ESM::EffectList& effects)
|
||||
ESM::EffectList getMagicBoltData(std::vector<std::string>& projectileIDs, std::vector<std::string>& sounds, float& speed, std::string& texture, std::string& sourceName, const std::string& id)
|
||||
{
|
||||
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
||||
const ESM::EffectList* effects;
|
||||
if (const ESM::Spell* spell = esmStore.get<ESM::Spell>().search(id)) // check if it's a spell
|
||||
{
|
||||
sourceName = spell->mName;
|
||||
effects = &spell->mEffects;
|
||||
}
|
||||
else // check if it's an enchanted item
|
||||
{
|
||||
MWWorld::ManualRef ref(esmStore, id);
|
||||
MWWorld::Ptr ptr = ref.getPtr();
|
||||
const ESM::Enchantment* ench = esmStore.get<ESM::Enchantment>().find(ptr.getClass().getEnchantment(ptr));
|
||||
sourceName = ptr.getClass().getName(ptr);
|
||||
effects = &ench->mEffects;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
speed = 0.0f;
|
||||
ESM::EffectList projectileEffects;
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.mList.begin());
|
||||
iter!=effects.mList.end(); ++iter)
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects->mList.begin());
|
||||
iter!=effects->mList.end(); ++iter)
|
||||
{
|
||||
const ESM::MagicEffect *magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find (
|
||||
iter->mEffectID);
|
||||
|
@ -82,14 +99,14 @@ namespace
|
|||
if (projectileEffects.mList.size() == 1)
|
||||
{
|
||||
const ESM::MagicEffect *magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find (
|
||||
effects.mList.begin()->mEffectID);
|
||||
effects->mList.begin()->mEffectID);
|
||||
texture = magicEffect->mParticle;
|
||||
}
|
||||
|
||||
if (projectileEffects.mList.size() > 1) // insert a VFX_Multiple projectile if there are multiple projectile effects
|
||||
{
|
||||
std::ostringstream ID;
|
||||
ID << "VFX_Multiple" << effects.mList.size();
|
||||
ID << "VFX_Multiple" << effects->mList.size();
|
||||
std::vector<std::string>::iterator it;
|
||||
it = projectileIDs.begin();
|
||||
it = projectileIDs.insert(it, ID.str());
|
||||
|
@ -235,8 +252,7 @@ namespace MWWorld
|
|||
state.mEffectAnimationTime->addTime(duration);
|
||||
}
|
||||
|
||||
void ProjectileManager::launchMagicBolt(const std::string &spellId, bool stack, const ESM::EffectList &effects, const Ptr &caster,
|
||||
const std::string &sourceName, const osg::Vec3f& fallbackDirection)
|
||||
void ProjectileManager::launchMagicBolt(const std::string &spellId, const Ptr &caster, const osg::Vec3f& fallbackDirection)
|
||||
{
|
||||
osg::Vec3f pos = caster.getRefData().getPosition().asVec3();
|
||||
if (caster.getClass().isActor())
|
||||
|
@ -257,18 +273,16 @@ namespace MWWorld
|
|||
orient.makeRotate(osg::Vec3f(0,1,0), osg::Vec3f(fallbackDirection));
|
||||
|
||||
MagicBoltState state;
|
||||
state.mSourceName = sourceName;
|
||||
state.mSpellId = spellId;
|
||||
state.mCasterHandle = caster;
|
||||
if (caster.getClass().isActor())
|
||||
state.mActorId = caster.getClass().getCreatureStats(caster).getActorId();
|
||||
else
|
||||
state.mActorId = -1;
|
||||
state.mStack = stack;
|
||||
|
||||
std::string texture = "";
|
||||
|
||||
state.mEffects = getMagicBoltData(state.mIdMagic, state.mSoundIds, state.mSpeed, texture, effects);
|
||||
state.mEffects = getMagicBoltData(state.mIdMagic, state.mSoundIds, state.mSpeed, texture, state.mSourceName, state.mSpellId);
|
||||
|
||||
// Non-projectile should have been removed by getMagicBoltData
|
||||
if (state.mEffects.mList.empty())
|
||||
|
@ -277,7 +291,7 @@ namespace MWWorld
|
|||
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), state.mIdMagic.at(0));
|
||||
MWWorld::Ptr ptr = ref.getPtr();
|
||||
|
||||
osg::Vec4 lightDiffuseColor = getMagicBoltLightDiffuseColor(effects);
|
||||
osg::Vec4 lightDiffuseColor = getMagicBoltLightDiffuseColor(state.mEffects);
|
||||
createModel(state, ptr.getClass().getModel(ptr), pos, orient, true, true, lightDiffuseColor, texture);
|
||||
|
||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||
|
@ -364,7 +378,7 @@ namespace MWWorld
|
|||
cast.mHitPosition = pos;
|
||||
cast.mId = it->mSpellId;
|
||||
cast.mSourceName = it->mSourceName;
|
||||
cast.mStack = it->mStack;
|
||||
cast.mStack = false;
|
||||
cast.inflict(result.mHitObject, caster, it->mEffects, ESM::RT_Target, false, true);
|
||||
}
|
||||
}
|
||||
|
@ -504,11 +518,7 @@ namespace MWWorld
|
|||
state.mActorId = it->mActorId;
|
||||
|
||||
state.mSpellId = it->mSpellId;
|
||||
state.mEffects = it->mEffects;
|
||||
state.mSound = it->mSoundIds.at(0);
|
||||
state.mSourceName = it->mSourceName;
|
||||
state.mSpeed = it->mSpeed;
|
||||
state.mStack = it->mStack;
|
||||
|
||||
state.save(writer);
|
||||
|
||||
|
@ -553,13 +563,21 @@ namespace MWWorld
|
|||
esm.load(reader);
|
||||
|
||||
MagicBoltState state;
|
||||
state.mSourceName = esm.mSourceName;
|
||||
state.mIdMagic.push_back(esm.mId);
|
||||
state.mSpellId = esm.mSpellId;
|
||||
state.mActorId = esm.mActorId;
|
||||
state.mStack = esm.mStack;
|
||||
std::string texture = "";
|
||||
state.mEffects = getMagicBoltData(state.mIdMagic, state.mSoundIds, state.mSpeed, texture, esm.mEffects);
|
||||
|
||||
try
|
||||
{
|
||||
state.mEffects = getMagicBoltData(state.mIdMagic, state.mSoundIds, state.mSpeed, texture, state.mSourceName, state.mSpellId);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "Warning: Failed to recreate magic projectile from saved data (id \"" << state.mSpellId << "\" no longer exists?)" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
state.mSpeed = esm.mSpeed; // speed is derived from non-projectile effects as well as
|
||||
// projectile effects, so we can't calculate it from the save
|
||||
// file's effect list, which is already trimmed of non-projectile
|
||||
|
@ -577,7 +595,7 @@ namespace MWWorld
|
|||
return true;
|
||||
}
|
||||
|
||||
osg::Vec4 lightDiffuseColor = getMagicBoltLightDiffuseColor(esm.mEffects);
|
||||
osg::Vec4 lightDiffuseColor = getMagicBoltLightDiffuseColor(state.mEffects);
|
||||
createModel(state, model, osg::Vec3f(esm.mPosition), osg::Quat(esm.mOrientation), true, true, lightDiffuseColor, texture);
|
||||
|
||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||
|
|
|
@ -49,8 +49,7 @@ namespace MWWorld
|
|||
MWRender::RenderingManager* rendering, MWPhysics::PhysicsSystem* physics);
|
||||
|
||||
/// If caster is an actor, the actor's facing orientation is used. Otherwise fallbackDirection is used.
|
||||
void launchMagicBolt (const std::string &spellId, bool stack, const ESM::EffectList& effects,
|
||||
const MWWorld::Ptr& caster, const std::string& sourceName, const osg::Vec3f& fallbackDirection);
|
||||
void launchMagicBolt (const std::string &spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection);
|
||||
|
||||
void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
|
||||
const osg::Vec3f& pos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength);
|
||||
|
@ -101,8 +100,6 @@ namespace MWWorld
|
|||
|
||||
float mSpeed;
|
||||
|
||||
bool mStack;
|
||||
|
||||
std::vector<MWBase::Sound*> mSounds;
|
||||
std::vector<std::string> mSoundIds;
|
||||
};
|
||||
|
|
|
@ -2816,10 +2816,9 @@ namespace MWWorld
|
|||
mProjectileManager->launchProjectile(actor, projectile, worldPos, orient, bow, speed, attackStrength);
|
||||
}
|
||||
|
||||
void World::launchMagicBolt (const std::string &spellId, bool stack, const ESM::EffectList& effects,
|
||||
const MWWorld::Ptr& caster, const std::string& sourceName, const osg::Vec3f& fallbackDirection)
|
||||
void World::launchMagicBolt (const std::string &spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection)
|
||||
{
|
||||
mProjectileManager->launchMagicBolt(spellId, stack, effects, caster, sourceName, fallbackDirection);
|
||||
mProjectileManager->launchMagicBolt(spellId, caster, fallbackDirection);
|
||||
}
|
||||
|
||||
const std::vector<std::string>& World::getContentFiles() const
|
||||
|
|
|
@ -601,8 +601,7 @@ namespace MWWorld
|
|||
*/
|
||||
virtual void castSpell (const MWWorld::Ptr& actor);
|
||||
|
||||
virtual void launchMagicBolt (const std::string& spellId, bool stack, const ESM::EffectList& effects,
|
||||
const MWWorld::Ptr& caster, const std::string& sourceName, const osg::Vec3f& fallbackDirection);
|
||||
virtual void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) override;
|
||||
virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
|
||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength);
|
||||
|
||||
|
|
|
@ -27,11 +27,7 @@ namespace ESM
|
|||
BaseProjectileState::save(esm);
|
||||
|
||||
esm.writeHNString ("SPEL", mSpellId);
|
||||
esm.writeHNString ("SRCN", mSourceName);
|
||||
mEffects.save(esm);
|
||||
esm.writeHNT ("SPED", mSpeed);
|
||||
esm.writeHNT ("STCK", mStack);
|
||||
esm.writeHNString ("SOUN", mSound);
|
||||
}
|
||||
|
||||
void MagicBoltState::load(ESMReader &esm)
|
||||
|
@ -39,11 +35,14 @@ namespace ESM
|
|||
BaseProjectileState::load(esm);
|
||||
|
||||
mSpellId = esm.getHNString("SPEL");
|
||||
mSourceName = esm.getHNString ("SRCN");
|
||||
mEffects.load(esm);
|
||||
if (esm.isNextSub("SRCN")) // for backwards compatibility
|
||||
esm.skipHSub();
|
||||
ESM::EffectList().load(esm); // for backwards compatibility
|
||||
esm.getHNT (mSpeed, "SPED");
|
||||
esm.getHNT (mStack, "STCK");
|
||||
mSound = esm.getHNString ("SOUN");
|
||||
if (esm.isNextSub("STCK")) // for backwards compatibility
|
||||
esm.skipHSub();
|
||||
if (esm.isNextSub("SOUN")) // for backwards compatibility
|
||||
esm.skipHSub();
|
||||
}
|
||||
|
||||
void ProjectileState::save(ESMWriter &esm) const
|
||||
|
|
|
@ -31,11 +31,7 @@ namespace ESM
|
|||
struct MagicBoltState : public BaseProjectileState
|
||||
{
|
||||
std::string mSpellId;
|
||||
std::string mSourceName;
|
||||
ESM::EffectList mEffects;
|
||||
float mSpeed;
|
||||
bool mStack;
|
||||
std::string mSound;
|
||||
|
||||
void load (ESMReader &esm);
|
||||
void save (ESMWriter &esm) const;
|
||||
|
|
Loading…
Reference in a new issue