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

📄 dungeongenerator.cpp

📁 S.C.O.U.R.G.E.是一款类似Rogue的游戏
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			Item *item = scourge->newItem(mission->getObjective()->item[i]);			item->setBlocking(true); // don't let monsters pick this up			Item *pedestal = scourge->newItem(RpgItem::getItemByName("Pedestal"));			getRandomLocation(map, pedestal->getShape(), &x, &y);			addItem(map, NULL, pedestal, NULL, x, y);			addItem(map, NULL, item, NULL, 					x + (pedestal->getShape()->getWidth()/2) - (item->getShape()->getWidth()/2), 					y - (pedestal->getShape()->getDepth()/2) + (item->getShape()->getDepth()/2), 					pedestal->getShape()->getHeight());			cerr << "*** Added mission item: " << item->getItemName() << endl;		  }		  // add mission creatures		  for(int i = 0; i < mission->getObjective()->monsterCount; i++) {			GLShape *shape = 			  scourge->getShapePalette()->			  getCreatureBlockShape(mission->getObjective()->monster[i]->getModelName());			getRandomLocation(map, shape, &x, &y);					Creature *creature = scourge->newCreature(mission->getObjective()->monster[i]);			addItem(map, creature, NULL, NULL, x, y);			creature->moveTo(x, y, 0);			cerr << "*** Added mission monster: " << creature->getMonster()->getType() << endl;		  }		}    // add some scrolls with spells    for(int i = 0; i < objectCount / 4; i++) {			Spell *spell = MagicSchool::getRandomSpell(level);			if(!spell) {				cerr << "Warning: no spells defined for level: " << level << endl;				break;			}			Item *item = scourge->newItem(RpgItem::getItemByName("Scroll"), spell);			getRandomLocation(map, item->getShape(), &x, &y);			addItem(map, NULL, item, NULL, x, y);		}	}	updateStatus();  // add monsters in every room	if(monsters) {	  int totalLevel = scourge->getParty()->getTotalLevel();		//fprintf(stderr, "creating monsters for total player level: %d\n", totalLevel);		for(int i = 0; i < roomCount; i++) {			int levelSum = 0;			while(levelSum < totalLevel) {				Monster *monster = Monster::getRandomMonster(level - 1);				//fprintf(stderr, "Trying to add %s to room %d\n", monster->getType(), i);				if(!monster) {					cerr << "Warning: no monsters defined for level: " << level << endl;					break;				}				// use the creature's block shape to see if it would fit				GLShape *shape = 				  scourge->getShapePalette()->				  getCreatureBlockShape(monster->getModelName());				bool fits = getLocationInRoom(map, i, shape, &x, &y);				if(fits) {					//fprintf(stderr, "\tmonster fits at %d,%d.\n", x, y);					Creature *creature = scourge->newCreature(monster);					addItem(map, creature, NULL, NULL, x, y);					creature->moveTo(x, y, 0);					levelSum += level;				} else {					//fprintf(stderr, "\tmonster DOESN'T fit.\n");					break;				}			}		}			// add a few misc. monsters in the corridors (use objectCount to approx. number of wandering monsters)		for(int i = 0; i < objectCount * 2; i++) {			Monster *monster = Monster::getRandomMonster(level - 1);			if(!monster) {				cerr << "Warning: no monsters defined for level: " << level << endl;				break;			}				Creature *creature = scourge->newCreature(monster);			getRandomLocation(map, creature->getShape(), &x, &y);			addItem(map, creature, NULL, NULL, x, y);			creature->moveTo(x, y, 0);		}	}	updateStatus();	// add tables, chairs, etc.	addItemsInRoom(RpgItem::getItemByName("Table"), 1, preGenerated, locationIndex);	addItemsInRoom(RpgItem::getItemByName("Chair"), 2, preGenerated, locationIndex);		updateStatus();	// add a teleporters	if(!preGenerated) {	  int teleportersAdded = 0;	  for(int teleporterCount = 0; teleporterCount < 3; teleporterCount++) {		getRandomLocation(map, scourge->getShapePalette()->findShapeByName("TELEPORTER"), &x, &y);		if( x < MAP_WIDTH ) {		  cerr << "teleporter at " << x << "," << y << endl;		  addItem(scourge->getMap(), NULL, NULL, 				  scourge->getShapePalette()->findShapeByName("TELEPORTER"), 				  x, y, 1);		  addItem(scourge->getMap(), NULL, NULL, 				  scourge->getShapePalette()->findShapeByName("TELEPORTER_BASE"), 				  x, y);		  teleportersAdded++;		} else {		  cerr << "ERROR: couldn't add teleporter!!! #" << teleporterCount << endl;		}	  }	  if(teleportersAdded == 0) exit(0);	}	updateStatus();			// add the party in the first room	// FIXME: what happens if the party doesn't fit in the room?	//  for(int i = 0; i < roomCount; i++) {	for(int t = 0; t < scourge->getParty()->getPartySize(); t++) {		if(scourge->getParty()->getParty(t)->getStateMod(Constants::dead)) continue;		bool fits;		if(preGenerated && location[locationIndex].start[t][0] > 0) {			fits = true;			x = location[locationIndex].start[t][0] + offset;			y = location[locationIndex].start[t][1] + offset;		} else {			fits = 				getLocationInRoom(map, 								  0,								  scourge->getParty()->getParty(t)->getShape(), 								  &x, &y,								  true);		}		if(fits) {			addItem(map, scourge->getParty()->getParty(t), NULL, NULL, x, y);			scourge->getParty()->getParty(t)->moveTo(x, y, 0);			scourge->getParty()->getParty(t)->setSelXY(-1,-1);		}	}	updateStatus();	//}	  // free empty space container  free(ff);  }void DungeonGenerator::drawDoor(Map *map, ShapePalette *shapePal, 								Sint16 mapx, Sint16 mapy, int doorType) {  switch(doorType) {  case E_DOOR:	if(!coversDoor(map, shapePal, 				   shapePal->findShapeByName("EW_DOOR"), 				   mapx + unitSide - unitOffset + 1, mapy + unitSide - unitOffset - 2)) {	  map->setPosition(mapx + unitSide - unitOffset, mapy + unitSide - unitOffset, 					   wallHeight - 2, shapePal->findShapeByName("EW_DOOR_TOP"));	  map->setPosition(mapx + unitSide - unitOffset, mapy + unitOffset +  2, 					   0, shapePal->findShapeByName("DOOR_SIDE"));	  map->setPosition(mapx + unitSide - unitOffset, mapy + unitOffset * 2 +  2, 					   0, shapePal->findShapeByName("DOOR_SIDE"));	  map->setPosition(mapx + unitSide - unitOffset + 1, mapy + unitSide - unitOffset - 2, 					   0, shapePal->findShapeByName("EW_DOOR"));	  map->setPosition(mapx + unitSide - unitOffset, mapy + unitSide - unitOffset, 					   0, shapePal->findShapeByName("DOOR_SIDE"));	}	break;  case W_DOOR:	if(!coversDoor(map, shapePal, 				   shapePal->findShapeByName("EW_DOOR"), 				   mapx + 1, mapy + unitSide - unitOffset - 2)) {	  map->setPosition(mapx, mapy + unitSide - unitOffset, 					   wallHeight - 2, shapePal->findShapeByName("EW_DOOR_TOP"));	  map->setPosition(mapx, mapy + unitOffset +  2, 					   0, shapePal->findShapeByName("DOOR_SIDE"));	  map->setPosition(mapx, mapy + unitOffset * 2 +  2, 					   0, shapePal->findShapeByName("DOOR_SIDE"));	  map->setPosition(mapx + 1, mapy + unitSide - unitOffset - 2, 					   0, shapePal->findShapeByName("EW_DOOR"));	  map->setPosition(mapx, mapy + unitSide - unitOffset, 					   0, shapePal->findShapeByName("DOOR_SIDE"));	}	break;  case N_DOOR:	if(!coversDoor(map, shapePal, 				   shapePal->findShapeByName("NS_DOOR"), 				   mapx + unitOffset * 2, mapy + unitOffset - 1)) {	  map->setPosition(mapx + unitOffset, mapy + unitOffset, 					   wallHeight - 2, shapePal->findShapeByName("NS_DOOR_TOP"));	  map->setPosition(mapx + unitOffset, mapy + unitOffset, 					   0, shapePal->findShapeByName("DOOR_SIDE"));	  map->setPosition(mapx + unitOffset * 2, mapy + unitOffset - 1, 					   0, shapePal->findShapeByName("NS_DOOR"));	  map->setPosition(mapx + unitSide - unitOffset * 2, mapy + unitOffset, 					   0, shapePal->findShapeByName("DOOR_SIDE"));	  map->setPosition(mapx + unitSide - unitOffset * 3, mapy + unitOffset, 					   0, shapePal->findShapeByName("DOOR_SIDE"));	}	break;  case S_DOOR:	if(!coversDoor(map, shapePal, 				   shapePal->findShapeByName("NS_DOOR"), 				   mapx + unitOffset * 2, mapy + unitSide - 1)) {	  map->setPosition(mapx + unitOffset, mapy + unitSide, 					   wallHeight - 2, shapePal->findShapeByName("NS_DOOR_TOP"));	  map->setPosition(mapx + unitOffset, mapy + unitSide, 					   0, shapePal->findShapeByName("DOOR_SIDE"));	  map->setPosition(mapx + unitOffset * 2, mapy + unitSide - 1, 					   0, shapePal->findShapeByName("NS_DOOR"));	  map->setPosition(mapx + unitSide - unitOffset * 2, mapy + unitSide, 					   0, shapePal->findShapeByName("DOOR_SIDE"));	  map->setPosition(mapx + unitSide - unitOffset * 3, mapy + unitSide, 					   0, shapePal->findShapeByName("DOOR_SIDE"));	}	break;  }}// FIXME: low likelyhood of infinite loopvoid DungeonGenerator::getRandomLocation(Map *map, Shape *shape, int *xpos, int *ypos) {  int x, y;  while(1) {	// get a random location	int n = (int)((float)ffCount * rand()/RAND_MAX);	x = ff[n * 2];	y = ff[n * 2 + 1];		// can it fit?	bool fits = map->shapeFits(shape, x, y, 0);	// doesn't fit? try again (could be inf. loop)	if(fits && !coversDoor(map, scourge->getShapePalette(), shape, x, y)) {	  // remove from ff list	  for(int i = n + 1; i < ffCount - 1; i++) {		ff[i * 2] = ff[i * 2 + 2];		ff[i * 2 + 1] = ff[ i * 2 + 3];	  }	  ffCount--;	  // return result	  *xpos = x;	  *ypos = y;	  return;	}  }	}void DungeonGenerator::addItemsInRoom(RpgItem *rpgItem, int n, 																			bool preGenerated, int locationIndex) {	int x, y;	for(int i = 0; i < roomCount; i++) {		if(preGenerated && !location[locationIndex].roomDimension[i][4]) continue;		for(int r = 0; r < n; r++) {			for(int t = 0; t < 5; t++) { // 5 tries				Shape *shape = scourge->getShapePalette()->getShape(rpgItem->getShapeIndex());				bool fits = getLocationInRoom(scourge->getMap(), i, shape, &x, &y);				if(fits && !coversDoor(scourge->getMap(), scourge->getShapePalette(), shape, x, y)) {					Item *item = scourge->newItem(rpgItem);					addItem(scourge->getMap(), NULL, item, NULL, x, y);					break;				}			}		}	}}bool DungeonGenerator::addShapeInARoom(int shapeIndex) {	int x, y;	for(int tt = 0; tt < 5; tt++) { // 5 room tries		int i = (int)(roomCount * rand() / RAND_MAX);			for(int t = 0; t < 5; t++) { // 5 tries			Shape *shape = scourge->getShapePalette()->getShape(shapeIndex);			bool fits = getLocationInRoom(scourge->getMap(), i, shape, &x, &y);			if(fits && !coversDoor(scourge->getMap(), scourge->getShapePalette(), shape, x, y)) {				addItem(scourge->getMap(), NULL, NULL, shape, x, y);				return true;			}		}	}	return false;}// return false if the creature won't fit in the roombool DungeonGenerator::getLocationInRoom(Map *map, int roomIndex, Shape *shape, 										 int *xpos, int *ypos,										 bool startMiddle) {  int startx = offset + room[roomIndex].x * unitSide + unitOffset;  int endx = offset + (room[roomIndex].x + room[roomIndex].w) * unitSide;  int starty = offset + room[roomIndex].y * unitSide + unitOffset;  int endy = offset + (room[roomIndex].y + room[roomIndex].h) * unitSide;  Sint16* fff = (Sint16*)malloc( 2 * sizeof(Sint16) * (endx - startx) * (endy - starty) );    int count = 0;  for(int n = 0; n < ffCount; n++) {	if(ff[n * 2] >= startx && ff[n * 2] < endx &&	   ff[n * 2 + 1] >=starty && ff[n * 2 + 1] < endy) {	  fff[count * 2] = ff[n * 2];	  fff[count * 2 + 1] = ff[n * 2 + 1];	  count++;	}  }  bool fits = false;  while(count > 0) {	int pos = (int)((float)count * rand() / RAND_MAX);	int x = fff[pos * 2];	int y = fff[pos * 2 + 1];	fits = map->shapeFits(shape, x, y, 0);	if(fits) {	  // find this location in ff list	  for(int n = 0; n < ffCount; n++) {		if(x == ff[n * 2] && y == ff[n * 2 + 1]) {		  ff[n * 2] = ff[(ffCount - 1) * 2];		  ff[n * 2 + 1] = ff[(ffCount - 1) * 2 + 1];		  /*		  // remove from ff list		  for(int i = n + 1; i < ffCount - 1; i++) {			ff[i * 2] = ff[i * 2 + 2];			ff[i * 2 + 1] = ff[ i * 2 + 3];		  }		  */		  ffCount--;		  break;		}	  }	  *xpos = x;	  *ypos = y;	  break;	  	} else {	  // "remove" this from fff (replace w. last element and decrement counter)	  fff[pos * 2] = fff[(count - 1) * 2];	  fff[pos * 2 + 1] = fff[(count - 1) * 2 + 1];	  count--;	}  }  free(fff);  return fits;}bool DungeonGenerator::coversDoor(Map *map, ShapePalette *shapePal, 								  Shape *shape, int x, int y) {  for(int ty = y - shape->getDepth() - 3; ty < y + 3; ty++) {	for(int tx = x - 3; tx < x + shape->getWidth() + 3; tx++) {	  if(isDoor(map, shapePal, tx, ty)) return true;	}  }  return false;}bool DungeonGenerator::isDoor(Map *map, ShapePalette *shapePal, int tx, int ty) {  if(tx >= 0 && tx < MAP_WIDTH && 	 ty >= 0 && ty < MAP_DEPTH) {	Location *loc = map->getLocation(tx, ty, 0);	if(loc && 	   (loc->shape == shapePal->findShapeByName("EW_DOOR") ||		loc->shape == shapePal->findShapeByName("NS_DOOR"))) {	  return true;	}  }  return false;}void DungeonGenerator::addItem(Map *map, Creature *creature, Item *item, Shape *shape, int x, int y, int z) {  if(creature) map->setCreature(x, y, z, creature);  else if(item) map->setItem(x, y, z, item);  else map->setPosition(x, y, z, shape);  // populate containers  if(item && item->getRpgItem()->getType() == RpgItem::CONTAINER) {    // some items    int n = (int)(3.0f * rand() / RAND_MAX);    for(int i = 0; i < n; i++) {      RpgItem *containedItem = RpgItem::getRandomItem(level);      if(containedItem) item->addContainedItem(scourge->newItem(containedItem));    }    // some spells    if(!((int)(25.0f * rand() / RAND_MAX))) {      int n = (int)(2.0f * rand() / RAND_MAX) + 1;      for(int i = 0; i < n; i++) {        Spell *spell = MagicSchool::getRandomSpell(level);        if(spell) {          Item *scroll = scourge->newItem(RpgItem::getItemByName("Scroll"), spell);          item->addContainedItem(scroll);        }      }    }  }}

⌨️ 快捷键说明

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