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; } }
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; }
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(); }
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; }
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 ); } } } }
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; }
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; }
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); }
Engine::Engine(StringPtr title) { this->window_ = std::make_unique<Window>(title, IVec2(1280, 800)); this->frameCount_ = 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; } } }
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; }
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) {
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; }
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; }