예제 #1
0
bool CSpellEffectAnimation::init()
{
	if(!isEarliest(true))
		return false;

	if(effect == 12) //armageddon
	{
		if(effect == -1 || graphics->battleACToDef[effect].size() != 0)
		{
			CDefHandler * anim;
			if(customAnim.size())
				anim = CDefHandler::giveDef(customAnim);
			else
				anim = CDefHandler::giveDef(graphics->battleACToDef[effect][0]);

			if (Vflip)
			{
				for (auto & elem : anim->ourImages)
				{
					CSDL_Ext::VflipSurf(elem.bitmap);
				}
			}

			for(int i=0; i * anim->width < owner->pos.w ; ++i)
			{
				for(int j=0; j * anim->height < owner->pos.h ; ++j)
				{
					BattleEffect be;
					be.effectID = ID;
					be.anim = CDefHandler::giveDef(graphics->battleACToDef[effect][0]);
					if (Vflip)
					{
						for (auto & elem : be.anim->ourImages)
						{
							CSDL_Ext::VflipSurf(elem.bitmap);
						}
					}
					be.currentFrame = 0;
					be.maxFrame = be.anim->ourImages.size();
					be.x = i * anim->width + owner->pos.x;
					be.y = j * anim->height + owner->pos.y;
					be.position = BattleHex::INVALID;

					owner->battleEffects.push_back(be);
				}
			}
		}
		else //there is nothing to play
		{
			endAnim();
			return false;
		}
	}
	else // Effects targeted at a specific creature/hex.
	{
		if(effect == -1 || graphics->battleACToDef[effect].size() != 0)
		{
			const CStack* destStack = owner->getCurrentPlayerInterface()->cb->battleGetStackByPos(destTile, false);
			Rect &tilePos = owner->bfield[destTile]->pos;
			BattleEffect be;
			be.effectID = ID;
			if(customAnim.size())
				be.anim = CDefHandler::giveDef(customAnim);
			else
				be.anim = CDefHandler::giveDef(graphics->battleACToDef[effect][0]);

			if (Vflip)
			{
				for (auto & elem : be.anim->ourImages)
				{
					CSDL_Ext::VflipSurf(elem.bitmap);
				}
			}

			be.currentFrame = 0;
			be.maxFrame = be.anim->ourImages.size();
			if(effect == 1)
				be.maxFrame = 3;

			switch (effect)
			{
			case ui32(-1):
				be.x = x;
				be.y = y;
				break;
			case 0: // Prayer and Lightning Bolt.
			case 1:
			case 19: // Slow
				// Position effect with it's bottom center touching the bottom center of affected tile(s).
				be.x = tilePos.x + tilePos.w/2 - be.anim->width/2;
				be.y = tilePos.y + tilePos.h - be.anim->height;
				break;

			default:
				// Position effect with it's center touching the top center of affected tile(s).
				be.x = tilePos.x + tilePos.w/2 - be.anim->width/2;
				be.y = tilePos.y - be.anim->height/2;
				break;
			}

			// Correction for 2-hex creatures.
			if (destStack != nullptr && destStack->doubleWide())
				be.x += (destStack->attackerOwned ? -1 : 1)*tilePos.w/2;

			//Indicate if effect should be drawn on top of everything or just on top of the hex
			if(areaEffect)
				be.position = BattleHex::INVALID;
			else
				be.position = destTile;

			owner->battleEffects.push_back(be);
		}
		else //there is nothing to play
		{
			endAnim();
			return false;
		}
	}
	//battleEffects 
	return true;
}
예제 #2
0
파일: CMessage.cpp 프로젝트: andrew889/vcmi
std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineWidth, EFonts font )
{
	std::vector<std::string> ret;

	boost::algorithm::trim_right_if(text,boost::algorithm::is_any_of(std::string(" ")));

	// each interation generates one output line
	while (text.length())
	{
		ui32 lineWidth = 0;    //in characters or given char metric
		ui32 wordBreak = -1;    //last position for line break (last space character)
		ui32 currPos = 0;       //current position in text
		bool opened = false;    //set to true when opening brace is found

		size_t symbolSize = 0; // width of character, in bytes
		size_t glyphWidth = 0; // width of printable glyph, pixels

		// loops till line is full or end of text reached
		while(currPos < text.length()  &&  text[currPos] != 0x0a  &&  lineWidth < maxLineWidth)
		{
			symbolSize = Unicode::getCharacterSize(text[currPos]);
			glyphWidth = graphics->fonts[font]->getGlyphWidth(text.data() + currPos);

			// candidate for line break
			if (ui8(text[currPos]) <= ui8(' '))
				wordBreak = currPos;

			/* We don't count braces in string length. */
			if (text[currPos] == '{')
				opened=true;
			else if (text[currPos]=='}')
				opened=false;
			else
				lineWidth += glyphWidth;
			currPos += symbolSize;
		}

		// long line, create line break
		if (currPos < text.length()  &&  (text[currPos] != 0x0a))
		{
			if (wordBreak != ui32(-1))
				currPos = wordBreak;
			else
				currPos -= symbolSize;
		}

		//non-blank line
		if(currPos != 0)
		{
			ret.push_back(text.substr(0, currPos));

			if (opened)
				/* Close the brace for the current line. */
				ret.back() += '}';

			text.erase(0, currPos);
		}
		else if(text[currPos] == 0x0a)
		{
			ret.push_back(""); //add empty string, no extra actions needed
		}

		if (text.length() != 0 && text[0] == 0x0a)
		{
			/* Remove LF */
			text.erase(0, 1);
		}
		else
		{
			// trim only if line does not starts with LF
			// FIXME: necessary? All lines will be trimmed before returning anyway
			boost::algorithm::trim_left_if(text,boost::algorithm::is_any_of(std::string(" ")));
		}

		if (opened)
		{
			/* Add an opening brace for the next line. */
			if (text.length() != 0)
				text.insert(0, "{");
		}
	}

	/* Trim whitespaces of every line. */
	for (auto & elem : ret)
		boost::algorithm::trim(elem);

	return ret;
}
예제 #3
0
파일: Client.cpp 프로젝트: DavidZeni/vcmi
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;
// 	}
}
예제 #4
0
파일: Client.cpp 프로젝트: lightsgoout/vcmi
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();

}