1 #include "controlextensions.hpp"
2 
3 #include <components/compiler/opcodes.hpp>
4 
5 #include <components/interpreter/interpreter.hpp>
6 #include <components/interpreter/runtime.hpp>
7 #include <components/interpreter/opcodes.hpp>
8 
9 #include "../mwbase/environment.hpp"
10 #include "../mwbase/inputmanager.hpp"
11 #include "../mwbase/mechanicsmanager.hpp"
12 #include "../mwbase/world.hpp"
13 
14 #include "../mwworld/class.hpp"
15 #include "../mwworld/ptr.hpp"
16 
17 #include "interpretercontext.hpp"
18 #include "ref.hpp"
19 
20 namespace MWScript
21 {
22     namespace Control
23     {
24         class OpSetControl : public Interpreter::Opcode0
25         {
26                 std::string mControl;
27                 bool mEnable;
28 
29             public:
30 
OpSetControl(const std::string & control,bool enable)31                 OpSetControl (const std::string& control, bool enable)
32                 : mControl (control), mEnable (enable)
33                 {}
34 
execute(Interpreter::Runtime & runtime)35                 void execute (Interpreter::Runtime& runtime) override
36                 {
37                     MWBase::Environment::get()
38                         .getInputManager()
39                         ->toggleControlSwitch(mControl, mEnable);
40                 }
41         };
42 
43         class OpGetDisabled : public Interpreter::Opcode0
44         {
45                 std::string mControl;
46 
47             public:
48 
OpGetDisabled(const std::string & control)49                 OpGetDisabled (const std::string& control)
50                 : mControl (control)
51                 {}
52 
execute(Interpreter::Runtime & runtime)53                 void execute (Interpreter::Runtime& runtime) override
54                 {
55                     runtime.push(!MWBase::Environment::get().getInputManager()->getControlSwitch (mControl));
56                 }
57         };
58 
59         class OpToggleCollision : public Interpreter::Opcode0
60         {
61             public:
62 
execute(Interpreter::Runtime & runtime)63                 void execute (Interpreter::Runtime& runtime) override
64                 {
65                     bool enabled = MWBase::Environment::get().getWorld()->toggleCollisionMode();
66 
67                     runtime.getContext().report (enabled ? "Collision -> On" : "Collision -> Off");
68                 }
69         };
70 
71         template<class R>
72         class OpClearMovementFlag : public Interpreter::Opcode0
73         {
74                 MWMechanics::CreatureStats::Flag mFlag;
75 
76             public:
77 
OpClearMovementFlag(MWMechanics::CreatureStats::Flag flag)78                 OpClearMovementFlag (MWMechanics::CreatureStats::Flag flag) : mFlag (flag) {}
79 
execute(Interpreter::Runtime & runtime)80                 void execute (Interpreter::Runtime& runtime) override
81                 {
82                     MWWorld::Ptr ptr = R()(runtime);
83 
84                     ptr.getClass().getCreatureStats(ptr).setMovementFlag (mFlag, false);
85                 }
86         };
87 
88         template<class R>
89         class OpSetMovementFlag : public Interpreter::Opcode0
90         {
91                 MWMechanics::CreatureStats::Flag mFlag;
92 
93             public:
94 
OpSetMovementFlag(MWMechanics::CreatureStats::Flag flag)95                 OpSetMovementFlag (MWMechanics::CreatureStats::Flag flag) : mFlag (flag) {}
96 
execute(Interpreter::Runtime & runtime)97                 void execute (Interpreter::Runtime& runtime) override
98                 {
99                     MWWorld::Ptr ptr = R()(runtime);
100 
101                     ptr.getClass().getCreatureStats(ptr).setMovementFlag (mFlag, true);
102                 }
103         };
104 
105         template <class R>
106         class OpGetForceRun : public Interpreter::Opcode0
107         {
108             public:
109 
execute(Interpreter::Runtime & runtime)110                 void execute (Interpreter::Runtime& runtime) override
111                 {
112                     MWWorld::Ptr ptr = R()(runtime);
113 
114                     MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr);
115                     runtime.push (stats.getMovementFlag (MWMechanics::CreatureStats::Flag_ForceRun));
116                 }
117         };
118 
119         template <class R>
120         class OpGetForceJump : public Interpreter::Opcode0
121         {
122             public:
123 
execute(Interpreter::Runtime & runtime)124                 void execute (Interpreter::Runtime& runtime) override
125                 {
126                     MWWorld::Ptr ptr = R()(runtime);
127 
128                     MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr);
129                     runtime.push (stats.getMovementFlag (MWMechanics::CreatureStats::Flag_ForceJump));
130                 }
131         };
132 
133         template <class R>
134         class OpGetForceMoveJump : public Interpreter::Opcode0
135         {
136             public:
137 
execute(Interpreter::Runtime & runtime)138                 void execute (Interpreter::Runtime& runtime) override
139                 {
140                     MWWorld::Ptr ptr = R()(runtime);
141 
142                     MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr);
143                     runtime.push (stats.getMovementFlag (MWMechanics::CreatureStats::Flag_ForceMoveJump));
144                 }
145         };
146 
147         template <class R>
148         class OpGetForceSneak : public Interpreter::Opcode0
149         {
150             public:
151 
execute(Interpreter::Runtime & runtime)152                 void execute (Interpreter::Runtime& runtime) override
153                 {
154                     MWWorld::Ptr ptr = R()(runtime);
155 
156                     MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
157                     runtime.push (stats.getMovementFlag (MWMechanics::CreatureStats::Flag_ForceSneak));
158                 }
159         };
160 
161         class OpGetPcRunning : public Interpreter::Opcode0
162         {
163             public:
164 
execute(Interpreter::Runtime & runtime)165                 void execute (Interpreter::Runtime& runtime) override
166                 {
167                     MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayerPtr();
168                     MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
169                     MWBase::World* world = MWBase::Environment::get().getWorld();
170 
171                     bool stanceOn = stats.getStance(MWMechanics::CreatureStats::Stance_Run);
172                     bool running = MWBase::Environment::get().getMechanicsManager()->isRunning(ptr);
173                     bool inair = !world->isOnGround(ptr) && !world->isSwimming(ptr) && !world->isFlying(ptr);
174 
175                     runtime.push(stanceOn && (running || inair));
176                 }
177         };
178 
179         class OpGetPcSneaking : public Interpreter::Opcode0
180         {
181             public:
182 
execute(Interpreter::Runtime & runtime)183                 void execute (Interpreter::Runtime& runtime) override
184                 {
185                     MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayerPtr();
186                     runtime.push(MWBase::Environment::get().getMechanicsManager()->isSneaking(ptr));
187                 }
188         };
189 
190 
installOpcodes(Interpreter::Interpreter & interpreter)191         void installOpcodes (Interpreter::Interpreter& interpreter)
192         {
193             for (int i=0; i<Compiler::Control::numberOfControls; ++i)
194             {
195                 interpreter.installSegment5 (Compiler::Control::opcodeEnable+i, new OpSetControl (Compiler::Control::controls[i], true));
196                 interpreter.installSegment5 (Compiler::Control::opcodeDisable+i, new OpSetControl (Compiler::Control::controls[i], false));
197                 interpreter.installSegment5 (Compiler::Control::opcodeGetDisabled+i, new OpGetDisabled (Compiler::Control::controls[i]));
198             }
199 
200             interpreter.installSegment5 (Compiler::Control::opcodeToggleCollision, new OpToggleCollision);
201 
202             //Force Run
203             interpreter.installSegment5 (Compiler::Control::opcodeClearForceRun,
204                 new OpClearMovementFlag<ImplicitRef> (MWMechanics::CreatureStats::Flag_ForceRun));
205             interpreter.installSegment5 (Compiler::Control::opcodeClearForceRunExplicit,
206                 new OpClearMovementFlag<ExplicitRef> (MWMechanics::CreatureStats::Flag_ForceRun));
207             interpreter.installSegment5 (Compiler::Control::opcodeForceRun,
208                 new OpSetMovementFlag<ImplicitRef> (MWMechanics::CreatureStats::Flag_ForceRun));
209             interpreter.installSegment5 (Compiler::Control::opcodeForceRunExplicit,
210                 new OpSetMovementFlag<ExplicitRef> (MWMechanics::CreatureStats::Flag_ForceRun));
211 
212             //Force Jump
213             interpreter.installSegment5 (Compiler::Control::opcodeClearForceJump,
214                 new OpClearMovementFlag<ImplicitRef> (MWMechanics::CreatureStats::Flag_ForceJump));
215             interpreter.installSegment5 (Compiler::Control::opcodeClearForceJumpExplicit,
216                 new OpClearMovementFlag<ExplicitRef> (MWMechanics::CreatureStats::Flag_ForceJump));
217             interpreter.installSegment5 (Compiler::Control::opcodeForceJump,
218                 new OpSetMovementFlag<ImplicitRef> (MWMechanics::CreatureStats::Flag_ForceJump));
219             interpreter.installSegment5 (Compiler::Control::opcodeForceJumpExplicit,
220                 new OpSetMovementFlag<ExplicitRef> (MWMechanics::CreatureStats::Flag_ForceJump));
221 
222             //Force MoveJump
223             interpreter.installSegment5 (Compiler::Control::opcodeClearForceMoveJump,
224                 new OpClearMovementFlag<ImplicitRef> (MWMechanics::CreatureStats::Flag_ForceMoveJump));
225             interpreter.installSegment5 (Compiler::Control::opcodeClearForceMoveJumpExplicit,
226                 new OpClearMovementFlag<ExplicitRef> (MWMechanics::CreatureStats::Flag_ForceMoveJump));
227             interpreter.installSegment5 (Compiler::Control::opcodeForceMoveJump,
228                 new OpSetMovementFlag<ImplicitRef> (MWMechanics::CreatureStats::Flag_ForceMoveJump));
229             interpreter.installSegment5 (Compiler::Control::opcodeForceMoveJumpExplicit,
230                 new OpSetMovementFlag<ExplicitRef> (MWMechanics::CreatureStats::Flag_ForceMoveJump));
231 
232             //Force Sneak
233             interpreter.installSegment5 (Compiler::Control::opcodeClearForceSneak,
234                 new OpClearMovementFlag<ImplicitRef> (MWMechanics::CreatureStats::Flag_ForceSneak));
235             interpreter.installSegment5 (Compiler::Control::opcodeClearForceSneakExplicit,
236                 new OpClearMovementFlag<ExplicitRef> (MWMechanics::CreatureStats::Flag_ForceSneak));
237             interpreter.installSegment5 (Compiler::Control::opcodeForceSneak,
238                 new OpSetMovementFlag<ImplicitRef> (MWMechanics::CreatureStats::Flag_ForceSneak));
239             interpreter.installSegment5 (Compiler::Control::opcodeForceSneakExplicit,
240                 new OpSetMovementFlag<ExplicitRef> (MWMechanics::CreatureStats::Flag_ForceSneak));
241 
242             interpreter.installSegment5 (Compiler::Control::opcodeGetPcRunning, new OpGetPcRunning);
243             interpreter.installSegment5 (Compiler::Control::opcodeGetPcSneaking, new OpGetPcSneaking);
244             interpreter.installSegment5 (Compiler::Control::opcodeGetForceRun, new OpGetForceRun<ImplicitRef>);
245             interpreter.installSegment5 (Compiler::Control::opcodeGetForceRunExplicit, new OpGetForceRun<ExplicitRef>);
246             interpreter.installSegment5 (Compiler::Control::opcodeGetForceJump, new OpGetForceJump<ImplicitRef>);
247             interpreter.installSegment5 (Compiler::Control::opcodeGetForceJumpExplicit, new OpGetForceJump<ExplicitRef>);
248             interpreter.installSegment5 (Compiler::Control::opcodeGetForceMoveJump, new OpGetForceMoveJump<ImplicitRef>);
249             interpreter.installSegment5 (Compiler::Control::opcodeGetForceMoveJumpExplicit, new OpGetForceMoveJump<ExplicitRef>);
250             interpreter.installSegment5 (Compiler::Control::opcodeGetForceSneak, new OpGetForceSneak<ImplicitRef>);
251             interpreter.installSegment5 (Compiler::Control::opcodeGetForceSneakExplicit, new OpGetForceSneak<ExplicitRef>);
252         }
253     }
254 }
255