mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 20:26:43 +00:00 
			
		
		
		
	added get-, set- and mod-instructions for attributes
This commit is contained in:
		
							parent
							
								
									25e720cf65
								
							
						
					
					
						commit
						3f8c8c33f5
					
				
					 8 changed files with 279 additions and 6 deletions
				
			
		|  | @ -50,6 +50,7 @@ set(GAMESCRIPT | |||
|     mwscript/guiextensions.cpp | ||||
|     mwscript/soundextensions.cpp | ||||
|     mwscript/skyextensions.cpp | ||||
|     mwscript/statsextensions.cpp | ||||
|     mwscript/extensions.cpp | ||||
|     mwscript/globalscripts.cpp | ||||
|     ) | ||||
|  | @ -63,6 +64,7 @@ set(GAMESCRIPT_HEADER | |||
|     mwscript/guiextensions.hpp | ||||
|     mwscript/soundextensions.hpp | ||||
|     mwscript/skyextensions.hpp | ||||
|     mwscript/statsextensions.hpp | ||||
|     mwscript/extensions.hpp | ||||
|     mwscript/globalscripts.hpp | ||||
|     ) | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| #ifndef GAME_MWMECHANICS_STAT_H | ||||
| #define GAME_MWMECHANICS_STAT_H | ||||
| 
 | ||||
| #include <limits> | ||||
| 
 | ||||
| namespace MWMechanics | ||||
| { | ||||
|     template<typename T> | ||||
|  | @ -37,6 +39,26 @@ namespace MWMechanics | |||
|                 mModified += diff; | ||||
|             } | ||||
|              | ||||
|             /// Set modified value an adjust base accordingly.
 | ||||
|             void setModified (T value, const T& min, const T& max = std::numeric_limits<T>::max()) | ||||
|             { | ||||
|                 T diff = value - mModified; | ||||
|                  | ||||
|                 if (mBase+diff<min) | ||||
|                 { | ||||
|                     value = min + (mModified - mBase); | ||||
|                     diff = value - mModified; | ||||
|                 } | ||||
|                 else if (mBase>max-diff) | ||||
|                 { | ||||
|                     value = max + (mModified - mBase); | ||||
|                     diff = value - mModified; | ||||
|                 } | ||||
|                  | ||||
|                 mModified = value; | ||||
|                 mBase += diff; | ||||
|             } | ||||
|              | ||||
|             /// Change modified relatively.
 | ||||
|             void modify (const T& diff) | ||||
|             { | ||||
|  |  | |||
|  | @ -60,5 +60,11 @@ op 0x2000023: TurnMoonRed | |||
| op 0x2000024: GetMasserPhase | ||||
| op 0x2000025: GetSecundaPhase | ||||
| op 0x2000026: COC | ||||
| opcodes 0x2000027-0x3ffffff unused | ||||
| op 0x2000027-0x200002e: GetAttribute | ||||
| op 0x200002f-0x2000036: GetAttribute, explicit reference | ||||
| op 0x2000037-0x200003e: SetAttribute | ||||
| op 0x200003f-0x2000046: SetAttribute, explicit reference | ||||
| op 0x2000047-0x200004e: ModAttribute | ||||
| op 0x200004f-0x2000056: ModAttribute, explicit reference | ||||
| opcodes 0x2000057-0x3ffffff unused | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ | |||
| #include "miscextensions.hpp" | ||||
| #include "guiextensions.hpp" | ||||
| #include "skyextensions.hpp" | ||||
| #include "statsextensions.hpp" | ||||
| 
 | ||||
| namespace MWScript | ||||
| { | ||||
|  | @ -19,6 +20,7 @@ namespace MWScript | |||
|         Gui::registerExtensions (extensions); | ||||
|         Sound::registerExtensions (extensions); | ||||
|         Sky::registerExtensions (extensions); | ||||
|         Stats::registerExtensions (extensions); | ||||
|     } | ||||
|      | ||||
|     void installOpcodes (Interpreter::Interpreter& interpreter) | ||||
|  | @ -29,6 +31,7 @@ namespace MWScript | |||
|         Gui::installOpcodes (interpreter); | ||||
|         Sound::installOpcodes (interpreter); | ||||
|         Sky::installOpcodes (interpreter); | ||||
|         Stats::installOpcodes (interpreter); | ||||
|     }     | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -242,7 +242,7 @@ namespace MWScript | |||
|      | ||||
|     MWWorld::Ptr InterpreterContext::getReference() | ||||
|     { | ||||
|         return mReference; | ||||
|         return getReference ("", true); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										211
									
								
								apps/openmw/mwscript/statsextensions.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								apps/openmw/mwscript/statsextensions.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,211 @@ | |||
| 
 | ||||
| #include "statsextensions.hpp" | ||||
| 
 | ||||
| #include <components/compiler/extensions.hpp> | ||||
| 
 | ||||
| #include <components/interpreter/interpreter.hpp> | ||||
| #include <components/interpreter/runtime.hpp> | ||||
| #include <components/interpreter/opcodes.hpp> | ||||
| 
 | ||||
| #include "interpretercontext.hpp" | ||||
| 
 | ||||
| namespace MWScript | ||||
| { | ||||
|     namespace Stats | ||||
|     { | ||||
|         class OpGetAttribute : public Interpreter::Opcode0 | ||||
|         { | ||||
|                 int mIndex; | ||||
|                  | ||||
|             public: | ||||
|   | ||||
|                 OpGetAttribute (int index) : mIndex (index) {} | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     Interpreter::Type_Integer value = | ||||
|                         context.getReference().getCreatureStats().mAttributes[mIndex]. | ||||
|                         getModified(); | ||||
|                          | ||||
|                     runtime.push (value); | ||||
|                 }  | ||||
|         };   | ||||
| 
 | ||||
|         class OpGetAttributeExplicit : public Interpreter::Opcode0 | ||||
|         { | ||||
|                 int mIndex; | ||||
|                  | ||||
|             public: | ||||
|   | ||||
|                 OpGetAttributeExplicit (int index) : mIndex (index) {} | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
| 
 | ||||
|                     std::string id = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                      | ||||
|                     Interpreter::Type_Integer value = | ||||
|                         context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex]. | ||||
|                         getModified(); | ||||
|                          | ||||
|                     runtime.push (value);                         | ||||
|                 }  | ||||
|         };   | ||||
|          | ||||
|         class OpSetAttribute : public Interpreter::Opcode0 | ||||
|         { | ||||
|                 int mIndex; | ||||
|                  | ||||
|             public: | ||||
|   | ||||
|                 OpSetAttribute (int index) : mIndex (index) {} | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     Interpreter::Type_Integer value = runtime[0].mInteger; | ||||
|                     runtime.pop(); | ||||
|                     | ||||
|                     context.getReference().getCreatureStats().mAttributes[mIndex]. | ||||
|                         setModified (value, 0); | ||||
|                 }  | ||||
|         };   | ||||
| 
 | ||||
|         class OpSetAttributeExplicit : public Interpreter::Opcode0 | ||||
|         { | ||||
|                 int mIndex; | ||||
|                  | ||||
|             public: | ||||
|   | ||||
|                 OpSetAttributeExplicit (int index) : mIndex (index) {} | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
| 
 | ||||
|                     std::string id = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     Interpreter::Type_Integer value = runtime[0].mInteger; | ||||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex]. | ||||
|                         setModified (value, 0); | ||||
|                 }  | ||||
|         }; | ||||
|             | ||||
|         class OpModAttribute : public Interpreter::Opcode0 | ||||
|         { | ||||
|                 int mIndex; | ||||
|                  | ||||
|             public: | ||||
|   | ||||
|                 OpModAttribute (int index) : mIndex (index) {} | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     Interpreter::Type_Integer value = runtime[0].mInteger; | ||||
|                     runtime.pop(); | ||||
|                      | ||||
|                     value += context.getReference().getCreatureStats().mAttributes[mIndex]. | ||||
|                         getModified(); | ||||
|                     | ||||
|                     context.getReference().getCreatureStats().mAttributes[mIndex]. | ||||
|                         setModified (value, 0, 100); | ||||
|                 }  | ||||
|         };   | ||||
| 
 | ||||
|         class OpModAttributeExplicit : public Interpreter::Opcode0 | ||||
|         { | ||||
|                 int mIndex; | ||||
|                  | ||||
|             public: | ||||
|   | ||||
|                 OpModAttributeExplicit (int index) : mIndex (index) {} | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
| 
 | ||||
|                     std::string id = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     Interpreter::Type_Integer value = runtime[0].mInteger; | ||||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     value += | ||||
|                         context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex]. | ||||
|                         getModified(); | ||||
| 
 | ||||
|                     context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex]. | ||||
|                         setModified (value, 0, 100);                     | ||||
|                 }  | ||||
|         };            | ||||
|                  | ||||
|         const int numberOfAttributes = 8; | ||||
| 
 | ||||
|         const int opcodeGetAttribute = 0x2000027; | ||||
|         const int opcodeGetAttributeExplicit = 0x200002f; | ||||
|         const int opcodeSetAttribute = 0x2000037; | ||||
|         const int opcodeSetAttributeExplicit = 0x200003f; | ||||
|         const int opcodeModAttribute = 0x2000047; | ||||
|         const int opcodeModAttributeExplicit = 0x200004f; | ||||
|          | ||||
|         void registerExtensions (Compiler::Extensions& extensions) | ||||
|         { | ||||
|             static const char *attributes[numberOfAttributes] = | ||||
|             { | ||||
|                 "strength", "intelligence", "willpower", "agility", "speed", "endurance", | ||||
|                 "personality", "luck" | ||||
|             }; | ||||
|          | ||||
|             std::string get ("get"); | ||||
|             std::string set ("set"); | ||||
|             std::string mod ("mod"); | ||||
|          | ||||
|             for (int i=0; i<numberOfAttributes; ++i) | ||||
|             { | ||||
|                 extensions.registerFunction (get + attributes[i], 'l', "", | ||||
|                     opcodeGetAttribute+i, opcodeGetAttributeExplicit+i); | ||||
| 
 | ||||
|                 extensions.registerInstruction (set + attributes[i], "l", | ||||
|                     opcodeSetAttribute+i, opcodeSetAttributeExplicit+i); | ||||
| 
 | ||||
|                 extensions.registerInstruction (mod + attributes[i], "l", | ||||
|                     opcodeModAttribute+i, opcodeModAttributeExplicit+i);                     | ||||
|             } | ||||
|         }         | ||||
|          | ||||
|         void installOpcodes (Interpreter::Interpreter& interpreter) | ||||
|         { | ||||
|             for (int i=0; i<numberOfAttributes; ++i) | ||||
|             { | ||||
|                 interpreter.installSegment5 (opcodeGetAttribute+i, new OpGetAttribute (i)); | ||||
|                 interpreter.installSegment5 (opcodeGetAttributeExplicit+i, | ||||
|                     new OpGetAttributeExplicit (i)); | ||||
|                  | ||||
|                 interpreter.installSegment5 (opcodeSetAttribute+i, new OpSetAttribute (i)); | ||||
|                 interpreter.installSegment5 (opcodeSetAttributeExplicit+i, | ||||
|                     new OpSetAttributeExplicit (i)); | ||||
|                  | ||||
|                 interpreter.installSegment5 (opcodeModAttribute+i, new OpModAttribute (i)); | ||||
|                 interpreter.installSegment5 (opcodeModAttributeExplicit+i, | ||||
|                     new OpModAttributeExplicit (i)); | ||||
|             } | ||||
|         }         | ||||
|     } | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										25
									
								
								apps/openmw/mwscript/statsextensions.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								apps/openmw/mwscript/statsextensions.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | |||
| #ifndef GAME_SCRIPT_STATSEXTENSIONS_H | ||||
| #define GAME_SCRIPT_STATSEXTENSIONS_H | ||||
| 
 | ||||
| namespace Compiler | ||||
| { | ||||
|     class Extensions; | ||||
| } | ||||
| 
 | ||||
| namespace Interpreter | ||||
| { | ||||
|     class Interpreter; | ||||
| } | ||||
| 
 | ||||
| namespace MWScript | ||||
| { | ||||
|     /// \brief stats-related script functionality (creatures and NPCs)
 | ||||
|     namespace Stats | ||||
|     { | ||||
|         void registerExtensions (Compiler::Extensions& extensions); | ||||
|          | ||||
|         void installOpcodes (Interpreter::Interpreter& interpreter); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | @ -79,8 +79,8 @@ namespace MWWorld | |||
|                 { | ||||
|                     if (mPtr.type()==typeid (ESMS::LiveCellRef<ESM::Creature, RefData> *)) | ||||
|                     { | ||||
|                         boost::shared_ptr<MWMechanics::CreatureStats> stats; | ||||
|                         data.getCreatureStats() = stats; | ||||
|                         boost::shared_ptr<MWMechanics::CreatureStats> stats ( | ||||
|                             new MWMechanics::CreatureStats); | ||||
|                      | ||||
|                         ESMS::LiveCellRef<ESM::Creature, RefData> *ref = get<ESM::Creature>(); | ||||
|                          | ||||
|  | @ -92,11 +92,13 @@ namespace MWWorld | |||
|                         stats->mAttributes[5].set (ref->base->data.endurance); | ||||
|                         stats->mAttributes[6].set (ref->base->data.personality); | ||||
|                         stats->mAttributes[7].set (ref->base->data.luck); | ||||
| 
 | ||||
|                         data.getCreatureStats() = stats; | ||||
|                     } | ||||
|                     else if (mPtr.type()==typeid (ESMS::LiveCellRef<ESM::NPC, RefData> *)) | ||||
|                     { | ||||
|                         boost::shared_ptr<MWMechanics::CreatureStats> stats; | ||||
|                         data.getCreatureStats() = stats; | ||||
|                         boost::shared_ptr<MWMechanics::CreatureStats> stats ( | ||||
|                             new MWMechanics::CreatureStats); | ||||
|                      | ||||
|                         ESMS::LiveCellRef<ESM::NPC, RefData> *ref = get<ESM::NPC>(); | ||||
|                          | ||||
|  | @ -108,6 +110,8 @@ namespace MWWorld | |||
|                         stats->mAttributes[5].set (ref->base->npdt52.endurance); | ||||
|                         stats->mAttributes[6].set (ref->base->npdt52.personality); | ||||
|                         stats->mAttributes[7].set (ref->base->npdt52.luck); | ||||
| 
 | ||||
|                         data.getCreatureStats() = stats; | ||||
|                     } | ||||
|                     else | ||||
|                         throw std::runtime_error ( | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue