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:
parent
987788ef66
commit
3bf76cb719
10
Global.h
10
Global.h
@ -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)))
|
||||
|
@ -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,23 +1516,31 @@ 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;
|
||||
|
||||
//check if we have any marketplace
|
||||
const CGTownInstance *townWithMarket = NULL;
|
||||
BOOST_FOREACH(const CGTownInstance *t, LOCPLINT->cb->getTownsInfo())
|
||||
if(LOCPLINT->ctrlPressed()) //CTRL + T => open marketplace
|
||||
{
|
||||
if(vstd::contains(t->builtBuildings, 14))
|
||||
//check if we have any marketplace
|
||||
const CGTownInstance *townWithMarket = NULL;
|
||||
BOOST_FOREACH(const CGTownInstance *t, LOCPLINT->cb->getTownsInfo())
|
||||
{
|
||||
townWithMarket = t;
|
||||
break;
|
||||
if(vstd::contains(t->builtBuildings, 14))
|
||||
{
|
||||
townWithMarket = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if(townWithMarket) //if any town has marketplace, open window
|
||||
GH.pushInt(new CMarketplaceWindow(townWithMarket));
|
||||
else //if not - complain
|
||||
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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -234,14 +234,18 @@ void LibClasses::makeNull()
|
||||
LibClasses::LibClasses()
|
||||
{
|
||||
//load .lod archives
|
||||
CStopWatch pomtime;
|
||||
spriteh = new CLodHandler();
|
||||
spriteh->init(GameConstants::DATA_DIR + "/Data/H3sprite.lod", GameConstants::DATA_DIR + "/Sprites");
|
||||
bitmaph = new CLodHandler;
|
||||
bitmaph->init(GameConstants::DATA_DIR + "/Data/H3bitmap.lod", GameConstants::DATA_DIR + "/Data");
|
||||
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;
|
||||
|
||||
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");
|
||||
bitmaph = new CLodHandler;
|
||||
bitmaph->init(GameConstants::DATA_DIR + "/Data/H3bitmap.lod", GameConstants::DATA_DIR + "/Data");
|
||||
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();
|
||||
}
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user