Пример #1
0
PlayerColor CMapGenOptions::getNextPlayerColor() const
{
	for(PlayerColor i = PlayerColor(0); i < PlayerColor::PLAYER_LIMIT; i.advance(1))
	{
		if(!players.count(i))
		{
			return i;
		}
	}
	logGlobal->error("Failed to get next player color");
	assert(false);
	return PlayerColor(0);
}
Пример #2
0
void CInfoBar::CVisibleInfo::loadGameStatus()
{
    assert(children.empty()); // visible info should be re-created to change type

    //get amount of halls of each level
    std::vector<int> halls(4, 0);
    for(auto town : LOCPLINT->towns)
        halls[town->hallLevel()]++;

    std::vector<PlayerColor> allies, enemies;

    //generate list of allies and enemies
    for(int i = 0; i < PlayerColor::PLAYER_LIMIT_I; i++)
    {
        if(LOCPLINT->cb->getPlayerStatus(PlayerColor(i)) == EPlayerStatus::INGAME)
        {
            if (LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, PlayerColor(i)) != PlayerRelations::ENEMIES)
                allies.push_back(PlayerColor(i));
            else
                enemies.push_back(PlayerColor(i));
        }
    }

    //generate component
    OBJ_CONSTRUCTION_CAPTURING_ALL;
    new CPicture("ADSTATIN");
    auto allyLabel  = new CLabel(10, 106, FONT_SMALL, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[390] + ":");
    auto enemyLabel = new CLabel(10, 136, FONT_SMALL, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[391] + ":");

    int posx = allyLabel->pos.w + allyLabel->pos.x - pos.x + 4;
    for(PlayerColor & player : allies)
    {
        auto image = new CAnimImage("ITGFLAGS", player.getNum(), 0, posx, 102);
        posx += image->pos.w;
    }

    posx = enemyLabel->pos.w + enemyLabel->pos.x - pos.x + 4;
    for(PlayerColor & player : enemies)
    {
        auto image = new CAnimImage("ITGFLAGS", player.getNum(), 0, posx, 132);
        posx += image->pos.w;
    }

    for (size_t i=0; i<halls.size(); i++)
    {
        new CAnimImage("itmtl", i, 0, 6 + 42 * i , 11);
        if (halls[i])
            new CLabel( 26 + 42 * i, 64, FONT_SMALL, CENTER, Colors::WHITE, boost::lexical_cast<std::string>(halls[i]));
    }
}
Пример #3
0
void CMessage::init()
{
	{
		piecesOfBox.resize(PlayerColor::PLAYER_LIMIT_I);
		for (int i=0; i<PlayerColor::PLAYER_LIMIT_I; i++)
		{
			CDefHandler * bluePieces = CDefHandler::giveDef("DIALGBOX.DEF");
			if (i==1)
			{
				for (auto & elem : bluePieces->ourImages)
				{
					piecesOfBox[i].push_back(elem.bitmap);
					elem.bitmap->refcount++;
				}
			}
			for (auto & elem : bluePieces->ourImages)
			{
				graphics->blueToPlayersAdv(elem.bitmap, PlayerColor(i));
				piecesOfBox[i].push_back(elem.bitmap);
				elem.bitmap->refcount++;
			}
			delete bluePieces;
		}
		background = BitmapHandler::loadBitmap("DIBOXBCK.BMP");
		SDL_SetColorKey(background,SDL_SRCCOLORKEY,SDL_MapRGB(background->format,0,255,255));
	}
	ok = CDefHandler::giveDef("IOKAY.DEF");
	cancel = CDefHandler::giveDef("ICANCEL.DEF");
}
Пример #4
0
void CGObjectInstance::serializeJsonOwner(JsonSerializeFormat & handler)
{
	ui8 temp = tempOwner.getNum();

	handler.serializeEnum("owner", temp, PlayerColor::NEUTRAL.getNum(), GameConstants::PLAYER_COLOR_NAMES);

	if(!handler.saving)
		tempOwner = PlayerColor(temp);
}
Пример #5
0
void GiveBonus::applyCl(CClient *cl)
{
	cl->invalidatePaths();
	switch(who)
	{
	case HERO:
		{
			const CGHeroInstance *h = GS(cl)->getHero(ObjectInstanceID(id));
			INTERFACE_CALL_IF_PRESENT(h->tempOwner, heroBonusChanged, h, *h->getBonusList().back(),true);
		}
		break;
	case PLAYER:
		{
			const PlayerState *p = GS(cl)->getPlayer(PlayerColor(id));
			INTERFACE_CALL_IF_PRESENT(PlayerColor(id), playerBonusChanged, *p->getBonusList().back(), true);
		}
		break;
	}
}
Пример #6
0
	CMapTestFixture()
	{
		CMapGenOptions opt;

		opt.setHeight(CMapHeader::MAP_SIZE_MIDDLE);
		opt.setWidth(CMapHeader::MAP_SIZE_MIDDLE);
		opt.setHasTwoLevels(true);
		opt.setPlayerCount(4);

		opt.setPlayerTypeForStandardPlayer(PlayerColor(0), EPlayerType::HUMAN);
		opt.setPlayerTypeForStandardPlayer(PlayerColor(1), EPlayerType::AI);
		opt.setPlayerTypeForStandardPlayer(PlayerColor(2), EPlayerType::AI);
		opt.setPlayerTypeForStandardPlayer(PlayerColor(3), EPlayerType::AI);

		CMapGenerator gen;

		initialMap = gen.generate(&opt, TEST_RANDOM_SEED);
		initialMap->name = "Test";
	};
Пример #7
0
void CRClickPopup::createAndPush(const std::string &txt, const CInfoWindow::TCompsInfo &comps)
{
	PlayerColor player = LOCPLINT ? LOCPLINT->playerID : PlayerColor(1); //if no player, then use blue

	CSimpleWindow * temp = new CInfoWindow(txt, player, comps);
	temp->center(Point(GH.current->motion)); //center on mouse
	temp->fitToScreen(10);
	auto  rcpi = new CRClickPopupInt(temp,true);
	GH.pushInt(rcpi);
}
Пример #8
0
bool TradeOnMarketplace::applyGh( CGameHandler *gh )
{
	//market must be owned or visited
	const IMarket *m = IMarket::castFrom(market);

	if(!m)
		COMPLAIN_AND_RETURN("market is not-a-market! :/");

	PlayerColor player = market->tempOwner;

	if(player >= PlayerColor::PLAYER_LIMIT)
		player = gh->getTile(market->visitablePos())->visitableObjects.back()->tempOwner;

	if(player >= PlayerColor::PLAYER_LIMIT)
		COMPLAIN_AND_RETURN("No player can use this market!");

	if(hero && (player != hero->tempOwner || hero->visitablePos() != market->visitablePos()))
		COMPLAIN_AND_RETURN("This hero can't use this marketplace!");

	ERROR_IF_NOT(player);

	switch(mode)
	{
	case EMarketMode::RESOURCE_RESOURCE:
		return gh->tradeResources(m, val, player, r1, r2);
	case EMarketMode::RESOURCE_PLAYER:
		return gh->sendResources(val, player, static_cast<Res::ERes>(r1), PlayerColor(r2));
	case EMarketMode::CREATURE_RESOURCE:
		if(!hero)
			COMPLAIN_AND_RETURN("Only hero can sell creatures!");
		return gh->sellCreatures(val, m, hero, SlotID(r1), static_cast<Res::ERes>(r2));
	case EMarketMode::RESOURCE_ARTIFACT:
		if(!hero)
			COMPLAIN_AND_RETURN("Only hero can buy artifacts!");
		return gh->buyArtifact(m, hero, static_cast<Res::ERes>(r1), ArtifactID(r2));
	case EMarketMode::ARTIFACT_RESOURCE:
		if(!hero)
			COMPLAIN_AND_RETURN("Only hero can sell artifacts!");
		return gh->sellArtifact(m, hero, ArtifactInstanceID(r1), static_cast<Res::ERes>(r2));
	case EMarketMode::CREATURE_UNDEAD:
		return gh->transformInUndead(m, hero, SlotID(r1));
	case EMarketMode::RESOURCE_SKILL:
		return gh->buySecSkill(m, hero, SecondarySkill(r2));
	case EMarketMode::CREATURE_EXP:
		return gh->sacrificeCreatures(m, hero, SlotID(r1), val);
	case EMarketMode::ARTIFACT_EXP:
		return gh->sacrificeArtifact(m, hero, ArtifactPosition(r1));
	default:
		COMPLAIN_AND_RETURN("Unknown exchange mode!");
	}
}
Пример #9
0
void CMapGenOptions::resetPlayersMap()
{

	std::map<PlayerColor, TFaction> rememberTownTypes;

	for (auto p : players)
	{
		auto town = p.second.getStartingTown();
		if (town != RANDOM_SIZE)
			rememberTownTypes[p.first] = town;
	}


	players.clear();
	int realPlayersCnt = humanPlayersCount;
	int realCompOnlyPlayersCnt = (compOnlyPlayerCount == RANDOM_SIZE) ? (PlayerColor::PLAYER_LIMIT_I - realPlayersCnt) : compOnlyPlayerCount;
	int totalPlayersLimit = realPlayersCnt + realCompOnlyPlayersCnt;
	if (getPlayerCount() == RANDOM_SIZE || compOnlyPlayerCount == RANDOM_SIZE)
		totalPlayersLimit = static_cast<int>(PlayerColor::PLAYER_LIMIT_I);

	//FIXME: what happens with human players here?
	for(int color = 0; color < totalPlayersLimit; ++color)
	{
		CPlayerSettings player;
		auto pc = PlayerColor(color);
		player.setColor(pc);
		auto playerType = EPlayerType::AI;
		if (getPlayerCount() != RANDOM_SIZE && color < realPlayersCnt)
		{
			playerType = EPlayerType::HUMAN;
		}
		else if((getPlayerCount() != RANDOM_SIZE && color >= realPlayersCnt)
		   || (compOnlyPlayerCount != RANDOM_SIZE && color >= (PlayerColor::PLAYER_LIMIT_I-compOnlyPlayerCount)))
		{
			playerType = EPlayerType::COMP_ONLY;
		}
		player.setPlayerType(playerType);
		players[pc] = player;

		if (vstd::contains(rememberTownTypes, pc))
			players[pc].setStartingTown(rememberTownTypes[pc]);
	}
}
Пример #10
0
void CGObjectInstance::setProperty( ui8 what, ui32 val )
{
	setPropertyDer(what, val); // call this before any actual changes (needed at least for dwellings)

	switch(what)
	{
	case ObjProperty::OWNER:
		tempOwner = PlayerColor(val);
		break;
	case ObjProperty::BLOCKVIS:
		blockVisit = val;
		break;
	case ObjProperty::ID:
		ID = Obj(val);
		break;
	case ObjProperty::SUBID:
		subID = val;
		break;
	}
}
Пример #11
0
 * Full text of license available in license.txt file, in main folder
 *
 */

#define INSTANTIATE_BASE_FOR_ID_HERE

#include "StdInc.h"

#include "VCMI_Lib.h"
#include "mapObjects/CObjectClassesHandler.h"
#include "CArtHandler.h"
#include "CCreatureHandler.h"
#include "spells/CSpellHandler.h"

const SlotID SlotID::COMMANDER_SLOT_PLACEHOLDER = SlotID(-2);
const PlayerColor PlayerColor::CANNOT_DETERMINE = PlayerColor(253);
const PlayerColor PlayerColor::UNFLAGGABLE = PlayerColor(254);
const PlayerColor PlayerColor::NEUTRAL = PlayerColor(255);
const PlayerColor PlayerColor::PLAYER_LIMIT = PlayerColor(PLAYER_LIMIT_I);
const TeamID TeamID::NO_TEAM = TeamID(255);

#define ID_LIKE_OPERATORS_INTERNAL(A, B, AN, BN)	\
bool operator==(const A & a, const B & b)			\
{													\
	return AN == BN ;								\
}													\
bool operator!=(const A & a, const B & b)			\
{													\
	return AN != BN ;								\
}													\
bool operator<(const A & a, const B & b)			\
Пример #12
0
void OpenWindow::applyCl(CClient *cl)
{
	switch(window)
	{
	case RECRUITMENT_FIRST:
	case RECRUITMENT_ALL:
		{
			const CGDwelling *dw = dynamic_cast<const CGDwelling*>(cl->getObj(ObjectInstanceID(id1)));
			const CArmedInstance *dst = dynamic_cast<const CArmedInstance*>(cl->getObj(ObjectInstanceID(id2)));
			INTERFACE_CALL_IF_PRESENT(dst->tempOwner,showRecruitmentDialog, dw, dst, window == RECRUITMENT_FIRST ? 0 : -1);
		}
		break;
	case SHIPYARD_WINDOW:
		{
			const IShipyard *sy = IShipyard::castFrom(cl->getObj(ObjectInstanceID(id1)));
			INTERFACE_CALL_IF_PRESENT(sy->o->tempOwner, showShipyardDialog, sy);
		}
		break;
	case THIEVES_GUILD:
		{
			//displays Thieves' Guild window (when hero enters Den of Thieves)
			const CGObjectInstance *obj = cl->getObj(ObjectInstanceID(id2));
			INTERFACE_CALL_IF_PRESENT(PlayerColor(id1), showThievesGuildWindow, obj);
		}
		break;
	case UNIVERSITY_WINDOW:
		{
			//displays University window (when hero enters University on adventure map)
			const IMarket *market = IMarket::castFrom(cl->getObj(ObjectInstanceID(id1)));
			const CGHeroInstance *hero = cl->getHero(ObjectInstanceID(id2));
			INTERFACE_CALL_IF_PRESENT(hero->tempOwner,showUniversityWindow, market, hero);
		}
		break;
	case MARKET_WINDOW:
		{
			//displays Thieves' Guild window (when hero enters Den of Thieves)
			const CGObjectInstance *obj = cl->getObj(ObjectInstanceID(id1));
			const CGHeroInstance *hero = cl->getHero(ObjectInstanceID(id2));
			const IMarket *market = IMarket::castFrom(obj);
			INTERFACE_CALL_IF_PRESENT(cl->getTile(obj->visitablePos())->visitableObjects.back()->tempOwner, showMarketWindow, market, hero);
		}
		break;
	case HILL_FORT_WINDOW:
		{
			//displays Hill fort window
			const CGObjectInstance *obj = cl->getObj(ObjectInstanceID(id1));
			const CGHeroInstance *hero = cl->getHero(ObjectInstanceID(id2));
			INTERFACE_CALL_IF_PRESENT(cl->getTile(obj->visitablePos())->visitableObjects.back()->tempOwner, showHillFortWindow, obj, hero);
		}
		break;
	case PUZZLE_MAP:
		{
			INTERFACE_CALL_IF_PRESENT(PlayerColor(id1), showPuzzleMap);
		}
		break;
	case TAVERN_WINDOW:
		const CGObjectInstance *obj1 = cl->getObj(ObjectInstanceID(id1)),
								*obj2 = cl->getObj(ObjectInstanceID(id2));
		INTERFACE_CALL_IF_PRESENT(obj1->tempOwner, showTavernWindow, obj2);
		break;
	}

}
Пример #13
0
void CMapGenOptions::CPlayerSettings::setColor(PlayerColor value)
{
	assert(value >= PlayerColor(0) && value < PlayerColor::PLAYER_LIMIT);
	color = value;
}
Пример #14
0
void CLobbyScreen::startScenario(bool allowOnlyAI)
{
	try
	{
		CSH->sendStartGame(allowOnlyAI);
		buttonStart->block(true);
	}
	catch(ExceptionMapMissing & e)
	{

	}
	catch(ExceptionNoHuman & e)
	{
		// You must position yourself prior to starting the game.
		CInfoWindow::showYesNoDialog(std::ref(CGI->generaltexth->allTexts[530]), CInfoWindow::TCompsInfo(), 0, std::bind(&CLobbyScreen::startScenario, this, true), PlayerColor(1));
	}
	catch(ExceptionNoTemplate & e)
	{
		CInfoWindow::showInfoDialog(std::ref(CGI->generaltexth->allTexts[751]), CInfoWindow::TCompsInfo(), PlayerColor(1));
	}
	catch(...)
	{

	}
}
Пример #15
0
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;
}
Пример #16
0
void CWindowObject::showAll(SDL_Surface *to)
{
	CIntObject::showAll(to);
	if ((options & BORDERED) && (pos.h != to->h || pos.w != to->w))
		CMessage::drawBorder(LOCPLINT ? LOCPLINT->playerID : PlayerColor(1), to, pos.w+28, pos.h+29, pos.x-14, pos.y-15);
}