示例#1
0
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;
}