chunks.h

Go to the documentation of this file.
00001 
00007 /*
00008 Copyright (C) 2001 The Exult Team
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00023 */
00024 
00025 #ifndef CHUNKS_H
00026 #define CHUNKS_H
00027 
00028 #include "objlist.h"
00029 
00030 
00031 #include "exult_constants.h"
00032 #include "rect.h"
00033 #include "shapeid.h"
00034 #include "tiles.h"
00035 #include "vec.h"
00036 #include "chunkter.h"
00037 
00038 class Map_chunk;
00039 class Egg_object;
00040 class Game_object;
00041 class Npc_actor;
00042 class Image_buffer8;
00043 class Chunk_terrain;
00044 
00045 /*
00046  *  Data cached for a chunk to speed up processing, but which doesn't need
00047  *  to be saved to disk:
00048  */
00049 class Chunk_cache : public Game_singletons
00050   {
00051   Map_chunk *obj_list;
00052   unsigned long blocked[256]; // For each tile, 2 bits for each lift
00053           //   level for #objs blocking there.
00054   Egg_vector egg_objects;   // ->eggs which influence this chunk.
00055   unsigned short eggs[256]; // Bit #i (0-14) set means that the
00056           //   tile is within egg_object[i]'s
00057           //   influence.  Bit 15 means it's 1 or
00058           //   more of 
00059           //   egg_objects[15-(num_eggs-1)].
00060   Game_object_vector doors; // Keep special list of doors.
00061   friend class Map_chunk;
00062   Chunk_cache();  
00063   ~Chunk_cache();
00064   int get_num_eggs()
00065     { return egg_objects.size(); }
00066           // Set/unset blocked region.
00067   void set_blocked(int startx, int starty, int endx, int endy,
00068           int lift, int ztiles, bool set);
00069           // Add/remove object.
00070   void update_object(Map_chunk *chunk,
00071             Game_object *obj, bool add);
00072           // Set area within egg's influence.
00073   void set_egged(Egg_object *egg, Rectangle& tiles, bool add);
00074           // Add egg.
00075   void update_egg(Map_chunk *chunk, Egg_object *egg, bool add);
00076           // Set up with chunk's data.
00077   void setup(Map_chunk *chunk);
00078 #if 0 /* OLD WAY.  Goes away. */
00079           // Set blocked tile's bits.
00080   void set_blocked_tile(int tx, int ty, int lift, int ztiles)
00081     {
00082     unsigned short val = (((1 << ztiles) - 1) << lift);
00083     unsigned short inter = blocked[ty*c_tiles_per_chunk + tx]&val;
00084     if (inter)
00085       intersects(tx, ty, inter);
00086     blocked[ty*c_tiles_per_chunk + tx] |= val;
00087     }
00088           // Clear blocked tile's bits.
00089   void clear_blocked_tile(int tx, int ty, int lift, int ztiles)
00090     {
00091     blocked[ty*c_tiles_per_chunk + tx] &= 
00092           ~(((1 << ztiles) - 1) << lift);
00093     }
00094 #endif
00095           // Get highest lift blocked below a
00096           //   given level for a desired tile.
00097   int get_highest_blocked(int lift, unsigned long tflags);
00098   int get_highest_blocked(int lift, int tx, int ty);
00099   int get_lowest_blocked(int lift, unsigned long tflags);
00100   int get_lowest_blocked(int lift, int tx, int ty);
00101           // Is a spot occupied?
00102   int is_blocked(int height, int lift, int tx, int ty, int& new_lift,
00103     const int move_flags, int max_drop = 1, int max_rise = -1);
00104           // Activate eggs nearby.
00105   void activate_eggs(Game_object *obj, Map_chunk *chunk, 
00106       int tx, int ty, int tz, int from_tx, int from_ty, 
00107           unsigned short eggbits, bool now);
00108   void activate_eggs(Game_object *obj, Map_chunk *chunk, 
00109     int tx, int ty, int tz, int from_tx, int from_ty, bool now)
00110     {
00111     unsigned short eggbits = eggs[
00112       (ty%c_tiles_per_chunk)*c_tiles_per_chunk + 
00113             (tx%c_tiles_per_chunk)];
00114     if (eggbits)
00115       activate_eggs(obj, chunk, tx, ty, tz,
00116           from_tx, from_ty, eggbits, now);
00117     }
00118           // Find door blocking given tile.
00119   Game_object *find_door(Tile_coord t);
00120 public:
00121           // Quick is blocked
00122   inline int is_blocked_fast(int tx, int ty, int lift)
00123     {
00124     return blocked[ty*c_tiles_per_chunk + tx] & (3 << (2*lift));
00125     }
00126   };
00127 
00128 /*
00129  *  Game objects are stored in a list for each chunk, sorted from top-to-
00130  *  bottom, left-to-right.
00131  */
00132 class Map_chunk : public Game_singletons
00133   {
00134   Chunk_terrain *terrain;   // Flat landscape tiles.
00135   Object_list objects;    // ->first in list of all objs.  'Flat'
00136           //   obs. (lift=0,ht=0) stored 1st.
00137   Game_object *first_nonflat; // ->first nonflat in 'objects'.
00138           // Counts of overlapping objects from
00139           //    chunks below, to right.
00140   unsigned char from_below, from_right, from_below_right;
00141   unsigned char ice_dungeon;  // For SI, chunk split into 4 quadrants
00142   unsigned char *dungeon_levels;  // A 'dungeon' level value for each tile (4 bit).
00143   Chunk_cache *cache;   // Data for chunks near player.
00144   unsigned char roof;   // 1 if a roof present.
00145           // # light sources in chunk.
00146   unsigned char dungeon_lights, non_dungeon_lights;
00147   unsigned char cx, cy;   // Absolute chunk coords. of this.
00148   void add_dungeon_levels(Rectangle& tiles, unsigned int lift);
00149   void add_dependencies(Game_object *newobj,
00150           class Ordering_info& newinfo);
00151   static Map_chunk *add_outside_dependencies(int cx,
00152     int cy, Game_object *newobj, class Ordering_info& newinfo);
00153 public:
00154   friend class Npc_actor;
00155   Map_chunk(int chunkx, int chunky);
00156   ~Map_chunk();     // Delete everything in chunk.
00157   Chunk_terrain *get_terrain() const
00158     { return terrain; }
00159   void set_terrain(Chunk_terrain *ter);
00160   void add(Game_object *obj); // Add an object.
00161   void add_egg(Egg_object *egg);  // Add/remove an egg.
00162   void remove_egg(Egg_object *egg);
00163   void remove(Game_object *obj);  // Remove an object.
00164           // Apply gravity over given area.
00165   static void gravity(Rectangle area, int lift);
00166           // Is there a roof? Returns height
00167   int is_roof(int tx, int ty, int lift);
00168 
00169   Object_list& get_objects()
00170     { return objects; }
00171   Game_object* get_first_nonflat() const
00172     { return first_nonflat; }
00173 
00174   int get_cx() const
00175     { return cx; }
00176   int get_cy() const
00177     { return cy; }
00178   int get_dungeon_lights() const  // Get #lights.
00179     { return dungeon_lights; }
00180   int get_non_dungeon_lights() const
00181     { return non_dungeon_lights; }
00182   ShapeID get_flat(int tilex, int tiley) const
00183     { return terrain ? terrain->get_flat(tilex, tiley)
00184           : ShapeID(); }
00185   Image_buffer8 *get_rendered_flats()
00186     { return terrain ? terrain->get_rendered_flats() : 0; }
00187           // Get/create/setup cache.
00188   Chunk_cache *get_cache() const { return cache; }
00189   Chunk_cache *need_cache()
00190     { 
00191     if (!cache)
00192       { cache = new Chunk_cache(); cache->setup(this); }
00193     return cache;
00194     }
00195   void setup_cache()
00196     { (void) need_cache(); }
00197           // Set/unset blocked region.
00198   void set_blocked(int startx, int starty, int endx, int endy,
00199             int lift, int ztiles, bool set)
00200     { need_cache()->set_blocked(startx, starty, endx, endy,
00201               lift, ztiles, set); }
00202           // Get highest lift blocked.
00203   int get_highest_blocked(int lift, int tx, int ty)
00204     { return need_cache()->get_highest_blocked(lift, tx, ty); }
00205   int get_lowest_blocked(int lift, int tx, int ty)
00206     { return need_cache()->get_lowest_blocked(lift, tx, ty); }
00207           // Is a spot occupied?
00208   int is_blocked(int height, int lift, int tx, int ty, int& new_lift,
00209     const int move_flags, int max_drop = 1, int max_rise = -1)
00210     { return cache->is_blocked(height, lift, tx, ty, new_lift,
00211           move_flags, max_drop, max_rise); }
00212           // Check range.
00213   static int is_blocked(int height, int lift, int startx, int starty,
00214     int xtiles, int ytiles, int& new_lift, const int move_flags, 
00215           int max_drop, int max_rise = -1);
00216           // Check absolute tile.
00217   static int is_blocked(Tile_coord& tile, int height = 1,
00218     const int move_flags = MOVE_ALL_TERRAIN, 
00219         int max_drop = 1, int max_rise = -1);
00220           // Check for > 1x1 object.
00221   static int is_blocked(int xtiles, int ytiles, int ztiles,
00222       Tile_coord from, Tile_coord& to, const int move_flags,
00223           int max_drop = 1, int max_rise = -1);
00224   enum Find_spot_where    // For find_spot() below.
00225     {
00226     anywhere = 0,
00227     inside,     // Must be inside.
00228     outside     // Must be outside,
00229     };
00230           // Find spot for an object.
00231   static Tile_coord find_spot(Tile_coord pos, int dist,
00232     int shapenum, int framenum, int max_drop = 0,int dir = -1,
00233         Find_spot_where where = anywhere);
00234           // For approaching 'pos' by an object:
00235   static Tile_coord find_spot(Tile_coord pos, int dist,
00236         Game_object *obj, int max_drop = 0,
00237           Find_spot_where where = anywhere);
00238           // Set area within egg's influence.
00239   void set_egged(Egg_object *egg, Rectangle& tiles, bool add)
00240     { need_cache()->set_egged(egg, tiles, add); }
00241   void activate_eggs(Game_object *obj, int tx, int ty, int tz,
00242         int from_tx, int from_ty, bool now = false)
00243     { need_cache()->activate_eggs(obj, 
00244         this, tx, ty, tz, from_tx, from_ty, now);}
00245           // Find door blocking given tile.
00246   Game_object *find_door(Tile_coord t)
00247     { return need_cache()->find_door(t); }
00248   static int find_in_area(Game_object_vector& vec, Rectangle area,
00249           int shapenum, int framenum);
00250           // Use this when teleported in.
00251   static void try_all_eggs(Game_object *obj, int tx, int ty, int tz,
00252             int from_tx, int from_ty);
00253   void setup_dungeon_levels();  // Set up after IFIX objs. read.
00254   inline int has_dungeon()    // Any tiles within dungeon?
00255     { return dungeon_levels != 0; }
00256 
00257           // NOTE:  The following should only be
00258           //   called if has_dungeon()==1.
00259   inline int is_dungeon(int tx, int ty) // Is object within dungeon? (returns height)
00260     {
00261     int tnum = ty*c_tiles_per_chunk + tx;
00262     return tnum%2? dungeon_levels[tnum/2] >> 4: dungeon_levels[tnum/2] & 0xF;
00263     }
00264           // Is the dungeon an ICE dungeon.NOTE: This is a
00265           // Hack and splits the chunk into 4 parts. Only if
00266   inline bool is_ice_dungeon(int tx, int ty) // all 4 are ice, will we have an ice dungeon
00267     {
00268     return ice_dungeon == 0x0F;//0 != ((ice_dungeon >> ( (tx>>3) + 2*(ty>>3) ) )&1);
00269     }
00270 
00271           // Kill the items and the cache
00272   void kill_cache();
00273           // Get all objects and actors for use when writing memory cache.
00274           // returns size require to save
00275   int get_obj_actors(Game_object_vector &removes, Actor_vector &actors);
00276 
00277   };
00278 
00279 #endif

Generated on Mon Jul 9 14:42:49 2007 for ExultEngine by  doxygen 1.5.1