浏览代码

Merged Ivan's changes in trunk ( r1918 )

Michał W. Urbańczyk 14 年之前
父节点
当前提交
28550c85fd

+ 17 - 11
CConsoleHandler.cpp

@@ -17,8 +17,6 @@
 
 #ifndef _WIN32
 	typedef std::string TColor;
-	#define	_kill_thread(a) pthread_cancel(a)
-	typedef pthread_t ThreadHandle;
 	#define CONSOLE_GREEN "\x1b[1;32m"
 	#define CONSOLE_RED "\x1b[1;32m"
 	#define CONSOLE_MAGENTA "\x1b[1;35m"
@@ -33,10 +31,8 @@
 	#pragma comment(lib, "dbghelp.lib")
 
 	typedef WORD TColor;
-	#define _kill_thread(a) TerminateThread(a,0)
 	HANDLE handleIn;
 	HANDLE handleOut;
-	typedef void* ThreadHandle;
 	#define CONSOLE_GREEN FOREGROUND_GREEN | FOREGROUND_INTENSITY
 	#define CONSOLE_RED FOREGROUND_RED | FOREGROUND_INTENSITY
 	#define CONSOLE_MAGENTA FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY
@@ -186,12 +182,23 @@ void CConsoleHandler::setColor(int level)
 
 int CConsoleHandler::run()
 {
-	char buffer[5000];
-	while(true)
+	//disabling sync to make in_avail() work (othervice always returns 0)
+	std::ios::sync_with_stdio(false);
+	std::string buffer;
+
+	while ( std::cin.good() )
 	{
-		std::cin.getline(buffer, 5000);
-		if(cb && *cb)
-			(*cb)(buffer);
+		//check if we have some unreaded symbols
+		if (std::cin.rdbuf()->in_avail())
+		{
+			if ( getline(std::cin, buffer).good() )
+				if ( cb && *cb )
+					(*cb)(buffer);
+		}
+		else
+			boost::this_thread::sleep(boost::posix_time::millisec(100));
+
+		boost::this_thread::interruption_point();
 	}
 	return -1;
 }
@@ -222,8 +229,7 @@ CConsoleHandler::~CConsoleHandler()
 void CConsoleHandler::end()
 {
 	if (thread) {
-		ThreadHandle th = (ThreadHandle)thread->native_handle();
-		_kill_thread(th);
+		thread->interrupt();
 		thread->join();
 		delete thread;
 		thread = NULL;

+ 1 - 0
client/CCastleInterface.cpp

@@ -349,6 +349,7 @@ void CHeroGSlot::show(SDL_Surface * to)
 
 CHeroGSlot::CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h, CCastleInterface * Owner)
 {
+	used = LCLICK | HOVER;
 	owner = Owner;
 	pos.x = x;
 	pos.y = y;

+ 0 - 1
client/CPlayerInterface.cpp

@@ -3,7 +3,6 @@
 #include "CBattleInterface.h"
 #include "../CCallback.h"
 #include "CCastleInterface.h"
-#include "CKingdomInterface.h"
 #include "CCursorHandler.h"
 #include "CGameInfo.h"
 #include "CHeroWindow.h"

+ 30 - 20
client/CSpellWindow.cpp

@@ -578,7 +578,7 @@ Uint8 CSpellWindow::pagesWithinCurrentTab()
 void CSpellWindow::teleportTo( int town, const CGHeroInstance * hero )
 {
 	const CGTownInstance * dest = LOCPLINT->cb->getTownInfo(town, 1);
-	LOCPLINT->cb->castSpell(hero, Spells::TOWN_PORTAL, dest->visitablePos() + hero->getVisitableOffset());
+	LOCPLINT->cb->castSpell(hero, Spells::TOWN_PORTAL, dest->visitablePos());
 }
 
 CSpellWindow::SpellArea::SpellArea(SDL_Rect pos, CSpellWindow * owner)
@@ -654,23 +654,20 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
 			case TOWN_PORTAL:
 				{
 					std::vector <int> availableTowns;
-					std::vector <const CGTownInstance*> Towns = LOCPLINT->cb->getTownsInfo(false);
-					for(size_t i=0;i<Towns.size();i++)
+					std::vector <const CGTownInstance*> Towns = LOCPLINT->cb->getTownsInfo(true);
+					if (Towns.empty())
 					{
-						const CGTownInstance *t = Towns[i];
-						if (t->visitingHero == NULL) //empty town and this is
-						{
-							availableTowns.push_back(t->id);//add to the list
-						}
+						LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[124]);
+						return;
 					}
 
-					if (h->getSpellSchoolLevel(CGI->spellh->spells[spell]) < 3) //not expert - teleport to nearest available city
+					if (h->getSpellSchoolLevel(CGI->spellh->spells[spell]) < 2) //not advanced or expert - teleport to nearest available city
 					{
 						int nearest = -1; //nearest town's ID
 						double dist = -1;
-						for (int g=0; g<availableTowns.size(); ++g)
+						for (int g=0; g<Towns.size(); ++g)
 						{
-							const CGTownInstance * dest = LOCPLINT->cb->getTownInfo(availableTowns[g], 1);
+							const CGTownInstance * dest = LOCPLINT->cb->getTownInfo(Towns[g]->id, 1);
 							double curDist = dest->pos.dist2d(h->pos);
 							if (nearest == -1 || curDist < dist)
 							{
@@ -678,19 +675,32 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
 								dist = curDist;
 							}
 						}
-
-						LOCPLINT->cb->castSpell(h, spell,
-							LOCPLINT->cb->getTownInfo(availableTowns[nearest], 1)->visitablePos() + h->getVisitableOffset());
+						if ( Towns[nearest]->visitingHero )
+							LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[123]);
+						else
+						{
+							const CGTownInstance * town = LOCPLINT->cb->getTownInfo(Towns[nearest]->id, 1);
+							LOCPLINT->cb->castSpell(h, spell, town->visitablePos());// - town->getVisitableOffset());
+						}
 					}
 					else
 					{ //let the player choose
-						GH.pushInt (new CObjectListWindow(availableTowns,
-							new CPicture(graphics->spellscr->ourImages[spell].bitmap, 0, 0, false),
-							CGI->generaltexth->jktexts[40], CGI->generaltexth->jktexts[41],
-							boost::bind (&CSpellWindow::teleportTo, owner, _1, h)));
+						for(size_t i=0;i<Towns.size();i++)
+						{
+							const CGTownInstance *t = Towns[i];
+							if (t->visitingHero == NULL) //empty town and this is
+							{
+								availableTowns.push_back(t->id);//add to the list
+							}
+						}
+						if (availableTowns.empty())
+							LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[124]);
+						else
+							GH.pushInt (new CObjectListWindow(availableTowns,
+								new CPicture(graphics->spellscr->ourImages[spell].bitmap, 0, 0, false),
+								CGI->generaltexth->jktexts[40], CGI->generaltexth->jktexts[41],
+								boost::bind (&CSpellWindow::teleportTo, owner, _1, h)));
 					}
-					
-
 					return;
 				}
 				break;

+ 6 - 1
client/GUIClasses.cpp

@@ -1666,6 +1666,11 @@ void CCreaturePic::show(SDL_Surface *to)
 	CIntObject::show(to);
 }
 
+void CCreaturePic::showAll(SDL_Surface *to)
+{
+	show(to);
+}
+
 void CRecruitmentWindow::close()
 {
 	GH.popIntTotally(this);
@@ -2477,7 +2482,7 @@ CObjectListWindow::~CObjectListWindow()
 void CObjectListWindow::elementSelected()
 {
 	boost::function<void(int)> toCall = onSelect;//save
-	int where = items[slider->value];      //required variables
+	int where = items[selected];      //required variables
 	GH.popIntTotally(this);//then destroy window
 	toCall(where);//and send selected object
 }

+ 1 - 0
client/GUIClasses.h

@@ -449,6 +449,7 @@ public:
 	CCreaturePic(int x, int y, const CCreature *cre, bool Big=true, bool Animated=true); //c-tor
 	~CCreaturePic(); //d-tor
 	void show(SDL_Surface *to); //prints creature on screen
+	void showAll(SDL_Surface *to);
 	
 };
 

+ 2 - 0
lib/BattleState.cpp

@@ -862,6 +862,8 @@ ui32 BattleInfo::calculateSpellDmg( const CSpell * sp, const CGHeroInstance * ca
 
 	//15 - magic arrows, 16 - ice bolt, 17 - lightning bolt, 18 - implosion, 20 - frost ring, 21 - fireball, 22 - inferno, 23 - meteor shower,
 	//24 - death ripple, 25 - destroy undead, 26 - armageddon, 77 - thunderbolt
+	
+	//FIXME: what point of dmgMultipliers map? all damage multipliers are already present in CSpell::power 
 	static std::map <int, int> dmgMultipliers = boost::assign::map_list_of(15, 10)(16, 20)(17, 25)(18, 75)(20, 10)(21, 10)(22, 10)(23, 10)(24, 5)(25, 10)(26, 50)(77, 10);
 
 	//check if spell really does damage - if not, return 0

+ 1 - 1
lib/CObjectHandler.cpp

@@ -2752,7 +2752,7 @@ void COPWBonus::onHeroVisit (const CGHeroInstance * h) const
 				}
 				break;
 			case 5: //Mana Vortex
-				if (visitors.empty() && h->mana <= h->manaLimit())
+				if (visitors.empty() && h->mana <= h->manaLimit() * 2)
 				{
 					cb->setManaPoints (heroID, 2 * h->manaLimit()); 
 					cb->setObjProperty (id, ObjProperty::VISITED, true);

+ 32 - 2
server/CGameHandler.cpp

@@ -4498,8 +4498,38 @@ bool CGameHandler::castSpell(const CGHeroInstance *h, int spellID, const int3 &p
 		
 	case TOWN_PORTAL: //Town Portal 
 		{
-			//TODO: check if given position is valid
-			moveHero(h->id,pos,1);
+			if (!gs->map->isInTheMap(pos))
+				COMPLAIN_RET("Destination tile not present!")
+			TerrainTile tile = gs->map->getTile(pos);
+			if (tile.visitableObjects.empty() || tile.visitableObjects.back()->ID != TOWNI_TYPE )
+				COMPLAIN_RET("Town not found for Town Portal!");
+			
+			CGTownInstance * town = static_cast<CGTownInstance*>(tile.visitableObjects.back());
+			if (town->tempOwner != h->tempOwner)
+				COMPLAIN_RET("Can't teleport to another player!");
+			if (town->visitingHero)
+				COMPLAIN_RET("Can't teleport to occupied town!");
+			
+			if (h->getSpellSchoolLevel(s) < 2)
+			{
+				double dist = town->pos.dist2d(h->pos);
+				int nearest = town->id; //nearest town's ID
+				BOOST_FOREACH(const CGTownInstance * currTown, gs->getPlayer(h->tempOwner)->towns)
+				{
+					double curDist = currTown->pos.dist2d(h->pos);
+					if (nearest == -1 || curDist < dist)
+					{
+						nearest = town->id;
+						dist = curDist;
+					}
+				}
+				if (town->id != nearest)
+					COMPLAIN_RET("This hero can only teleport to nearest town!")
+			}
+			if (h->visitedTown)
+				stopHeroVisitCastle(town->id, h->id);
+			if (moveHero(h->id, town->visitablePos() + h->getVisitableOffset() ,1));
+				heroVisitCastle(town->id, h->id);
 		}
 		break;