예제 #1
0
// @author Andre Allan Ponce
// prepping the first two rooms
void Game::preGameInit(){
	world[currX][currY] = makeRoom(RoomData::ROOM_BEDROOM,currX,currY);
	std::cout << "here\n";
	world[currX][currY]->setPlayer(START_PLAYER_X,START_PLAYER_Y,PLAYER_SYMBOL);
	std::cout << "hree2\n";
	world[currX][START_ROOM_Y] = makeRoom(RoomData::ROOM_HALLWAY,currX,START_ROOM_Y);
	player = new Player(PLAYER_SYMBOL);
	player->setBoardLocX(currX);
	player->setBoardLocY(currY);
	player->setRoomLocX(START_PLAYER_X);
	player->setRoomLocY(START_PLAYER_Y);
	state = STATE_LEVEL_ONE;
}
ALWAYS_INLINE
void BaseSet::addImpl(int64_t k) {
  if (!raw) {
    mutate();
  }
  auto h = hashint(k);
  auto p = findForInsert(k, h);
  assert(p);
  if (validPos(*p)) {
    // When there is a conflict, the add() API is supposed to replace the
    // existing element with the new element in place. However since Sets
    // currently only support integer and string elements, there is no way
    // user code can really tell whether the existing element was replaced
    // so for efficiency we do nothing.
    return;
  }
  if (UNLIKELY(isFull())) {
    makeRoom();
    p = findForInsert(k, h);
  }
  auto& e = allocElm(p);
  e.setIntKey(k, h);
  e.data.m_type = KindOfInt64;
  e.data.m_data.num = k;
  updateNextKI(k);
  if (!raw) {
    ++m_version;
  }
}
예제 #3
0
ALWAYS_INLINE
void BaseMap::setImpl(int64_t h, const TypedValue* val) {
  if (!raw) {
    mutate();
  }
  assert(val->m_type != KindOfRef);
  assert(canMutateBuffer());
retry:
  auto p = findForInsert(h);
  assert(p);
  if (validPos(*p)) {
    auto& e = data()[*p];
    TypedValue old = e.data;
    cellDup(*val, e.data);
    tvRefcountedDecRef(old);
    return;
  }
  if (UNLIKELY(isFull())) {
    makeRoom();
    goto retry;
  }
  if (!raw) {
    ++m_version;
  }
  auto& e = allocElm(p);
  cellDup(*val, e.data);
  e.setIntKey(h);
  updateNextKI(h);
}
예제 #4
0
ALWAYS_INLINE
void BaseMap::setImpl(StringData* key, const TypedValue* val) {
  if (!raw) {
    mutate();
  }
  assert(val->m_type != KindOfRef);
  assert(canMutateBuffer());
retry:
  strhash_t h = key->hash();
  auto* p = findForInsert(key, h);
  assert(p);
  if (validPos(*p)) {
    auto& e = data()[*p];
    TypedValue old = e.data;
    cellDup(*val, e.data);
    tvRefcountedDecRef(old);
    return;
  }
  if (UNLIKELY(isFull())) {
    makeRoom();
    goto retry;
  }
  if (!raw) {
    ++m_version;
  }
  auto& e = allocElm(p);
  cellDup(*val, e.data);
  e.setStrKey(key, h);
  updateIntLikeStrKeys(key);
}
예제 #5
0
	void DataCompressionLayer::writeDouble(double toWrite)
	{
		makeRoom(8);
		ByteUtilities::writeLong(inBuf + bufferIndex, ByteUtilities::convertDoubleToLong(toWrite));
		bufferIndex += 8;
		pInc(8);
	}
예제 #6
0
int GvMField::set(const char* s)
{
	//delete contents 
	makeRoom(0);

	// TRACE("Parsing an MField from :%s\n",s);

	if (strcmp(s,"[]") == 0) {
		setDefault(TRUE);
		OnChanged();
  		return(1);
	} 


	// create a parser 
	GvInput in;

    in.setString(s);
	in.version = 2.0;
	in.vrml2 = 1;
	
	// read 
	int ret = this->readValue(&in);

	setDefault(FALSE);
	OnChanged();

	return ret;
}
예제 #7
0
	void DataCompressionLayer::writeInt(int toWrite)
	{
		makeRoom(4);
		ByteUtilities::writeInt(inBuf + bufferIndex, toWrite);
		bufferIndex += 4;
		pInc(4);
	}
예제 #8
0
	void DataCompressionLayer::writeLong(uint64_t toWrite)
	{
		makeRoom(8);
		ByteUtilities::writeLong(inBuf + bufferIndex, toWrite);
		bufferIndex += 8;
		pInc(8);
	}
예제 #9
0
int main(int aroom_gridc, char *argv[])
{
    roomGrid roomStuff, *room_grid;
    room_grid = &roomStuff;

    progress puzzlesolved, *puzzle;
    puzzle = &puzzlesolved;

    Chicken Fowl, *hen;
    hen = &Fowl;

    FILE *map_file = NULL;
    map_file = fopen(argv[1], "r");

    if (map_file == NULL){
        printf("File could not be opened.\n");
        exit(1);
    }

    printf("File was opened.\n");

    makeRoom(room_grid, map_file);

    fclose(map_file);

    run_menu_screen(room_grid);

    run_main_game(room_grid, puzzle, hen);

    print_room_array(room_grid, puzzle);

    free_room_array(room_grid);

    return(0);
}
예제 #10
0
_ANTLRTokenPtr ANTLRTokenBuffer::
getToken()
{
	if ( tp <= last )	// is there any buffered lookahead still to be read?
	{
		return *tp++;	// read buffered lookahead
	}
	// out of buffered lookahead, get some more "real"
	// input from getANTLRToken()
	if ( num_markers==0 )
	{
		if( next > threshold )
		{
#ifdef DBG_TBUF
fprintf(stderr,"getToken: next > threshold (high water is %d)\n", threshold-buffer);
#endif
			makeRoom();
		}
	}
	else {
		if ( next > end_of_buffer )
		{
#ifdef DBG_TBUF
fprintf(stderr,"getToken: next > end_of_buffer (size is %d)\n", buffer_size);
#endif
			extendBuffer();
		}
	}
	*next = getANTLRToken();
	(*next)->ref();				// say we have a copy of this pointer in buffer
	last = next;
	next++;
	tp = last;
	return *tp++;
}
예제 #11
0
ALWAYS_INLINE
void BaseSet::addImpl(StringData *key) {
  if (!raw) {
    mutate();
  }
  strhash_t h = key->hash();
  auto p = findForInsert(key, h);
  assert(p);
  if (validPos(*p)) {
    return;
  }
  if (UNLIKELY(isFull())) {
    makeRoom();
    p = findForInsert(key, h);
  }
  auto& e = allocElm(p);
  // This increments the string's refcount twice, once for
  // the key and once for the value
  e.setStrKey(key, h);
  cellDup(make_tv<KindOfString>(key), e.data);
  updateIntLikeStrKeys(key);
  if (!raw) {
    ++m_version;
  }
}
예제 #12
0
void NetworkMessageWriter::uint32(quint32 data)
{
    int size = sizeof(quint32);
    makeRoom(size);

    *((quint32 *)m_currentPos) = data;
    m_currentPos += size;
}
예제 #13
0
 void NetworkMessageWriter::int64(qint64 data)
 {
     int size = sizeof(qint64);
     makeRoom(size);

     *((qint64 *)m_currentPos) = data;
     m_currentPos += size;
 }
예제 #14
0
void NetworkMessageWriter::byteArray32(const QByteArray & data)
{
    int size = data.size();
    uint32(size);
    makeRoom(size);
    memcpy(m_currentPos, data.constData(), size);
    m_currentPos += size;
}
예제 #15
0
void NetworkMessageWriter::rgb(const QColor & color)
{
    int size = sizeof(QRgb);
    makeRoom(size);

    *((QRgb *)m_currentPos) = color.rgb();
    m_currentPos += size;
}
예제 #16
0
void NetworkMessageWriter::string(const QString & data, int sizeQChar)
{
    int sizeBytes = sizeQChar * sizeof(QChar);

    makeRoom(sizeBytes);
    memcpy(m_currentPos, data.constData(), sizeBytes);
    m_currentPos += sizeBytes;
}
예제 #17
0
void RowCache::addRowsOwn(RowBlock * rows)
{
    if (allRows.ordinality() == MaxBlocksCached)
        makeRoom();

    unsigned newPos = getInsertPosition(rows->getStartRow());
    allRows.add(*rows, newPos);
    ages.add(++rowCacheId, newPos);
}
예제 #18
0
//
// This function hands a KHttpCookie object over to the cookie jar.
//
// On return cookiePtr is set to 0.
//
void KCookieJar::addCookie(KHttpCookiePtr &cookiePtr)
{
    QStringList domains;
    KHttpCookieList *cookieList = 0L;

    // We always need to do this to make sure that the
    // that cookies of type hostname == cookie-domainname
    // are properly removed and/or updated as necessary!
    extractDomains( cookiePtr->host(), domains );
    for ( QStringList::ConstIterator it = domains.begin();
          (it != domains.end() && !cookieList);
          ++it )
    {
        QString key = (*it).isNull() ? L1("") : (*it);
        KHttpCookieList *list= m_cookieDomains[key];
        if ( !list ) continue;

        removeDuplicateFromList(list, cookiePtr, false, true);
    }

    QString domain = stripDomain( cookiePtr );
    QString key = domain.isNull() ? L1("") : domain;
    cookieList = m_cookieDomains[ key ];
    if (!cookieList)
    {
        // Make a new cookie list
        cookieList = new KHttpCookieList();
        cookieList->setAutoDelete(true);

        // All cookies whose domain is not already
        // known to us should be added with KCookieDunno.
        // KCookieDunno means that we use the global policy.
        cookieList->setAdvice( KCookieDunno );

        m_cookieDomains.insert( domain, cookieList);

        // Update the list of domains
        m_domainList.append(domain);
    }

    // Add the cookie to the cookie list
    // The cookie list is sorted 'longest path first'
    if (!cookiePtr->isExpired(time(0)))
    {
#ifdef MAX_COOKIE_LIMIT
        if (cookieList->count() >= MAX_COOKIES_PER_HOST)
           makeRoom(cookieList, cookiePtr); // Delete a cookie
#endif
        cookieList->inSort( cookiePtr );
        m_cookiesChanged = true;
    }
    else
    {
        delete cookiePtr;
    }
    cookiePtr = 0;
}
예제 #19
0
char* ResCache::allocate( unsigned int size ) {
	if( !makeRoom(size) )
		return NULL;

	char* mem = new char[size];
	if( mem ) {
		m_allocated += size;
	}

	return mem;
}//ResCache::allocate
예제 #20
0
	void DataCompressionLayer::writeFile(FILE* toWrite)
	{
		while (!feof(toWrite))
		{
			makeRoom(BUFFER_SIZE);
			assert(bufferIndex == 0);
			unsigned int read= fread(inBuf, sizeof(char), BUFFER_SIZE, toWrite);
			bufferIndex += read;
			pInc(read);
		}
		flush();
	}
예제 #21
0
void
SoMFName::setValues(int start, int num, const char *strings[])
{
    int	newNum = start + num;
    int	i;

    if (newNum > getNum())
	makeRoom(newNum);

    for (i = 0; i < num; i++)
	values[start + i] = strings[i];

    valueChanged();
}
예제 #22
0
// @author Andre Allan Ponce
// more randomly generating rooms
Location* Game::createRandomRoom(int x, int y, int roomDoor){
	int id;
	bool hasNoDoor = true;
	do{
		id = getRandomNumber();
		if(id == roomData.ROOM_LIVINGROOM && isFinalDoorIn){ // thats the final room, cant have two of those
			hasNoDoor = false;
		}
		else if(roomData.retrieveDoorSpot(id,roomDoor) > 0){
			hasNoDoor = false;
		}
	}while(hasNoDoor);
	if(id == roomData.ROOM_LIVINGROOM){
		isFinalDoorIn = true;
	}
	return makeRoom(id,x,y);
}
예제 #23
0
void
SoMFColor::setValues(int start,			// Starting index
		     int num,			// Number of values to set
		     const float rgb[][3])	// Array of RGB values
//
////////////////////////////////////////////////////////////////////////
{
    int	newNum = start + num;
    int	i;

    if (newNum > getNum())
	makeRoom(newNum);

    for (i = 0; i < num; i++)
	values[start + i].setValue(rgb[i]);

    valueChanged();
}
예제 #24
0
	bool createFeature(int x, int y, Direction dir)
	{
		static const int roomChance = 50; // corridorChance = 100 - roomChance

		int dx = 0;
		int dy = 0;

		if (dir == North)
			dy = 1;
		else if (dir == South)
			dy = -1;
		else if (dir == West)
			dx = 1;
		else if (dir == East)
			dx = -1;

		if (getTile(x + dx, y + dy) != Floor && getTile(x + dx, y + dy) != Corridor)
			return false;

		if (randomInt(100) < roomChance)
		{
			if (makeRoom(x, y, dir))
			{
				setTile(x, y, ClosedDoor);

				return true;
			}
		}

		else
		{
			if (makeCorridor(x, y, dir))
			{
				if (getTile(x + dx, y + dy) == Floor)
					setTile(x, y, ClosedDoor);
				else // don't place a door between corridors
					setTile(x, y, Corridor);

				return true;
			}
		}

		return false;
	}
예제 #25
0
	void generate(int maxFeatures)
	{
		// place the first room in the center
		if (!makeRoom(_width / 2, _height / 2, static_cast<Direction>(randomInt(4), true)))
		{
			std::cout << "Unable to place the first room.\n";
			return;
		}

		// we already placed 1 feature (the first room)
		for (int i = 1; i < maxFeatures; ++i)
		{
			if (!createFeature())
			{
				std::cout << "Unable to place more features (placed " << i << ").\n";
				break;
			}
		}

		if (!placeObject(UpStairs))
		{
			std::cout << "Unable to place up stairs.\n";
			return;
		}

		if (!placeObject(DownStairs))
		{
			std::cout << "Unable to place down stairs.\n";
			return;
		}

		for (char& tile : _tiles)
		{
			if (tile == Unused)
				tile = ' ';
			else if (tile == Floor || tile == Corridor)
				tile = ' ';
		}
	}
예제 #26
0
void DungeonGen::makeDungeon(v3s16 start_padding)
{
	v3s16 areasize = vmanip->m_area.getExtent();
	v3s16 roomsize;
	v3s16 roomplace;

	/*
		Find place for first room
	*/
	bool fits = false;
	for (u32 i = 0; i < 100; i++)
	{
		bool is_large_room = ((random.next() & 3) == 1);
		roomsize = is_large_room ?
			v3s16(random.range(8, 16),random.range(8, 16),random.range(8, 16)) :
			v3s16(random.range(4,  8),random.range(4,  6),random.range(4, 8));
		
		// start_padding is used to disallow starting the generation of
		// a dungeon in a neighboring generation chunk
		roomplace = vmanip->m_area.MinEdge + start_padding + v3s16(
			random.range(0,areasize.X-roomsize.X-1-start_padding.X),
			random.range(0,areasize.Y-roomsize.Y-1-start_padding.Y),
			random.range(0,areasize.Z-roomsize.Z-1-start_padding.Z));
			
		/*
			Check that we're not putting the room to an unknown place,
			otherwise it might end up floating in the air
		*/
		fits = true;
		for (s16 z = 1; z < roomsize.Z - 1; z++)
		for (s16 y = 1; y < roomsize.Y - 1; y++)
		for (s16 x = 1; x < roomsize.X - 1; x++)
		{
			v3s16 p = roomplace + v3s16(x, y, z);
			u32 vi = vmanip->m_area.index(p);
			if (vmanip->m_flags[vi] & VMANIP_FLAG_DUNGEON_INSIDE)
			{
				fits = false;
				break;
			}
			if (vmanip->m_data[vi].getContent() == CONTENT_IGNORE)
			{
				fits = false;
				break;
			}
		}
		if (fits)
			break;
	}
	// No place found
	if (fits == false)
		return;

	/*
		Stores the center position of the last room made, so that
		a new corridor can be started from the last room instead of
		the new room, if chosen so.
	*/
	v3s16 last_room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2);

	u32 room_count = random.range(2, 16);
	for (u32 i = 0; i < room_count; i++)
	{
		// Make a room to the determined place
		makeRoom(roomsize, roomplace);

		v3s16 room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2);

		// Place torch at room center (for testing)
		//vmanip->m_data[vmanip->m_area.index(room_center)] = MapNode(cid_torch);

		// Quit if last room
		if (i == room_count - 1)
			break;

		// Determine walker start position

		bool start_in_last_room = (random.range(0, 2) != 0);

		v3s16 walker_start_place;

		if(start_in_last_room)
		{
			walker_start_place = last_room_center;
		}
		else
		{
			walker_start_place = room_center;
			// Store center of current room as the last one
			last_room_center = room_center;
		}

		// Create walker and find a place for a door
		v3s16 doorplace;
		v3s16 doordir;
		
		m_pos = walker_start_place;
		bool r = findPlaceForDoor(doorplace, doordir);
		if (r == false)
			return;

		if (random.range(0,1) == 0)
			// Make the door
			makeDoor(doorplace, doordir);
		else
			// Don't actually make a door
			doorplace -= doordir;

		// Make a random corridor starting from the door
		v3s16 corridor_end;
		v3s16 corridor_end_dir;
		makeCorridor(doorplace, doordir, corridor_end, corridor_end_dir);

		// Find a place for a random sized room
		roomsize = v3s16(random.range(4,8),random.range(4,6),random.range(4,8));
		m_pos = corridor_end;
		m_dir = corridor_end_dir;
		r = findPlaceForRoomDoor(roomsize, doorplace, doordir, roomplace);
		if (r == false)
			return;

		if (random.range(0,1) == 0)
			// Make the door
			makeDoor(doorplace, doordir);
		else
			// Don't actually make a door
			roomplace -= doordir;

	}
}
예제 #27
0
int 
GvMField::ioValue(AStream &a)
{
    char c;
    int	curIndex = 0;

	if (a.IsInput()) {
    	c = a.Skip();
    	if (c == OPEN_BRACE_CHAR) {
			  c = a.getc();
			  c = a.Skip();

			  if (CLOSE_BRACE_CHAR) {
			  	 c = a.getc();
	    	   }						
			   else {

	    		while (TRUE) {

				if (curIndex >= num)
		    		makeRoom(curIndex + 1);

				if (!io1Value(a, curIndex++) ) {
		    		a.Error( "Couldn't read value %d of field",  curIndex);
		    	    return FALSE;
				}
				c = a.Skip();

				if (c == VALUE_SEPARATOR_CHAR) {
 				    c = a.getc();
		    		c = a.Skip();
					if (c == CLOSE_BRACE_CHAR) {
 				       c = a.getc();
			    	   break;
					}
				}

				else if (c == CLOSE_BRACE_CHAR) {
 				    c = a.getc();
		    		break;
				}
				else {
		    		a.Error("Expected '%c' or '%c' but got "
				      "'%c' while reading value %d",
				      VALUE_SEPARATOR_CHAR,
				      CLOSE_BRACE_CHAR, c,
				      curIndex);
		    		return FALSE;
				}
	    		} // While 
			}

	if (curIndex < num)
	    makeRoom(curIndex);
    
    }  // no open brace
    else {
		makeRoom(1);
		if (! io1Value(a, 0))
	    return FALSE;
    }
	}	// input 
	else { // output 

		if (Length() == 0 ) {
		  a.Sep(OPEN_BRACE_CHAR);
		  a.Sep(CLOSE_BRACE_CHAR);

		} else 
		if (Length() == 1 ) {
		   io1Value(a,0);
		} else {
		a.Sep(OPEN_BRACE_CHAR); a.TabIn();
		while (curIndex < Length()) {
		 	if (curIndex>0) a.Sep(VALUE_SEPARATOR_CHAR);
		 	io1Value(a,curIndex);
			if (curIndex % 4 == 0) a.nl();
			curIndex ++;
		}
		a.TabOut();
		a.Sep(CLOSE_BRACE_CHAR);
		}

	}

    return TRUE;
}
예제 #28
0
// read a list of value until endChar found
// endChar is not read !
GvBool
GvMField::readValueList(GvInput *in,int endChar)
{
    char c;
    int	curIndex = num; // means append

    GvBool needComma = FALSE;

    GvBool isMfNode = RTISA(this,GvMFNode);


    // check for list end 
	if (in->read(c)) {
        if ( c == endChar) {
	        in->putBack(c);
            return TRUE;
        }
    } else {
        if (endChar == EOF && in->eof()) 
            return TRUE;
		else return FALSE;
    }

    in->putBack(c);
    

    // read all values
    {
	    while (TRUE) {

		if (curIndex >= num)
		    makeRoom(curIndex + 1);

		if (! read1Value(in, curIndex++)) {
             num--; // ignore last value 

			// get next char
		    if (!in->read(c)) {
				if (endChar == EOF) break;
			}
			else if (c == endChar) {
  				in->putBack(c);
				break;
			}
			else if ((c == CLOSE_BRACE) || (c == CLOSE_BRACE_CHAR)) { // 22.09.96. Syntax error ? 
  				in->putBack(c);
				break;
			}


            GvReadError::post(in, GV_RE_SYNTAX_ERROR, "%s::Couldn't read value %d of field", getContainer() ? getContainer()->GetType():"",
                                    curIndex);
            return FALSE;
		}

        // get next char
        if (!in->read(c)) {
            if (endChar == EOF) break;
            else {
               GvReadError::post(in,GV_RE_SYNTAX_ERROR, "%s::Couldn't read value %d of field", getContainer() ? getContainer()->GetType():"",curIndex);
            }    
             return FALSE;
		}

		if (c == VALUE_SEPARATOR_CHAR) {
		    if (in->read(c)) {
			    if (c == endChar) {
			        in->putBack(c);
            	    break;
                }
			    else
			        in->putBack(c);
		    }
		}

		else if (c == endChar) {
  	        in->putBack(c);
		    break;
        }
		else if ((c == CLOSE_BRACE) || (c == CLOSE_BRACE_CHAR)) { // 22.09.96. Syntax error ? 
  	        in->putBack(c);
		    break;
		}
		else {
            if (!needComma || in->isVrml2()) { // VRML2: no comma required (whitespace)
			    in->putBack(c);
            }
            else {
       	    GvReadError::post(in,GV_RE_SYNTAX_ERROR,
				      "Expected '%c' or '%c' but got "
				      "'%c' while reading value %d",
				      VALUE_SEPARATOR_CHAR,
				      endChar, c,
				      curIndex);
		    return FALSE;
            }

            if (isMfNode)
				if (!GvNode::readRoutesOrProtos(in)) 
					return(FALSE);
		}
	  } // while
   }


    return TRUE;
}
예제 #29
0
GvBool
GvMField::readValue(GvInput *in)
{
    char c;
    int	curIndex = 0;

    if (in->read(c) && c == OPEN_BRACE_CHAR) { // we got the [ 

	if (in->read(c) && c == CLOSE_BRACE_CHAR)
	    ;				
	else {
	    in->putBack(c);

	    while (TRUE) {

		if (curIndex >= num)
		    makeRoom(curIndex + 1);

		if (! read1Value(in, curIndex++) || ! in->read(c)) {
			GvNode *container = getContainer();
			if (container) {
				GvName fieldName = container->getFieldName(container->getFieldIndex(this));
				GvReadError::post(in, GV_RE_SYNTAX_ERROR, "%s::Couldn't read value %d of %s field %s", container->GetType(),
                                    curIndex,this->GetType(),fieldName.getString());
			 }
			 else {
				GvReadError::post(in, GV_RE_SYNTAX_ERROR, "%s::Couldn't read value %d of field %s", "",
                                    curIndex,"");
			 }
             return FALSE;
		}

		if (c == VALUE_SEPARATOR_CHAR) {
		    if (in->read(c)) {
			if (c == CLOSE_BRACE_CHAR)
			    break;
			else
			    in->putBack(c);
		    }
		}
		else if (c == CLOSE_BRACE_CHAR)
		    break;

		else {
            if (in->isVrml2() && (c != CLOSE_BRACE)) { // VRML2: no comma required (whitespace)
			    in->putBack(c);
            }
            else {
       			GvReadError::post(in,GV_RE_SYNTAX_ERROR,
				      "Expected '%c' or '%c' but got "
				      "'%c' while reading value %d",
				      VALUE_SEPARATOR_CHAR,
				      CLOSE_BRACE_CHAR, c,
				      curIndex);

			in->putBack(c);
		    return FALSE;
            }
		}
		} // while 
	} //  [ xxxx ]


	// single value 

	if (curIndex < num)
	    makeRoom(curIndex);
    }

    else {
	    in->putBack(c);
	    makeRoom(1);
	    if (! read1Value(in, 0))
	        return FALSE;
        }

    return TRUE;
}
예제 #30
0
void DungeonGen::makeDungeon(v3s16 start_padding)
{
	v3s16 areasize = vm->m_area.getExtent();
	v3s16 roomsize;
	v3s16 roomplace;

	float far_multi = farscale(5, vm->m_area.MinEdge.X, vm->m_area.MinEdge.Y, vm->m_area.MinEdge.Z);

	/*
		Find place for first room
	*/
	bool fits = false;
	for (u32 i = 0; i < 100 && !fits; i++) {
		bool is_large_room = ((random.next() & 3) == 1);
		if (is_large_room) {
			roomsize.Z = random.range(8, 16 * far_multi);
			roomsize.Y = random.range(8, 16 * far_multi);
			roomsize.X = random.range(8, 16 * far_multi);
		} else {
			roomsize.Z = random.range(4, 8 * far_multi);
			roomsize.Y = random.range(4, 6 * far_multi);
			roomsize.X = random.range(4, 8 * far_multi);
		}
		roomsize += dp.roomsize;

		// start_padding is used to disallow starting the generation of
		// a dungeon in a neighboring generation chunk
		roomplace = vm->m_area.MinEdge + start_padding;
		roomplace.Z += random.range(0, areasize.Z - roomsize.Z - start_padding.Z);
		roomplace.Y += random.range(0, areasize.Y - roomsize.Y - start_padding.Y);
		roomplace.X += random.range(0, areasize.X - roomsize.X - start_padding.X);

		/*
			Check that we're not putting the room to an unknown place,
			otherwise it might end up floating in the air
		*/
		fits = true;
		for (s16 z = 0; z < roomsize.Z; z++)
		for (s16 y = 0; y < roomsize.Y; y++)
		for (s16 x = 0; x < roomsize.X; x++) {
			v3s16 p = roomplace + v3s16(x, y, z);
			u32 vi = vm->m_area.index(p);
			if ((vm->m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE) ||
					vm->m_data[vi].getContent() == CONTENT_IGNORE) {
				fits = false;
				break;
			}
		}
	}
	// No place found
	if (fits == false)
		return;

	/*
		Stores the center position of the last room made, so that
		a new corridor can be started from the last room instead of
		the new room, if chosen so.
	*/
	v3s16 last_room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2);

	u32 room_count = random.range(dp.rooms_min, random.range(dp.rooms_max, dp.rooms_max * far_multi));
	for (u32 i = 0; i < room_count; i++) {
		// Make a room to the determined place
		makeRoom(roomsize, roomplace);

		v3s16 room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2);
		if (gennotify)
			gennotify->addEvent(dp.notifytype, room_center);

#ifdef DGEN_USE_TORCHES
		// Place torch at room center (for testing)
		vm->m_data[vm->m_area.index(room_center)] = MapNode(c_torch);
#endif

		// Quit if last room
		if (i == room_count - 1)
			break;

		// Determine walker start position

		bool start_in_last_room = (random.range(0, 2) != 0);

		v3s16 walker_start_place;

		if (start_in_last_room) {
			walker_start_place = last_room_center;
		} else {
			walker_start_place = room_center;
			// Store center of current room as the last one
			last_room_center = room_center;
		}

		// Create walker and find a place for a door
		v3s16 doorplace;
		v3s16 doordir;

		m_pos = walker_start_place;
		if (!findPlaceForDoor(doorplace, doordir))
			return;

		if (random.range(0, 1) == 0)
			// Make the door
			makeDoor(doorplace, doordir);
		else
			// Don't actually make a door
			doorplace -= doordir;

		// Make a random corridor starting from the door
		v3s16 corridor_end;
		v3s16 corridor_end_dir;
		makeCorridor(doorplace, doordir, corridor_end, corridor_end_dir);

		// Find a place for a random sized room
		roomsize.Z = random.range(4, 8 * far_multi);
		roomsize.Y = random.range(4, 6 * far_multi);
		roomsize.X = random.range(4, 8 * far_multi);
		roomsize += dp.roomsize;

		m_pos = corridor_end;
		m_dir = corridor_end_dir;
		if (!findPlaceForRoomDoor(roomsize, doorplace, doordir, roomplace))
			return;

		if (random.range(0, 1) == 0)
			// Make the door
			makeDoor(doorplace, doordir);
		else
			// Don't actually make a door
			roomplace -= doordir;

	}
}