bool Map::load (const std::string& name) { ScopedPtr<IMapContext> ctx(getMapContext(name)); resetCurrentMap(); if (name.empty()) { info(LOG_MAP, "no map name given"); return false; } info(LOG_MAP, "load map " + name); if (!ctx->load(false)) { error(LOG_MAP, "failed to load the map " + name); return false; } ctx->save(); _settings = ctx->getSettings(); _startPositions = ctx->getStartPositions(); _name = ctx->getName(); _title = ctx->getTitle(); _theme = &ctx->getTheme(); _settings.insert(std::make_pair(msn::THEME, _theme->name)); _wind = getSetting(msn::WIND, msd::WIND).toFloat(); _gravity = getSetting(msn::GRAVITY, string::toString(msdv::GRAVITY)).toFloat(); _width = getSetting(msn::WIDTH, "-1").toInt(); _height = getSetting(msn::HEIGHT, "-1").toInt(); _finishPoints = getSetting(msn::POINTS, string::toString(msdv::POINTS)).toInt(); _referenceTime = getSetting(msn::REFERENCETIME, string::toString(msdv::REFERENCETIME)).toInt(); _waterChangeSpeed = getSetting(msn::WATER_CHANGE, msd::WATER_CHANGE).toFloat(); _waterRisingDelay = getSetting(msn::WATER_RISING_DELAY, msd::WATER_RISING_DELAY).toFloat(); _waterFallingDelay = getSetting(msn::WATER_FALLING_DELAY, msd::WATER_FALLING_DELAY).toFloat(); _activateflyingNPC = getSetting(msn::FLYING_NPC, msd::FLYING_NPC).toBool(); _activateFishNPC = getSetting(msn::FISH_NPC, msd::FISH_NPC).toBool(); _waterHeight = getSetting(msn::WATER_HEIGHT, msd::WATER_HEIGHT).toFloat(); _transferedPackageLimit = getSetting(msn::PACKAGE_TRANSFER_COUNT, msd::PACKAGE_TRANSFER_COUNT).toInt(); // TODO: properly implement a warmup phase _warmupPhase = 0; info(LOG_MAP, "theme: " + _theme->name); info(LOG_MAP, "reference time: " + string::toString(_referenceTime)); if (_width <= 0 || _height <= 0) { error(LOG_MAP, "invalid map dimensions given"); return false; } _spawnFlyingNPCTime = getSetting(msn::NPC_INITIAL_SPAWN_TIME, string::toString(4000 + rand() % SPAWN_FLYING_NPC_DELAY)).toInt(); _spawnFishNPCTime = getSetting(msn::NPC_INITIAL_SPAWN_TIME, string::toString(4000 + rand() % SPAWN_FISH_NPC_DELAY)).toInt(); _initialGeyserDelay = getSetting(msn::GEYSER_INITIAL_DELAY_TIME, string::toString(3000)).toInt(); if (_transferedPackageLimit <= 0) { error(LOG_MAP, "there is nothing to do in this map - set the npc or package limits"); return false; } initPhysics(); info(LOG_MAP, "physics initialized"); std::vector<MapTile*> mapTilesWithBody; const std::vector<MapTileDefinition>& mapTileList = ctx->getMapTileDefinitions(); for (std::vector<MapTileDefinition>::const_iterator i = mapTileList.begin(); i != mapTileList.end(); ++i) { MapTile *mapTile = createMapTileWithoutBody(i->spriteDef, i->x, i->y, i->angle); if (!mapTile->isDecoration() && !mapTile->isWindow()) mapTilesWithBody.push_back(mapTile); loadEntity(mapTile); } const std::vector<CaveTileDefinition>& caveList = ctx->getCaveTileDefinitions(); for (std::vector<CaveTileDefinition>::const_iterator i = caveList.begin(); i != caveList.end(); ++i) { MapTile *mapTile = new CaveMapTile(*this, i->spriteDef->id, i->x, i->y, *i->type, i->delay); mapTile->setGridDimensions(i->spriteDef->width, i->spriteDef->height, 0); mapTilesWithBody.push_back(mapTile); loadEntity(mapTile); } for (std::vector<MapTile*>::iterator i = mapTilesWithBody.begin(); i != mapTilesWithBody.end(); ++i) { MapTile* mapTile = *i; mapTile->createBody(); } info(LOG_MAP, "init platforms"); for (Map::EntityListIter i = _entities.begin(); i != _entities.end(); ++i) { IEntity* entity = *i; if (!entity->isGround()) continue; MapTile *mapTile = static_cast<MapTile*>(entity); int start = -1; int end = -1; const int y = mapTile->getGridY() - 1.0f + EPSILON; getPlatformDimensions(mapTile->getGridX(), y, &start, &end); if (start == -1 || end == -1) { continue; } getPlatform(mapTile, &start, &end); } info(LOG_MAP, "init caves"); for (Map::EntityListIter i = _entities.begin(); i != _entities.end(); ++i) { IEntity* entity = *i; if (!entity->isCave()) continue; CaveMapTile *cave = static_cast<CaveMapTile*>(entity); _caves.push_back(cave); } // do another loop when we have all caves - we have to know each of the caves in order to initialize them properly for (Map::CaveListIter i = _caves.begin(); i != _caves.end(); ++i) { CaveMapTile* cave = *i; initCave(cave); } const std::vector<EmitterDefinition>& emitterList = ctx->getEmitterDefinitions(); for (std::vector<EmitterDefinition>::const_iterator i = emitterList.begin(); i != emitterList.end(); ++i) { const EntityType &type = *i->type; if (type.isNone()) continue; EntityEmitter *entity = new EntityEmitter(*this, i->x, i->y, i->amount, i->delay, type, i->settings); loadEntity(entity); } if (!hasPackageTarget()) { error(LOG_MAP, "there is no package target in this map"); return false; } info(LOG_MAP, "map loading done"); ctx->onMapLoaded(); _frontend->onMapLoaded(); const LoadMapMessage msg(_name, _title); _serviceProvider->getNetwork().sendToClients(0, msg); _mapRunning = true; return true; }