Ejemplo n.º 1
0
void SaveGame::applyCl(CClient *cl)
{
	CFileInfo info(fname);
	CResourceHandler::get("local")->createResource(info.getStem() + ".vcgm1");

	try
	{
		CSaveFile save(*CResourceHandler::get()->getResourceName(ResourceID(info.getStem(), EResType::CLIENT_SAVEGAME)));
		cl->saveCommonState(save);
		save << *cl;
	}
	catch(std::exception &e)
	{
        logNetwork->errorStream() << "Failed to save game:" << e.what();
	}
}
Ejemplo n.º 2
0
std::unordered_map<ResourceID, std::string> CFilesystemLoader::listFiles(size_t depth, bool initial) const
{
	std::set<EResType::Type> initialTypes;
	initialTypes.insert(EResType::DIRECTORY);
	initialTypes.insert(EResType::TEXT);
	initialTypes.insert(EResType::ARCHIVE_LOD);
	initialTypes.insert(EResType::ARCHIVE_VID);
	initialTypes.insert(EResType::ARCHIVE_SND);

	assert(boost::filesystem::is_directory(baseDirectory));
	std::unordered_map<ResourceID, std::string> fileList;

	std::vector<std::string> path;//vector holding relative path to our file

	boost::filesystem::recursive_directory_iterator enddir;
	boost::filesystem::recursive_directory_iterator it(baseDirectory, boost::filesystem::symlink_option::recurse);

	for(; it != enddir; ++it)
	{
		EResType::Type type;

		if (boost::filesystem::is_directory(it->status()))
		{
			path.resize(it.level()+1);
			path.back() = it->path().leaf().string();
			it.no_push(depth <= it.level()); // don't iterate into directory if depth limit reached

			type = EResType::DIRECTORY;
		}
		else
			type = EResTypeHelper::getTypeFromExtension(boost::filesystem::extension(*it));

		if (!initial || vstd::contains(initialTypes, type))
		{
			//reconstruct relative filename (not possible via boost AFAIK)
			std::string filename;
			for (size_t i=0; i<it.level() && i<path.size(); i++)
				filename += path[i] + '/';
			filename += it->path().leaf().string();

			fileList[ResourceID(filename, type)] = filename;
		}
	}

	return fileList;
}
Ejemplo n.º 3
0
bool CResourceLoader::createResource(std::string URI)
{
	std::string filename = URI;
	boost::to_upper(URI);
	BOOST_REVERSE_FOREACH (const LoaderEntry & entry, loaders)
	{
		if (entry.writeable && boost::algorithm::starts_with(URI, entry.prefix))
		{
			// remove loader prefix from filename
			filename = filename.substr(entry.prefix.size());
			if (!entry.loader->createEntry(filename))
				return false; //or continue loop?

			resources[ResourceID(URI)].push_back(ResourceLocator(entry.loader.get(), filename));
		}
	}
	return false;
}
Ejemplo n.º 4
0
	ui8 * getCachedFile(ResourceID && rid)
	{
		BOOST_FOREACH(auto & file, cache)
		{
			if (file.name == rid)
				return file.getCopy();
		}
		// Still here? Cache miss
		if (cache.size() > cacheSize)
			cache.pop_front();
		cache.push_back(FileData());

		auto data =  CResourceHandler::get()->loadData(rid);
		cache.back().name = ResourceID(rid);
		cache.back().size = data.second;
		cache.back().data = data.first.release();

		return cache.back().getCopy();
	}
Ejemplo n.º 5
0
CDefObjInfoHandler::CDefObjInfoHandler()
{
	VLC->dobjinfo = this;

	auto textFile = CResourceHandler::get()->load(ResourceID("DATA/OBJECTS.TXT"))->readAll();
	std::istringstream inp(std::string((char*)textFile.first.get(), textFile.second));
	int objNumber;
	inp>>objNumber;
	std::string mapStr;
	for(int hh=0; hh<objNumber; ++hh)
	{
		auto  nobj = new CGDefInfo();
		std::string dump;
		inp>>nobj->name;

		std::transform(nobj->name.begin(), nobj->name.end(), nobj->name.begin(), (int(*)(int))toupper);

		for(int o=0; o<6; ++o)
		{
			nobj->blockMap[o] = 0xff;
			nobj->visitMap[o] = 0x00;
			nobj->coverageMap[o] = 0x00;
			nobj->shadowCoverage[o] = 0x00;
		}
		inp>>mapStr;
		std::reverse(mapStr.begin(), mapStr.end());
		for(int v=0; v<mapStr.size(); ++v)
		{
			if(mapStr[v]=='0')
			{
				nobj->blockMap[v/8] &= 255 - (128 >> (v%8));
			}
		}
		inp>>mapStr;
		std::reverse(mapStr.begin(), mapStr.end());
		for(int v=0; v<mapStr.size(); ++v)
		{
			if(mapStr[v]=='1')
			{
				nobj->visitMap[v/8] |= (128 >> (v%8));
			}
		}
Ejemplo n.º 6
0
bool CFilesystemList::createResource(std::string filename, bool update)
{
	logGlobal->traceStream()<< "Creating " << filename;
	for (auto & loader : boost::adaptors::reverse(loaders))
	{
		if (writeableLoaders.count(loader.get()) != 0                       // writeable,
			&& loader->createResource(filename, update))          // successfully created
		{
			// Check if resource was created successfully. Possible reasons for this to fail
			// a) loader failed to create resource (e.g. read-only FS)
			// b) in update mode, call with filename that does not exists
			assert(load(ResourceID(filename)));

			logGlobal->traceStream()<< "Resource created successfully";
			return true;
		}
	}
	logGlobal->traceStream()<< "Failed to create resource";
	return false;
}
Ejemplo n.º 7
0
void MusicEntry::load(std::string musicURI)
{
	if (music)
	{
		logGlobal->traceStream()<<"Del-ing music file "<<currentName;
		Mix_FreeMusic(music);
		music = nullptr;
	}

	currentName = musicURI;

	logGlobal->traceStream()<<"Loading music file "<<musicURI;

	data = CResourceHandler::get()->load(ResourceID(musicURI, EResType::MUSIC))->readAll();
	musicFile = SDL_RWFromConstMem(data.first.get(), data.second);
	
	#ifdef VCMI_SDL1
	music = Mix_LoadMUS_RW(musicFile);

	if(!music)
	{
		SDL_FreeRW(musicFile);
		musicFile = nullptr;
		logGlobal->warnStream() << "Warning: Cannot open " << currentName << ": " << Mix_GetError();
		return;
	}

	#else
	music = Mix_LoadMUS_RW(musicFile, SDL_FALSE);

	if(!music)
	{
		SDL_FreeRW(musicFile);
		musicFile = nullptr;
		logGlobal->warnStream() << "Warning: Cannot open " << currentName << ": " << Mix_GetError();
		return;
	}

	#endif // 0

}
Ejemplo n.º 8
0
Mix_Chunk *CSoundHandler::GetSoundChunk(std::string &sound)
{
	if (sound.empty())
		return nullptr;

	// Load and insert
	try
	{
		auto data = CResourceHandler::get()->load(ResourceID(std::string("SOUNDS/") + sound, EResType::SOUND))->readAll();

		SDL_RWops *ops = SDL_RWFromMem(data.first.release(), data.second);
		Mix_Chunk *chunk;
		chunk = Mix_LoadWAV_RW(ops, 1);	// will free ops
		return chunk;
	}
	catch(std::exception &e)
	{
        logGlobal->warnStream() << "Cannot get sound " << sound << " chunk: " << e.what();
		return nullptr;
	}
}
Ejemplo n.º 9
0
void CModHandler::loadConfigFromFile (std::string name)
{
	std::string paths;
	for(auto& p : CResourceHandler::get()->getResourceNames(ResourceID("config/" + name)))
	{
		paths += p.string() + ", ";
	}
	paths = paths.substr(0, paths.size() - 2);
	logGlobal->debugStream() << "Loading hardcoded features settings from [" << paths << "], result:";
	settings.data = JsonUtils::assembleFromFiles("config/" + name);
	const JsonNode & hardcodedFeatures = settings.data["hardcodedFeatures"];
	settings.MAX_HEROES_AVAILABLE_PER_PLAYER = hardcodedFeatures["MAX_HEROES_AVAILABLE_PER_PLAYER"].Float();
	logGlobal->debugStream() << "\tMAX_HEROES_AVAILABLE_PER_PLAYER\t" << settings.MAX_HEROES_AVAILABLE_PER_PLAYER;
	settings.MAX_HEROES_ON_MAP_PER_PLAYER = hardcodedFeatures["MAX_HEROES_ON_MAP_PER_PLAYER"].Float();
	logGlobal->debugStream() << "\tMAX_HEROES_ON_MAP_PER_PLAYER\t" << settings.MAX_HEROES_ON_MAP_PER_PLAYER;
	settings.CREEP_SIZE = hardcodedFeatures["CREEP_SIZE"].Float();
	logGlobal->debugStream() << "\tCREEP_SIZE\t" << settings.CREEP_SIZE;
	settings.WEEKLY_GROWTH = hardcodedFeatures["WEEKLY_GROWTH_PERCENT"].Float();
	logGlobal->debugStream() << "\tWEEKLY_GROWTH\t" << settings.WEEKLY_GROWTH;
	settings.NEUTRAL_STACK_EXP = hardcodedFeatures["NEUTRAL_STACK_EXP_DAILY"].Float();
	logGlobal->debugStream() << "\tNEUTRAL_STACK_EXP\t" << settings.NEUTRAL_STACK_EXP;
	settings.MAX_BUILDING_PER_TURN = hardcodedFeatures["MAX_BUILDING_PER_TURN"].Float();
	logGlobal->debugStream() << "\tMAX_BUILDING_PER_TURN\t" << settings.MAX_BUILDING_PER_TURN;
	settings.DWELLINGS_ACCUMULATE_CREATURES = hardcodedFeatures["DWELLINGS_ACCUMULATE_CREATURES"].Bool();
	logGlobal->debugStream() << "\tDWELLINGS_ACCUMULATE_CREATURES\t" << settings.DWELLINGS_ACCUMULATE_CREATURES;
	settings.ALL_CREATURES_GET_DOUBLE_MONTHS = hardcodedFeatures["ALL_CREATURES_GET_DOUBLE_MONTHS"].Bool();
	logGlobal->debugStream() << "\tALL_CREATURES_GET_DOUBLE_MONTHS\t" << settings.ALL_CREATURES_GET_DOUBLE_MONTHS;
	settings.WINNING_HERO_WITH_NO_TROOPS_RETREATS = hardcodedFeatures["WINNING_HERO_WITH_NO_TROOPS_RETREATS"].Bool();
	logGlobal->debugStream() << "\tWINNING_HERO_WITH_NO_TROOPS_RETREATS\t" << settings.WINNING_HERO_WITH_NO_TROOPS_RETREATS;
	const JsonNode & gameModules = settings.data["modules"];
	modules.STACK_EXP = gameModules["STACK_EXPERIENCE"].Bool();
  logGlobal->debugStream() << "\tSTACK_EXP\t" << modules.STACK_EXP;
	modules.STACK_ARTIFACT = gameModules["STACK_ARTIFACTS"].Bool();
	logGlobal->debugStream() << "\tSTACK_ARTIFACT\t" << modules.STACK_ARTIFACT;
	modules.COMMANDERS = gameModules["COMMANDERS"].Bool();
	logGlobal->debugStream() << "\tCOMMANDERS\t" << modules.COMMANDERS;
	modules.MITHRIL = gameModules["MITHRIL"].Bool();
	logGlobal->debugStream() << "\tMITHRIL\t" << modules.MITHRIL;
}
Ejemplo n.º 10
0
void CHeroHandler::loadObstacles()
{
	auto loadObstacles = [](const JsonNode &node, bool absolute, std::map<int, CObstacleInfo> &out)
	{
		for(const JsonNode &obs : node.Vector())
		{
			int ID = obs["id"].Float();
			CObstacleInfo & obi = out[ID];
			obi.ID = ID;
			obi.defName = obs["defname"].String();
			obi.width = obs["width"].Float();
			obi.height = obs["height"].Float();
			obi.allowedTerrains = obs["allowedTerrain"].convertTo<std::vector<ETerrainType> >();
			obi.allowedSpecialBfields = obs["specialBattlefields"].convertTo<std::vector<BFieldType> >();
			obi.blockedTiles = obs["blockedTiles"].convertTo<std::vector<si16> >();
			obi.isAbsoluteObstacle = absolute;
		}
	};

	const JsonNode config(ResourceID("config/obstacles.json"));
	loadObstacles(config["obstacles"], false, obstacles);
	loadObstacles(config["absoluteObstacles"], true, absoluteObstacles);
	//loadObstacles(config["moats"], true, moats);
}
Ejemplo n.º 11
0
CMusicHandler::CMusicHandler():
	listener(settings.listen["general"]["music"])
{
	listener(std::bind(&CMusicHandler::onVolumeChange, this, _1));
	// Map music IDs
	// Vectors for helper
	const std::string setEnemy[] = {"AITheme0", "AITheme1", "AITheme2"};
	const std::string setBattle[] = {"Combat01", "Combat02", "Combat03", "Combat04"};

	auto fillSet = [=](std::string setName, const std::string list[], size_t amount)
	{
		for (size_t i=0; i < amount; i++)
			addEntryToSet(setName, i, "music/" + list[i]);
	};
	fillSet("enemy-turn", setEnemy, ARRAY_COUNT(setEnemy));
	fillSet("battle", setBattle, ARRAY_COUNT(setBattle));

	JsonNode terrains(ResourceID("config/terrains.json"));
	for (auto entry : terrains.Struct())
	{
		int terrIndex = vstd::find_pos(GameConstants::TERRAIN_NAMES, entry.first);
		addEntryToSet("terrain", terrIndex, "Music/" + entry.second["music"].String());
	}
}
Ejemplo n.º 12
0
// Allocate an SDL chunk and cache it.
Mix_Chunk *CSoundHandler::GetSoundChunk(soundBase::soundID soundID)
{
	// Find its name
	auto fname = sounds[soundID];
	if (fname.empty())
		return nullptr;

	// Load and insert
	try
	{
		auto data = CResourceHandler::get()->load(ResourceID(std::string("SOUNDS/") + fname, EResType::SOUND))->readAll();

		SDL_RWops *ops = SDL_RWFromMem(data.first.release(), data.second);
		Mix_Chunk *chunk;
		chunk = Mix_LoadWAV_RW(ops, 1);	// will free ops
		soundChunks.insert(std::pair<soundBase::soundID, Mix_Chunk *>(soundID, chunk));
		return chunk;
	}
	catch(std::exception &e)
	{
        logGlobal->warnStream() << "Cannot get sound " << soundID << " chunk: " << e.what();
		return nullptr;
	}
}
Ejemplo n.º 13
0
Archivo: CMT.cpp Proyecto: yzliang/vcmi
int main(int argc, char** argv)
#endif
{
#ifdef __APPLE__
	// Correct working dir executable folder (not bundle folder) so we can use executable relative pathes
    std::string executablePath = argv[0];
    std::string workDir = executablePath.substr(0, executablePath.rfind('/'));
    chdir(workDir.c_str());
    
    // Check for updates
    OSX_checkForUpdates();

    // Check that game data is prepared. Otherwise run vcmibuilder helper application
    FILE* check = fopen((VCMIDirs::get().localPath() + "/game_data_prepared").c_str(), "r");
    if (check == nullptr) {
        system("open ./vcmibuilder.app");
        return 0;
    }
    fclose(check);
#endif
    std::cout << "Starting... " << std::endl;
	po::options_description opts("Allowed options");
	opts.add_options()
		("help,h", "display help and exit")
		("version,v", "display version information and exit")
		("battle,b", po::value<std::string>(), "runs game in duel mode (battle-only")
		("start", po::value<std::string>(), "starts game from saved StartInfo file")
		("onlyAI", "runs without human player, all players will be default AI")
		("noGUI", "runs without GUI, implies --onlyAI")
		("ai", po::value<std::vector<std::string>>(), "AI to be used for the player, can be specified several times for the consecutive players")
		("oneGoodAI", "puts one default AI and the rest will be EmptyAI")
		("autoSkip", "automatically skip turns in GUI")
		("disable-video", "disable video player")
		("nointro,i", "skips intro movies");

	if(argc > 1)
	{
		try
		{
			po::store(po::parse_command_line(argc, argv, opts), vm);
		}
		catch(std::exception &e) 
		{
            std::cerr << "Failure during parsing command-line options:\n" << e.what() << std::endl;
		}
	}

	po::notify(vm);
	if(vm.count("help"))
	{
		prog_help(opts);
		return 0;
	}
	if(vm.count("version"))
	{
		prog_version();
		return 0;
	}
	if(vm.count("noGUI"))
	{
		gNoGUI = true;
		vm.insert(std::pair<std::string, po::variable_value>("onlyAI", po::variable_value()));
	}

	//Set environment vars to make window centered. Sometimes work, sometimes not. :/
	putenv((char*)"SDL_VIDEO_WINDOW_POS");
	putenv((char*)"SDL_VIDEO_CENTERED=1");

	// Have effect on X11 system only (Linux).
	// For whatever reason in fullscreen mode SDL takes "raw" mouse input from DGA X11 extension
	// (DGA = Direct graphics access). Because this is raw input (before any speed\acceleration proceesing)
	// it may result in very small \ very fast mouse when game in fullscreen mode
	putenv((char*)"SDL_VIDEO_X11_DGAMOUSE=0");

    // Init old logging system and new (temporary) logging system
	CStopWatch total, pomtime;
	std::cout.flags(std::ios::unitbuf);
	console = new CConsoleHandler;
	*console->cb = boost::bind(&processCommand, _1);
	console->start();
	atexit(dispose);

	CBasicLogConfigurator logConfig(VCMIDirs::get().userCachePath() + "/VCMI_Client_log.txt", console);
    logConfig.configureDefault();
	logGlobal->infoStream() <<"Creating console "<<pomtime.getDiff();

    // Init filesystem and settings
	preinitDLL(::console);
    settings.init();

    // Initialize logging based on settings
    logConfig.configure();

	// Some basic data validation to produce better error messages in cases of incorrect install
	auto testFile = [](std::string filename, std::string message) -> bool
	{
		if (CResourceHandler::get()->existsResource(ResourceID(filename)))
			return true;

        logGlobal->errorStream() << "Error: " << message << " was not found!";
		return false;
	};

	if (!testFile("DATA/HELP.TXT", "Heroes III data") &&
	    !testFile("MODS/VCMI/MOD.JSON", "VCMI mod") &&
	    !testFile("DATA/StackQueueBgBig.PCX", "VCMI data"))
		exit(1); // These are unrecoverable errors

	// these two are optional + some installs have them on CD and not in data directory
	testFile("VIDEO/GOOD1A.SMK", "campaign movies");
	testFile("SOUNDS/G1A.WAV", "campaign music"); //technically not a music but voiced intro sounds

	conf.init();
    logGlobal->infoStream() <<"Loading settings: "<<pomtime.getDiff();
    logGlobal->infoStream() << NAME;

	srand ( time(nullptr) );
	

	const JsonNode& video = settings["video"];
	const JsonNode& res = video["screenRes"];

	//something is really wrong...
	if (res["width"].Float() < 100 || res["height"].Float() < 100)
	{
        logGlobal->errorStream() << "Fatal error: failed to load settings!";
        logGlobal->errorStream() << "Possible reasons:";
        logGlobal->errorStream() << "\tCorrupted local configuration file at " << VCMIDirs::get().userConfigPath() << "/settings.json";
        logGlobal->errorStream() << "\tMissing or corrupted global configuration file at " << VCMIDirs::get().userConfigPath() << "/schemas/settings.json";
        logGlobal->errorStream() << "VCMI will now exit...";
		exit(EXIT_FAILURE);
	}

	if(!gNoGUI)
	{
		if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO))
		{
			logGlobal->errorStream()<<"Something was wrong: "<< SDL_GetError();
			exit(-1);
		}
		atexit(SDL_Quit);
		setScreenRes(res["width"].Float(), res["height"].Float(), video["bitsPerPixel"].Float(), video["fullscreen"].Bool());
		logGlobal->infoStream() <<"\tInitializing screen: "<<pomtime.getDiff();
	}


	CCS = new CClientState;
	CGI = new CGameInfo; //contains all global informations about game (texts, lodHandlers, map handler etc.)
	// Initialize video
#if DISABLE_VIDEO
	CCS->videoh = new CEmptyVideoPlayer;
#else
	if (!gNoGUI && !vm.count("disable-video"))
		CCS->videoh = new CVideoPlayer;
	else
		CCS->videoh = new CEmptyVideoPlayer;
#endif

    logGlobal->infoStream()<<"\tInitializing video: "<<pomtime.getDiff();



	//we can properly play intro only in the main thread, so we have to move loading to the separate thread
	boost::thread loading(init);

	if(!gNoGUI )
	{
		if(!vm.count("battle") && !vm.count("nointro"))
			playIntro();
		SDL_FillRect(screen,nullptr,0);
	}

	CSDL_Ext::update(screen);
	loading.join();
    logGlobal->infoStream()<<"Initialization of VCMI (together): "<<total.getDiff();

	if(!vm.count("battle"))
	{
		Settings session = settings.write["session"];
		session["autoSkip"].Bool()  = vm.count("autoSkip");
		session["oneGoodAI"].Bool() = vm.count("oneGoodAI");

		std::string fileToStartFrom; //none by default
		if(vm.count("start"))
			fileToStartFrom = vm["start"].as<std::string>();

		if(fileToStartFrom.size() && boost::filesystem::exists(fileToStartFrom))
			startGameFromFile(fileToStartFrom); //ommit pregame and start the game using settings from fiel
		else
		{
			if(fileToStartFrom.size())
			{
                logGlobal->warnStream() << "Warning: cannot find given file to start from (" << fileToStartFrom
                    << "). Falling back to main menu.";
			}
			GH.curInt = CGPreGame::create(); //will set CGP pointer to itself
		}
	}
	else
	{
		auto  si = new StartInfo();
		si->mode = StartInfo::DUEL;
		si->mapname = vm["battle"].as<std::string>();
		si->playerInfos[PlayerColor(0)].color = PlayerColor(0);
		si->playerInfos[PlayerColor(1)].color = PlayerColor(1);
		startGame(si);
	}

	if(!gNoGUI)
	{
		mainGUIThread = new boost::thread(&CGuiHandler::run, &GH);
		listenForEvents();
	}
	else
	{
		while(true)
			boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
	}

	return 0;
}
Ejemplo n.º 14
0
Archivo: Fonts.cpp Proyecto: qdii/vcmi
std::pair<std::unique_ptr<ui8[]>, ui64> CTrueTypeFont::loadData(const JsonNode & config)
{
    std::string filename = "Data/" + config["file"].String();
    return CResourceHandler::get()->load(ResourceID(filename, EResType::TTF_FONT))->readAll();
}
Ejemplo n.º 15
0
Archivo: Fonts.cpp Proyecto: qdii/vcmi
CBitmapFont::CBitmapFont(const std::string & filename):
    data(CResourceHandler::get()->load(ResourceID("data/" + filename, EResType::BMP_FONT))->readAll()),
    chars(loadChars()),
    height(data.first.get()[5])
{}
Ejemplo n.º 16
0
SDL_Surface * BitmapHandler::loadBitmapFromDir(std::string path, std::string fname, bool setKey)
{
    if(!fname.size())
    {
        logGlobal->warnStream() << "Call to loadBitmap with void fname!";
        return nullptr;
    }
    if (!CResourceHandler::get()->existsResource(ResourceID(path + fname, EResType::IMAGE)))
    {
        return nullptr;
    }

    SDL_Surface * ret=nullptr;

    auto readFile = CResourceHandler::get()->load(ResourceID(path + fname, EResType::IMAGE))->readAll();

    if (isPCX(readFile.first.get()))
    {   //H3-style PCX
        ret = loadH3PCX(readFile.first.get(), readFile.second);
        if (ret)
        {
            if(ret->format->BytesPerPixel == 1  &&  setKey)
            {
                const SDL_Color &c = ret->format->palette->colors[0];
                SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format, c.r, c.g, c.b));
            }
        }
        else
            logGlobal->errorStream()<<"Failed to open "<<fname<<" as H3 PCX!";
    }
    else
    {   //loading via SDL_Image
        ret = IMG_Load_RW(
                  //create SDL_RW with our data (will be deleted by SDL)
                  SDL_RWFromConstMem((void*)readFile.first.get(), readFile.second),
                  1); // mark it for auto-deleting
        if (ret)
        {
            if (ret->format->palette)
            {
                //set correct value for alpha\unused channel
                for (int i=0; i< ret->format->palette->ncolors; i++)
                    ret->format->palette->colors[i].unused = 255;
            }
        }
        else
        {
            logGlobal->errorStream()<<"Failed to open "<<fname<<" via SDL_Image";
            logGlobal->errorStream()<<"Reason: " << IMG_GetError();
        }
    }

    // When modifyin anything here please check two use cases:
    // 1) Vampire mansion in Necropolis (not 1st color is transparent)
    // 2) Battle background when fighting on grass/dirt, topmost sky part (NO transparent color)
    // 3) New objects that may use 24-bit images for icons (e.g. witchking arts)
    auto colorID = SDL_MapRGB(ret->format, 0, 255, 255);

    if (ret->format->palette)
    {
        auto & color = ret->format->palette->colors[colorID];

        // set color key only if exactly such color was found
        if (color.r == 0 && color.g == 255 && color.b == 255)
            SDL_SetColorKey(ret, SDL_SRCCOLORKEY, colorID);
    }
    else // always set
    {
        SDL_SetColorKey(ret, SDL_SRCCOLORKEY, colorID);
    }
    return ret;
}
Ejemplo n.º 17
0
void CClient::loadGame( const std::string & fname )
{
    logNetwork->infoStream() <<"Loading procedure started!";

	CServerHandler sh;
	sh.startServer();

	CStopWatch tmh;
	try
	{
		std::string clientSaveName = CResourceHandler::get()->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME));
		std::string controlServerSaveName;

		if (CResourceHandler::get()->existsResource(ResourceID(fname, EResType::SERVER_SAVEGAME)))
		{
			controlServerSaveName = CResourceHandler::get()->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME));
		}
		else// create entry for server savegame. Triggered if save was made after launch and not yet present in res handler
		{
			controlServerSaveName = clientSaveName.substr(0, clientSaveName.find_last_of(".")) + ".vsgm1";
			CResourceHandler::get()->createResource(controlServerSaveName, true);
		}

		if(clientSaveName.empty())
			throw std::runtime_error("Cannot open client part of " + fname);
		if(controlServerSaveName.empty())
			throw std::runtime_error("Cannot open server part of " + fname);

		unique_ptr<CLoadFile> loader;
		{
			CLoadIntegrityValidator checkingLoader(clientSaveName, controlServerSaveName);
			loadCommonState(checkingLoader);
			loader = checkingLoader.decay();
		}
        logNetwork->infoStream() << "Loaded common part of save " << tmh.getDiff();
		const_cast<CGameInfo*>(CGI)->mh = new CMapHandler();
		const_cast<CGameInfo*>(CGI)->mh->map = gs->map;
		pathInfo = make_unique<CPathsInfo>(getMapSize());
		CGI->mh->init();
        logNetwork->infoStream() <<"Initing maphandler: "<<tmh.getDiff();

		*loader >> *this;
        logNetwork->infoStream() << "Loaded client part of save " << tmh.getDiff();
	}
	catch(std::exception &e)
	{
		logGlobal->errorStream() << "Cannot load game " << fname << ". Error: " << e.what();
		throw; //obviously we cannot continue here
	}

	serv = sh.connectToServer();
	serv->addStdVecItems(gs);

	tmh.update();
	ui8 pom8;
	*serv << ui8(3) << ui8(1); //load game; one client
	*serv << fname;
	*serv >> pom8;
	if(pom8) 
		throw std::runtime_error("Server cannot open the savegame!");
	else
        logNetwork->infoStream() << "Server opened savegame properly.";

	*serv << ui32(gs->scenarioOps->playerInfos.size()+1); //number of players + neutral
	for(auto it = gs->scenarioOps->playerInfos.begin(); 
		it != gs->scenarioOps->playerInfos.end(); ++it)
	{
		*serv << ui8(it->first.getNum()); //players
	}
	*serv << ui8(PlayerColor::NEUTRAL.getNum());
    logNetwork->infoStream() <<"Sent info to server: "<<tmh.getDiff();

	serv->enableStackSendingByID();
	serv->disableSmartPointerSerialization();

}
Ejemplo n.º 18
0
std::unique_ptr<CInputStream> CMappedFileLoader::load(const std::string & resourceName) const
{
	return CResourceHandler::get()->load(ResourceID(resourceName));
}
Ejemplo n.º 19
0
std::string CMappedFileLoader::getFullName(const std::string & resourceName) const
{
	return CResourceHandler::get()->getResourceName(ResourceID(resourceName));
}
Ejemplo n.º 20
0
void CBonusTypeHandler::load()
{
	const JsonNode gameConf(ResourceID("config/gameConfig.json"));
	const JsonNode config(JsonUtils::assembleFromFiles(gameConf["bonuses"].convertTo<std::vector<std::string> >()));
	load(config);
}
Ejemplo n.º 21
0
void CModHandler::initialize(std::vector<std::string> availableMods)
{
	std::string confName = "config/modSettings.json";
	JsonNode modConfig;

	// Porbably new install. Create initial configuration
	if (!CResourceHandler::get()->existsResource(ResourceID(confName)))
		CResourceHandler::get()->createResource(confName);
	else
		modConfig = JsonNode(ResourceID(confName));

	const JsonNode & modList = modConfig["activeMods"];
	JsonNode resultingList;

	std::vector <TModID> detectedMods;

	for(std::string name : availableMods)
	{
		boost::to_lower(name);
		std::string modFileName = "mods/" + name + "/mod.json";

		if (CResourceHandler::get()->existsResource(ResourceID(modFileName)))
		{
			const JsonNode config = JsonNode(ResourceID(modFileName));

			if (config.isNull())
				continue;

			if (!modList[name].isNull() && modList[name].Bool() == false )
			{
				resultingList[name].Bool() = false;
				continue; // disabled mod
			}
			resultingList[name].Bool() = true;

			CModInfo & mod = allMods[name];

			mod.identifier = name;
			mod.name = config["name"].String();
			mod.description =  config["description"].String();
			mod.dependencies = config["depends"].convertTo<std::set<std::string> >();
			mod.conflicts =    config["conflicts"].convertTo<std::set<std::string> >();
			detectedMods.push_back(name);
		}
		else
            logGlobal->warnStream() << "\t\t Directory " << name << " does not contains VCMI mod";
	}

	if (!checkDependencies(detectedMods))
	{
        logGlobal->errorStream() << "Critical error: failed to load mods! Exiting...";
		exit(1);
	}

	activeMods = resolveDependencies(detectedMods);

	modConfig["activeMods"] = resultingList;
	CResourceHandler::get()->createResource("CONFIG/modSettings.json");

	std::ofstream file(CResourceHandler::get()->getResourceName(ResourceID("config/modSettings.json")), std::ofstream::trunc);
	file << modConfig;
}
Ejemplo n.º 22
0
std::unique_ptr<CInputStream> CMapService::getStreamFromFS(const std::string & name)
{
	return CResourceHandler::get()->load(ResourceID(name, EResType::MAP));
}
Ejemplo n.º 23
0
void CClient::loadGame(const std::string & fname, const bool server, const std::vector<int>& humanplayerindices, const int loadNumPlayers, int player_, const std::string & ipaddr, const std::string & port)
{
    PlayerColor player(player_); //intentional shadowing

    logNetwork->infoStream() <<"Loading procedure started!";

	CServerHandler sh;
    if(server)
         sh.startServer();
    else
         serv = sh.justConnectToServer(ipaddr,port=="" ? "3030" : port);

	CStopWatch tmh;
    unique_ptr<CLoadFile> loader;
	try
	{
		std::string clientSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME));
		std::string controlServerSaveName;

		if (CResourceHandler::get("local")->existsResource(ResourceID(fname, EResType::SERVER_SAVEGAME)))
		{
			controlServerSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME));
		}
		else// create entry for server savegame. Triggered if save was made after launch and not yet present in res handler
		{
			controlServerSaveName = clientSaveName.substr(0, clientSaveName.find_last_of(".")) + ".vsgm1";
			CResourceHandler::get("local")->createResource(controlServerSaveName, true);
		}

		if(clientSaveName.empty())
			throw std::runtime_error("Cannot open client part of " + fname);
		if(controlServerSaveName.empty())
			throw std::runtime_error("Cannot open server part of " + fname);

		{
			CLoadIntegrityValidator checkingLoader(clientSaveName, controlServerSaveName, minSupportedVersion);
			loadCommonState(checkingLoader);
			loader = checkingLoader.decay();
		}
        logNetwork->infoStream() << "Loaded common part of save " << tmh.getDiff();
		const_cast<CGameInfo*>(CGI)->mh = new CMapHandler();
		const_cast<CGameInfo*>(CGI)->mh->map = gs->map;
		pathInfo = make_unique<CPathsInfo>(getMapSize());
		CGI->mh->init();
        logNetwork->infoStream() <<"Initing maphandler: "<<tmh.getDiff();
	}
	catch(std::exception &e)
	{
		logGlobal->errorStream() << "Cannot load game " << fname << ". Error: " << e.what();
		throw; //obviously we cannot continue here
	}

/*
    if(!server)
         player = PlayerColor(player_);
*/

    std::set<PlayerColor> clientPlayers;
    if(server)
         serv = sh.connectToServer();
    //*loader >> *this;

    if(server)
    {
         tmh.update();
         ui8 pom8;
         *serv << ui8(3) << ui8(loadNumPlayers); //load game; one client if single-player
         *serv << fname;
         *serv >> pom8;
         if(pom8) 
              throw std::runtime_error("Server cannot open the savegame!");
         else
              logNetwork->infoStream() << "Server opened savegame properly.";
    }

    if(server)
    {
         for(auto & elem : gs->scenarioOps->playerInfos)
              if(!std::count(humanplayerindices.begin(),humanplayerindices.end(),elem.first.getNum()) || elem.first==player)
              {
                  clientPlayers.insert(elem.first);
              }
         clientPlayers.insert(PlayerColor::NEUTRAL);
    }
    else
    {
        clientPlayers.insert(player);
    }

    std::cout << "CLIENTPLAYERS:\n";
    for(auto x : clientPlayers)
         std::cout << x << std::endl;
    std::cout << "ENDCLIENTPLAYERS\n";

    serialize(loader->serializer,0,clientPlayers);
    *serv << ui32(clientPlayers.size());
    for(auto & elem : clientPlayers)
        *serv << ui8(elem.getNum());
    serv->addStdVecItems(gs); /*why is this here?*/

    //*loader >> *this;
    logNetwork->infoStream() << "Loaded client part of save " << tmh.getDiff();

    logNetwork->infoStream() <<"Sent info to server: "<<tmh.getDiff();

    //*serv << clientPlayers;
	serv->enableStackSendingByID();
	serv->disableSmartPointerSerialization();

// 	logGlobal->traceStream() << "Objects:";
// 	for(int i = 0; i < gs->map->objects.size(); i++)
// 	{
// 		auto o = gs->map->objects[i];
// 		if(o)
// 			logGlobal->traceStream() << boost::format("\tindex=%5d, id=%5d; address=%5d, pos=%s, name=%s") % i % o->id % (int)o.get() % o->pos % o->getHoverText();
// 		else
// 			logGlobal->traceStream() << boost::format("\tindex=%5d --- nullptr") % i;
// 	}
}
Ejemplo n.º 24
0
void CJsonRmgTemplateLoader::loadTemplates()
{
	const JsonNode rootNode(ResourceID("config/rmg.json"));
	for(const auto & templatePair : rootNode.Struct())
	{
		auto tpl = new CRmgTemplate();
		try
		{
			tpl->setName(templatePair.first);
			const auto & templateNode = templatePair.second;

			// Parse main template data
			tpl->setMinSize(parseMapTemplateSize(templateNode["minSize"].String()));
			tpl->setMaxSize(parseMapTemplateSize(templateNode["maxSize"].String()));
			tpl->setPlayers(parsePlayers(templateNode["players"].String()));
			tpl->setCpuPlayers(parsePlayers(templateNode["cpu"].String()));

			// Parse zones
			std::map<TRmgTemplateZoneId, CRmgTemplateZone *> zones;
			for (const auto & zonePair : templateNode["zones"].Struct())
			{
				auto zone = new CRmgTemplateZone();
				auto zoneId = boost::lexical_cast<TRmgTemplateZoneId>(zonePair.first);
				zone->setId(zoneId);

				const auto & zoneNode = zonePair.second;
				zone->setType(parseZoneType(zoneNode["type"].String()));
				zone->setSize(zoneNode["size"].Float());
				if (!zoneNode["owner"].isNull()) zone->setOwner(zoneNode["owner"].Float());

				zone->setPlayerTowns(parseTemplateZoneTowns(zoneNode["playerTowns"]));
				zone->setNeutralTowns(parseTemplateZoneTowns(zoneNode["neutralTowns"]));
				if (!zoneNode["matchTerrainToTown"].isNull()) //default : true
					zone->setMatchTerrainToTown(zoneNode["matchTerrainToTown"].Bool());
				zone->setTerrainTypes(parseTerrainTypes(zoneNode["terrainTypes"].Vector(), zone->getDefaultTerrainTypes()));

				if (!zoneNode["townsAreSameType"].isNull()) //default : false
					zone->setTownsAreSameType((zoneNode["townsAreSameType"].Bool()));

				for (int i = 0; i < 2; ++i)
				{
					std::set<TFaction> allowedTownTypes;
					if (i)
					{
						if (zoneNode["allowedTowns"].isNull())
							allowedTownTypes = zone->getDefaultTownTypes();
					}
					else
					{
						if (zoneNode["allowedMonsters"].isNull())
							allowedTownTypes = VLC->townh->getAllowedFactions(false);
					}

					if (allowedTownTypes.empty())
					{
						for (const JsonNode & allowedTown : zoneNode[i ? "allowedTowns" : "allowedMonsters"].Vector())
						{
							//complain if the town type is not present in our game
							if (auto id = VLC->modh->identifiers.getIdentifier("faction", allowedTown, false))
								allowedTownTypes.insert(id.get());
						}
					}

					if (!zoneNode[i ? "bannedTowns" : "bannedMonsters"].isNull())
					{
						for (const JsonNode & bannedTown : zoneNode[i ? "bannedTowns" : "bannedMonsters"].Vector())
						{
							//erase unindentified towns silently
							if (auto id = VLC->modh->identifiers.getIdentifier("faction", bannedTown, true))
								vstd::erase_if_present(allowedTownTypes, id.get());
						}
					}
					if (i)
						zone->setTownTypes(allowedTownTypes);
					else
						zone->setMonsterTypes(allowedTownTypes);
				}

				const std::string monsterStrength = zoneNode["monsters"].String();
				if (monsterStrength == "weak")
					zone->setMonsterStrength(EMonsterStrength::ZONE_WEAK);
				else if (monsterStrength == "normal")
					zone->setMonsterStrength(EMonsterStrength::ZONE_NORMAL);
				else if (monsterStrength == "strong")
					zone->setMonsterStrength(EMonsterStrength::ZONE_STRONG);
				else
					throw (rmgException("incorrect monster power"));

				if (!zoneNode["mines"].isNull())
				{
					auto mines = zoneNode["mines"].Struct();
					//FIXME: maybe there is a smarter way to parse it already?
					zone->setMinesAmount(Res::WOOD, mines["wood"].Float());
					zone->setMinesAmount(Res::ORE, mines["ore"].Float());
					zone->setMinesAmount(Res::GEMS, mines["gems"].Float());
					zone->setMinesAmount(Res::CRYSTAL, mines["crystal"].Float());
					zone->setMinesAmount(Res::SULFUR, mines["sulfur"].Float());
					zone->setMinesAmount(Res::MERCURY, mines["mercury"].Float());
					zone->setMinesAmount(Res::GOLD, mines["gold"].Float());
					//TODO: Mithril
				}

				//treasures
				if (!zoneNode["treasure"].isNull())
				{
					//TODO: parse vector of different treasure settings
					if (zoneNode["treasure"].getType() == JsonNode::DATA_STRUCT)
					{
						auto treasureInfo = zoneNode["treasure"].Struct();
						{
							CTreasureInfo ti;
							ti.min = treasureInfo["min"].Float();
							ti.max = treasureInfo["max"].Float();
							ti.density = treasureInfo["density"].Float(); //TODO: use me
							zone->addTreasureInfo(ti);
						}
					}
					else if (zoneNode["treasure"].getType() == JsonNode::DATA_VECTOR)
					{
						for (auto treasureInfo : zoneNode["treasure"].Vector())
						{
							CTreasureInfo ti;
							ti.min = treasureInfo["min"].Float();
							ti.max = treasureInfo["max"].Float();
							ti.density = treasureInfo["density"].Float();
							zone->addTreasureInfo(ti);
						}
					}
				}

				zones[zone->getId()] = zone;
			}

			//copy settings from already parsed zones
			for (const auto & zonePair : templateNode["zones"].Struct())
			{
				auto zoneId = boost::lexical_cast<TRmgTemplateZoneId>(zonePair.first);
				auto zone = zones[zoneId];

				const auto & zoneNode = zonePair.second;

				if (!zoneNode["terrainTypeLikeZone"].isNull())
				{
					int id = zoneNode["terrainTypeLikeZone"].Float();
					zone->setTerrainTypes(zones[id]->getTerrainTypes());
					zone->setMatchTerrainToTown(zones[id]->getMatchTerrainToTown());
				}

				if (!zoneNode["townTypeLikeZone"].isNull())
					zone->setTownTypes (zones[zoneNode["townTypeLikeZone"].Float()]->getTownTypes());

				if (!zoneNode["treasureLikeZone"].isNull())
				{
					for (auto treasureInfo : zones[zoneNode["treasureLikeZone"].Float()]->getTreasureInfo())
					{
						zone->addTreasureInfo(treasureInfo);
					}
				}

				if (!zoneNode["minesLikeZone"].isNull())
				{
					for (auto mineInfo : zones[zoneNode["minesLikeZone"].Float()]->getMinesInfo())
					{
						zone->setMinesAmount (mineInfo.first, mineInfo.second);
					}
					
				}
			}

			tpl->setZones(zones);

			// Parse connections
			std::list<CRmgTemplateZoneConnection> connections;
			for(const auto & connPair : templateNode["connections"].Vector())
			{
				CRmgTemplateZoneConnection conn;
				conn.setZoneA(zones.find(boost::lexical_cast<TRmgTemplateZoneId>(connPair["a"].String()))->second);
				conn.setZoneB(zones.find(boost::lexical_cast<TRmgTemplateZoneId>(connPair["b"].String()))->second);
				conn.setGuardStrength(connPair["guard"].Float());
				connections.push_back(conn);
			}
			tpl->setConnections(connections);
			{
				auto zones = tpl->getZones();
				for (auto con : tpl->getConnections())
				{
					auto idA = con.getZoneA()->getId();
					auto idB = con.getZoneB()->getId();
					zones[idA]->addConnection(idB);
					zones[idB]->addConnection(idA);
				}
			}
			tpl->validate();
			templates[tpl->getName()] = tpl;
		}
		catch(const std::exception & e)
		{
			logGlobal->errorStream() << boost::format("Template %s has errors. Message: %s.") % tpl->getName() % std::string(e.what());
		}
	}
}