/*! * \brief create a single forest at the point specified * \param pos Position on the map to start from * \param size Radius of the forest to paint. */ static void CreateForest(UInt32 pos, UInt16 size) { UInt16 x, y, i, j, s; x = (UInt16)(pos % getMapWidth()); y = (UInt16)(pos / getMapWidth()); zone_lock(lz_world); zone_lock(lz_flags); i = x - size > 0 ? x - size : 0; j = y - size > 0 ? y - size : 0; for (; i <= x + size; i++) { for (j = y - size; j <= y + size; j++) { if (i >= getMapWidth() || j >= getMapHeight()) continue; if (getWorld(WORLDPOS(i, j)) != Z_DIRT) continue; s = ((y > j) ? (y - j) : (j - y)) + ((x > i) ? (x - i) : (i - x)); if (GetRandomNumber(s) < 2) { /*! * \todo count_trees or count_real_trees */ setWorldAndFlag(WORLDPOS(i, j), Z_REALTREE, 0); vgame.BuildCount[bc_count_trees]++; } } j = y - size > 0 ? y - size : 0; } zone_unlock(lz_flags); zone_unlock(lz_world); }
void DoNastyStuffTo(welem_t type, UInt16 probability, UInt8 purge) { /* nasty stuff means: turn it into wasteland */ UInt32 randomTile; UInt16 i, x, y; if (GetRandomNumber(probability) != 0) return; zone_lock(lz_world); zone_lock(lz_flags); for (i = 0; i < 50; i++) { randomTile = GetRandomNumber(MapMul()); if (getWorld(randomTile) == type) { /* wee, let's destroy something */ x = (UInt16)(randomTile % getMapWidth()); y = (UInt16)(randomTile / getMapWidth()); if (!purge) CreateWaste(x, y); else Build_Destroy(x, y); break; } } zone_unlock(lz_flags); zone_unlock(lz_world); }
//-------------------------------- // //-------------------------------- bool AflMapData::saveMap(LPCSTR pFileName) { int i,j,k; FILE* pFile; pFile = fopen(pFileName,TEXT("wb")); if(!pFile) return false; m_strFileName = pFileName; setRelativePath(); fwrite(m_strMapHeader[MAP_BINHEADER],strlen(m_strMapHeader[MAP_BINHEADER])+1,1,pFile); //----------------------------- writeHeader(pFile,m_strMapHeader[MAP_VERSION],getVersion()); writeHeader(pFile,m_strMapHeader[MAP_MAPNAME],getMapName()); writeHeader(pFile,m_strMapHeader[MAP_BITMAP],getImageName(0)); writeHeader(pFile,m_strMapHeader[MAP_SPRITE],getImageName(1)); writeHeader(pFile,m_strMapHeader[MAP_WIDTH],getMapWidth()); writeHeader(pFile,m_strMapHeader[MAP_HEIGHT],getMapHeight()); writeHeader(pFile,m_strMapHeader[MAP_OPATTERN],getOutTipIndex()); writeHeader(pFile,m_strMapHeader[MAP_PARTSWIDTH],getTipWidth()); writeHeader(pFile,m_strMapHeader[MAP_PARTSHEIGHT],getTipHeight()); writeHeader(pFile,m_strMapHeader[MAP_OBJECT],getObjectFileName()); //----------------------------- //マップデータ for(k=0;k<4;k++) { if(!isZero(k)) { PSHORT pData = m_ptrData[k].get(); writeHeader(pFile,m_strMapHeader[MAP_MAPDATA0+k], pData,getMapWidth()*getMapHeight()*sizeof(short)); } } //----------------------------- //パーツ接触フラグ for(j=0;j<5;j++) { int nCollide; for(nCollide=i=0;i<0xffff/8;i++) if(m_byCollide[j][i]) nCollide = i+1; writeHeader(pFile,m_strMapHeader[MAP_PAERSCOLLIDE0+j],m_byCollide,nCollide); } //----------------------------- //----------------------------- //マップ個別フラグ writeHeader(pFile,m_strMapHeader[MAP_MAPFLAG0],getMapFlag(),getMapWidth()*getMapHeight()); //----------------------------- fclose(pFile); return true; }
void AflMapData::setMapFlag(INT iX,INT iY,BYTE byFlag) { if(iX < 0 || iY < 0 || iX >= m_iMapWidth || iY >= m_iMapHeight) return; LPBYTE pbyFlag = getMapFlag(); pbyFlag[iX + getMapWidth()*iY] = byFlag; }
bool AflMapData::isMapCollide(INT iX,INT iY) { if(iX < 0 || iY < 0 || iX >= getMapWidth() || iY >= getMapHeight()) return true; BYTE byFlag = getMapFlag(iX,iY); return (byFlag & 0x80) != 0; }
void Map::handleFishNPC () { if (!_activateFishNPC) return; const float waterBodyY = getWaterHeight(); // no fish if water is too low if (waterBodyY <= 0.5f) return; if (_spawnFishNPCTime > _time) return; const float gap = 2.0f; if (_fishNPC == nullptr) { if (_players.empty()) return; const int index = rand() % _players.size(); const Player* player = _players[index]; const b2Vec2& pos = player->getPos(); const float mapHeight = static_cast<float>(getMapHeight()); float y = std::min(waterBodyY, std::max(mapHeight, mapHeight - 0.5f)); if (y < 0.f) { return; } float x; if (pos.x > getMapWidth() / 2.0) x = -gap; else x = getMapWidth() + gap; const b2Vec2 npcSpawnPos(x, y); _fishNPC = createFishNPC(npcSpawnPos); } else { const b2Vec2 &pos = _fishNPC->getPos(); const float x = pos.x; const float y = pos.y; if (x < -gap || y < 0 || x > getMapWidth() + gap || y > getMapHeight()) { _fishNPC->setRemove(); _spawnFishNPCTime = _time + 2000 + rand() % SPAWN_FISH_NPC_DELAY; _fishNPC = nullptr; } } }
/*! * \todo Make the river more interesting */ static void CreateFullRiver(void) { UInt16 i, j, k, width; int axis; UInt16 kmax; width = (UInt16)(GetRandomNumber(5) + 5); axis = (int)GetRandomNumber(1); kmax = axis ? getMapWidth() : getMapHeight(); /* This is the start position of the center of the river */ j = (UInt16)GetRandomNumber(kmax); zone_lock(lz_world); zone_lock(lz_flags); for (i = 0; i < kmax; i++) { for (k = j; k < (width + j); k++) { if (k < kmax) { if (axis) setWorldAndFlag(WORLDPOS(i, k), Z_REALWATER, 0); else setWorldAndFlag(WORLDPOS(k, i), Z_REALWATER, 0); } } switch (GetRandomNumber(3)) { case 0: if (width > 5) width--; break; case 1: if (width < 15) width++; break; default: break; } switch (GetRandomNumber(4)) { case 0: if (j > 0) j--; break; case 1: if (j < kmax) j++; break; default: break; } } zone_unlock(lz_flags); zone_unlock(lz_world); }
BYTE AflMapData::getMapFlag(INT iX,INT iY) { if(iX < 0 || iY < 0 || iX >= m_iMapWidth || iY >= m_iMapHeight) { return 0; } LPBYTE pbyFlag = getMapFlag(); return pbyFlag[iX + getMapWidth()*iY]; }
void Map::handleFlyingNPC () { if (!_activateflyingNPC) return; if (_spawnFlyingNPCTime > _time) return; const float gap = 2.0f; if (_flyingNPC == nullptr) { if (_players.empty()) return; const int index = rand() % _players.size(); const Player* player = _players[index]; const b2Vec2& pos = player->getPos(); const float waterBodyY = getWaterHeight(); float y = pos.y; if (y >= waterBodyY) { y = waterBodyY - 1.0f; } if (y < 0.f) { return; } float x; if (pos.x > getMapWidth() / 2.0) x = -gap; else x = getMapWidth() + gap; const b2Vec2 npcSpawnPos(x, y); _flyingNPC = createFlyingNPC(npcSpawnPos); } else { const b2Vec2 &pos = _flyingNPC->getPos(); const float x = pos.x; const float y = pos.y; if (x < -gap || y < 0 || x > getMapWidth() + gap || y > getMapHeight()) { _flyingNPC->setRemove(); _spawnFlyingNPCTime = _time + 2000 + rand() % SPAWN_FLYING_NPC_DELAY; _flyingNPC = nullptr; } } }
/*! * \brief Cause a fire to spread out from the point chosen * \param x position on horizontal of map to spread fire * \param y position on vertical of map to spread fire */ static void FireSpread(UInt16 x, UInt16 y) { if (x > 0) BurnField((UInt16)(x - 1), (UInt16)y, 0); if (x < (UInt16)(getMapWidth() - 1)) BurnField((UInt16)(x + 1), (UInt16)y, 0); if (y > 0) BurnField((UInt16)x, (UInt16)(y - 1), 0); if (y < (UInt16)(getMapHeight() - 1)) BurnField((UInt16)x, (UInt16)(y + 1), 0); }
/*-------------------------------------------------------------------------------------------- -- FUNCTION: drawMap -- -- DATE: April 7th, 2016 -- -- DESIGNERS: Jaegar Sarauer -- -- REVISIONS: NONE -- -- PROGRAMMERS: Jaegar Sarauer -- -- INTERFACE: void Map::drawMap (int ** mapArray) -- int ** mapArray = A 2D array of ints which represent tile id's of a map. -- -- RETURNS: void -- -- NOTES: This function will draw a map layer (passed in as a parameter) as ascii characters -- which are represented from the tile id's of the map array. -- Mainly used for debugging. ------------------------------------------------------------------------------------------*/ void Map::drawMap (int ** mapArray) { printf ("\n\n -------------------------------------------------------------- \n\n"); for (size_t x = 0; x < getMapWidth (); x++) { printf ("\n "); for (size_t y = 0; y < getMapHeight (); y++) { printf ("%-4d ", mapArray[x][y]); } /*if (map.isBaseWall(x,y)) printf ("W "); else printf (" ");*/ } }
void DoRandomDisaster(void) { UInt32 randomTile; Int16 i, type, random; UInt16 x, y; UInt8 disaster_level; disaster_level = getDisasterLevel(); /* for those who can't handle the game (truth?) */ if (disaster_level == 0) return; zone_lock(lz_world); zone_lock(lz_flags); for (i = 0; i < 100; i++) { /* 100 tries to hit a useful tile */ randomTile = GetRandomNumber(MapMul()); type = getWorld(randomTile); if (type != Z_DIRT && type != Z_REALWATER && type != Z_CRATER) { x = (UInt16)(randomTile % getMapWidth()); y = (UInt16)(randomTile / getMapHeight()); /* TODO: should depend on difficulty */ random = (Int16)GetRandomNumber(1000 / disaster_level); WriteLog("Random Disaster: %d\n", (int)random); if (random < 10 && vgame.BuildCount[bc_fire] == 0) { DoSpecificDisaster(diFireOutbreak, x, y); } else if (random < 15 && game.objects[obj_monster].active == 0) { DoSpecificDisaster(diMonster, x, y); } else if (random < 17 && game.objects[obj_dragon].active == 0) { DoSpecificDisaster(diDragon, x, y); } else if (random < 19) { DoSpecificDisaster(diMeteor, x, y); } /* only one chance for disaster per turn */ break; } } zone_unlock(lz_flags); zone_unlock(lz_world); }
Int16 UpdateDisasters(void) { /* return false if no disasters are found */ UInt16 i, j; welem_t type; int retval = 0; zone_lock(lz_world); zone_lock(lz_flags); clearScratch(SCRATCHDISASTER); for (i = 0; i < getMapHeight(); i++) { for (j = 0; j < getMapWidth(); j++) { type = getWorld(WORLDPOS(i, j)); /* already looked at this one? */ if (getWorldFlags(WORLDPOS(i, j)) & SCRATCHDISASTER) { if (type == Z_FIRE2) { retval = 1; if (GetRandomNumber(5) != 0) { /* are there any defences */ if (GetDefenceValue(i, j) < 3) { FireSpread(i, j); } setWorldAndFlag(WORLDPOS(i, j), Z_FIRE3, 0); } else { CreateWaste(i, j); } } else if (type == Z_FIRE1) { retval = 1; setWorldAndFlag(WORLDPOS(i, j), Z_FIRE2, 0); } else if (type == Z_FIRE3) { retval = 1; CreateWaste(i, j); } } } } zone_unlock(lz_flags); zone_unlock(lz_world); return (retval); }
void DoCommitmentNasties(void) { int i; zone_lock(lz_world); for (i = 0; i < 60 - getTax(); i++) { UInt32 loc = GetRandomNumber(MapMul()); welem_t world = getWorld(GetRandomNumber(MapMul())); int x = loc % getMapWidth(); int y = loc % getMapHeight(); if ((IsTransport(world)) && (GetRandomNumber(100) > getUpkeep(ue_traffic))) Build_Destroy(x, y); if ((IsWaterPipe(world) || IsPowerLine(world) || IsPowerWater(world)) && (GetRandomNumber(100) > getUpkeep(ue_power))) Build_Destroy(x, y); } zone_unlock(lz_world); }
/*! * \brief Create a waste zone for the meteor. * \param x horizontal position * \param y vertical position * \param size size of the meteor */ static void CreateMeteor(UInt16 x, UInt16 y, Int16 size) { UInt16 j; UInt16 i = (Int16)(x - size) < 0 ? 0 : (UInt16)(x - size); zone_lock(lz_world); zone_lock(lz_flags); UILockScreen(); for (; i <= x + size; i++) { j = (Int16)(y - size) < 0 ? 0 : (UInt16)(y - size); for (; j <= y + size; j++) { if (i < getMapWidth() && j < getMapHeight()) { if (GetRandomNumber(5) < 2) { if (getWorld(WORLDPOS(i, j)) != Z_REALWATER) { CreateWaste(i, j); } } else if (GetRandomNumber(5) < 4) { if (getWorld(WORLDPOS(i, j)) != Z_REALWATER && getWorld(WORLDPOS(i, j)) != Z_FAKEWATER) { BurnField(i, j, 1); } } } } } Build_Destroy(x, y); setWorldAndFlag(WORLDPOS(x, y), Z_CRATER, 0); zone_unlock(lz_flags); zone_unlock(lz_world); UIUnlockScreen(); RedrawAllFields(); }
int BaseAI::mapWidth() { return getMapWidth(c); }
void Map::initPhysics () { b2Vec2 gravity; gravity.Set(0.0f, getGravity()); _world = new b2World(gravity); _world->SetDestructionListener(&_destructionListener); //_world->SetWarmStarting(false); //_world->SetContinuousPhysics(false); //_world->SetSubStepping(false); _world->SetAutoClearForces(true); _world->SetContactListener(this); _world->SetContactFilter(this); const float zeroX = 0.0f; const float zeroY = -0.5f; const float width = getMapWidth(); // added a small offset to allow water diving out of screen const float height = getMapHeight() + 1.0f; b2BodyDef lineBodyDef; lineBodyDef.type = b2_staticBody; lineBodyDef.position.Set(0, 0); b2Body* boxBody = _world->CreateBody(&lineBodyDef); b2EdgeShape edge; b2FixtureDef fd; fd.friction = 1.0f; fd.restitution = 0.2f; fd.shape = &edge; _borders.resize(BORDER_MAX); const bool isSideBorderFail = getSetting(msn::SIDEBORDERFAIL).toBool(); _borders[BORDER_TOP] = new Border(BorderType::TOP, *this); _borders[BORDER_LEFT] = new Border(BorderType::LEFT, *this, isSideBorderFail); _borders[BORDER_RIGHT] = new Border(BorderType::RIGHT, *this, isSideBorderFail); _borders[BORDER_BOTTOM] = new Border(BorderType::BOTTOM, *this); _borders[BORDER_PLAYER_BOTTOM] = new Border(BorderType::PLAYER_BOTTOM, *this); edge.Set(b2Vec2(zeroX, zeroY), b2Vec2(width, zeroY)); b2Fixture *top = boxBody->CreateFixture(&fd); top->SetUserData(_borders[BORDER_TOP]); edge.Set(b2Vec2(zeroX, zeroY), b2Vec2(zeroX, height)); b2Fixture *left = boxBody->CreateFixture(&fd); left->SetUserData(_borders[BORDER_LEFT]); edge.Set(b2Vec2(width, height), b2Vec2(width, zeroY)); b2Fixture *right = boxBody->CreateFixture(&fd); right->SetUserData(_borders[BORDER_RIGHT]); edge.Set(b2Vec2(zeroX, height), b2Vec2(width, height)); b2Fixture *bottom = boxBody->CreateFixture(&fd); bottom->SetUserData(_borders[BORDER_BOTTOM]); edge.Set(b2Vec2(zeroX, height), b2Vec2(width, getMapHeight())); b2Fixture *playerBottom = boxBody->CreateFixture(&fd); playerBottom->SetUserData(_borders[BORDER_PLAYER_BOTTOM]); initWater(); }
void MoveAllObjects(void) { UInt16 i, x, y; for (i = 0; i < NUM_OF_OBJECTS; i++) { if (game.objects[i].active != 0) { /* hmm, is this thing destructive? */ if (i == obj_dragon) { if (!BurnField(game.objects[i].x, game.objects[i].y, 1)) { CreateWaste(game.objects[i].x, game.objects[i].y); } MonsterCheckSurrounded(i); } else if (i == obj_monster) { /* whoo-hoo, bingo again */ CreateWaste(game.objects[i].x, game.objects[i].y); MonsterCheckSurrounded(i); } x = game.objects[i].x; /* save old position */ y = game.objects[i].y; switch (GetRandomNumber(OBJ_CHANCE_OF_TURNING)) { case 1: /* yes, clockwise */ game.objects[i].dir = (game.objects[i].dir+1)%8; break; case 2: /* yes, counter-clockwise */ game.objects[i].dir = (game.objects[i].dir+7)%8; break; default: break; } /* now move it a nod */ switch (game.objects[i].dir) { /* first up/down */ case 0: /* up */ case 1: /* up-right */ case 7: /* up-left */ if (game.objects[i].y > 0) { game.objects[i].y--; } else { game.objects[i].dir = 4; } break; case 3: /* down-right */ case 4: /* down */ case 5: /* down-left */ if (game.objects[i].y < (UInt16)(getMapHeight()-1)) { game.objects[i].y++; } else { game.objects[i].dir = 0; } break; default: break; } switch (game.objects[i].dir) { /* then left/right */ case 1: /* up-right */ case 2: /* right */ case 3: /* down-right */ if (game.objects[i].x < (UInt16)(getMapWidth()-1)) { game.objects[i].x++; } else { game.objects[i].dir = 6; } break; case 5: /* down-left */ case 6: /* left */ case 7: /* up-left */ if (game.objects[i].x > 0) { game.objects[i].x--; } else { game.objects[i].dir = 2; } break; default: break; } zone_lock(lz_world); zone_lock(lz_flags); DrawCross(x, y, 1, 1); /* (erase it) */ DrawField(game.objects[i].x, game.objects[i].y); zone_unlock(lz_flags); zone_unlock(lz_world); } } }