ScummVM API documentation
current_map.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 ULTIMA8_WORLD_CURRENTMAP_H
23 #define ULTIMA8_WORLD_CURRENTMAP_H
24 
25 #include "common/list.h"
26 #include "ultima/ultima8/misc/common_types.h"
27 #include "ultima/ultima8/misc/direction.h"
28 #include "ultima/ultima8/misc/point3.h"
29 #include "ultima/ultima8/usecode/intrinsics.h"
30 #include "ultima/ultima8/world/position_info.h"
31 
32 namespace Ultima {
33 namespace Ultima8 {
34 
35 struct Box;
36 class Map;
37 class Item;
38 class UCList;
39 class TeleportEgg;
40 class EggHatcherProcess;
41 
42 #define MAP_NUM_CHUNKS 64
43 #define MAP_NUM_TARGET_ITEMS 200
44 
45 class CurrentMap {
46  friend class World;
47 public:
48  CurrentMap();
49  ~CurrentMap();
50 
51  void clear();
52  void writeback();
53  void loadMap(Map *map);
54 
57  void setMap(Map *map) {
58  _currentMap = map;
59  }
60 
62  uint32 getNum() const;
63 
64  unsigned int getChunkSize() const {
65  return _mapChunkSize;
66  }
67 
69  void addItem(Item *item);
70 
72  void addItemToEnd(Item *item);
73 
74  void removeItemFromList(Item *item, int32 oldx, int32 oldy);
75  void removeItem(Item *item);
76 
78  void addTargetItem(const Item *item);
80  void removeTargetItem(const Item *item);
82  Item *findBestTargetItem(int32 x, int32 y, int32 z, Direction dir, DirectionMode dirmode);
83 
85  void updateFastArea(const Point3 &from, const Point3 &to);
86 
97  void areaSearch(UCList *itemlist, const uint8 *loopscript,
98  uint32 scriptsize, const Item *item, uint16 range,
99  bool recurse, int32 x = 0, int32 y = 0) const;
100 
101  // Surface search: Search above and below an item.
102  void surfaceSearch(UCList *itemlist, const uint8 *loopscript,
103  uint32 scriptsize, const Item *item, bool above,
104  bool below, bool recurse = false) const;
105 
106  // Collision detection. Returns position information with valid being true
107  // when the target box does not collide with any solid items.
108  // Ignores collisions when overlapping with the start box.
109  PositionInfo getPositionInfo(const Box &target, const Box &start, uint32 shapeflags, ObjId id) const;
110 
111  // Note that this version of getPositionInfo can not take 'flipped' into account!
112  PositionInfo getPositionInfo(int32 x, int32 y, int32 z, uint32 shape, ObjId id) const;
113 
115  bool scanForValidPosition(int32 x, int32 y, int32 z, const Item *item,
116  Direction movedir, bool wantsupport,
117  int32 &tx, int32 &ty, int32 &tz);
118 
119  struct SweepItem {
120  SweepItem(ObjId it, int32 ht, int32 et, bool touch,
121  bool touchfloor, bool block, uint8 dir)
122  : _item(it), _hitTime(ht), _endTime(et), _touching(touch),
123  _touchingFloor(touchfloor), _blocking(block), _dirs(dir) { }
124 
125  ObjId _item; // Item that was hit
126 
127  //
128  // The time values here are 'normalized' fixed point values
129  // They range from 0 for the start of the move to 0x4000 for the end of
130  // The move.
131  //
132  // Linear interpolate between the start and end positions using
133  // hit_time to find where the moving item was when the hit occurs
134  //
135 
136  int32 _hitTime; // if -1, already hitting when sweep started.
137  int32 _endTime; // if 0x4000, still hitting when sweep finished
138 
139  bool _touching; // We are only touching (don't actually overlap)
140  bool _touchingFloor; // touching and directly below the moving item
141 
142  bool _blocking; // This item blocks the moving item
143 
144  uint8 _dirs; // Directions in which the item is being hit.
145  // Bitmask. Bit 0 is x, 1 is y, 2 is z.
146 
147  // Use this func to get the interpolated location of the hit
148  Point3 GetInterpolatedCoords(const Point3 &start, const Point3 &end) const {
149  Point3 pt;
150  pt.x = start.x + ((end.x - start.x) * (_hitTime >= 0 ? _hitTime : 0) + (end.x > start.x ? 0x2000 : -0x2000)) / 0x4000;
151  pt.y = start.y + ((end.y - start.y) * (_hitTime >= 0 ? _hitTime : 0) + (end.y > start.y ? 0x2000 : -0x2000)) / 0x4000;
152  pt.z = start.z + ((end.z - start.z) * (_hitTime >= 0 ? _hitTime : 0) + (end.z > start.z ? 0x2000 : -0x2000)) / 0x4000;
153  return pt;
154  }
155  };
156 
169  bool sweepTest(const Point3 &start, const Point3 &end,
170  const int32 dims[3], uint32 shapeflags,
171  ObjId item, bool solid_only, Common::List<SweepItem> *hit) const;
172 
173  TeleportEgg *findDestination(uint16 id);
174 
175  // Not allowed to modify the list. Remember to use const_iterator
176  const Common::List<Item *> *getItemList(int32 gx, int32 gy) const;
177 
178  bool isChunkFast(int32 cx, int32 cy) const {
179  // CONSTANTS!
180  if (cx < 0 || cy < 0 || cx >= MAP_NUM_CHUNKS || cy >= MAP_NUM_CHUNKS)
181  return false;
182  return (_fast[cy][cx / 32] & (1 << (cx & 31))) != 0;
183  }
184 
185  void setFastAtPoint(const Point3 &pt);
186 
187  // Set the entire map as being 'fast'
188  void setWholeMapFast();
189 
190  void save(Common::WriteStream *ws);
191  bool load(Common::ReadStream *rs, uint32 version);
192 
193  INTRINSIC(I_canExistAt);
194  INTRINSIC(I_canExistAtPoint);
195 
196 private:
197  void loadItems(const Common::List<Item *> &itemlist, bool callCacheIn);
198  void createEggHatcher();
199 
201  static void clipMapChunks(int &minx, int &maxx, int &miny, int &maxy);
202 
203  Map *_currentMap;
204 
205  // item lists. Lots of them :-)
206  // items[x][y]
207  Common::List<Item *> _items[MAP_NUM_CHUNKS][MAP_NUM_CHUNKS];
208 
209  ProcId _eggHatcher;
210 
211  // Fast area bit masks -> fast[ry][rx/32]&(1<<(rx&31));
212  uint32 _fast[MAP_NUM_CHUNKS][MAP_NUM_CHUNKS / 32];
213  int32 _fastXMin, _fastYMin, _fastXMax, _fastYMax;
214 
215  int _mapChunkSize;
216 
219  ObjId _targets[MAP_NUM_TARGET_ITEMS];
220 
221  void setChunkFast(int32 cx, int32 cy);
222  void unsetChunkFast(int32 cx, int32 cy);
223 };
224 
225 } // End of namespace Ultima8
226 } // End of namespace Ultima
227 
228 #endif
void addTargetItem(const Item *item)
Add an item to the list of possible targets (in Crusader)
Definition: stream.h:77
Definition: map.h:38
void removeTargetItem(const Item *item)
Remove an item from the list of possible targets (in Crusader)
Definition: item.h:42
Definition: point3.h:30
Definition: list.h:44
void addItem(Item *item)
Add an item to the beginning of the item list.
Definition: box.h:36
Definition: detection.h:27
Definition: position_info.h:44
Definition: world.h:75
uint32 getNum() const
Get the map number of the CurrentMap.
void areaSearch(UCList *itemlist, const uint8 *loopscript, uint32 scriptsize, const Item *item, uint16 range, bool recurse, int32 x=0, int32 y=0) const
Definition: current_map.h:119
Item * findBestTargetItem(int32 x, int32 y, int32 z, Direction dir, DirectionMode dirmode)
Find the best target item in the given direction from the given start point.
bool scanForValidPosition(int32 x, int32 y, int32 z, const Item *item, Direction movedir, bool wantsupport, int32 &tx, int32 &ty, int32 &tz)
Scan for a valid position for item in directions orthogonal to movedir.
Definition: uc_list.h:45
Definition: stream.h:385
void addItemToEnd(Item *item)
Add an item to the end of the item list.
bool sweepTest(const Point3 &start, const Point3 &end, const int32 dims[3], uint32 shapeflags, ObjId item, bool solid_only, Common::List< SweepItem > *hit) const
void updateFastArea(const Point3 &from, const Point3 &to)
Update the fast area for the cameras position.
Definition: current_map.h:45
Definition: teleport_egg.h:30
void setMap(Map *map)
Definition: current_map.h:57