mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 01:56:52 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1518 lines
		
	
	
	
		
			60 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1518 lines
		
	
	
	
		
			60 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "statsextensions.hpp"
 | |
| 
 | |
| #include <cmath>
 | |
| 
 | |
| #include <components/esm/loadnpc.hpp>
 | |
| 
 | |
| #include "../mwworld/esmstore.hpp"
 | |
| 
 | |
| #include <components/compiler/extensions.hpp>
 | |
| #include <components/compiler/opcodes.hpp>
 | |
| #include <components/debug/debuglog.hpp>
 | |
| #include <components/interpreter/interpreter.hpp>
 | |
| #include <components/interpreter/runtime.hpp>
 | |
| #include <components/interpreter/opcodes.hpp>
 | |
| 
 | |
| #include "../mwbase/environment.hpp"
 | |
| #include "../mwbase/mechanicsmanager.hpp"
 | |
| #include "../mwbase/statemanager.hpp"
 | |
| #include "../mwbase/windowmanager.hpp"
 | |
| #include "../mwbase/world.hpp"
 | |
| 
 | |
| #include "../mwworld/class.hpp"
 | |
| #include "../mwworld/player.hpp"
 | |
| 
 | |
| #include "../mwmechanics/creaturestats.hpp"
 | |
| #include "../mwmechanics/npcstats.hpp"
 | |
| #include "../mwmechanics/actorutil.hpp"
 | |
| #include "../mwmechanics/spellcasting.hpp"
 | |
| 
 | |
| #include "ref.hpp"
 | |
| 
 | |
| namespace
 | |
| {
 | |
|     std::string getDialogueActorFaction(MWWorld::ConstPtr actor)
 | |
|     {
 | |
|         std::string factionId = actor.getClass().getPrimaryFaction(actor);
 | |
|         if (factionId.empty())
 | |
|             throw std::runtime_error (
 | |
|                 "failed to determine dialogue actors faction (because actor is factionless)");
 | |
| 
 | |
|         return factionId;
 | |
|     }
 | |
| }
 | |
| 
 | |
| namespace MWScript
 | |
| {
 | |
|     namespace Stats
 | |
|     {
 | |
|         template<class R>
 | |
|         class OpGetLevel : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Integer value =
 | |
|                         ptr.getClass()
 | |
|                             .getCreatureStats (ptr)
 | |
|                             .getLevel();
 | |
| 
 | |
|                     runtime.push (value);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpSetLevel : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Integer value = runtime[0].mInteger;
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     ptr.getClass()
 | |
|                         .getCreatureStats (ptr)
 | |
|                         .setLevel(value);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpGetAttribute : public Interpreter::Opcode0
 | |
|         {
 | |
|                 int mIndex;
 | |
| 
 | |
|             public:
 | |
| 
 | |
|                 OpGetAttribute (int index) : mIndex (index) {}
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Float value =
 | |
|                         ptr.getClass()
 | |
|                             .getCreatureStats (ptr)
 | |
|                             .getAttribute(mIndex)
 | |
|                             .getModified();
 | |
| 
 | |
|                     runtime.push (value);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpSetAttribute : public Interpreter::Opcode0
 | |
|         {
 | |
|                 int mIndex;
 | |
| 
 | |
|             public:
 | |
| 
 | |
|                 OpSetAttribute (int index) : mIndex (index) {}
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Float value = runtime[0].mFloat;
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     MWMechanics::AttributeValue attribute = ptr.getClass().getCreatureStats(ptr).getAttribute(mIndex);
 | |
|                     attribute.setBase (value);
 | |
|                     ptr.getClass().getCreatureStats(ptr).setAttribute(mIndex, attribute);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpModAttribute : public Interpreter::Opcode0
 | |
|         {
 | |
|                 int mIndex;
 | |
| 
 | |
|             public:
 | |
| 
 | |
|                 OpModAttribute (int index) : mIndex (index) {}
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Float value = runtime[0].mFloat;
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     MWMechanics::AttributeValue attribute = ptr.getClass()
 | |
|                         .getCreatureStats(ptr)
 | |
|                         .getAttribute(mIndex);
 | |
| 
 | |
|                     if (value == 0)
 | |
|                         return;
 | |
| 
 | |
|                     if (((attribute.getBase() <= 0) && (value < 0))
 | |
|                         || ((attribute.getBase() >= 100) && (value > 0)))
 | |
|                         return;
 | |
| 
 | |
|                     if (value < 0)
 | |
|                         attribute.setBase(std::max(0.f, attribute.getBase() + value));
 | |
|                     else
 | |
|                         attribute.setBase(std::min(100.f, attribute.getBase() + value));
 | |
| 
 | |
|                     ptr.getClass().getCreatureStats(ptr).setAttribute(mIndex, attribute);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpGetDynamic : public Interpreter::Opcode0
 | |
|         {
 | |
|                 int mIndex;
 | |
| 
 | |
|             public:
 | |
| 
 | |
|                 OpGetDynamic (int index) : mIndex (index) {}
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
|                     Interpreter::Type_Float value;
 | |
| 
 | |
|                     if (mIndex==0 && ptr.getClass().hasItemHealth (ptr))
 | |
|                     {
 | |
|                         // health is a special case
 | |
|                         value = static_cast<Interpreter::Type_Float>(ptr.getClass().getItemMaxHealth(ptr));
 | |
|                     } else {
 | |
|                         value =
 | |
|                             ptr.getClass()
 | |
|                                 .getCreatureStats(ptr)
 | |
|                                 .getDynamic(mIndex)
 | |
|                                 .getCurrent();
 | |
|                         // GetMagicka shouldn't return negative values
 | |
|                         if(mIndex == 1 && value < 0)
 | |
|                             value = 0;
 | |
|                     }
 | |
|                     runtime.push (value);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpSetDynamic : public Interpreter::Opcode0
 | |
|         {
 | |
|                 int mIndex;
 | |
| 
 | |
|             public:
 | |
| 
 | |
|                 OpSetDynamic (int index) : mIndex (index) {}
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Float value = runtime[0].mFloat;
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     MWMechanics::DynamicStat<float> stat (ptr.getClass().getCreatureStats (ptr)
 | |
|                         .getDynamic (mIndex));
 | |
| 
 | |
|                     stat.setModified (value, 0);
 | |
|                     stat.setCurrent(value);
 | |
| 
 | |
|                     ptr.getClass().getCreatureStats (ptr).setDynamic (mIndex, stat);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpModDynamic : public Interpreter::Opcode0
 | |
|         {
 | |
|                 int mIndex;
 | |
| 
 | |
|             public:
 | |
| 
 | |
|                 OpModDynamic (int index) : mIndex (index) {}
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     int peek = R::implicit ? 0 : runtime[0].mInteger;
 | |
| 
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Float diff = runtime[0].mFloat;
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     // workaround broken endgame scripts that kill dagoth ur
 | |
|                     if (!R::implicit &&
 | |
|                         ::Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "dagoth_ur_1"))
 | |
|                     {
 | |
|                         runtime.push (peek);
 | |
| 
 | |
|                         if (R()(runtime, false, true).isEmpty())
 | |
|                         {
 | |
|                             Log(Debug::Warning)
 | |
|                                 << "Warning: Compensating for broken script in Morrowind.esm by "
 | |
|                                 << "ignoring remote access to dagoth_ur_1";
 | |
| 
 | |
|                             return;
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr);
 | |
| 
 | |
|                     Interpreter::Type_Float current = stats.getDynamic(mIndex).getCurrent();
 | |
| 
 | |
|                     MWMechanics::DynamicStat<float> stat (ptr.getClass().getCreatureStats (ptr)
 | |
|                         .getDynamic (mIndex));
 | |
| 
 | |
|                     stat.setModified (diff + stat.getModified(), 0);
 | |
|                     stat.setCurrentModified (diff + stat.getCurrentModified());
 | |
| 
 | |
|                     stat.setCurrent (diff + current);
 | |
| 
 | |
|                     ptr.getClass().getCreatureStats (ptr).setDynamic (mIndex, stat);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpModCurrentDynamic : public Interpreter::Opcode0
 | |
|         {
 | |
|                 int mIndex;
 | |
| 
 | |
|             public:
 | |
| 
 | |
|                 OpModCurrentDynamic (int index) : mIndex (index) {}
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Float diff = runtime[0].mFloat;
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr);
 | |
| 
 | |
|                     Interpreter::Type_Float current = stats.getDynamic(mIndex).getCurrent();
 | |
| 
 | |
|                     MWMechanics::DynamicStat<float> stat (ptr.getClass().getCreatureStats (ptr)
 | |
|                         .getDynamic (mIndex));
 | |
| 
 | |
|                     bool allowDecreaseBelowZero = false;
 | |
|                     if (mIndex == 2) // Fatigue-specific logic
 | |
|                     {
 | |
|                         // For fatigue, a negative current value is allowed and means the actor will be knocked down
 | |
|                         allowDecreaseBelowZero = true;
 | |
|                         // Knock down the actor immediately if a non-positive new value is the case
 | |
|                         if (diff + current <= 0.f)
 | |
|                             ptr.getClass().getCreatureStats(ptr).setKnockedDown(true);
 | |
|                     }
 | |
|                     stat.setCurrent (diff + current, allowDecreaseBelowZero);
 | |
| 
 | |
|                     ptr.getClass().getCreatureStats (ptr).setDynamic (mIndex, stat);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpGetDynamicGetRatio : public Interpreter::Opcode0
 | |
|         {
 | |
|                 int mIndex;
 | |
| 
 | |
|             public:
 | |
| 
 | |
|                 OpGetDynamicGetRatio (int index) : mIndex (index) {}
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr);
 | |
| 
 | |
|                     Interpreter::Type_Float value = 0;
 | |
| 
 | |
|                     Interpreter::Type_Float max = stats.getDynamic(mIndex).getModified();
 | |
| 
 | |
|                     if (max>0)
 | |
|                         value = stats.getDynamic(mIndex).getCurrent() / max;
 | |
| 
 | |
|                     runtime.push (value);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpGetSkill : public Interpreter::Opcode0
 | |
|         {
 | |
|                 int mIndex;
 | |
| 
 | |
|             public:
 | |
| 
 | |
|                 OpGetSkill (int index) : mIndex (index) {}
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Float value = ptr.getClass().getSkill(ptr, mIndex);
 | |
| 
 | |
|                     runtime.push (value);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpSetSkill : public Interpreter::Opcode0
 | |
|         {
 | |
|                 int mIndex;
 | |
| 
 | |
|             public:
 | |
| 
 | |
|                 OpSetSkill (int index) : mIndex (index) {}
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Float value = runtime[0].mFloat;
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     MWMechanics::NpcStats& stats = ptr.getClass().getNpcStats (ptr);
 | |
| 
 | |
|                     stats.getSkill (mIndex).setBase (value);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpModSkill : public Interpreter::Opcode0
 | |
|         {
 | |
|                 int mIndex;
 | |
| 
 | |
|             public:
 | |
| 
 | |
|                 OpModSkill (int index) : mIndex (index) {}
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Float value = runtime[0].mFloat;
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     MWMechanics::SkillValue &skill = ptr.getClass()
 | |
|                         .getNpcStats(ptr)
 | |
|                         .getSkill(mIndex);
 | |
| 
 | |
|                     if (value == 0)
 | |
|                         return;
 | |
| 
 | |
|                     if (((skill.getBase() <= 0.f) && (value < 0.f))
 | |
|                         || ((skill.getBase() >= 100.f) && (value > 0.f)))
 | |
|                         return;
 | |
| 
 | |
|                     if (value < 0)
 | |
|                         skill.setBase(std::max(0.f, skill.getBase() + value));
 | |
|                     else
 | |
|                         skill.setBase(std::min(100.f, skill.getBase() + value));
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         class OpGetPCCrimeLevel : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWBase::World *world = MWBase::Environment::get().getWorld();
 | |
|                     MWWorld::Ptr player = world->getPlayerPtr();
 | |
|                     runtime.push (static_cast <Interpreter::Type_Float> (player.getClass().getNpcStats (player).getBounty()));
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         class OpSetPCCrimeLevel : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWBase::World *world = MWBase::Environment::get().getWorld();
 | |
|                     MWWorld::Ptr player = world->getPlayerPtr();
 | |
| 
 | |
|                     int bounty = static_cast<int>(runtime[0].mFloat);
 | |
|                     runtime.pop();
 | |
|                     player.getClass().getNpcStats (player).setBounty(bounty);
 | |
| 
 | |
|                     if (bounty == 0)
 | |
|                         MWBase::Environment::get().getWorld()->getPlayer().recordCrimeId();
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         class OpModPCCrimeLevel : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWBase::World *world = MWBase::Environment::get().getWorld();
 | |
|                     MWWorld::Ptr player = world->getPlayerPtr();
 | |
| 
 | |
|                     player.getClass().getNpcStats(player).setBounty(static_cast<int>(runtime[0].mFloat) + player.getClass().getNpcStats(player).getBounty());
 | |
|                     runtime.pop();
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpAddSpell : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     std::string id = runtime.getStringLiteral (runtime[0].mInteger);
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (id);
 | |
| 
 | |
|                     MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr);
 | |
|                     creatureStats.getSpells().add(id);
 | |
|                     ESM::Spell::SpellType type = static_cast<ESM::Spell::SpellType>(spell->mData.mType);
 | |
|                     if (type != ESM::Spell::ST_Spell && type != ESM::Spell::ST_Power)
 | |
|                     {
 | |
|                         // Apply looping particles immediately for constant effects
 | |
|                         MWBase::Environment::get().getWorld()->applyLoopingParticles(ptr);
 | |
|                     }
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpRemoveSpell : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     std::string id = runtime.getStringLiteral (runtime[0].mInteger);
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr);
 | |
|                     // The spell may have an instant effect which must be handled before the spell's removal.
 | |
|                     for (const auto& effect : creatureStats.getSpells().getMagicEffects())
 | |
|                     {
 | |
|                         if (effect.second.getMagnitude() <= 0)
 | |
|                             continue;
 | |
|                         MWMechanics::CastSpell cast(ptr, ptr);
 | |
|                         if (cast.applyInstantEffect(ptr, ptr, effect.first, effect.second.getMagnitude()))
 | |
|                             creatureStats.getSpells().purgeEffect(effect.first.mId);
 | |
|                     }
 | |
| 
 | |
|                     MWBase::Environment::get().getMechanicsManager()->restoreStatsAfterCorprus(ptr, id);
 | |
|                     creatureStats.getSpells().remove (id);
 | |
| 
 | |
|                     MWBase::WindowManager *wm = MWBase::Environment::get().getWindowManager();
 | |
| 
 | |
|                     if (ptr == MWMechanics::getPlayer() &&
 | |
|                         id == wm->getSelectedSpell())
 | |
|                     {
 | |
|                         wm->unsetSelectedSpell();
 | |
|                     }
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpRemoveSpellEffects : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     std::string spellid = runtime.getStringLiteral (runtime[0].mInteger);
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     ptr.getClass().getCreatureStats (ptr).getActiveSpells().removeEffects(spellid);
 | |
|                     ptr.getClass().getCreatureStats (ptr).getSpells().removeEffects(spellid);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpRemoveEffects : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Integer effectId = runtime[0].mInteger;
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     ptr.getClass().getCreatureStats (ptr).getActiveSpells().purgeEffect(effectId);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpGetSpell : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
| 
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     std::string id = runtime.getStringLiteral (runtime[0].mInteger);
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     Interpreter::Type_Integer value = 0;
 | |
| 
 | |
|                     if (ptr.getClass().isActor() && ptr.getClass().getCreatureStats(ptr).getSpells().hasSpell(id))
 | |
|                         value = 1;
 | |
| 
 | |
|                     runtime.push (value);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpPCJoinFaction : public Interpreter::Opcode1
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime, unsigned int arg0) override
 | |
|                 {
 | |
|                     MWWorld::ConstPtr actor = R()(runtime, false);
 | |
| 
 | |
|                     std::string factionID = "";
 | |
| 
 | |
|                     if(arg0==0)
 | |
|                     {
 | |
|                         factionID = getDialogueActorFaction(actor);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         factionID = runtime.getStringLiteral (runtime[0].mInteger);
 | |
|                         runtime.pop();
 | |
|                     }
 | |
|                     ::Misc::StringUtils::lowerCaseInPlace(factionID);
 | |
|                     // Make sure this faction exists
 | |
|                     MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(factionID);
 | |
| 
 | |
|                     if(factionID != "")
 | |
|                     {
 | |
|                         MWWorld::Ptr player = MWMechanics::getPlayer();
 | |
|                         player.getClass().getNpcStats(player).joinFaction(factionID);
 | |
|                     }
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpPCRaiseRank : public Interpreter::Opcode1
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime, unsigned int arg0) override
 | |
|                 {
 | |
|                     MWWorld::ConstPtr actor = R()(runtime, false);
 | |
| 
 | |
|                     std::string factionID = "";
 | |
| 
 | |
|                     if(arg0==0)
 | |
|                     {
 | |
|                         factionID = getDialogueActorFaction(actor);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         factionID = runtime.getStringLiteral (runtime[0].mInteger);
 | |
|                         runtime.pop();
 | |
|                     }
 | |
|                     ::Misc::StringUtils::lowerCaseInPlace(factionID);
 | |
|                     // Make sure this faction exists
 | |
|                     MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(factionID);
 | |
| 
 | |
|                     if(factionID != "")
 | |
|                     {
 | |
|                         MWWorld::Ptr player = MWMechanics::getPlayer();
 | |
|                         if(player.getClass().getNpcStats(player).getFactionRanks().find(factionID) == player.getClass().getNpcStats(player).getFactionRanks().end())
 | |
|                         {
 | |
|                             player.getClass().getNpcStats(player).joinFaction(factionID);
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             player.getClass().getNpcStats(player).raiseRank(factionID);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpPCLowerRank : public Interpreter::Opcode1
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime, unsigned int arg0) override
 | |
|                 {
 | |
|                     MWWorld::ConstPtr actor = R()(runtime, false);
 | |
| 
 | |
|                     std::string factionID = "";
 | |
| 
 | |
|                     if(arg0==0)
 | |
|                     {
 | |
|                         factionID = getDialogueActorFaction(actor);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         factionID = runtime.getStringLiteral (runtime[0].mInteger);
 | |
|                         runtime.pop();
 | |
|                     }
 | |
|                     ::Misc::StringUtils::lowerCaseInPlace(factionID);
 | |
|                     // Make sure this faction exists
 | |
|                     MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(factionID);
 | |
| 
 | |
|                     if(factionID != "")
 | |
|                     {
 | |
|                         MWWorld::Ptr player = MWMechanics::getPlayer();
 | |
|                         player.getClass().getNpcStats(player).lowerRank(factionID);
 | |
|                     }
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpGetPCRank : public Interpreter::Opcode1
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime, unsigned int arg0) override
 | |
|                 {
 | |
|                     MWWorld::ConstPtr ptr = R()(runtime, false);
 | |
| 
 | |
|                     std::string factionID = "";
 | |
|                     if(arg0 >0)
 | |
|                     {
 | |
|                         factionID = runtime.getStringLiteral (runtime[0].mInteger);
 | |
|                         runtime.pop();
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         factionID = ptr.getClass().getPrimaryFaction(ptr);
 | |
|                     }
 | |
|                     ::Misc::StringUtils::lowerCaseInPlace(factionID);
 | |
|                     // Make sure this faction exists
 | |
|                     MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(factionID);
 | |
| 
 | |
|                     MWWorld::Ptr player = MWMechanics::getPlayer();
 | |
|                     if(factionID!="")
 | |
|                     {
 | |
|                         if(player.getClass().getNpcStats(player).getFactionRanks().find(factionID) != player.getClass().getNpcStats(player).getFactionRanks().end())
 | |
|                         {
 | |
|                             runtime.push(player.getClass().getNpcStats(player).getFactionRanks().at(factionID));
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             runtime.push(-1);
 | |
|                         }
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         runtime.push(-1);
 | |
|                     }
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpModDisposition : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Integer value = runtime[0].mInteger;
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     if (ptr.getClass().isNpc())
 | |
|                         ptr.getClass().getNpcStats (ptr).setBaseDisposition
 | |
|                             (ptr.getClass().getNpcStats (ptr).getBaseDisposition() + value);
 | |
| 
 | |
|                     // else: must not throw exception (used by an Almalexia dialogue script)
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpSetDisposition : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Integer value = runtime[0].mInteger;
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     if (ptr.getClass().isNpc())
 | |
|                         ptr.getClass().getNpcStats (ptr).setBaseDisposition (value);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpGetDisposition : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     if (!ptr.getClass().isNpc())
 | |
|                         runtime.push(0);
 | |
|                     else
 | |
|                         runtime.push (MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(ptr));
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         class OpGetDeadCount : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     std::string id = runtime.getStringLiteral (runtime[0].mInteger);
 | |
|                     runtime[0].mInteger = MWBase::Environment::get().getMechanicsManager()->countDeaths (id);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpGetPCFacRep : public Interpreter::Opcode1
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime, unsigned int arg0) override
 | |
|                 {
 | |
|                     MWWorld::ConstPtr ptr = R()(runtime, false);
 | |
| 
 | |
|                     std::string factionId;
 | |
| 
 | |
|                     if (arg0==1)
 | |
|                     {
 | |
|                         factionId = runtime.getStringLiteral (runtime[0].mInteger);
 | |
|                         runtime.pop();
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         factionId = getDialogueActorFaction(ptr);
 | |
|                     }
 | |
| 
 | |
|                     if (factionId.empty())
 | |
|                         throw std::runtime_error ("failed to determine faction");
 | |
| 
 | |
|                     ::Misc::StringUtils::lowerCaseInPlace (factionId);
 | |
| 
 | |
|                     MWWorld::Ptr player = MWMechanics::getPlayer();
 | |
|                     runtime.push (
 | |
|                         player.getClass().getNpcStats (player).getFactionReputation (factionId));
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpSetPCFacRep : public Interpreter::Opcode1
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime, unsigned int arg0) override
 | |
|                 {
 | |
|                     MWWorld::ConstPtr ptr = R()(runtime, false);
 | |
| 
 | |
|                     Interpreter::Type_Integer value = runtime[0].mInteger;
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     std::string factionId;
 | |
| 
 | |
|                     if (arg0==1)
 | |
|                     {
 | |
|                         factionId = runtime.getStringLiteral (runtime[0].mInteger);
 | |
|                         runtime.pop();
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         factionId = getDialogueActorFaction(ptr);
 | |
|                     }
 | |
| 
 | |
|                     if (factionId.empty())
 | |
|                         throw std::runtime_error ("failed to determine faction");
 | |
| 
 | |
|                     ::Misc::StringUtils::lowerCaseInPlace (factionId);
 | |
| 
 | |
|                     MWWorld::Ptr player = MWMechanics::getPlayer();
 | |
|                     player.getClass().getNpcStats (player).setFactionReputation (factionId, value);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpModPCFacRep : public Interpreter::Opcode1
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime, unsigned int arg0) override
 | |
|                 {
 | |
|                     MWWorld::ConstPtr ptr = R()(runtime, false);
 | |
| 
 | |
|                     Interpreter::Type_Integer value = runtime[0].mInteger;
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     std::string factionId;
 | |
| 
 | |
|                     if (arg0==1)
 | |
|                     {
 | |
|                         factionId = runtime.getStringLiteral (runtime[0].mInteger);
 | |
|                         runtime.pop();
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         factionId = getDialogueActorFaction(ptr);
 | |
|                     }
 | |
| 
 | |
|                     if (factionId.empty())
 | |
|                         throw std::runtime_error ("failed to determine faction");
 | |
| 
 | |
|                     ::Misc::StringUtils::lowerCaseInPlace (factionId);
 | |
| 
 | |
|                     MWWorld::Ptr player = MWMechanics::getPlayer();
 | |
|                     player.getClass().getNpcStats (player).setFactionReputation (factionId,
 | |
|                         player.getClass().getNpcStats (player).getFactionReputation (factionId)+
 | |
|                         value);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpGetCommonDisease : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     runtime.push (ptr.getClass().getCreatureStats (ptr).hasCommonDisease());
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpGetBlightDisease : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     runtime.push (ptr.getClass().getCreatureStats (ptr).hasBlightDisease());
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template<class R>
 | |
|         class OpGetRace : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::ConstPtr ptr = R()(runtime);
 | |
| 
 | |
|                     std::string race = runtime.getStringLiteral(runtime[0].mInteger);
 | |
|                     ::Misc::StringUtils::lowerCaseInPlace(race);
 | |
|                     runtime.pop();
 | |
| 
 | |
|                     std::string npcRace = ptr.get<ESM::NPC>()->mBase->mRace;
 | |
|                     ::Misc::StringUtils::lowerCaseInPlace(npcRace);
 | |
| 
 | |
|                     runtime.push (npcRace == race);
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         class OpGetWerewolfKills : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayerPtr();
 | |
| 
 | |
|                     runtime.push (ptr.getClass().getNpcStats (ptr).getWerewolfKills ());
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template <class R>
 | |
|         class OpPcExpelled : public Interpreter::Opcode1
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime, unsigned int arg0) override
 | |
|                 {
 | |
|                     MWWorld::ConstPtr ptr = R()(runtime, false);
 | |
| 
 | |
|                     std::string factionID = "";
 | |
|                     if(arg0 >0 )
 | |
|                     {
 | |
|                         factionID = runtime.getStringLiteral (runtime[0].mInteger);
 | |
|                         runtime.pop();
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         factionID = ptr.getClass().getPrimaryFaction(ptr);
 | |
|                     }
 | |
|                     ::Misc::StringUtils::lowerCaseInPlace(factionID);
 | |
|                     MWWorld::Ptr player = MWMechanics::getPlayer();
 | |
|                     if(factionID!="")
 | |
|                     {
 | |
|                         runtime.push(player.getClass().getNpcStats(player).getExpelled(factionID));
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         runtime.push(0);
 | |
|                     }
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template <class R>
 | |
|         class OpPcExpell : public Interpreter::Opcode1
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime, unsigned int arg0) override
 | |
|                 {
 | |
|                     MWWorld::ConstPtr ptr = R()(runtime, false);
 | |
| 
 | |
|                     std::string factionID = "";
 | |
|                     if(arg0 >0 )
 | |
|                     {
 | |
|                         factionID = runtime.getStringLiteral (runtime[0].mInteger);
 | |
|                         runtime.pop();
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         factionID = ptr.getClass().getPrimaryFaction(ptr);
 | |
|                     }
 | |
|                     MWWorld::Ptr player = MWMechanics::getPlayer();
 | |
|                     if(factionID!="")
 | |
|                     {
 | |
|                         player.getClass().getNpcStats(player).expell(factionID);
 | |
|                     }
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template <class R>
 | |
|         class OpPcClearExpelled : public Interpreter::Opcode1
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime, unsigned int arg0) override
 | |
|                 {
 | |
|                     MWWorld::ConstPtr ptr = R()(runtime, false);
 | |
| 
 | |
|                     std::string factionID = "";
 | |
|                     if(arg0 >0 )
 | |
|                     {
 | |
|                         factionID = runtime.getStringLiteral (runtime[0].mInteger);
 | |
|                         runtime.pop();
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         factionID = ptr.getClass().getPrimaryFaction(ptr);
 | |
|                     }
 | |
|                     MWWorld::Ptr player = MWMechanics::getPlayer();
 | |
|                     if(factionID!="")
 | |
|                         player.getClass().getNpcStats(player).clearExpelled(factionID);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template <class R>
 | |
|         class OpRaiseRank : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     std::string factionID = ptr.getClass().getPrimaryFaction(ptr);
 | |
|                     if(factionID.empty())
 | |
|                         return;
 | |
| 
 | |
|                     MWWorld::Ptr player = MWMechanics::getPlayer();
 | |
| 
 | |
|                     // no-op when executed on the player
 | |
|                     if (ptr == player)
 | |
|                         return;
 | |
| 
 | |
|                     // If we already changed rank for this NPC, modify current rank in the NPC stats.
 | |
|                     // Otherwise take rank from base NPC record, increase it and put it to NPC data.
 | |
|                     int currentRank = ptr.getClass().getNpcStats(ptr).getFactionRank(factionID);
 | |
|                     if (currentRank >= 0)
 | |
|                         ptr.getClass().getNpcStats(ptr).raiseRank(factionID);
 | |
|                     else
 | |
|                     {
 | |
|                         int rank = ptr.getClass().getPrimaryFactionRank(ptr);
 | |
|                         rank++;
 | |
|                         ptr.getClass().getNpcStats(ptr).joinFaction(factionID);
 | |
|                         for (int i=0; i<rank; i++)
 | |
|                             ptr.getClass().getNpcStats(ptr).raiseRank(factionID);
 | |
|                     }
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template <class R>
 | |
|         class OpLowerRank : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     std::string factionID = ptr.getClass().getPrimaryFaction(ptr);
 | |
|                     if(factionID.empty())
 | |
|                         return;
 | |
| 
 | |
|                     MWWorld::Ptr player = MWMechanics::getPlayer();
 | |
| 
 | |
|                     // no-op when executed on the player
 | |
|                     if (ptr == player)
 | |
|                         return;
 | |
| 
 | |
|                     // If we already changed rank for this NPC, modify current rank in the NPC stats.
 | |
|                     // Otherwise take rank from base NPC record, decrease it and put it to NPC data.
 | |
|                     int currentRank = ptr.getClass().getNpcStats(ptr).getFactionRank(factionID);
 | |
|                     if (currentRank == 0)
 | |
|                         return;
 | |
|                     else if (currentRank > 0)
 | |
|                         ptr.getClass().getNpcStats(ptr).lowerRank(factionID);
 | |
|                     else
 | |
|                     {
 | |
|                         int rank = ptr.getClass().getPrimaryFactionRank(ptr);
 | |
|                         rank--;
 | |
|                         ptr.getClass().getNpcStats(ptr).joinFaction(factionID);
 | |
|                         for (int i=0; i<rank; i++)
 | |
|                             ptr.getClass().getNpcStats(ptr).raiseRank(factionID);
 | |
|                     }
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template <class R>
 | |
|         class OpOnDeath : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Integer value =
 | |
|                         ptr.getClass().getCreatureStats (ptr).hasDied();
 | |
| 
 | |
|                     if (value)
 | |
|                         ptr.getClass().getCreatureStats (ptr).clearHasDied();
 | |
| 
 | |
|                     runtime.push (value);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template <class R>
 | |
|         class OpOnMurder : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Integer value =
 | |
|                         ptr.getClass().getCreatureStats (ptr).hasBeenMurdered();
 | |
| 
 | |
|                     if (value)
 | |
|                         ptr.getClass().getCreatureStats (ptr).clearHasBeenMurdered();
 | |
| 
 | |
|                     runtime.push (value);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template <class R>
 | |
|         class OpOnKnockout : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     Interpreter::Type_Integer value =
 | |
|                         ptr.getClass().getCreatureStats (ptr).getKnockedDownOneFrame();
 | |
| 
 | |
|                     runtime.push (value);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template <class R>
 | |
|         class OpIsWerewolf : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
|                     runtime.push(ptr.getClass().getNpcStats(ptr).isWerewolf());
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template <class R, bool set>
 | |
|         class OpSetWerewolf : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
|                     MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptr, set);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template <class R>
 | |
|         class OpSetWerewolfAcrobatics : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
|                     MWBase::Environment::get().getMechanicsManager()->applyWerewolfAcrobatics(ptr);
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template <class R>
 | |
|         class OpResurrect : public Interpreter::Opcode0
 | |
|         {
 | |
|             public:
 | |
| 
 | |
|                 void execute (Interpreter::Runtime& runtime) override
 | |
|                 {
 | |
|                     MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                     if (ptr == MWMechanics::getPlayer())
 | |
|                     {
 | |
|                         MWBase::Environment::get().getMechanicsManager()->resurrect(ptr);
 | |
|                         if (MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_Ended)
 | |
|                             MWBase::Environment::get().getStateManager()->resumeGame();
 | |
|                     }
 | |
|                     else if (ptr.getClass().getCreatureStats(ptr).isDead())
 | |
|                     {
 | |
|                         bool wasEnabled = ptr.getRefData().isEnabled();
 | |
|                         MWBase::Environment::get().getWorld()->undeleteObject(ptr);
 | |
|                         MWBase::Environment::get().getWorld()->removeContainerScripts(ptr);
 | |
| 
 | |
|                         // HACK: disable/enable object to re-add it to the scene properly (need a new Animation).
 | |
|                         MWBase::Environment::get().getWorld()->disable(ptr);
 | |
|                         // resets runtime state such as inventory, stats and AI. does not reset position in the world
 | |
|                         ptr.getRefData().setCustomData(nullptr);
 | |
|                         if (wasEnabled)
 | |
|                             MWBase::Environment::get().getWorld()->enable(ptr);
 | |
|                     }
 | |
|                 }
 | |
|         };
 | |
| 
 | |
|         template <class R>
 | |
|         class OpGetStat : public Interpreter::Opcode0
 | |
|         {
 | |
|         public:
 | |
|             void execute (Interpreter::Runtime& runtime) override
 | |
|             {
 | |
|                 // dummy
 | |
|                 runtime.push(0);
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         template <class R>
 | |
|         class OpGetMagicEffect : public Interpreter::Opcode0
 | |
|         {
 | |
|             int mPositiveEffect;
 | |
|             int mNegativeEffect;
 | |
| 
 | |
|         public:
 | |
|             OpGetMagicEffect (int positiveEffect, int negativeEffect)
 | |
|                 : mPositiveEffect(positiveEffect)
 | |
|                 , mNegativeEffect(negativeEffect)
 | |
|             {
 | |
|             }
 | |
| 
 | |
|             void execute (Interpreter::Runtime& runtime) override
 | |
|             {
 | |
|                 MWWorld::Ptr ptr = R()(runtime);
 | |
| 
 | |
|                 const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects();
 | |
|                 float currentValue = effects.get(mPositiveEffect).getMagnitude();
 | |
|                 if (mNegativeEffect != -1)
 | |
|                     currentValue -= effects.get(mNegativeEffect).getMagnitude();
 | |
| 
 | |
|                 // GetResist* should take in account elemental shields
 | |
|                 if (mPositiveEffect == ESM::MagicEffect::ResistFire)
 | |
|                     currentValue += effects.get(ESM::MagicEffect::FireShield).getMagnitude();
 | |
|                 if (mPositiveEffect == ESM::MagicEffect::ResistShock)
 | |
|                     currentValue += effects.get(ESM::MagicEffect::LightningShield).getMagnitude();
 | |
|                 if (mPositiveEffect == ESM::MagicEffect::ResistFrost)
 | |
|                     currentValue += effects.get(ESM::MagicEffect::FrostShield).getMagnitude();
 | |
| 
 | |
|                 int ret = static_cast<int>(currentValue);
 | |
|                 runtime.push(ret);
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         template <class R>
 | |
|         class OpSetMagicEffect : public Interpreter::Opcode0
 | |
|         {
 | |
|             int mPositiveEffect;
 | |
|             int mNegativeEffect;
 | |
| 
 | |
|         public:
 | |
|             OpSetMagicEffect (int positiveEffect, int negativeEffect)
 | |
|                 : mPositiveEffect(positiveEffect)
 | |
|                 , mNegativeEffect(negativeEffect)
 | |
|             {
 | |
|             }
 | |
| 
 | |
|             void execute(Interpreter::Runtime &runtime) override
 | |
|             {
 | |
|                 MWWorld::Ptr ptr = R()(runtime);
 | |
|                 MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects();
 | |
|                 float currentValue = effects.get(mPositiveEffect).getMagnitude();
 | |
|                 if (mNegativeEffect != -1)
 | |
|                     currentValue -= effects.get(mNegativeEffect).getMagnitude();
 | |
| 
 | |
|                 // SetResist* should take in account elemental shields
 | |
|                 if (mPositiveEffect == ESM::MagicEffect::ResistFire)
 | |
|                     currentValue += effects.get(ESM::MagicEffect::FireShield).getMagnitude();
 | |
|                 if (mPositiveEffect == ESM::MagicEffect::ResistShock)
 | |
|                     currentValue += effects.get(ESM::MagicEffect::LightningShield).getMagnitude();
 | |
|                 if (mPositiveEffect == ESM::MagicEffect::ResistFrost)
 | |
|                     currentValue += effects.get(ESM::MagicEffect::FrostShield).getMagnitude();
 | |
| 
 | |
|                 int arg = runtime[0].mInteger;
 | |
|                 runtime.pop();
 | |
|                 effects.modifyBase(mPositiveEffect, (arg - static_cast<int>(currentValue)));
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         template <class R>
 | |
|         class OpModMagicEffect : public Interpreter::Opcode0
 | |
|         {
 | |
|             int mPositiveEffect;
 | |
|             int mNegativeEffect;
 | |
| 
 | |
|         public:
 | |
|             OpModMagicEffect (int positiveEffect, int negativeEffect)
 | |
|                 : mPositiveEffect(positiveEffect)
 | |
|                 , mNegativeEffect(negativeEffect)
 | |
|             {
 | |
|             }
 | |
| 
 | |
|             void execute(Interpreter::Runtime &runtime) override
 | |
|             {
 | |
|                 MWWorld::Ptr ptr = R()(runtime);
 | |
|                 MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
 | |
| 
 | |
|                 int arg = runtime[0].mInteger;
 | |
|                 runtime.pop();
 | |
|                 stats.getMagicEffects().modifyBase(mPositiveEffect, arg);
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         struct MagicEffect
 | |
|         {
 | |
|             int mPositiveEffect;
 | |
|             int mNegativeEffect;
 | |
|         };
 | |
| 
 | |
|         void installOpcodes (Interpreter::Interpreter& interpreter)
 | |
|         {
 | |
|             for (int i=0; i<Compiler::Stats::numberOfAttributes; ++i)
 | |
|             {
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeGetAttribute+i, new OpGetAttribute<ImplicitRef> (i));
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeGetAttributeExplicit+i,
 | |
|                     new OpGetAttribute<ExplicitRef> (i));
 | |
| 
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeSetAttribute+i, new OpSetAttribute<ImplicitRef> (i));
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeSetAttributeExplicit+i,
 | |
|                     new OpSetAttribute<ExplicitRef> (i));
 | |
| 
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeModAttribute+i, new OpModAttribute<ImplicitRef> (i));
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeModAttributeExplicit+i,
 | |
|                     new OpModAttribute<ExplicitRef> (i));
 | |
|             }
 | |
| 
 | |
|             for (int i=0; i<Compiler::Stats::numberOfDynamics; ++i)
 | |
|             {
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeGetDynamic+i, new OpGetDynamic<ImplicitRef> (i));
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeGetDynamicExplicit+i,
 | |
|                     new OpGetDynamic<ExplicitRef> (i));
 | |
| 
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeSetDynamic+i, new OpSetDynamic<ImplicitRef> (i));
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeSetDynamicExplicit+i,
 | |
|                     new OpSetDynamic<ExplicitRef> (i));
 | |
| 
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeModDynamic+i, new OpModDynamic<ImplicitRef> (i));
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeModDynamicExplicit+i,
 | |
|                     new OpModDynamic<ExplicitRef> (i));
 | |
| 
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeModCurrentDynamic+i,
 | |
|                     new OpModCurrentDynamic<ImplicitRef> (i));
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeModCurrentDynamicExplicit+i,
 | |
|                     new OpModCurrentDynamic<ExplicitRef> (i));
 | |
| 
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeGetDynamicGetRatio+i,
 | |
|                     new OpGetDynamicGetRatio<ImplicitRef> (i));
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeGetDynamicGetRatioExplicit+i,
 | |
|                     new OpGetDynamicGetRatio<ExplicitRef> (i));
 | |
|             }
 | |
| 
 | |
|             for (int i=0; i<Compiler::Stats::numberOfSkills; ++i)
 | |
|             {
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeGetSkill+i, new OpGetSkill<ImplicitRef> (i));
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeGetSkillExplicit+i, new OpGetSkill<ExplicitRef> (i));
 | |
| 
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeSetSkill+i, new OpSetSkill<ImplicitRef> (i));
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeSetSkillExplicit+i, new OpSetSkill<ExplicitRef> (i));
 | |
| 
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeModSkill+i, new OpModSkill<ImplicitRef> (i));
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeModSkillExplicit+i, new OpModSkill<ExplicitRef> (i));
 | |
|             }
 | |
| 
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeGetPCCrimeLevel, new OpGetPCCrimeLevel);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeSetPCCrimeLevel, new OpSetPCCrimeLevel);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeModPCCrimeLevel, new OpModPCCrimeLevel);
 | |
| 
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeAddSpell, new OpAddSpell<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeAddSpellExplicit, new OpAddSpell<ExplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeRemoveSpell, new OpRemoveSpell<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeRemoveSpellExplicit,
 | |
|                 new OpRemoveSpell<ExplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeRemoveSpellEffects, new OpRemoveSpellEffects<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeRemoveSpellEffectsExplicit,
 | |
|                 new OpRemoveSpellEffects<ExplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeResurrect, new OpResurrect<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeResurrectExplicit,
 | |
|                 new OpResurrect<ExplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeRemoveEffects, new OpRemoveEffects<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeRemoveEffectsExplicit,
 | |
|                 new OpRemoveEffects<ExplicitRef>);
 | |
| 
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeGetSpell, new OpGetSpell<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeGetSpellExplicit, new OpGetSpell<ExplicitRef>);
 | |
| 
 | |
|             interpreter.installSegment3(Compiler::Stats::opcodePCRaiseRank,new OpPCRaiseRank<ImplicitRef>);
 | |
|             interpreter.installSegment3(Compiler::Stats::opcodePCLowerRank,new OpPCLowerRank<ImplicitRef>);
 | |
|             interpreter.installSegment3(Compiler::Stats::opcodePCJoinFaction,new OpPCJoinFaction<ImplicitRef>);
 | |
|             interpreter.installSegment3(Compiler::Stats::opcodePCRaiseRankExplicit,new OpPCRaiseRank<ExplicitRef>);
 | |
|             interpreter.installSegment3(Compiler::Stats::opcodePCLowerRankExplicit,new OpPCLowerRank<ExplicitRef>);
 | |
|             interpreter.installSegment3(Compiler::Stats::opcodePCJoinFactionExplicit,new OpPCJoinFaction<ExplicitRef>);
 | |
|             interpreter.installSegment3(Compiler::Stats::opcodeGetPCRank,new OpGetPCRank<ImplicitRef>);
 | |
|             interpreter.installSegment3(Compiler::Stats::opcodeGetPCRankExplicit,new OpGetPCRank<ExplicitRef>);
 | |
| 
 | |
|             interpreter.installSegment5(Compiler::Stats::opcodeModDisposition,new OpModDisposition<ImplicitRef>);
 | |
|             interpreter.installSegment5(Compiler::Stats::opcodeModDispositionExplicit,new OpModDisposition<ExplicitRef>);
 | |
|             interpreter.installSegment5(Compiler::Stats::opcodeSetDisposition,new OpSetDisposition<ImplicitRef>);
 | |
|             interpreter.installSegment5(Compiler::Stats::opcodeSetDispositionExplicit,new OpSetDisposition<ExplicitRef>);
 | |
|             interpreter.installSegment5(Compiler::Stats::opcodeGetDisposition,new OpGetDisposition<ImplicitRef>);
 | |
|             interpreter.installSegment5(Compiler::Stats::opcodeGetDispositionExplicit,new OpGetDisposition<ExplicitRef>);
 | |
| 
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeGetLevel, new OpGetLevel<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeGetLevelExplicit, new OpGetLevel<ExplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeSetLevel, new OpSetLevel<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeSetLevelExplicit, new OpSetLevel<ExplicitRef>);
 | |
| 
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeGetDeadCount, new OpGetDeadCount);
 | |
| 
 | |
|             interpreter.installSegment3 (Compiler::Stats::opcodeGetPCFacRep, new OpGetPCFacRep<ImplicitRef>);
 | |
|             interpreter.installSegment3 (Compiler::Stats::opcodeGetPCFacRepExplicit, new OpGetPCFacRep<ExplicitRef>);
 | |
|             interpreter.installSegment3 (Compiler::Stats::opcodeSetPCFacRep, new OpSetPCFacRep<ImplicitRef>);
 | |
|             interpreter.installSegment3 (Compiler::Stats::opcodeSetPCFacRepExplicit, new OpSetPCFacRep<ExplicitRef>);
 | |
|             interpreter.installSegment3 (Compiler::Stats::opcodeModPCFacRep, new OpModPCFacRep<ImplicitRef>);
 | |
|             interpreter.installSegment3 (Compiler::Stats::opcodeModPCFacRepExplicit, new OpModPCFacRep<ExplicitRef>);
 | |
| 
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeGetCommonDisease, new OpGetCommonDisease<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeGetCommonDiseaseExplicit, new OpGetCommonDisease<ExplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeGetBlightDisease, new OpGetBlightDisease<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeGetBlightDiseaseExplicit, new OpGetBlightDisease<ExplicitRef>);
 | |
| 
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeGetRace, new OpGetRace<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeGetRaceExplicit, new OpGetRace<ExplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeGetWerewolfKills, new OpGetWerewolfKills);
 | |
| 
 | |
|             interpreter.installSegment3 (Compiler::Stats::opcodePcExpelled, new OpPcExpelled<ImplicitRef>);
 | |
|             interpreter.installSegment3 (Compiler::Stats::opcodePcExpelledExplicit, new OpPcExpelled<ExplicitRef>);
 | |
|             interpreter.installSegment3 (Compiler::Stats::opcodePcExpell, new OpPcExpell<ImplicitRef>);
 | |
|             interpreter.installSegment3 (Compiler::Stats::opcodePcExpellExplicit, new OpPcExpell<ExplicitRef>);
 | |
|             interpreter.installSegment3 (Compiler::Stats::opcodePcClearExpelled, new OpPcClearExpelled<ImplicitRef>);
 | |
|             interpreter.installSegment3 (Compiler::Stats::opcodePcClearExpelledExplicit, new OpPcClearExpelled<ExplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeRaiseRank, new OpRaiseRank<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeRaiseRankExplicit, new OpRaiseRank<ExplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeLowerRank, new OpLowerRank<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeLowerRankExplicit, new OpLowerRank<ExplicitRef>);
 | |
| 
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeOnDeath, new OpOnDeath<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeOnDeathExplicit, new OpOnDeath<ExplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeOnMurder, new OpOnMurder<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeOnMurderExplicit, new OpOnMurder<ExplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeOnKnockout, new OpOnKnockout<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeOnKnockoutExplicit, new OpOnKnockout<ExplicitRef>);
 | |
| 
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeIsWerewolf, new OpIsWerewolf<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeIsWerewolfExplicit, new OpIsWerewolf<ExplicitRef>);
 | |
| 
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeBecomeWerewolf, new OpSetWerewolf<ImplicitRef, true>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeBecomeWerewolfExplicit, new OpSetWerewolf<ExplicitRef, true>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeUndoWerewolf, new OpSetWerewolf<ImplicitRef, false>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeUndoWerewolfExplicit, new OpSetWerewolf<ExplicitRef, false>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeSetWerewolfAcrobatics, new OpSetWerewolfAcrobatics<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeSetWerewolfAcrobaticsExplicit, new OpSetWerewolfAcrobatics<ExplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeGetStat, new OpGetStat<ImplicitRef>);
 | |
|             interpreter.installSegment5 (Compiler::Stats::opcodeGetStatExplicit, new OpGetStat<ExplicitRef>);
 | |
| 
 | |
|             static const MagicEffect sMagicEffects[] = {
 | |
|                 { ESM::MagicEffect::ResistMagicka, ESM::MagicEffect::WeaknessToMagicka },
 | |
|                 { ESM::MagicEffect::ResistFire, ESM::MagicEffect::WeaknessToFire },
 | |
|                 { ESM::MagicEffect::ResistFrost, ESM::MagicEffect::WeaknessToFrost },
 | |
|                 { ESM::MagicEffect::ResistShock, ESM::MagicEffect::WeaknessToShock },
 | |
|                 { ESM::MagicEffect::ResistCommonDisease, ESM::MagicEffect::WeaknessToCommonDisease },
 | |
|                 { ESM::MagicEffect::ResistBlightDisease, ESM::MagicEffect::WeaknessToBlightDisease },
 | |
|                 { ESM::MagicEffect::ResistCorprusDisease, ESM::MagicEffect::WeaknessToCorprusDisease },
 | |
|                 { ESM::MagicEffect::ResistPoison, ESM::MagicEffect::WeaknessToPoison },
 | |
|                 { ESM::MagicEffect::ResistParalysis, -1 },
 | |
|                 { ESM::MagicEffect::ResistNormalWeapons, ESM::MagicEffect::WeaknessToNormalWeapons },
 | |
|                 { ESM::MagicEffect::WaterBreathing, -1 },
 | |
|                 { ESM::MagicEffect::Chameleon, -1 },
 | |
|                 { ESM::MagicEffect::WaterWalking, -1 },
 | |
|                 { ESM::MagicEffect::SwiftSwim, -1 },
 | |
|                 { ESM::MagicEffect::Jump, -1 },
 | |
|                 { ESM::MagicEffect::Levitate, -1 },
 | |
|                 { ESM::MagicEffect::Shield, -1 },
 | |
|                 { ESM::MagicEffect::Sound, -1 },
 | |
|                 { ESM::MagicEffect::Silence, -1 },
 | |
|                 { ESM::MagicEffect::Blind, -1 },
 | |
|                 { ESM::MagicEffect::Paralyze, -1 },
 | |
|                 { ESM::MagicEffect::Invisibility, -1 },
 | |
|                 { ESM::MagicEffect::FortifyAttack, -1 },
 | |
|                 { ESM::MagicEffect::Sanctuary, -1 },
 | |
|             };
 | |
| 
 | |
|             for (int i=0; i<24; ++i)
 | |
|             {
 | |
|                 int positive = sMagicEffects[i].mPositiveEffect;
 | |
|                 int negative = sMagicEffects[i].mNegativeEffect;
 | |
| 
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeGetMagicEffect+i, new OpGetMagicEffect<ImplicitRef> (positive, negative));
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeGetMagicEffectExplicit+i, new OpGetMagicEffect<ExplicitRef> (positive, negative));
 | |
| 
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeSetMagicEffect+i, new OpSetMagicEffect<ImplicitRef> (positive, negative));
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeSetMagicEffectExplicit+i, new OpSetMagicEffect<ExplicitRef> (positive, negative));
 | |
| 
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeModMagicEffect+i, new OpModMagicEffect<ImplicitRef> (positive, negative));
 | |
|                 interpreter.installSegment5 (Compiler::Stats::opcodeModMagicEffectExplicit+i, new OpModMagicEffect<ExplicitRef> (positive, negative));
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |