⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 map.cpp

📁 S.C.O.U.R.G.E.是一款类似Rogue的游戏
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		  pos[x + xp][y - yp][z + zp] = NULL;                  }      }    }  }  return shape;}void Map::setItem(Sint16 x, Sint16 y, Sint16 z, Item *item) {  if(item) {    if(item->getShape()) {	  mapChanged = true;      for(int xp = 0; xp < item->getShape()->getWidth(); xp++) {        for(int yp = 0; yp < item->getShape()->getDepth(); yp++) {                    for(int zp = 0; zp < item->getShape()->getHeight(); zp++) {			            if(!pos[x + xp][y - yp][z + zp]) {              pos[x + xp][y - yp][z + zp] = new Location();            }            pos[x + xp][y - yp][z + zp]->item = item;			pos[x + xp][y - yp][z + zp]->shape = item->getShape();			pos[x + xp][y - yp][z + zp]->creature = NULL;            pos[x + xp][y - yp][z + zp]->x = x;            pos[x + xp][y - yp][z + zp]->y = y;            pos[x + xp][y - yp][z + zp]->z = z;          }        }      }  	}  }}Item *Map::removeItem(Sint16 x, Sint16 y, Sint16 z) {  Item *item = NULL;  if(pos[x][y][z] &&     pos[x][y][z]->item &&     pos[x][y][z]->x == x &&     pos[x][y][z]->y == y &&     pos[x][y][z]->z == z) {	mapChanged = true;	item = pos[x][y][z]->item;    for(int xp = 0; xp < item->getShape()->getWidth(); xp++) {      for(int yp = 0; yp < item->getShape()->getDepth(); yp++) {               for(int zp = 0; zp < item->getShape()->getHeight(); zp++) {		  		  delete pos[x + xp][y - yp][z + zp];		  pos[x + xp][y - yp][z + zp] = NULL;		        }      }    }  }  return item;}// drop items above this onevoid Map::dropItemsAbove(int x, int y, int z, Item *item) {  int count = 0;  Location drop[100];  for(int tx = 0; tx < item->getShape()->getWidth(); tx++) {	for(int ty = 0; ty < item->getShape()->getDepth(); ty++) {	  for(int tz = z + item->getShape()->getHeight(); tz < MAP_VIEW_HEIGHT; tz++) {		Location *loc2 = pos[x + tx][y - ty][tz];		if(loc2 && loc2->item) {		  drop[count].x = loc2->x;		  drop[count].y = loc2->y;		  drop[count].z = loc2->z - item->getShape()->getHeight();		  drop[count].item = loc2->item;		  count++;		  removeItem(loc2->x, loc2->y, loc2->z);		  tz += drop[count - 1].item->getShape()->getHeight() - 1;		}	  }	}  }  for(int i = 0; i < count; i++) {	cerr << "item " << drop[i].item->getItemName() << " new z=" << drop[i].z << endl;	setItem(drop[i].x, drop[i].y, drop[i].z, drop[i].item);  }}void Map::setCreature(Sint16 x, Sint16 y, Sint16 z, Creature *creature) {  char message[120];    if(creature) {    if(creature->getShape()) {	  mapChanged = true;	  while(true) {		for(int xp = 0; xp < creature->getShape()->getWidth(); xp++) {		  for(int yp = 0; yp < creature->getShape()->getDepth(); yp++) {			for(int zp = 0; zp < creature->getShape()->getHeight(); zp++) {			  //			  cerr <<"adding pos " << x + xp << "," << y - yp << "," << z + zp;			  if(!pos[x + xp][y - yp][z + zp]) {                if(!USE_LOC_CACHE || nbPosCache < 0){				  //                    cerr << " no cache available!" << endl;				    pos[x + xp][y - yp][z + zp] = new Location();                }                else{				  //                    cerr << " cache number : " << nbPosCache << endl;                    pos[x + xp][y - yp][z + zp] = posCache[nbPosCache];                    //posCache[nbPosCache] = NULL;                    nbPosCache--;                }			  } else if(pos[x + xp][y - yp][z + zp]->item) {				// creature picks up non-blocking item (this is the only way to handle 				// non-blocking items. It's also very 'roguelike'.				Item *item = pos[x + xp][y - yp][z + zp]->item;				removeItem(pos[x + xp][y - yp][z + zp]->x,						   pos[x + xp][y - yp][z + zp]->y,						   pos[x + xp][y - yp][z + zp]->z);				creature->addInventory(item);				sprintf(message, "%s picks up %s.", 						creature->getName(), 						item->getItemName());				addDescription(message);								// since the above will have removed some locations, try adding the creature again				continue;			  }			  pos[x + xp][y - yp][z + zp]->item = NULL;			  pos[x + xp][y - yp][z + zp]->shape = creature->getShape();			  pos[x + xp][y - yp][z + zp]->creature = creature;			  pos[x + xp][y - yp][z + zp]->x = x;			  pos[x + xp][y - yp][z + zp]->y = y;			  pos[x + xp][y - yp][z + zp]->z = z;			  //creature->moveTo(x, y, z);			}		  }		}		break;	  }	}  }}Creature *Map::removeCreature(Sint16 x, Sint16 y, Sint16 z) {  Creature *creature = NULL;  if(pos[x][y][z] &&     pos[x][y][z]->creature &&     pos[x][y][z]->x == x &&     pos[x][y][z]->y == y &&     pos[x][y][z]->z == z) {	mapChanged = true;    creature = pos[x][y][z]->creature;	//    cout<<"width : "<< creature->getShape()->getWidth()<<endl;	//    cout<<"depth: "<< creature->getShape()->getDepth()<<endl;	//    cout<<"height: "<< creature->getShape()->getHeight()<<endl;    for(int xp = 0; xp < creature->getShape()->getWidth(); xp++) {      for(int yp = 0; yp < creature->getShape()->getDepth(); yp++) {        for(int zp = 0; zp < creature->getShape()->getHeight(); zp++) {		  //            cerr <<"deleting pos " << x + xp << "," << y - yp << "," << z + zp;            if(!USE_LOC_CACHE || nbPosCache >= MAX_POS_CACHE - 1){			  //                cerr << " no cache available!" << endl;                delete pos[x + xp][y - yp][z + zp];                pos[x + xp][y - yp][z + zp] = NULL;            }            else{                nbPosCache++;				//                cerr << " cache number : " << nbPosCache << endl;                posCache[nbPosCache] = pos[x + xp][y - yp][z + zp];                pos[x + xp][y - yp][z + zp] = NULL;                            }        }      }    }  }  return creature;}// FIXME: only uses x,y for now// return false if there is any hole in the wallsbool Map::isWallBetweenShapes(int x1, int y1, int z1,							  Shape *shape1,							  int x2, int y2, int z2,							  Shape *shape2) {  for(int x = x1; x < x1 + shape1->getWidth(); x++) {	for(int y = y1; y < y1 + shape1->getDepth(); y++) {	  for(int xx = x2; xx < x2 + shape2->getWidth(); xx++) {		for(int yy = y2; yy < y2 + shape2->getDepth(); yy++) {		  if(!isWallBetween(x, y, z1, xx, yy, z2)) return false;		}	  }	}  }  return true;	  }// FIXME: only uses x,y for nowbool Map::isWallBetween(int x1, int y1, int z1,						int x2, int y2, int z2) {  if(x1 == x2 && y1 == y2) return isWall(x1, y1, z1);  if(x1 == x2) {	if(y1 > y2) SWAP(y1, y2);	for(int y = y1; y <= y2; y++) {	  if(isWall(x1, y, z1)) return true;	}	return false;  }  if(y1 == y2) {	if(x1 > x2) SWAP(x1, x2);	for(int x = x1; x <= x2; x++) {	  if(isWall(x, y1, z1)) return true;	}	return false;  }    //  fprintf(stderr, "Checking for wall: from: %d,%d to %d,%d\n", x1, y1, x2, y2);  bool ret = false;  bool yDiffBigger = (abs(y2 - y1) > abs(x2 - x1));  float m = (float)(y2 - y1) / (float)(x2 - x1);  int steps = (yDiffBigger ? abs(y2 - y1) : abs(x2 - x1));  float x = x1;  float y = y1;  for(int i = 0; i < steps; i++) {	//	fprintf(stderr, "\tat=%f,%f\n", x, y);	if(isWall((int)x, (int)y, z1)) {	  //fprintf(stderr, "wall at %f, %f\n", x, y);	  ret = true;	  break;	}	if(yDiffBigger) {	  if(y1 < y2) y += 1.0f;	  else y -= 1.0f;	  if(x1 < x2) x += 1.0f / abs((int)m);	  else x += -1.0f / abs((int)m);	} else {	  if(x1 < x2) x += 1.0f;	  else x -= 1.0f;	  if(y1 < y2) y += abs((int)m);	  else y += -1.0 * abs((int)m);	}  }  //  fprintf(stderr, "wall in between? %s\n", (ret ? "TRUE": "FALSE"));  return ret;}bool Map::isWall(int x, int y, int z) {  Location *loc = getLocation((int)x, (int)y, z);  return (loc && 		  (!loc->item || loc->item->getShape() != loc->shape) && 		  (!loc->creature || loc->creature->getShape() != loc->shape));}// FIXME: only uses x, y for nowbool Map::shapeFits(Shape *shape, int x, int y, int z) {  for(int tx = 0; tx < shape->getWidth(); tx++) {	for(int ty = 0; ty < shape->getDepth(); ty++) {	  if(getLocation(x + tx, y - ty, 0)) {		return false;	  }	}  }  return true;}// FIXME: only uses x, y for nowLocation *Map::getBlockingLocation(Shape *shape, int x, int y, int z) {  for(int tx = 0; tx < shape->getWidth(); tx++) {	for(int ty = 0; ty < shape->getDepth(); ty++) {	  Location *loc = getLocation(x + tx, y - ty, 0);	  if(loc) return loc;	}  }  return NULL;}/**   Return the drop location, or NULL if none */Location *Map::getDropLocation(Shape *shape, int x, int y, int z) {  for(int tx = 0; tx < shape->getWidth(); tx++) {	for(int ty = 0; ty < shape->getDepth(); ty++) {	  Location *loc = getLocation(x + tx, y - ty, z);	  if(loc) {		return loc;	  }	}  }  return NULL;}// the world has changed...void Map::configureLightMap() {  lightMapChanged = false;  // draw nothing at first  for(int x = 0; x < MAP_WIDTH / MAP_UNIT; x++) {	for(int y = 0; y < MAP_DEPTH / MAP_UNIT; y++) {	  lightMap[x][y] = (LIGHTMAP_ENABLED ? 0 : 1);	}  }  if(!LIGHTMAP_ENABLED) return;  int chunkX = (scourge->getParty()->getPlayer()->getX() + 				(scourge->getParty()->getPlayer()->getShape()->getWidth() / 2) - 				MAP_OFFSET) / MAP_UNIT;  int chunkY = (scourge->getParty()->getPlayer()->getY() - 				(scourge->getParty()->getPlayer()->getShape()->getDepth() / 2) - 				MAP_OFFSET) / MAP_UNIT;  traceLight(chunkX, chunkY);}void Map::traceLight(int chunkX, int chunkY) {  if(chunkX < 0 || chunkX >= MAP_WIDTH / MAP_UNIT ||	 chunkY < 0 || chunkY >= MAP_DEPTH / MAP_UNIT)	return;  // already visited?  if(lightMap[chunkX][chunkY]) return;  // let there be light  lightMap[chunkX][chunkY] = 1;    // can we go N?  int x, y;  bool blocked = false;  x = chunkX * MAP_UNIT + MAP_OFFSET + (MAP_UNIT / 2);  for(y = chunkY * MAP_UNIT + MAP_OFFSET - (MAP_UNIT / 2);	  y < chunkY * MAP_UNIT + MAP_OFFSET + (MAP_UNIT / 2);	  y++) {   	if(isLocationBlocked(x, y, 0)) {	  blocked = true;	  break;	}  }  if(!blocked) traceLight(chunkX, chunkY - 1);    // can we go E?  blocked = false;  y = chunkY * MAP_UNIT + MAP_OFFSET + (MAP_UNIT / 2);  for(x = chunkX * MAP_UNIT + MAP_OFFSET + (MAP_UNIT / 2);	  x < chunkX * MAP_UNIT + MAP_OFFSET + (MAP_UNIT / 2) + MAP_UNIT;	  x++) {	if(isLocationBlocked(x, y, 0)) {	  blocked = true;	  break;	}  }  if(!blocked) traceLight(chunkX + 1, chunkY);    // can we go S?  blocked = false;  x = chunkX * MAP_UNIT + MAP_OFFSET + (MAP_UNIT / 2);  for(y = chunkY * MAP_UNIT + MAP_OFFSET + (MAP_UNIT / 2);	  y < chunkY * MAP_UNIT + MAP_OFFSET + (MAP_UNIT / 2) + MAP_UNIT;	  y++) {	if(isLocationBlocked(x, y, 0)) {	  blocked = true;	  break;	}  }  if(!blocked) traceLight(chunkX, chunkY + 1);  // can we go W?  blocked = false;  y = chunkY * MAP_UNIT + MAP_OFFSET + (MAP_UNIT / 2);  for(x = chunkX * MAP_UNIT + MAP_OFFSET - (MAP_UNIT / 2);	  x < chunkX * MAP_UNIT + MAP_OFFSET + (MAP_UNIT / 2);	  x++) {	if(isLocationBlocked(x, y, 0)) {	  blocked = true;	  break;	}  }  if(!blocked) traceLight(chunkX - 1, chunkY);}bool Map::isLocationBlocked(int x, int y, int z) {	if(x >= 0 && x < MAP_WIDTH && 		 y >= 0 && y < MAP_DEPTH && 		 z >= 0 && z < MAP_VIEW_HEIGHT) {		Location *pos = getLocation(x, y, z);		if(pos == NULL || pos->item || pos->creature || 			 !( ((GLShape*)(pos->shape))->isLightBlocking()) ) {			return false;		}	}	return true;}void Map::drawCube(float x, float y, float z, float r) {  glBegin(GL_QUADS);  // front  glNormal3f(0.0, 0.0, 1.0);  glVertex3f(-r+x, -r+y, r+z);  glVertex3f(r+x, -r+y, r+z);  glVertex3f(r+x, r+y, r+z);  glVertex3f(-r+x, r+y, r+z);    // back  glNormal3f(0.0, 0.0, -1.0);  glVertex3f(r+x, -r+y, -r+z);  glVertex3f(-r+x, -r+y, -r+z);  glVertex3f(-r+x, r+y, -r+z);  glVertex3f(r+x, r+y, -r+z);    // top  glNormal3f(0.0, 1.0, 0.0);  glVertex3f(-r+x, r+y, r+z);  glVertex3f(r+x, r+y, r+z);  glVertex3f(r+x, r+y, -r+z);  glVertex3f(-r+x, r+y, -r+z);    // bottom  glNormal3f(0.0, -1.0, 0.0);  glVertex3f(-r+x, -r+y, -r+z);  glVertex3f(r+x, -r+y, -r+z);  glVertex3f(r+x, -r+y, r+z);  glVertex3f(-r+x, -r+y, r+z);    // left  glNormal3f(-1.0, 0.0, 0.0);  glVertex3f(-r+x, -r+y, -r+z);  glVertex3f(-r+x, -r+y, r+z);  glVertex3f(-r+x, r+y, r+z);  glVertex3f(-r+x, r+y, -r+z);    // right  glNormal3f(1.0, 0.0, 0.0);  glVertex3f(r+x, -r+y, r+z);  glVertex3f(r+x, -r+y, -r+z);  glVertex3f(r+x, r+y, -r+z);  glVertex3f(r+x, r+y, r+z);    glEnd();  }/** * Find the creatures in this area and add them to the targets array. * Returns the number of creatures found. (0 if none.) * It's the caller responsibility to create the targets array. */int Map::getCreaturesInArea(int x, int y, int radius, Creature *targets[]) {  int count = 0;  for(int xx = x - radius; xx < x + radius && xx < MAP_WIDTH; xx++) {    for(int yy = y - radius; yy < y + radius && yy < MAP_DEPTH; yy++) {      Location *loc = pos[xx][yy][0];            if(loc && loc->creature) {        bool alreadyFound = false;        for(int i = 0; i < count; i++) {          if(targets[i] == loc->creature) {            alreadyFound = true;            break;          }        }        if(!alreadyFound) {          targets[count++] = loc->creature;        }      }    }  }  return count;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -