mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-26 14:56:39 +00:00 
			
		
		
		
	Merge branch 'selected_spell' into 'master'
Lua commands getSelectedSpell/setSelectedSpell See merge request OpenMW/openmw!3018
This commit is contained in:
		
						commit
						41c9e3c449
					
				
					 3 changed files with 70 additions and 8 deletions
				
			
		|  | @ -9,10 +9,12 @@ | |||
| #include <components/resource/resourcesystem.hpp> | ||||
| 
 | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwbase/windowmanager.hpp" | ||||
| #include "../mwbase/world.hpp" | ||||
| #include "../mwmechanics/activespells.hpp" | ||||
| #include "../mwmechanics/creaturestats.hpp" | ||||
| #include "../mwmechanics/npcstats.hpp" | ||||
| #include "../mwmechanics/spellutil.hpp" | ||||
| #include "../mwworld/action.hpp" | ||||
| #include "../mwworld/class.hpp" | ||||
| #include "../mwworld/esmstore.hpp" | ||||
|  | @ -217,6 +219,13 @@ namespace MWLua | |||
| 
 | ||||
|     void addActorMagicBindings(sol::table& actor, const Context& context) | ||||
|     { | ||||
|         auto toSpellId = [](const sol::object& spellOrId) -> ESM::RefId { | ||||
|             if (spellOrId.is<ESM::Spell>()) | ||||
|                 return spellOrId.as<const ESM::Spell*>()->mId; | ||||
|             else | ||||
|                 return ESM::RefId::deserializeText(LuaUtil::cast<std::string_view>(spellOrId)); | ||||
|         }; | ||||
| 
 | ||||
|         const MWWorld::Store<ESM::Spell>* spellStore | ||||
|             = &MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>(); | ||||
| 
 | ||||
|  | @ -226,6 +235,52 @@ namespace MWLua | |||
|         spellsT[sol::meta_function::to_string] | ||||
|             = [](const ActorSpells& spells) { return "ActorSpells[" + spells.mActor.object().toString(); }; | ||||
| 
 | ||||
|         actor["getSelectedSpell"] = [spellStore](const Object& o) -> sol::optional<const ESM::Spell*> { | ||||
|             const MWWorld::Ptr& ptr = o.ptr(); | ||||
|             const MWWorld::Class& cls = ptr.getClass(); | ||||
|             if (!cls.isActor()) | ||||
|                 throw std::runtime_error("Actor expected"); | ||||
|             ESM::RefId spellId; | ||||
|             if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()) | ||||
|                 spellId = MWBase::Environment::get().getWindowManager()->getSelectedSpell(); | ||||
|             else | ||||
|                 spellId = cls.getCreatureStats(ptr).getSpells().getSelectedSpell(); | ||||
|             if (spellId.empty()) | ||||
|                 return sol::nullopt; | ||||
|             else | ||||
|                 return spellStore->find(spellId); | ||||
|         }; | ||||
|         actor["setSelectedSpell"] | ||||
|             = [context, spellStore, toSpellId](const SelfObject& o, const sol::object& spellOrId) { | ||||
|                   const MWWorld::Ptr& ptr = o.ptr(); | ||||
|                   const MWWorld::Class& cls = ptr.getClass(); | ||||
|                   if (!cls.isActor()) | ||||
|                       throw std::runtime_error("Actor expected"); | ||||
|                   ESM::RefId spellId; | ||||
|                   if (spellOrId != sol::nil) | ||||
|                   { | ||||
|                       spellId = toSpellId(spellOrId); | ||||
|                       const ESM::Spell* spell = spellStore->find(spellId); | ||||
|                       if (spell->mData.mType != ESM::Spell::ST_Spell && spell->mData.mType != ESM::Spell::ST_Power) | ||||
|                           throw std::runtime_error("Ability or disease can not be casted: " + spellId.toDebugString()); | ||||
|                   } | ||||
|                   context.mLuaManager->addAction([obj = Object(ptr), spellId]() { | ||||
|                       const MWWorld::Ptr& ptr = obj.ptr(); | ||||
|                       auto& stats = ptr.getClass().getCreatureStats(ptr); | ||||
|                       if (!stats.getSpells().hasSpell(spellId)) | ||||
|                           throw std::runtime_error("Actor doesn't know spell " + spellId.toDebugString()); | ||||
|                       if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()) | ||||
|                       { | ||||
|                           int chance = 0; | ||||
|                           if (!spellId.empty()) | ||||
|                               chance = MWMechanics::getSpellSuccessChance(spellId, ptr); | ||||
|                           MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, chance); | ||||
|                       } | ||||
|                       else | ||||
|                           ptr.getClass().getCreatureStats(ptr).getSpells().setSelectedSpell(spellId); | ||||
|                   }); | ||||
|               }; | ||||
| 
 | ||||
|         // #(types.Actor.spells(o))
 | ||||
|         spellsT[sol::meta_function::length] = [](const ActorSpells& spells) -> size_t { | ||||
|             const MWWorld::Ptr& ptr = spells.mActor.ptr(); | ||||
|  | @ -253,13 +308,6 @@ namespace MWLua | |||
|         // ipairs(types.Actor.spells(o))
 | ||||
|         spellsT[sol::meta_function::ipairs] = context.mLua->sol()["ipairsForArray"].template get<sol::function>(); | ||||
| 
 | ||||
|         auto toSpellId = [](const sol::object& spellOrId) -> ESM::RefId { | ||||
|             if (spellOrId.is<ESM::Spell>()) | ||||
|                 return spellOrId.as<const ESM::Spell*>()->mId; | ||||
|             else | ||||
|                 return ESM::RefId::deserializeText(LuaUtil::cast<std::string_view>(spellOrId)); | ||||
|         }; | ||||
| 
 | ||||
|         // types.Actor.spells(o):add(id)
 | ||||
|         spellsT["add"] = [context, toSpellId](const ActorSpells& spells, const sol::object& spellOrId) { | ||||
|             if (spells.mActor.isLObject()) | ||||
|  |  | |||
|  | @ -5,7 +5,6 @@ | |||
| 
 | ||||
| #include <apps/openmw/mwbase/mechanicsmanager.hpp> | ||||
| #include <apps/openmw/mwbase/windowmanager.hpp> | ||||
| #include <apps/openmw/mwlua/luabindings.hpp> | ||||
| #include <apps/openmw/mwmechanics/creaturestats.hpp> | ||||
| #include <apps/openmw/mwmechanics/drawstate.hpp> | ||||
| #include <apps/openmw/mwworld/class.hpp> | ||||
|  | @ -174,6 +173,9 @@ namespace MWLua | |||
|             stats.setDrawState(newDrawState); | ||||
|         }; | ||||
| 
 | ||||
|         // TODO
 | ||||
|         // getSelectedEnchantedItem, setSelectedEnchantedItem
 | ||||
| 
 | ||||
|         actor["canMove"] = [](const Object& o) { | ||||
|             const MWWorld::Class& cls = o.ptr().getClass(); | ||||
|             return cls.getMaxSpeed(o.ptr()) > 0; | ||||
|  |  | |||
|  | @ -149,6 +149,18 @@ | |||
| -- local Actor = require('openmw.types').Actor | ||||
| -- Actor.setEquipment(self, {}) -- unequip all | ||||
| 
 | ||||
| --- | ||||
| -- Get currently selected spell | ||||
| -- @function [parent=#Actor] getSelectedSpell | ||||
| -- @param openmw.core#GameObject actor | ||||
| -- @return openmw.core#Spell, nil | ||||
| 
 | ||||
| --- | ||||
| -- Set selected spell | ||||
| -- @function [parent=#Actor] setSelectedSpell | ||||
| -- @param openmw.core#GameObject actor | ||||
| -- @param openmw.core#Spell spell Spell (can be nil) | ||||
| 
 | ||||
| --- | ||||
| -- Return the spells (@{ActorSpells}) of the given actor. | ||||
| -- @function [parent=#Actor] spells | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue