예제 #1
0
namespace Stairs
{

static const Fragment		kStair(gCastUCharToChar(205), ETextWhite);
static const Fragment		kRenderMeshData[] = { kStair, kStair, kStair, kStair, kStair };
static const AsciiMesh		kRenderMesh( kRenderMeshData, 5, 1, IVec2(1, 0) );
static const bool			kCollisionMeshData[] = 
{ 
	true,	true,	true,	true,	true,	true,	true,
	true,	false,	false,	false,	false,	false,	true 
};
static const CollisionMesh	kCollisionMesh(kCollisionMeshData, 7, 2, IVec2(0, -1));

Entity Create(World& inWorld, MessageBroadcaster& inMsgBroadcaster, const IVec2& inPosition)
{
	auto entity = inWorld.CreateEntity();
	
	entity.AddComponent<CollisionComponent>(kCollisionMesh);
	entity.AddComponent<PositionComponent>(inPosition);
	entity.AddComponent<RenderableComponent>(kRenderMesh);
	entity.AddComponent<TriggerBoxComponent>( IRect(1, 0, 5, 1) )->RegisterOnEnterCallback( [&] (const Entity&, const Entity& inTriggerer)
	{
		if (!inTriggerer.HasComponent<PlayerComponent>())
		{
			return;
		}

		inMsgBroadcaster.Broadcast( PlayerWentDownStairs() );
	} );

	return entity;
}

}
예제 #2
0
void DungeonTest::createRooms()
{
	for (int i = 0 ; i < ROOM_COUNT ; i++)
	{
		int size = random(1,3) * 2 + 1;
		int rec = random(0,size/2) * 2;

		int width = size;
		int height = size;
		if (random(0,1) == 1)
		{
			width += rec;
		}else
		{
			height += rec;
		}

		int x = random(0,(_width - width-1)/2) * 2 +1;
		int y = random(0,(_height - height-1)/2) * 2 +1;

		Room* room = new Room(IVec2(x,y),IVec2(width,height));
		bool overlaps = false;
		size_t len = _rooms.size();
		for (int t = 0 ; t < len ; t++)
		{
			if (room->Overlap(_rooms[t]))
			{
				overlaps = true;
				break;
			}
		}

		if (overlaps)
		{
			continue;
		}

		_rooms.push_back(room);
		_currentRegion++;
		for (int p = x; p < x+width ; p++)
		{
			for (int q = y; q < y+height ; q++)
			{
				_blocks[p][q] = _currentRegion;
			}
		}
	}

	_regionRoomMax = _currentRegion;
}
예제 #3
0
void LocalBackEnd::updateMap(TileDataEvent *event) {
  ClientArea* currentArea = _world.getCurrentArea();

  #pragma message "Fix this so it displays something intelligent and useful"
  if(!currentArea) { return; }

  if(!event) {
    // No tile data update, just regenerate the whole area
    IVec2 areaSize = currentArea->getSize();
    for(int j = 0; j < areaSize.y; j++) {
      for(int i = 0; i < areaSize.x; i++) {
        updateTileRepresentation(IVec2(i, j), currentArea);
      }
    }
  } else {
    // We got tile data from the server, update only the updated tiles
    for(auto tileData : event->updated) {
      updateTileRepresentation(tileData.first, currentArea);
    }
    for(auto shroudedTile : event->shrouded) {
      updateTileRepresentation(shroudedTile, currentArea);
    }
    for(auto visibleTile : event->visible) {
      updateTileRepresentation(visibleTile, currentArea);
    }
  }

  _mapPanel->render();
}
예제 #4
0
Tile* Area::getRandomEmptyTile() {
    const int maxAttempts = 100;
    Tile* ret = 0;
    for(int c = 0; c < maxAttempts; c++) {
        int x = rand() % _size.x,
            y = rand() % _size.y;

        ret = (Tile*)getTile(IVec2(x, y));
        if(!ret) {
            Error("Found null tile at " << IVec2(x, y));
        }

        if(ret && ret->getType() == TileType::Ground) {
            return ret;
        }
    }

    Error("Failed to find random empty tile");
    return 0;
}
예제 #5
0
void partUpdate() {
	simulationFrameNumber++;

	// DIFFUSE (@TODO: replace w more realisitic simulation, see CheY paper)
	for( int i=0; i<partCount; i++ ) {
		IVec2 p = part[i].pos;
		static IVec2 dirs[4] = { IVec2(1,0), IVec2(-1,0), IVec2(0,1), IVec2(0,-1) };
		p.add( dirs[zrandI(0,4)] );
		if( partInBounds(p) ) {
			Part *react = partAt(p);
			if( react ) {
				int hit = (*partReactCallback)( react, &part[i] );
				if( !hit ) {
					(*partReactCallback)( &part[i], react );
				}
			}
			else if( part[i].diffuses ) {
				partMove( &part[i], p );
			}
		}
	}
}
예제 #6
0
Entity Create(World& inWorld, MessageBroadcaster& inMsgBroadcaster, GameData* inGameData)
{
	Entity entity = inWorld.CreateEntity();

	IVec2	startingRoomIndex	= inGameData->mDungeonMap.GetPlayerStartingRoomIndex();
	Entity	room				= inGameData->mDungeonMap.GetRoomEntities().Get(startingRoomIndex);
	IVec2	roomPosition		= room.GetComponent<PositionComponent>()->GetPosition();
	
	entity.AddComponent<AnimationComponent>();
	entity.AddComponent<CollisionComponent>();
	entity.AddComponent<HealthComponent>( inGameData->mPlayerData.mMaxHealth );
	entity.AddComponent<PlayerComponent>( &inGameData->mPlayerData );
	entity.AddComponent<OrientationComponent>( EOrientation_FaceDown );
	entity.AddComponent<PositionComponent>( roomPosition + IVec2(10, 10) );
	entity.AddComponent<RenderableComponent>();
	entity.AddComponent<TriggererComponent>();
	
	entity.AddComponent<InputHandlerComponent>()->RegisterHandler
	(
		[] (const Entity& inPlayer, const InputBuffer& inBuffer)
		{
			inPlayer.GetComponent<PlayerComponent>()->HandleInput(inBuffer);
		}
	);

	entity.AddComponent<ProgramComponent>()->RegisterProgram
	(
		[] (const Entity& inPlayer, float inFrameTime)
		{
			inPlayer.GetComponent<PlayerComponent>()->Update(inPlayer, inFrameTime);
		}
	);

	entity.AddComponent<MessageReceiverComponent>()->Register<AttackMsg>
	(
		[entity, &inMsgBroadcaster] (const AttackMsg& inAttackMsg)
		{
			entity.GetComponent<PlayerComponent>()->OnAttacked(entity, inAttackMsg, inMsgBroadcaster);
		}
	);

	return entity;
}
예제 #7
0
bool InspectState::act(int action) {
  switch(action) {
  case UpLeft:
    _client->moveCursor(IVec2(-1, -1));
    break;
  case Up:
    _client->moveCursor(IVec2(0, -1));
    break;
  case UpRight:
    _client->moveCursor(IVec2(1, -1));
    break;
  case Right:
    _client->moveCursor(IVec2(1, 0));
    break;
  case DownRight:
    _client->moveCursor(IVec2(1, 1));
    break;
  case Down:
    _client->moveCursor(IVec2(0, 1));
    break;
  case DownLeft:
    _client->moveCursor(IVec2(-1, 1));
    break;
  case Left:
    _client->moveCursor(IVec2(-1, 0));
    break;
  case Exit:
    return false;
    break;

  default:
    Warn("No handler for action " << action);
  }

  return true;
}
예제 #8
0
void LocalBackEnd::updateTileRepresentation(const IVec2& coords, ClientArea* currentArea) {
  if(_cursorEnabled && _cursorLocation == coords) {
    _mapSource->setData(coords.x, coords.y, 'X', A_BLINK | COLOR_PAIR(BLUE_ON_BLACK));
    _mapPanel->setCenter(coords);
    return;
  }

  auto tile = currentArea->getTile(coords);
  if(!tile) {
    _mapSource->setData(coords.x, coords.y, ' ', A_NORMAL);
    return;
  }

  const set<BObjectID>& contents = tile->getContents();
  if(contents.find(_characterID) != contents.end()) {
    _mapSource->setData(coords.x, coords.y, '@', A_BOLD | COLOR_PAIR(RED_ON_BLACK));
    _lastPlayerLocation = coords;
    if(!_cursorEnabled) {
      _mapPanel->setCenter(coords);
      updateInfoPanel();
    }
    return;
  }

  chtype c;
  if(contents.size() > 0) {
    set<const ProtoBObject*> protos;
    for(auto obj : contents) {
      auto objectStub = _objects.find(obj);
      if(objectStub == _objects.end()) { continue; }
      const ProtoBObject* proto = _raw.getObject(objectStub->second.prototype);
      if(proto) {
        protos.insert(proto);
      } else {
        Debug("No prototype found for " << objectStub->second.prototype);
      }
    }
    c = _objectRepresentation.get(protos);
  } else {
    // Generate a symbol by terrain
    TileType tileType = tile->getType();
    if(tileType == TileType::Wall) {
      short wallBits = 0;
      for(int i = -1; i <= 1; i++) {
        for(int j = -1; j <= 1; j++) {
          if(i == j && i == 0) { continue; }
          IVec2 local = coords + IVec2(i, j);

          TileBase* tile = 0;
          if(local.x < 0 || local.x >= currentArea->getSize().x ||
             local.y < 0 || local.y >= currentArea->getSize().y ||
             !(tile = currentArea->getTile(local)) ||
             tile->getType() == TileType::Wall) {
            wallBits |= MARCHING_SQUARES_BIT(i, j);
          }
        }
      }
      c = getMarchingSquaresRepresentation(wallBits);
    } else if(tileType == TileType::Ground) {
      c = '.';
    } else {
      c = '?';
    }
  }
  _mapSource->setData(coords.x, coords.y, c, currentArea->isTileShrouded(coords) ? A_NORMAL : A_BOLD);
}
예제 #9
0
	Engine::Engine(StringPtr title)
	{
		this->window_ = std::make_unique<Window>(title, IVec2(1280, 800));
		this->frameCount_ = 0;
	}
예제 #10
0
void DungeonTest::connect()
{
	map<IVec2,hash_set<int>> connector;

	for (int i = 0 ; i < _width ; i++)
	{
		for (int j = 0 ; j < _height ; j++)
		{
			if (_blocks[i][j] != BLOCK_BLANK)
				continue;

			hash_set<int> regions;
			regions.clear();
			if (inRegion(i-1,j))
				regions.insert(_blocks[i-1][j]);
			if (inRegion(i+1,j))
				regions.insert(_blocks[i+1][j]);
			if (inRegion(i,j+1))
				regions.insert(_blocks[i][j+1]);
			if (inRegion(i,j-1))
				regions.insert(_blocks[i][j-1]);

			if (regions.size() < 2)
				continue;
			
			//_blocks[i][j] =  BLOCK_DOOR;
			connector[IVec2(i,j)] = regions;
			

		}
	}

	vector<int> merged;
	list<int> openRegions;
	for (int i = 0 ; i < _currentRegion+1 ; i++)
	{		
		merged.push_back(i);
		openRegions.push_back(i);
	}
	
	while (openRegions.size() > 1)
	{
		int ranNum = random(0,connector.size() - 1);
		map<IVec2,hash_set<int>>::iterator it = connector.begin();
		while (ranNum != 0)
		{
			++it;
			ranNum --;
		}

		IVec2 pos = IVec2((it->first).x,(it->first).y);
		_blocks[pos.x][pos.y] = BLOCK_DOOR;
		int dest = merged[*((it->second).begin())];
		int source = merged[*((it->second).rbegin())];

		//merged[source] = dest;
		for(int i = 0 ; i < _currentRegion+1 ; i++)
		{
			if(merged[i] == source)
				merged[i] = dest;
		}

		list<int>::iterator list_it = openRegions.begin();
		for( ; list_it != openRegions.end() ;)
		{
			if (*list_it == source)
			{
				openRegions.erase(list_it++);
				break;
			}
			else
			{
				++list_it;
			}
		}

		for (it = connector.begin() ; it != connector.end() ;)
		{
			int first = *((it->second).begin());
			int second = *((it->second).rbegin());

			if(merged[first] == dest && merged[second] == dest)
			{
				if (random(0,100) <= EXTRA_CONNECT && pos.dis(IVec2((it->first).x,(it->first.y))) > 2)
					_blocks[(it->first).x][(it->first).y] = BLOCK_DOOR;
				connector.erase(it++);
			}
				
			else
				++it;
		}
	}
}
예제 #11
0
void DungeonTest::createCorridors()
{
	stack<IVec2> blocks;
	vector<IVec2> unmadedirs;
	IVec2 lastdir;

	for (int i = 1 ; i < _width ; i += 2)
	{
		for (int j = 1; j < _height ; j += 2)
		{

			if (_blocks[i][j] != BLOCK_BLANK)
				continue;

			_currentRegion++;
			_blocks[i][j] = _currentRegion;
			blocks.push(IVec2(i,j));
			while (!blocks.empty())
			{
				IVec2 block = blocks.top();
				unmadedirs.clear();
				if (isUnmade(block.x+2,block.y))
					unmadedirs.push_back(DIR_RIGHT);
				if (isUnmade(block.x-2,block.y))
					unmadedirs.push_back(DIR_LEFT);
				if (isUnmade(block.x,block.y+2))
					unmadedirs.push_back(DIR_UP);
				if (isUnmade(block.x,block.y-2))
					unmadedirs.push_back(DIR_DOWN);

				if (!unmadedirs.empty())
				{
					vector<IVec2>::iterator it = find(unmadedirs.begin(),unmadedirs.end(),lastdir);

					IVec2 dir;
					if (it != unmadedirs.end() && random(0,100) > windingPercent)
					{
						dir = lastdir;
					}
					else
					{
						dir = unmadedirs[random(0,unmadedirs.size()-1)];
					}

					_blocks[block.x+dir.x][block.y+dir.y] = _currentRegion;
					_blocks[block.x+dir.x*2][block.y+dir.y*2] = _currentRegion;
					blocks.push(IVec2(block.x+dir.x*2,block.y+dir.y*2));
					lastdir = dir;

				}
				else
				{
					blocks.pop();
					lastdir = DIR_INVID;
				}

			}
		}
	}
	_regionCorridorMax = _currentRegion;
}
예제 #12
0
bool DungeonTest::isEquel(int x,int y,int value)
{
	return  isExist(x,y) && (_blocks[x][y] == value);
}

bool DungeonTest::isUnmade(int x,int y)
{
	return isEquel(x,y,BLOCK_BLANK);
}

bool DungeonTest::inRegion(int x,int y)
{
	return isExist(x,y) && (_blocks[x][y] > BLOCK_BLANK);
}

const IVec2 DIR_UP    = IVec2(0,1);
const IVec2 DIR_DOWN  = IVec2(0,-1);
const IVec2 DIR_LEFT  = IVec2(-1,0);
const IVec2 DIR_RIGHT = IVec2(1,0);
const IVec2 DIR_INVID = IVec2(0,0);
void DungeonTest::createCorridors()
{
	stack<IVec2> blocks;
	vector<IVec2> unmadedirs;
	IVec2 lastdir;

	for (int i = 1 ; i < _width ; i += 2)
	{
		for (int j = 1; j < _height ; j += 2)
		{
예제 #13
0
void cheReactionUpdate() {
	framesSinceLastReset++;

	int i;

	if( Band_signalOmega != oldOmega ) {
		cheReactionReset();
	}

	avgBuf[avgBufCount++] = (float)outputHits;
	if( avgBufCount == avgBufSize ) {
		float sum = 0.f;
		for( i=0; i<avgBufCount; i++ ) {
			sum += avgBuf[i];
		}
		fftBuf[fftBufCount] = sum / (float)avgBufCount;
		fftBufCount++;
		avgBufCount = 0;
		if( fftBufCount == fftBufSize ) {
			FFT fft( fftBuf, fftBufSize );
			fft.fft();
			float *p = fft.computePowerSpectrum();
			for( i=0; i<fftBufCount/2-1; i++ ) {
				cumPowerSpectrum[i] += p[i];
				cumPowerSpectrumLog[i] = logf( 1.f + cumPowerSpectrum[i] );
			}
			fftBufCount = 0;
			cumPowerSpectrumCount++;
			FILE *file = fopen( ZTmpStr("/transfer/fft/fft-diff-%d.txt",cumPowerSpectrumCount), "wt" );
			for( i=1; i<100; i++ ) {
				fprintf( file, "%f\n", cumPowerSpectrum[i] / (float)cumPowerSpectrumCount );
			}
			fclose( file );
		}
	}

	if( !(simulationFrameNumber % 100 ) ) {
		spatialHistogramCount++;
		for( int x=0; x<DIMX; x++ ) {
			for( int y=0; y<DIMY; y++ ) {
				Part *p = partAt( IVec2(x,y) );
				if( p && p->type == TYPE_CHEYP ) {
					spatialHistogram[x]++;
				}
			}
		}
	}

	outputHistory.setAvgWindow( Band_plotWindowRadius );
	outputHistory.add( (float)outputHits );

	// COMPUTE input signal
	signal = Band_signal;
	if( Band_useSinSignal ) {
		signal = (float)( Band_signalTop * 0.5*( 1.0+sin( Band_signalOmega * (double)simulationFrameNumber ) ) );
	}
	inputHistory.add( signal );

	// SETUP for next computation
	outputHits = 0;
}
예제 #14
0
void cheReactionReset() {
	partReset( Band_dimX, Band_dimY );

	int i;
	Part *p;

	partReactCallback = cheReactionCallback;

	for( i=0; i<Band_a; i++ ) {
		p = partAddAtPos( IVec2( 0, Band_dimY*i/Band_a ) );
		assert( p );
		p->type = TYPE_CHEA;
		p->diffuses = 0;
		cheySetColor( p );
	}

	for( i=0; i<Band_f; i++ ) {
		p = partAddAtPos( IVec2( DIMX-1, Band_dimY*i/Band_f ) );
		assert( p );
		p->type = TYPE_FLIM;
		p->diffuses = 0;
		cheySetColor( p );
	}

	for( i=0; i<Band_y; i++ ) {
		Part *p = partAdd();
		if( p ) {
			p->type = TYPE_CHEY;
			p->diffuses = 1;
			cheySetColor( p );
		}
	}

	for( i=0; i<Band_z/2; i++ ) {
		//Part *p = partAdd();
		Part *p = partAddAtPos( IVec2( 1, Band_dimY*i/(Band_z/2) ) );
		if( p ) {
			p->type = TYPE_CHEZ;
			p->diffuses = Band_cheZDiffuses;
			cheySetColor( p );
		}
	}

//	for( i=0; i<Band_z/2; i++ ) {
//		//Part *p = partAdd();
//		Part *p = partAddAtPos( IVec2( Band_dimX-2, Band_dimY*i/(Band_z/2) ) );
//		if( p ) {
//			p->type = TYPE_CHEZ;
//			p->diffuses = Band_cheZDiffuses;
//			cheySetColor( p );
//		}
//	}

	// ALLOCATE fft buffers, etc
	avgBufSize = int( (float)cyclesToSample * PI2F / (float)Band_signalOmega / (float)fftBufSize );
	assert( avgBufSize >= 1 );
		// This is the number of samples that have to be averaged for each position in the box
	if( avgBuf ) {
		free( avgBuf );
	}
	avgBuf = (float *)malloc( sizeof(float) * avgBufSize );
	memset( avgBuf, 0, sizeof(float) * avgBufSize );
	avgBufCount = 0;
	oldOmega = Band_signalOmega;
	fftBufCount = 0;
	memset( cumPowerSpectrum, 0, sizeof(float) * (fftBufSize/2) );
	memset( cumPowerSpectrumLog, 0, sizeof(float) * (fftBufSize/2) );
	memset( spatialHistogram, 0, sizeof(spatialHistogram) );
	spatialHistogramCount = 0;
	cumPowerSpectrumCount = 0;
	zReactHits = 0;
	framesSinceLastReset = 0;
}