1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00
* CTRL+T will open marketplace window
* T in adventure map will switch to next town
* T in castle window will open a tavern window (if available)
* G will open thieves guild window if player owns at least one town with tavern
* various minor changes
This commit is contained in:
Michał W. Urbańczyk 2012-04-08 01:15:18 +00:00
parent 987788ef66
commit 3bf76cb719
13 changed files with 103 additions and 58 deletions

View File

@ -65,6 +65,7 @@
#include <boost/lexical_cast.hpp>
#include <boost/logic/tribool.hpp>
#include <boost/program_options.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/thread.hpp>
#include <boost/unordered_set.hpp>
@ -313,10 +314,15 @@ namespace vstd
return std::unique_ptr<T>(new T());
}
template<typename T, typename Arg1>
std::unique_ptr<T> make_unique(Arg1&& arg1)
std::unique_ptr<T> make_unique(Arg1 &&arg1)
{
return std::unique_ptr<T>(new T(std::forward<Arg1>(arg1)));
}
template<typename T, typename Arg1, typename Arg2>
std::unique_ptr<T> make_unique(Arg1 &&arg1, Arg2 &&arg2)
{
return std::unique_ptr<T>(new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2)));
}
}
using std::shared_ptr;
@ -326,6 +332,8 @@ using vstd::make_unique;
using vstd::operator-=;
namespace range = boost::range;
// can be used for counting arrays
template<typename T, size_t N> char (&_ArrayCountObj(const T (&)[N]))[N];
#define ARRAY_COUNT(arr) (sizeof(_ArrayCountObj(arr)))

View File

@ -1453,6 +1453,19 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
switch(k)
{
case SDLK_g:
if(key.state != SDL_PRESSED || GH.topInt()->type & BLOCK_ADV_HOTKEYS)
return;
{
//find first town with tavern
auto itr = range::find_if(LOCPLINT->towns, boost::bind(&CGTownInstance::hasBuilt, _1, EBuilding::TAVERN));
if(itr != LOCPLINT->towns.end())
LOCPLINT->showThievesGuildWindow(*itr);
else
LOCPLINT->showInfoDialog("No available town with tavern!");
}
return;
case SDLK_i:
if(isActive())
CAdventureOptions::showScenarioInfo();
@ -1503,8 +1516,11 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
case SDLK_t:
{
//act on key down if marketplace windows is not already opened
if(key.state != SDL_PRESSED || GH.topInt()->type & BLOCK_ADV_HOTKEYS) return;
if(key.state != SDL_PRESSED || GH.topInt()->type & BLOCK_ADV_HOTKEYS)
return;
if(LOCPLINT->ctrlPressed()) //CTRL + T => open marketplace
{
//check if we have any marketplace
const CGTownInstance *townWithMarket = NULL;
BOOST_FOREACH(const CGTownInstance *t, LOCPLINT->cb->getTownsInfo())
@ -1519,7 +1535,12 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
if(townWithMarket) //if any town has marketplace, open window
GH.pushInt(new CMarketplaceWindow(townWithMarket));
else //if not - complain
LOCPLINT->showInfoDialog("No available marketplace!", std::vector<CComponent*>(), soundBase::sound_todo);
LOCPLINT->showInfoDialog("No available marketplace!");
}
else if(isActive()) //no ctrl, advmapint is on the top => switch to town
{
townList.selectNext();
}
return;
}
default:
@ -2123,6 +2144,7 @@ void CAdvMapInt::adjustActiveness(bool aiTurnStart)
if(wasActive)
activate();
}
CAdventureOptions::CAdventureOptions()
{
OBJ_CONSTRUCTION_CAPTURING_ALL;

View File

@ -1257,6 +1257,10 @@ void CCastleInterface::keyPressed( const SDL_KeyboardEvent & key )
LOCPLINT->cb->swapGarrisonHero(town);
}
break;
case SDLK_t:
if(town->hasBuilt(EBuilding::TAVERN))
LOCPLINT->showTavernWindow(town);
break;
default:
break;
}

View File

@ -1415,6 +1415,12 @@ void CPlayerInterface::showRecruitmentDialog(const CGDwelling *dwelling, const C
void CPlayerInterface::waitWhileDialog(bool unlockPim /*= true*/)
{
if(GH.amIGuiThread())
{
tlog3 << "Cannot wait for dialogs in gui thread (deadlock risk)!\n";
return;
}
auto unlock = vstd::makeUnlockGuardIf(*pim, unlockPim);
boost::unique_lock<boost::mutex> un(showingDialog->mx);
while(showingDialog->data)

View File

@ -1332,8 +1332,7 @@ void CTownList::genList()
void CTownList::select(int which)
{
if (which>=LOCPLINT->towns.size())
return;
which %= LOCPLINT->towns.size();
selected = which;
fixPos();
if(!fun.empty())
@ -1528,6 +1527,11 @@ int CTownList::size()
return LOCPLINT->towns.size();
}
void CTownList::selectNext()
{
select(selected+1);
}
CCreaturePic::CCreaturePic(int x, int y, const CCreature *cre, bool Big, bool Animated)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
@ -5726,7 +5730,7 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket
yellow->recActions =
red->recActions = DISPOSE;
if ( market->o->ID == 104 ) // this is adventure map university
if ( market->o->ID == Obj::UNIVERSITY ) // this is adventure map university
{
SDL_Surface * titleImage = BitmapHandler::loadBitmap("UNIVBLDG.PCX");
blitAtLoc(titleImage, 232-titleImage->w/2, 76-titleImage->h/2, bg->bg);
@ -6028,6 +6032,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner)
:owner(_owner)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
type |= BLOCK_ADV_HOTKEYS;
SThievesGuildInfo tgi; //info to be displayed
LOCPLINT->cb->getThievesGuildInfo(tgi, owner);
@ -6048,9 +6053,10 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner)
resdatabar->pos.x += pos.x;
resdatabar->pos.y += pos.y;
static std::vector< std::list< ui8 > > SThievesGuildInfo::* fields[] = { &SThievesGuildInfo::numOfTowns, &SThievesGuildInfo::numOfHeroes, &SThievesGuildInfo::gold,
&SThievesGuildInfo::woodOre, &SThievesGuildInfo::mercSulfCrystGems, &SThievesGuildInfo::obelisks, &SThievesGuildInfo::artifacts, &SThievesGuildInfo::army,
&SThievesGuildInfo::income};
static std::vector< std::list< ui8 > > SThievesGuildInfo::* fields[] =
{ &SThievesGuildInfo::numOfTowns, &SThievesGuildInfo::numOfHeroes, &SThievesGuildInfo::gold,
&SThievesGuildInfo::woodOre, &SThievesGuildInfo::mercSulfCrystGems, &SThievesGuildInfo::obelisks,
&SThievesGuildInfo::artifacts, &SThievesGuildInfo::army, &SThievesGuildInfo::income };
//printing texts & descriptions to background

View File

@ -322,6 +322,7 @@ public:
~CTownList(); //d-tor
void genList();
void select(int which); //call-in
void selectNext(); //switches to the next town or the first one if none is selected
void mouseMoved (const SDL_MouseMotionEvent & sEvent); //call-in
void clickLeft(tribool down, bool previousState); //call-in
void clickRight(tribool down, bool previousState); //call-in

View File

@ -12,6 +12,8 @@ extern SDL_Surface * screenBuf, * screen2, * screen;
extern std::queue<SDL_Event*> events;
extern boost::mutex eventsM;
boost::thread_specific_ptr<bool> inGuiThread;
SObjectConstruction::SObjectConstruction( CIntObject *obj )
:myObj(obj)
{
@ -344,6 +346,8 @@ void CGuiHandler::fakeMouseMove()
void CGuiHandler::run()
{
setThreadName(-1, "CGuiHandler::run");
bool iAmGui = true;
inGuiThread.reset(&iAmGui);
try
{
if (settings["video"]["fullscreen"].Bool())
@ -457,6 +461,10 @@ bool CGuiHandler::isArrowKey( SDLKey key )
return key >= SDLK_UP && key <= SDLK_LEFT;
}
bool CGuiHandler::amIGuiThread()
{
return inGuiThread.get() && *inGuiThread;
}
CFramerateManager::CFramerateManager(int rate)
{

View File

@ -96,6 +96,7 @@ public:
static SDLKey numToDigit(SDLKey key);//converts numpad digit key to normal digit key
static bool isNumKey(SDLKey key, bool number = true); //checks if key is on numpad (numbers - check only for numpad digits)
static bool isArrowKey(SDLKey key);
static bool amIGuiThread();
};
extern CGuiHandler GH; //global gui handler

View File

@ -248,7 +248,6 @@ void CConnection::sendPackToServer(const CPack &pack, ui8 player, ui32 requestID
}
CSaveFile::CSaveFile( const std::string &fname )
:sfile(NULL)
{
registerTypes(*this);
openNextFile(fname);
@ -256,7 +255,6 @@ CSaveFile::CSaveFile( const std::string &fname )
CSaveFile::~CSaveFile()
{
delete sfile;
}
int CSaveFile::write( const void * data, unsigned size )
@ -265,17 +263,10 @@ int CSaveFile::write( const void * data, unsigned size )
return size;
}
void CSaveFile::close()
{
delete sfile;
sfile = NULL;
}
void CSaveFile::openNextFile(const std::string &fname)
{
fName = fname;
close();
sfile = new std::ofstream(fname.c_str(),std::ios::binary);
sfile = make_unique<std::ofstream>(fname.c_str(), std::ios::binary);
if(!(*sfile))
{
tlog1 << "Error: cannot open to write " << fname << std::endl;
@ -291,14 +282,13 @@ void CSaveFile::openNextFile(const std::string &fname)
void CSaveFile::reportState(CLogger &out)
{
out << "CSaveFile" << std::endl;
if(sfile && *sfile)
if(sfile.get() && *sfile)
{
out << "\tOpened " << fName << "\n\tPosition: " << sfile->tellp() << std::endl;
}
}
CLoadFile::CLoadFile(const std::string &fname, int minimalVersion /*= version*/)
:sfile(NULL)
{
registerTypes(*this);
openNextFile(fname, minimalVersion);
@ -306,7 +296,6 @@ CLoadFile::CLoadFile(const std::string &fname, int minimalVersion /*= version*/)
CLoadFile::~CLoadFile()
{
delete sfile;
}
int CLoadFile::read( const void * data, unsigned size )
@ -315,20 +304,14 @@ int CLoadFile::read( const void * data, unsigned size )
return size;
}
void CLoadFile::close()
{
delete sfile;
sfile = NULL;
}
void CLoadFile::openNextFile(const std::string &fname, int minimalVersion)
{
fName = fname;
sfile = new std::ifstream(fname.c_str(),std::ios::binary);
sfile = make_unique<std::ifstream>(fname.c_str(),std::ios::binary);
if(!(*sfile))
{
tlog1 << "Error: cannot open to read " << fname << std::endl;
sfile = NULL;
sfile.release();
}
else
{
@ -338,8 +321,7 @@ void CLoadFile::openNextFile(const std::string &fname, int minimalVersion)
if(std::memcmp(buffer,"VCMI",4))
{
tlog1 << "Error: not a VCMI file! ( " << fname << " )\n";
delete sfile;
sfile = NULL;
sfile.release();
return;
}
@ -347,8 +329,7 @@ void CLoadFile::openNextFile(const std::string &fname, int minimalVersion)
if(myVersion < minimalVersion)
{
tlog1 << "Error: Old file format! (file " << fname << " )\n";
delete sfile;
sfile = NULL;
sfile.release();
}
}
}
@ -356,7 +337,7 @@ void CLoadFile::openNextFile(const std::string &fname, int minimalVersion)
void CLoadFile::reportState(CLogger &out)
{
out << "CLoadFile" << std::endl;
if(sfile && *sfile)
if(!!sfile && *sfile)
{
out << "\tOpened " << fName << "\n\tPosition: " << sfile->tellg() << std::endl;
}

View File

@ -845,13 +845,12 @@ class DLL_LINKAGE CSaveFile
}
public:
std::string fName;
std::ofstream *sfile;
unique_ptr<std::ofstream> sfile;
CSaveFile(const std::string &fname);
~CSaveFile();
int write(const void * data, unsigned size);
void close();
void openNextFile(const std::string &fname);
void reportState(CLogger &out);
};
@ -866,13 +865,12 @@ class DLL_LINKAGE CLoadFile
}
public:
std::string fName;
std::ifstream *sfile;
unique_ptr<std::ifstream> sfile;
CLoadFile(const std::string &fname, int minimalVersion = version);
~CLoadFile();
int read(const void * data, unsigned size);
void close();
void openNextFile(const std::string &fname, int minimalVersion);
void reportState(CLogger &out);
};
@ -898,7 +896,6 @@ public:
std::string name; //who uses this connection
int connectionID;
CConnection *c;
boost::thread *handler;
bool receivedStop, sendStop;

View File

@ -199,6 +199,7 @@ namespace Obj
STABLES = 94,
TRADING_POST = 99,
SUBTERRANEAN_GATE = 103,
UNIVERSITY = 104,
SCHOOL_OF_WAR = 107,
WHIRLPOOL = 111,
BORDER_GATE = 212,

View File

@ -234,6 +234,9 @@ void LibClasses::makeNull()
LibClasses::LibClasses()
{
//load .lod archives
if(!spriteh) //don't reload lods if we are starting a secoond game
{
CStopWatch pomtime;
spriteh = new CLodHandler();
spriteh->init(GameConstants::DATA_DIR + "/Data/H3sprite.lod", GameConstants::DATA_DIR + "/Sprites");
@ -242,6 +245,7 @@ LibClasses::LibClasses()
bitmaph_ab = new CLodHandler();
bitmaph_ab->init(GameConstants::DATA_DIR + "/Data/H3ab_bmp.lod", GameConstants::DATA_DIR + "/Data");
tlog0<<"Loading .lod files: "<<pomtime.getDiff()<<std::endl;
}
//init pointers to handlers
makeNull();
@ -253,3 +257,8 @@ void LibClasses::callWhenDeserializing()
generaltexth->load();
arth->loadArtifacts(true);
}
LibClasses::~LibClasses()
{
clear();
}

View File

@ -37,6 +37,7 @@ public:
CGeneralTextHandler * generaltexth;
LibClasses(); //c-tor, loads .lods and NULLs handlers
~LibClasses();
void init(); //uses standard config file
void clear(); //deletes all handlers and its data
void makeNull(); //sets all handler (except of lodhs) pointers to null