ScummVM API documentation
record.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef NANCY_SCRIPT_RECORD_H
23 #define NANCY_SCRIPT_RECORD_H
24 
25 #include "common/keyboard.h"
26 #include "common/str.h"
27 
28 #include "engines/nancy/script/mathtypes.h"
29 
30 struct lua_State;
31 
32 namespace Nancy {
33 
34 struct NancyInput;
35 
36 namespace Script {
37 
38 class SceneContext;
39 
40 // What the player does that records get told about
41 enum RecordEvent {
42  kEventLeftClick = 0,
43  kEventRightClick = 1,
44  kEventLeftDown = 2,
45  kEventLeftUp = 3,
46  kEventRightDown = 4,
47  kEventRightUp = 5,
48  kEventKeyDown = 6,
49  kEventKey = 7,
50  kEventKeyUp = 8,
51 
52  kNumRecordEvents = 9
53 };
54 
55 // One of the things a scene of Nancy19 and up is made of, the way action records
56 // were before. A scene's script makes its records by handing tables to the "AR"
57 // object:
58 //
59 // door_HS = AR:NavLogic({ onScreen = Rect:New(...), scene = 2010,
60 // active = function() return Flags.Got_Key end })
61 //
62 // There are only a handful of kinds, since what used to take a record type of its
63 // own is now written in the scripts themselves. A record is active while its
64 // "active" value, or the function in its place, says so; an active record runs
65 // every frame until it calls itself done. Scripts read each other's "active" and
66 // "done" to chain records together.
67 //
68 // Besides the fields its kind knows, a record keeps whatever else a script
69 // stores in it. That includes the functions the engine calls at certain points
70 // (RunOnce, OnDone, OnReset...), which every kind of record can have.
71 class Record {
72 public:
73  Record(SceneContext &context, const char *typeName);
74  virtual ~Record();
75 
76  const char *getTypeName() const { return _typeName; }
77  SceneContext &getContext() const { return _context; }
78 
79  // Takes over the fields of the table that made the record
80  void create(int tableIndex);
81 
82  // Pushes an object for the scripts that stands for this record
83  void push();
84 
85  // Nancy20: a record made with "scriptOwns" lives only as long as scripts can
86  // still reach it. Once the last object standing for it has been collected, it
87  // stops and is taken out of the scene.
88  void onObjectCollected();
89  bool isDropped() const { return _isDropped; }
90 
91  // One frame. Times are in seconds.
92  void update(double sceneTime, double elapsedTime);
93 
94  // The record has done its job, and stops running
95  void finish();
96 
97  // Makes a record that ran start over. Only some kinds can.
98  bool reset();
99 
100  // Draws an active record right away, where its transform puts it on the
101  // screen. Scripts do this for what hangs off the cursor.
102  void render();
103 
104  // A record another one keeps for later stays out of the way until it is
105  // released, and then runs right away
106  void hold();
107  void release();
108 
109  // The game is about to be saved, which is when the records that keep
110  // something across scenes store it
111  virtual void onSave() {}
112 
113  // The scene of the record is being taken down
114  virtual void onDie() {}
115 
116  // Whether messages sent to the given name are for this record
117  virtual bool hasMessagingName(const Common::String &name) { return false; }
118 
119  bool isActive() const { return _isActive && !_isDone; }
120  bool isDone() const { return _isDone; }
121  bool hasStarted() const { return _hasStarted; }
122  double getZ() const { return _z; }
123 
124  // Puts the record no closer to the player than the given z
125  void limitZ(double z);
126 
127  // Reads or writes one of the fields of the record on behalf of a script.
128  // The key is at stack index 2, and a new value at 3.
129  int getScriptField();
130  int setScriptField();
131 
132  // Calls a function a script stored in the record, with the record itself in
133  // front of the arguments on the stack. Returns false when there is no such
134  // function, or when it failed; no results are left then.
135  bool callFunction(const char *name, int numArgs = 0, int numResults = 0);
136 
137  // What the player does goes to every record that is active, as a call to
138  // the function a script gave the record for it, or to what the kind of
139  // record does by itself. Positions are in the coordinates of the viewport.
140  // A click, a key and the cursor are up to the first record that takes them.
141  void sendMouseMove(const ScriptPoint &point, bool inViewport);
142  bool sendChangeCursor(const ScriptPoint &point, bool inViewport, uint &cursorType, bool &isHot);
143  bool sendMouseEvent(RecordEvent event, const ScriptPoint &point, bool inViewport);
144  bool sendKeyEvent(RecordEvent event, Common::KeyCode key);
145 
146  // Where the record puts what it shows, for the kinds that show something
147  const ScriptMatrix &getTransform() const { return _transform; }
148 
149  // Shows or hides what the record draws, once the records of a frame have run
150  virtual void updateGraphics() {}
151 
152  // Enhancement: the player can skip what a scene plays. Whether the record is
153  // something that can be skipped, and what it does when the skipping begins.
154  virtual bool isSkippable() const { return false; }
155  virtual void onSkip() {}
156 
157 protected:
158  lua_State *getLua() const;
159 
160  // The fields of the kind of record, from the table that made it
161  virtual void readTable(int tableIndex) {}
162 
163  // What the record does when no script took its place
164  virtual void runOnce() {}
165  virtual void run(double sceneTime, double elapsedTime) {}
166  virtual void onActivation() {}
167  virtual void onDeactivation() {}
168  virtual void onZChanged() {}
169  virtual void renderNow() {}
170 
171  // Whether the record can start over, after getting itself ready for it
172  virtual bool prepareReset() { return false; }
173 
174  // Whether the functions of the scripts take the place of what the record does
175  // by itself: Run, Render, and everything the player does
176  virtual bool isScripted() const { return false; }
177 
178  virtual void onMouseMove(const ScriptPoint &point, bool inViewport) {}
179  virtual bool getCursor(const ScriptPoint &point, bool inViewport, uint &cursorType, bool &isHot) { return false; }
180  virtual bool onMouseEvent(RecordEvent event, const ScriptPoint &point, bool inViewport) { return false; }
181 
182  // Whether the kind of record has a "transform", and what to do when it changes
183  virtual bool hasTransform() const { return false; }
184  virtual void onTransformChanged() {}
185 
186  // The fields of the kind of record. Reading pushes the value and returns true;
187  // writing takes the value at index 3. Both return false for unknown fields.
188  virtual bool getField(const Common::String &key) { return false; }
189  virtual bool setField(const Common::String &key) { return false; }
190 
191  // What scripts stored in the record
192  void pushStoredValue(const char *name);
193  void storeValue(const char *name); // pops the value
194 
195 private:
196  void pushStorage();
197 
198  SceneContext &_context;
199  const char *_typeName;
200 
201  double _z = 0.0;
202  ScriptMatrix _transform;
203  bool _hasActiveFunction = false;
204  bool _hasStarted = false;
205  bool _isActive = true;
206  bool _wasActive = false;
207  bool _isDone = false;
208  bool _hasRunOnce = false;
209 
210  bool _isScriptOwned = false;
211  uint _numObjects = 0; // the objects standing for the record that Lua still has
212  bool _isDropped = false;
213 };
214 
215 // Makes the "AR" object, and the types of the records
216 void registerRecordAPI(lua_State *L);
217 
218 // The record a script handed in, or a script error
219 Record *checkRecord(lua_State *L, int index);
220 
221 } // End of namespace Script
222 } // End of namespace Nancy
223 
224 #endif // NANCY_SCRIPT_RECORD_H
Definition: mathtypes.h:47
Definition: str.h:59
Definition: lstate.h:100
Definition: scenecontext.h:52
Definition: record.h:71
Definition: types.h:62
Definition: actionmanager.h:32