Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields

map.h

00001 /***************************************************************************
00002                           map.h  -  description
00003                              -------------------
00004     begin                : Sat May 3 2003
00005     copyright            : (C) 2003 by Gabor Torok
00006     email                : cctorok@yahoo.com
00007 ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #ifndef MAP_H
00019 #define MAP_H
00020 
00021 #include "constants.h"
00022 #include "sdlhandler.h"
00023 #include "shape.h"
00024 #include "location.h"
00025 #include "dungeongenerator.h"
00026 #include "creature.h"
00027 #include "session.h"
00028 #include "item.h"
00029 #include "projectile.h"
00030 #include "gui/scrollinglist.h"
00031 #include "frustum.h"
00032 
00033 using namespace std;
00034 
00035 // forward decl.
00036 class Location;
00037 class EffectLocation;
00038 class DungeonGenerator;
00039 class Session;
00040 class Creature;
00041 class Item;
00042 class Projectile;
00043 
00044 typedef struct _DrawLater {
00045   float xpos, ypos, zpos;
00046   Shape *shape;
00047   Creature *creature;
00048   Item *item;
00049   Projectile *projectile;
00050   EffectLocation *effect;
00051   GLuint name;  
00052   Location *pos;
00053   bool inFront;
00054 } DrawLater;
00055 
00056 #define SWAP(src, dst) { int _t; _t = src; src = dst; dst = _t; }
00057 #define POS_CACHE_WIDTH    5
00058 #define POS_CACHE_DEPTH    5
00059 #define POS_CACHE_HEIGHT   10
00060 #define MAX_POS_CACHE (POS_CACHE_WIDTH * POS_CACHE_DEPTH * POS_CACHE_HEIGHT)
00061 
00062 // used by locked doors
00063 class Pos3 {
00064 public:
00065   int x, y, z;
00066   Pos3(int x, int y, int z) {
00067     this->x = x;
00068     this->y = y;
00069     this->z = z;
00070   }
00071   ~Pos3() {
00072   }
00073 };
00074 
00075 
00076 // how many water points per 1 floor tile
00077 #define WATER_TILE_X 8
00078 #define WATER_TILE_Y 8
00079 
00080 
00084 class Map {
00085  private:
00086   bool mapChanged;
00087   bool resortShapes;
00088   float zoom;
00089   bool zoomIn, zoomOut;
00090   Sint16 x;
00091   Sint16 y;
00092   int viewX, viewY, viewWidth, viewHeight;
00093   float mapx, mapy;
00094   Location *pos[MAP_WIDTH][MAP_DEPTH][MAP_VIEW_HEIGHT];
00095   EffectLocation *effect[MAP_WIDTH][MAP_DEPTH][MAP_VIEW_HEIGHT];
00096   Location *posCache[MAX_POS_CACHE];
00097   signed int nbPosCache;
00098   Shape *floorPositions[MAP_WIDTH][MAP_DEPTH];
00099   typedef struct _WaterTile {
00100     float z[WATER_TILE_X][WATER_TILE_Y];
00101     float step[WATER_TILE_X][WATER_TILE_Y];
00102     Uint32 lastTime[WATER_TILE_X][WATER_TILE_Y];
00103   } WaterTile;
00104   map<Uint32, WaterTile*> water;
00105   Session *session;
00106   bool debugGridFlag;
00107   bool drawGridFlag;
00108   float xrot, yrot, zrot;  
00109   float xpos, ypos, zpos;
00110   float xRotating, yRotating, zRotating;
00111   Uint16 selX, selY, selZ, oldLocatorSelX, oldLocatorSelY, oldLocatorSelZ;
00112   float fShadowMatrix[16];
00113   //bool alwaysCenter;
00114   static const int X_CENTER_TOLERANCE = 8;
00115   static const int Y_CENTER_TOLERANCE = 8;
00116 
00117   // on screen item descriptions
00118   static const int MAX_DESCRIPTION_COUNT = 200;
00119   int descriptionCount;
00120   bool descriptionsChanged;
00121   char *descriptions[MAX_DESCRIPTION_COUNT];
00122   Color descriptionsColor[MAX_DESCRIPTION_COUNT];
00123 
00124   bool lightMapChanged;
00125   int lightMap[MAP_WIDTH / MAP_UNIT][MAP_DEPTH / MAP_UNIT];
00126   
00127   // FIXME: either make this value adjustable or find a faster way to blast it onscreen?
00128   static const int SHADE_SIZE = 20;
00129 
00130   bool useShadow;
00131   // squish on z and shear x,y
00132   static const float shadowTransformMatrix[16];
00133 
00134   bool colorAlreadySet;
00135   Location *selectedDropTarget;
00136 
00137   int accessMap[MAP_WIDTH / MAP_UNIT][MAP_DEPTH / MAP_UNIT];
00138   map<Uint32, bool> locked;
00139   map<Uint32, Uint32> doorToKey;
00140   map<Uint32, Uint32> keyToDoor;
00141 
00142   int LIGHTMAP_ENABLED;
00143 
00144 #define OVERLAY_SIZE 16
00145   GLuint overlay_tex;
00146   unsigned char overlay_data[OVERLAY_SIZE * OVERLAY_SIZE * 3];
00147 
00148   static int dir_index[];
00149   
00150   void drawGrid(SDL_Surface *surface);
00151   void debugGrid(SDL_Surface *surface);
00152 
00153   int mapViewWidth, mapViewDepth;
00154   char mapDebugStr[200];
00155 
00156   bool hasWater;
00157 
00158  public:
00159   bool useFrustum;
00160   static bool debugMd2Shapes;
00161 
00162   Map(Session *session);
00163   ~Map();
00164 
00165   void reset();
00166 
00167   inline bool getHasWater() { return hasWater; }
00168   inline void setHasWater(bool b) { hasWater = b; }
00169 
00170   int debugX, debugY, debugZ;  
00171 
00172   int toggleLightMap();
00173 
00174   bool selectMode;
00175   bool floorOnly;
00176 
00177   inline void setSelectedDropTarget(Location *loc) { selectedDropTarget = loc; }
00178   inline Location *getSelectedDropTarget() { return selectedDropTarget; }
00179   
00180   inline void setZoomIn(bool b) { zoomIn = b; }
00181   inline void setZoomOut(bool b) { zoomOut = b; }
00182   inline float getZoom() { return zoom; }
00183 
00184   inline void setXRot(float b) { xRotating = b; }
00185   inline void setYRot(float b) { yRotating = b; }
00186   inline void setZRot(float b) { zRotating = b; }
00187 
00188   inline float getXRot() { return xrot; }
00189   inline float getYRot() { return yrot; }
00190   inline float getZRot() { return zrot; }  
00191 
00192   inline void addXPos(float f) { xpos += f; }
00193   inline void addYPos(float f) { ypos += f; }  
00194   inline void addZPos(float f) { zpos += f; }
00195 
00196   inline float getXPos() { return xpos; }
00197   inline float getYPos() { return ypos; }
00198   inline float getZPos() { return zpos; } 
00199 
00200   bool isLocationVisible(int x, int y);
00201 
00202   bool isLocationInLight(int x, int y);
00203     
00204   void draw();
00205 
00206   void drawBorder();
00207   
00211   inline int getX() { return x; }
00212   
00216   inline int getY() { return y; }
00217   
00218   inline void setXY(int x, int y) { this->x = x; this->y = y; }
00219   
00220   void center(Sint16 x, Sint16 y, bool force=false);
00221 
00222   void startEffect(Sint16 x, Sint16 y, Sint16 z, 
00223                    int effect_type, GLuint duration = Constants::DAMAGE_DURATION,
00224                    int width=1, int height=1,
00225                                    GLuint delay = 0);
00226     
00227   void setPosition(Sint16 x, Sint16 y, Sint16 z, Shape *shape);
00228   Shape *removePosition(Sint16 x, Sint16 y, Sint16 z);
00229   
00230   void Map::setItem(Sint16 x, Sint16 y, Sint16 z, Item *item);
00231   Item *removeItem(Sint16 x, Sint16 y, Sint16 z);
00232   
00233   void Map::setCreature(Sint16 x, Sint16 y, Sint16 z, Creature *creature);
00234   Creature *removeCreature(Sint16 x, Sint16 y, Sint16 z);
00235   
00240   Location *moveCreature(Sint16 x, Sint16 y, Sint16 z, Uint16 dir, 
00241                                                  Creature *newCreature);
00242   Location *moveCreature(Sint16 x, Sint16 y, Sint16 z, 
00243                                                  Sint16 nx, Sint16 ny, Sint16 nz, 
00244                                                  Creature *newCreature);
00245   
00246   void setFloorPosition(Sint16 x, Sint16 y, Shape *shape);
00247   Shape *removeFloorPosition(Sint16 x, Sint16 y);
00248   
00255   Location *isBlocked(Sint16 x, Sint16 y, Sint16 z, 
00256                                           Sint16 shapex, Sint16 shapey, Sint16 shapez,
00257                                           Shape *shape,
00258                                           int *newz = NULL);
00259   
00261   Location *getPosition(Sint16 x, Sint16 y, Sint16 z);
00263   inline Location *getLocation(Sint16 x, Sint16 y, Sint16 z) { return pos[x][y][z]; }
00264   inline Shape *getFloorPosition(Sint16 x, Sint16 y) { if(x < 0 || x >= MAP_WIDTH || y < 0 || y >= MAP_DEPTH) return NULL; else return floorPositions[x][y]; }
00265   
00266   //void showInfoAtMapPos(Uint16 mapx, Uint16 mapy, Uint16 mapz, char *message);
00267   void showCreatureInfo(Creature *creature, bool player, bool selected, bool groupMode);
00268   
00269   void initMapView(bool ignoreRot = false);
00270   
00271   void addDescription(char *description, float r=1.0f, float g=1.0f, float b=0.4f);
00272   
00273   void drawDescriptions(ScrollingList *list);
00274   
00275   void handleMouseMove(Uint16 mapx, Uint16 mapy, Uint16 mapz);
00276   
00277   inline Uint16 getSelX() { return selX; }
00278   inline Uint16 getSelY() { return selY; }
00279   inline Uint16 getSelZ() { return selZ; }
00280 
00281   void move(int dir);
00282 
00283   bool isWallBetweenShapes(int x1, int y1, int z1,
00284                                                    Shape *shape1,
00285                                                    int x2, int y2, int z2,
00286                                                    Shape *shape2);
00287   
00288   bool isWallBetween(int x1, int y1, int z1,
00289                                          int x2, int y2, int z2);
00290   
00291   bool shapeFits(Shape *shape, int x, int y, int z);
00292 
00293   // like shapefits, but returns the blocking location or, NULL if there's nothing there
00294   Location *getBlockingLocation(Shape *shape, int x, int y, int z);
00295 
00296   Location *Map::getDropLocation(Shape *shape, int x, int y, int z);
00297 
00298   inline void updateLightMap() { lightMapChanged = resortShapes = true; }
00299 
00300   inline void refresh() { mapChanged = lightMapChanged = resortShapes = true; }
00301 
00302   inline void refreshTransparency() { resortShapes = true; }
00303 
00304   void setViewArea(int x, int y, int w, int h);
00305   inline int getViewWidth() { return viewWidth; }
00306   inline int getViewHeight() { return viewHeight; }
00307 
00308   // drop items above this one
00309   void dropItemsAbove(int x, int y, int z, Item *item);
00310 
00316   int getCreaturesInArea(int x, int y, int radius, Creature *targets[]);
00317 
00318   bool isOnScreen(Uint16 mapx, Uint16 mapy, Uint16 mapz);
00319   void doDrawShape(DrawLater *later, int effect=0);
00320   void doDrawShape(float xpos2, float ypos2, float zpos2, 
00321            Shape *shape, GLuint name, int effect=0,
00322            DrawLater *later=NULL);
00323 
00324   bool isDoor(int x, int y);
00325   bool Map::isDoor(Shape *shape);
00326 
00327   // ====================================================================
00328   // Locked doors/chests code
00329   void setLocked(int doorX, int doorY, int doorZ, bool value);
00330   inline void removeLocked(int doorX, int doorY, int doorZ) {
00331     Uint32 door = createTripletKey(doorX, doorY, doorZ);
00332     locked.erase(door);
00333     if(doorToKey.find(door) != doorToKey.end()) {
00334       Uint32 key = doorToKey[door];
00335       doorToKey.erase(key);
00336       keyToDoor.erase(door);
00337     }
00338   }
00339 
00340   inline void clearLocked() {
00341     if(locked.size()) locked.erase(locked.begin(), locked.end());
00342     if(doorToKey.size()) doorToKey.erase(doorToKey.begin(), doorToKey.end());
00343     if(keyToDoor.size()) keyToDoor.erase(keyToDoor.begin(), keyToDoor.end());
00344   }
00345 
00346   inline bool isLocked(int doorX, int doorY, int doorZ) {
00347     Uint32 door = createTripletKey(doorX, doorY, doorZ);
00348     return (locked.find(door) != locked.end() ? locked[door] : false);
00349   }
00350 
00351   inline void getDoorLocation(int keyX, int keyY, int keyZ, 
00352                               int *doorX, int *doorY, int *doorZ) {
00353     Uint32 key = createTripletKey(keyX, keyY, keyZ);
00354     if(keyToDoor.find(key) != keyToDoor.end()) {
00355       decodeTripletKey(keyToDoor[key], doorX, doorY, doorZ);
00356     } else {
00357       *doorX = *doorY = *doorZ = -1;
00358     }
00359   }
00360 
00361   inline void updateDoorLocation(int oldDoorX, int oldDoorY, int oldDoorZ, 
00362                                  int newDoorX, int newDoorY, int newDoorZ) {
00363     //cerr << "**********************" << endl;
00364     Uint32 oldDoor = createTripletKey(oldDoorX, oldDoorY, oldDoorZ);
00365     Uint32 newDoor = createTripletKey(newDoorX, newDoorY, newDoorZ);
00366     //cerr << "oldDoor=" << oldDoor << " pos: " << oldDoorX << "," << oldDoorY << "," << oldDoorZ << endl;
00367     //cerr << "newDoor=" << newDoor << " pos: " << newDoorX << "," << newDoorY << "," << newDoorZ << endl;
00368     if(locked.find(oldDoor) != locked.end()) {
00369       //cerr << "\tfound locked." << endl;
00370       locked[newDoor] = locked[oldDoor];
00371       locked.erase(oldDoor);
00372     }
00373     if(doorToKey.find(oldDoor) != doorToKey.end()) {
00374       //cerr << "\tfound door<->key." << endl;
00375       Uint32 key = doorToKey[oldDoor];
00376       int keyX, keyY, keyZ;
00377       decodeTripletKey(key, &keyX, &keyY, &keyZ);
00378       //cerr << "\tkey=" << key << " pos: " << keyX << "," << keyY << "," << keyZ << endl;
00379       doorToKey[newDoor] = key;
00380       doorToKey.erase(oldDoor);
00381       keyToDoor[key] = newDoor;
00382     }
00383     //cerr << "**********************" << endl;
00384   }
00385 
00386   void setKeyLocation(int doorX, int doorY, int doorZ, 
00387                       int keyX, int keyY, int keyZ) {
00388     Uint32 door = createTripletKey(doorX, doorY, doorZ);
00389     Uint32 key = createTripletKey(keyX, keyY, keyZ);
00390     doorToKey[door] = key;
00391     keyToDoor[key] = door;
00392   }
00393   // ====================================================================
00394   
00395   // access map methods for locked doors/chests
00396   void configureAccessMap(int fromX, int fromY);
00397   bool isPositionAccessible(int atX, int atY);
00398 
00399  protected:
00400    // This assumes that MAP_WIDTH >= MAP_HEIGHT and that MAP_WIDTH^3 < 2^32.
00401    inline Uint32 createTripletKey(int x, int y, int z) {
00402      Uint32 key = 
00403        ((Uint32)x * (Uint32)MAP_WIDTH * (Uint32)MAP_WIDTH) + 
00404        ((Uint32)y * (Uint32)MAP_WIDTH) + 
00405        ((Uint32)z);
00406      //cerr << "DEBUG: createTripletKey, x=" << x << " y=" << y << " z=" << z << " key=" << key << endl;
00407      return key;
00408    }
00409 
00410    inline void decodeTripletKey(Uint32 key, int *x, int *y, int *z) {
00411      *x = (int)(key / ((Uint32)MAP_WIDTH * (Uint32)MAP_WIDTH));
00412      *y = (int)((key % ((Uint32)MAP_WIDTH * (Uint32)MAP_WIDTH)) / (Uint32)MAP_WIDTH);
00413      *z = (int)((key % ((Uint32)MAP_WIDTH * (Uint32)MAP_WIDTH)) % (Uint32)MAP_WIDTH);
00414      //cerr << "DEBUG: decodeTripletKey, key=" << key << " x=" << (*x) << " y=" << (*y) << " z=" << (*z) << endl;
00415    }
00416 
00417    inline Uint32 createPairKey(int x, int y) {
00418      Uint32 key = 
00419        ((Uint32)x * (Uint32)MAP_WIDTH) + 
00420        ((Uint32)y);
00421      return key;
00422    }
00423 
00424    inline void decodePairKey(Uint32 key, int *x, int *y) {
00425      *x = (int)(key / ((Uint32)MAP_WIDTH));
00426      *y = (int)(key % ((Uint32)MAP_WIDTH));
00427    }
00428 
00429    CFrustum *frustum;
00430    CVector3 chunks[100];
00431    int chunkCount;
00432    DrawLater later[100], stencil[1000], other[1000], damage[1000];
00433    int laterCount, stencilCount, otherCount, damageCount;
00434    map<Uint32, EffectLocation*> currentEffectsMap;
00435   
00440   void setupShapes(bool ground, bool water, int *csx=NULL, int *cex=NULL, int *csy=NULL, int *cey=NULL);
00441   void setupPosition(int posX, int posY, int posZ,
00442                      float xpos2, float ypos2, float zpos2,
00443                      Shape *shape, Item *item, Creature *creature, 
00444                      EffectLocation *effect);
00445   void drawGroundPosition(int posX, int posY,
00446                                                   float xpos2, float ypos2,
00447                                                   Shape *shape);
00448   void drawWaterPosition(int posX, int posY,
00449                          float xpos2, float ypos2,
00450                          Shape *shape);
00451   bool isWall(int x, int y, int z);
00452 
00453   void configureLightMap();
00454   void traceLight(int chunkX, int chunkY, int lightMap[MAP_WIDTH / MAP_UNIT][MAP_DEPTH / MAP_UNIT], bool onlyLockedDoors);
00455   bool isLocationBlocked(int x, int y, int z, bool onlyLockedDoors);
00456 
00457   void drawShade();
00458 
00459   void drawProjectiles();
00460 
00461   void drawCube(float x, float y, float z, float r);
00462 
00463   void createOverlayTexture();    
00464 
00465   void removeEffect(Sint16 x, Sint16 y, Sint16 z);
00466   void removeAllEffects();
00467 
00468   void moveCreaturePos(Sint16 nx, Sint16 ny, Sint16 nz,
00469                        Sint16 ox, Sint16 oy, Sint16 oz,
00470                        Creature *creature);
00471 
00472   void drawWater();
00473 
00474   void removeCurrentEffects();
00475 
00476   void sortShapes( DrawLater *playerDrawLater,
00477                    DrawLater *shapes,
00478                    int shapeCount );
00479 };
00480 
00481 #endif

Generated on Thu Jun 16 21:50:43 2005 for scourge by  doxygen 1.4.0