diff --git a/CConsoleHandler.cpp b/CConsoleHandler.cpp index 0f238d8eb..f5a062b67 100644 --- a/CConsoleHandler.cpp +++ b/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; diff --git a/client/CCastleInterface.cpp b/client/CCastleInterface.cpp index ec636bfed..e8cd56ac6 100644 --- a/client/CCastleInterface.cpp +++ b/client/CCastleInterface.cpp @@ -347,6 +347,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; diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 4d018cfaf..1abe3b684 100644 --- a/client/CPlayerInterface.cpp +++ b/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" diff --git a/client/CSpellWindow.cpp b/client/CSpellWindow.cpp index 2617c0f60..95ba989b7 100644 --- a/client/CSpellWindow.cpp +++ b/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 availableTowns; - std::vector Towns = LOCPLINT->cb->getTownsInfo(false); - for(size_t i=0;i 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; gcb->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;ivisitingHero == 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; diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index c787a6fbc..fd1a45e57 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -1665,6 +1665,11 @@ void CCreaturePic::show(SDL_Surface *to) CIntObject::show(to); } +void CCreaturePic::showAll(SDL_Surface *to) +{ + show(to); +} + void CRecruitmentWindow::close() { GH.popIntTotally(this); @@ -2471,7 +2476,7 @@ CObjectListWindow::~CObjectListWindow() void CObjectListWindow::elementSelected() { boost::function 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 } diff --git a/client/GUIClasses.h b/client/GUIClasses.h index 2d03753ee..160b27d8d 100644 --- a/client/GUIClasses.h +++ b/client/GUIClasses.h @@ -446,6 +446,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); }; diff --git a/hch/CObjectHandler.cpp b/hch/CObjectHandler.cpp index 979219804..d679246ec 100644 --- a/hch/CObjectHandler.cpp +++ b/hch/CObjectHandler.cpp @@ -2753,7 +2753,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); diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index d96a64112..6f081e3bb 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -3578,7 +3578,9 @@ 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 - static std::map 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); + + //FIXME: what point of dmgMultipliers map? all damage multipliers are already present in CSpell::power + static std::map dmgMultipliers = boost::assign::map_list_of(15, 10)(16, 20)(17, 25)(18, 75)(20, 10)(21, 10)(22, 10)(23, 25)(24, 5)(25, 10)(26, 50)(77, 10); //check if spell really does damage - if not, return 0 if(dmgMultipliers.find(sp->id) == dmgMultipliers.end()) diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index b4a4c8f5d..82a6cf890 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -5244,8 +5244,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(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;