ScummVM API documentation
walking.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 DRACI_WALKING_H
23 #define DRACI_WALKING_H
24 
25 #include "common/array.h"
26 #include "common/rect.h"
27 
28 namespace Draci {
29 
30 class Sprite;
31 
32 typedef Common::Array<Common::Point> WalkingPath;
33 
34 class WalkingMap {
35 public:
36  WalkingMap() : _realWidth(0), _realHeight(0), _deltaX(1), _deltaY(1),
37  _mapWidth(0), _mapHeight(0), _byteWidth(0), _data(NULL) { }
38 
39  void load(const byte *data, uint length);
40 
41  bool getPixel(int x, int y) const;
42  bool isWalkable(const Common::Point &p) const;
43 
44  Sprite *newOverlayFromMap(byte color) const;
45  Common::Point findNearestWalkable(int x, int y) const;
46 
47  bool findShortestPath(Common::Point p1, Common::Point p2, WalkingPath *path) const;
48  void obliquePath(const WalkingPath& path, WalkingPath *obliquedPath);
49  Sprite *newOverlayFromPath(const WalkingPath &path, byte color) const;
50  Common::Point getDelta() const { return Common::Point(_deltaX, _deltaY); }
51 
52  static int pointsBetween(const Common::Point &p1, const Common::Point &p2);
53  static Common::Point interpolate(const Common::Point &p1, const Common::Point &p2, int i, int n);
54 
55 private:
56  int _realWidth, _realHeight;
57  int _deltaX, _deltaY;
58  int _mapWidth, _mapHeight;
59  int _byteWidth;
60 
61  // We don't own the pointer. It points to the BArchive cache for this room.
62  const byte *_data;
63 
64  // 4 possible directions to walk from a pixel.
65  static const int kDirections[][2];
66 
67  void drawOverlayRectangle(const Common::Point &p, byte color, byte *buf) const;
68  bool lineIsCovered(const Common::Point &p1, const Common::Point &p2) const;
69 
70  // Returns true if the number of vertices on the path was decreased.
71  bool managedToOblique(WalkingPath *path) const;
72 };
73 
74 /*
75  * Enumerates the directions the dragon can look into when arrived.
76  */
77 enum SightDirection {
78  kDirectionLast, kDirectionMouse, kDirectionUnknown,
79  kDirectionRight, kDirectionLeft, kDirectionIntelligent
80 };
81 
85 enum Movement {
86  kMoveUndefined = -1,
87  kMoveDown, kMoveUp, kMoveRight, kMoveLeft,
88 
89  kFirstTurning,
90  kMoveRightDown = kFirstTurning, kMoveRightUp, kMoveLeftDown, kMoveLeftUp,
91  kMoveDownRight, kMoveUpRight, kMoveDownLeft, kMoveUpLeft,
92  kMoveLeftRight, kMoveRightLeft, kMoveUpStopLeft, kMoveUpStopRight,
93  kLastTurning = kMoveUpStopRight,
94 
95  kSpeakRight, kSpeakLeft, kStopRight, kStopLeft,
96 
97  kFirstTemporaryAnimation
98 };
99 
100 class DraciEngine;
101 struct GPL2Program;
102 
104 public:
105  explicit WalkingState(DraciEngine *vm) : _vm(vm) {
106  _dir = kDirectionLast;
107  _startingDirection = kMoveUndefined;
108  _segment = 0;
109  _lastAnimPhase = 0;
110  _turningFinished = 0;
111  _callbackOffset = 0;
112  _callbackOffsetLast = 0;
113  _callbackLast = 0;
114 
115  stopWalking();
116  }
117 
118  ~WalkingState() {}
119 
120  void stopWalking();
121  void startWalking(const Common::Point &p1, const Common::Point &p2,
122  const Common::Point &mouse, SightDirection dir,
123  const Common::Point &delta, const WalkingPath& path);
124  const WalkingPath& getPath() const { return _path; }
125 
126  void setCallback(const GPL2Program *program, uint16 offset);
127  void callback();
128  void callbackLast();
129 
130  bool isActive() const { return _path.size() > 0; }
131 
132  // Advances the hero along the path and changes animation accordingly.
133  // Walking MUST be active when calling this method. When the hero has
134  // arrived to the target, returns false, but leaves the callback
135  // untouched (the caller must call it).
136  // The second variant also clears the path when returning false.
137  bool continueWalking();
138  bool continueWalkingOrClearPath();
139 
140  // Called when the hero's turning animation has finished.
141  void heroAnimationFinished();
142 
143  // Returns the hero's animation corresponding to looking into given
144  // direction. The direction can be smart and in that case this
145  // function needs to know the whole last path, the current position of
146  // the hero, or the mouse position.
147  static Movement animationForSightDirection(SightDirection dir, const Common::Point &hero, const Common::Point &mouse, const WalkingPath &path, Movement startingDirection);
148 
149 private:
150  DraciEngine *_vm;
151 
152  WalkingPath _path;
153  Common::Point _mouse;
154  SightDirection _dir;
155  Movement _startingDirection;
156 
157  uint _segment; // Index of the path vertex we are currently going to / rotation on
158  int _lastAnimPhase;
159  bool _turningFinished;
160 
161  const GPL2Program *_callback;
162  const GPL2Program *_callbackLast;
163  uint16 _callbackOffset;
164  uint16 _callbackOffsetLast;
165 
166  // Initiates turning of the dragon into the direction for the next
167  // segment / after walking. Returns false when there is nothing left
168  // to do and walking is done.
169  bool turnForTheNextSegment();
170 
171  // Starts walking on the next edge. Returns false if we are already at
172  // the final vertex and walking is done.
173  bool walkOnNextEdge();
174 
175  // Return one of the 4 animations kMove{Down,Up,Right,Left}
176  // corresponding to walking from here to there.
177  static Movement animationForDirection(const Common::Point &here, const Common::Point &there);
178 
179  // Returns the desired facing direction to begin the next phase of the
180  // walk. It's either a direction for the given edge or the desired
181  // final direction.
182  Movement directionForNextPhase() const;
183 
184  // Returns either animation that needs to be played between given two
185  // animations (e.g., kMoveRightDown after kMoveRight and before
186  // kMoveDown), or kMoveUndefined if none animation is to be played.
187  static Movement transitionBetweenAnimations(Movement previous, Movement next);
188 
189  static bool isTurningMovement(Movement m) {
190  return m >= kFirstTurning && m <= kLastTurning;
191  }
192 
193  // Projects hero to the given edge. Returns true when hero has reached
194  // at least p2. prevHero is passed so that we can compute how much to
195  // adjust in the other-than-walking direction.
196  static bool alignHeroToEdge(const Common::Point &p1, const Common::Point &p2, const Common::Point &prevHero, Common::Point *hero);
197 };
198 
199 } // End of namespace Draci
200 
201 #endif // DRACI_WALKING_H
Definition: walking.h:103
Definition: draci.h:68
Definition: walking.h:34
Definition: sprite.h:102
Definition: rect.h:45
Movement
Definition: walking.h:85
Definition: animation.h:30
Definition: script.h:83