mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 10:56:42 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			265 lines
		
	
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			265 lines
		
	
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#ifndef INTERPRETER_MISCOPCODES_H_INCLUDED
 | 
						|
#define INTERPRETER_MISCOPCODES_H_INCLUDED
 | 
						|
 | 
						|
#include <cstdlib>
 | 
						|
#include <stdexcept>
 | 
						|
#include <vector>
 | 
						|
#include <string>
 | 
						|
#include <sstream>
 | 
						|
#include <algorithm>
 | 
						|
 | 
						|
#include "opcodes.hpp"
 | 
						|
#include "runtime.hpp"
 | 
						|
#include "defines.hpp"
 | 
						|
 | 
						|
#include <components/misc/rng.hpp>
 | 
						|
#include <components/misc/messageformatparser.hpp>
 | 
						|
 | 
						|
namespace Interpreter
 | 
						|
{
 | 
						|
    class RuntimeMessageFormatter : public Misc::MessageFormatParser
 | 
						|
    {
 | 
						|
        private:
 | 
						|
            std::string mFormattedMessage;
 | 
						|
            Runtime& mRuntime;
 | 
						|
 | 
						|
        protected:
 | 
						|
            virtual void visitedPlaceholder(Placeholder placeholder, char padding, int width, int precision)
 | 
						|
            {
 | 
						|
                std::ostringstream out;
 | 
						|
                out.fill(padding);
 | 
						|
                if (width != -1)
 | 
						|
                    out.width(width);
 | 
						|
                if (precision != -1)
 | 
						|
                    out.precision(precision);
 | 
						|
 | 
						|
                switch (placeholder)
 | 
						|
                {
 | 
						|
                    case StringPlaceholder:
 | 
						|
                        {
 | 
						|
                            int index = mRuntime[0].mInteger;
 | 
						|
                            mRuntime.pop();
 | 
						|
 | 
						|
                            out << mRuntime.getStringLiteral(index);
 | 
						|
                            mFormattedMessage += out.str();
 | 
						|
                        }
 | 
						|
                        break;
 | 
						|
                    case IntegerPlaceholder:
 | 
						|
                        {
 | 
						|
                            Type_Integer value = mRuntime[0].mInteger;
 | 
						|
                            mRuntime.pop();
 | 
						|
 | 
						|
                            out << value;
 | 
						|
                            mFormattedMessage += out.str();
 | 
						|
                        }
 | 
						|
                        break;
 | 
						|
                    case FloatPlaceholder:
 | 
						|
                        {
 | 
						|
                            float value = mRuntime[0].mFloat;
 | 
						|
                            mRuntime.pop();
 | 
						|
 | 
						|
                            out << std::fixed << value;
 | 
						|
                            mFormattedMessage += out.str();
 | 
						|
                        }
 | 
						|
                        break;
 | 
						|
                    default:
 | 
						|
                        break;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            virtual void visitedCharacter(char c)
 | 
						|
            {
 | 
						|
                mFormattedMessage += c;
 | 
						|
            }
 | 
						|
 | 
						|
        public:
 | 
						|
            RuntimeMessageFormatter(Runtime& runtime)
 | 
						|
                : mRuntime(runtime)
 | 
						|
            {
 | 
						|
            }
 | 
						|
 | 
						|
            virtual void process(const std::string& message)
 | 
						|
            {
 | 
						|
                mFormattedMessage.clear();
 | 
						|
                MessageFormatParser::process(message);
 | 
						|
            }
 | 
						|
 | 
						|
            std::string getFormattedMessage() const
 | 
						|
            {
 | 
						|
                return mFormattedMessage;
 | 
						|
            }
 | 
						|
    };
 | 
						|
 | 
						|
    inline std::string formatMessage (const std::string& message, Runtime& runtime)
 | 
						|
    {
 | 
						|
        RuntimeMessageFormatter formatter(runtime);
 | 
						|
        formatter.process(message);
 | 
						|
 | 
						|
        std::string formattedMessage = formatter.getFormattedMessage();
 | 
						|
        formattedMessage = fixDefinesMsgBox(formattedMessage, runtime.getContext());
 | 
						|
        return formattedMessage;
 | 
						|
    }
 | 
						|
 | 
						|
    class OpMessageBox : public Opcode1
 | 
						|
    {
 | 
						|
        public:
 | 
						|
 | 
						|
            virtual void execute (Runtime& runtime, unsigned int arg0)
 | 
						|
            {
 | 
						|
                // message
 | 
						|
                int index = runtime[0].mInteger;
 | 
						|
                runtime.pop();
 | 
						|
                std::string message = runtime.getStringLiteral (index);
 | 
						|
 | 
						|
                // buttons
 | 
						|
                std::vector<std::string> buttons;
 | 
						|
 | 
						|
                for (std::size_t i=0; i<arg0; ++i)
 | 
						|
                {
 | 
						|
                    int index = runtime[0].mInteger;
 | 
						|
                    runtime.pop();
 | 
						|
                    buttons.push_back (runtime.getStringLiteral (index));
 | 
						|
                }
 | 
						|
 | 
						|
                std::reverse (buttons.begin(), buttons.end());
 | 
						|
 | 
						|
                // handle additional parameters
 | 
						|
                std::string formattedMessage = formatMessage (message, runtime);
 | 
						|
 | 
						|
                runtime.getContext().messageBox (formattedMessage, buttons);
 | 
						|
            }
 | 
						|
    };
 | 
						|
 | 
						|
    class OpReport : public Opcode0
 | 
						|
    {
 | 
						|
        public:
 | 
						|
 | 
						|
            virtual void execute (Runtime& runtime)
 | 
						|
            {
 | 
						|
                // message
 | 
						|
                int index = runtime[0].mInteger;
 | 
						|
                runtime.pop();
 | 
						|
                std::string message = runtime.getStringLiteral (index);
 | 
						|
 | 
						|
                // handle additional parameters
 | 
						|
                std::string formattedMessage = formatMessage (message, runtime);
 | 
						|
 | 
						|
                runtime.getContext().report (formattedMessage);
 | 
						|
            }
 | 
						|
    };
 | 
						|
 | 
						|
    class OpMenuMode : public Opcode0
 | 
						|
    {
 | 
						|
        public:
 | 
						|
 | 
						|
            virtual void execute (Runtime& runtime)
 | 
						|
            {
 | 
						|
                runtime.push (runtime.getContext().menuMode());
 | 
						|
            }
 | 
						|
    };
 | 
						|
 | 
						|
    class OpRandom : public Opcode0
 | 
						|
    {
 | 
						|
        public:
 | 
						|
 | 
						|
            virtual void execute (Runtime& runtime)
 | 
						|
            {
 | 
						|
                Type_Integer limit = runtime[0].mInteger;
 | 
						|
 | 
						|
                if (limit<0)
 | 
						|
                    throw std::runtime_error (
 | 
						|
                        "random: argument out of range (Don't be so negative!)");
 | 
						|
 | 
						|
                Type_Integer value = Misc::Rng::rollDice(limit); // [o, limit)
 | 
						|
 | 
						|
                runtime[0].mInteger = value;
 | 
						|
            }
 | 
						|
    };
 | 
						|
 | 
						|
    class OpGetSecondsPassed : public Opcode0
 | 
						|
    {
 | 
						|
        public:
 | 
						|
 | 
						|
            virtual void execute (Runtime& runtime)
 | 
						|
            {
 | 
						|
                Type_Float duration = runtime.getContext().getSecondsPassed();
 | 
						|
 | 
						|
                runtime.push (duration);
 | 
						|
            }
 | 
						|
    };
 | 
						|
 | 
						|
    class OpEnable : public Opcode0
 | 
						|
    {
 | 
						|
        public:
 | 
						|
 | 
						|
            virtual void execute (Runtime& runtime)
 | 
						|
            {
 | 
						|
                runtime.getContext().enable();
 | 
						|
            }
 | 
						|
    };
 | 
						|
 | 
						|
    class OpDisable : public Opcode0
 | 
						|
    {
 | 
						|
        public:
 | 
						|
 | 
						|
            virtual void execute (Runtime& runtime)
 | 
						|
            {
 | 
						|
                runtime.getContext().disable();
 | 
						|
            }
 | 
						|
    };
 | 
						|
 | 
						|
    class OpGetDisabled : public Opcode0
 | 
						|
    {
 | 
						|
        public:
 | 
						|
 | 
						|
            virtual void execute (Runtime& runtime)
 | 
						|
            {
 | 
						|
                runtime.push (runtime.getContext().isDisabled());
 | 
						|
            }
 | 
						|
    };
 | 
						|
 | 
						|
    class OpEnableExplicit : public Opcode0
 | 
						|
    {
 | 
						|
        public:
 | 
						|
 | 
						|
            virtual void execute (Runtime& runtime)
 | 
						|
            {
 | 
						|
                int index = runtime[0].mInteger;
 | 
						|
                runtime.pop();
 | 
						|
                std::string id = runtime.getStringLiteral (index);
 | 
						|
 | 
						|
                runtime.getContext().enable (id);
 | 
						|
            }
 | 
						|
    };
 | 
						|
 | 
						|
    class OpDisableExplicit : public Opcode0
 | 
						|
    {
 | 
						|
        public:
 | 
						|
 | 
						|
            virtual void execute (Runtime& runtime)
 | 
						|
            {
 | 
						|
                int index = runtime[0].mInteger;
 | 
						|
                runtime.pop();
 | 
						|
                std::string id = runtime.getStringLiteral (index);
 | 
						|
 | 
						|
                runtime.getContext().disable (id);
 | 
						|
            }
 | 
						|
    };
 | 
						|
 | 
						|
    class OpGetDisabledExplicit : public Opcode0
 | 
						|
    {
 | 
						|
        public:
 | 
						|
 | 
						|
            virtual void execute (Runtime& runtime)
 | 
						|
            {
 | 
						|
                int index = runtime[0].mInteger;
 | 
						|
                runtime.pop();
 | 
						|
                std::string id = runtime.getStringLiteral (index);
 | 
						|
 | 
						|
                runtime.push (runtime.getContext().isDisabled (id));
 | 
						|
            }
 | 
						|
    };
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |