00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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
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
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
00114 static const int X_CENTER_TOLERANCE = 8;
00115 static const int Y_CENTER_TOLERANCE = 8;
00116
00117
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
00128 static const int SHADE_SIZE = 20;
00129
00130 bool useShadow;
00131
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
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
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
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
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
00364 Uint32 oldDoor = createTripletKey(oldDoorX, oldDoorY, oldDoorZ);
00365 Uint32 newDoor = createTripletKey(newDoorX, newDoorY, newDoorZ);
00366
00367
00368 if(locked.find(oldDoor) != locked.end()) {
00369
00370 locked[newDoor] = locked[oldDoor];
00371 locked.erase(oldDoor);
00372 }
00373 if(doorToKey.find(oldDoor) != doorToKey.end()) {
00374
00375 Uint32 key = doorToKey[oldDoor];
00376 int keyX, keyY, keyZ;
00377 decodeTripletKey(key, &keyX, &keyY, &keyZ);
00378
00379 doorToKey[newDoor] = key;
00380 doorToKey.erase(oldDoor);
00381 keyToDoor[key] = newDoor;
00382 }
00383
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
00396 void configureAccessMap(int fromX, int fromY);
00397 bool isPositionAccessible(int atX, int atY);
00398
00399 protected:
00400
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
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
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