mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-03 00:46:55 +02:00
- Refactored victory loss condition checks
- Added toString() method to EVictoryLossCheckResult enum class to improve debugging - Removed mostly unused CFunctionList2 - Added missing header files for vcmiclient project to CMakeLists - Tweaked SDL suggests bpp message a bit - Added showInfoDialogAndWait (info dialog and waits, used from client thread) and showOkDialog (callback to ok click, used from GUI thread) to player interface - Added showOkDialog method to CInfoWindow (unused for now, but may be used later)
This commit is contained in:
@ -755,7 +755,7 @@ static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo
|
|||||||
|
|
||||||
if(suggestedBpp != bpp)
|
if(suggestedBpp != bpp)
|
||||||
{
|
{
|
||||||
logGlobal->warnStream() << "Note: SDL suggests to use " << suggestedBpp << " bpp instead of" << bpp << " bpp ";
|
logGlobal->infoStream() << boost::format("Using %s bpp (bits per pixel) for the video mode. Default or overriden setting was %s bpp.") % suggestedBpp % bpp;
|
||||||
}
|
}
|
||||||
|
|
||||||
//For some reason changing fullscreen via config window checkbox result in SDL_Quit event
|
//For some reason changing fullscreen via config window checkbox result in SDL_Quit event
|
||||||
|
@ -6,17 +6,13 @@ include_directories(${SDL_INCLUDE_DIR} ${SDLIMAGE_INCLUDE_DIR} ${SDLMIXER_INCLUD
|
|||||||
include_directories(${Boost_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR} ${FFMPEG_INCLUDE_DIRS})
|
include_directories(${Boost_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR} ${FFMPEG_INCLUDE_DIRS})
|
||||||
|
|
||||||
set(client_SRCS
|
set(client_SRCS
|
||||||
CPreGame.cpp
|
|
||||||
Client.cpp
|
|
||||||
CPlayerInterface.cpp
|
|
||||||
CMT.cpp
|
|
||||||
GUIClasses.cpp
|
|
||||||
battle/CBattleInterface.cpp
|
|
||||||
|
|
||||||
../CCallback.cpp
|
../CCallback.cpp
|
||||||
|
|
||||||
|
battle/CBattleInterface.cpp
|
||||||
battle/CBattleAnimations.cpp
|
battle/CBattleAnimations.cpp
|
||||||
battle/CBattleInterfaceClasses.cpp
|
battle/CBattleInterfaceClasses.cpp
|
||||||
battle/CCreatureAnimation.cpp
|
battle/CCreatureAnimation.cpp
|
||||||
|
|
||||||
gui/CGuiHandler.cpp
|
gui/CGuiHandler.cpp
|
||||||
gui/CIntObject.cpp
|
gui/CIntObject.cpp
|
||||||
gui/CIntObjectClasses.cpp
|
gui/CIntObjectClasses.cpp
|
||||||
@ -24,6 +20,12 @@ set(client_SRCS
|
|||||||
gui/Geometries.cpp
|
gui/Geometries.cpp
|
||||||
gui/CCursorHandler.cpp
|
gui/CCursorHandler.cpp
|
||||||
gui/SDL_Extensions.cpp
|
gui/SDL_Extensions.cpp
|
||||||
|
|
||||||
|
CPreGame.cpp
|
||||||
|
Client.cpp
|
||||||
|
CPlayerInterface.cpp
|
||||||
|
CMT.cpp
|
||||||
|
GUIClasses.cpp
|
||||||
AdventureMapClasses.cpp
|
AdventureMapClasses.cpp
|
||||||
CAdvmapInterface.cpp
|
CAdvmapInterface.cpp
|
||||||
CAnimation.cpp
|
CAnimation.cpp
|
||||||
@ -44,15 +46,22 @@ set(client_SRCS
|
|||||||
NetPacksClient.cpp
|
NetPacksClient.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(client_HEADERS
|
||||||
|
CSoundBase.h
|
||||||
|
FunctionList.h
|
||||||
|
|
||||||
|
gui/SDL_Pixels.h
|
||||||
|
)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_executable(vcmiclient WIN32 ${client_SRCS})
|
add_executable(vcmiclient WIN32 ${client_SRCS} ${client_HEADERS})
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
# OS X specific includes
|
# OS X specific includes
|
||||||
include_directories(${SPARKLE_INCLUDE_DIR})
|
include_directories(${SPARKLE_INCLUDE_DIR})
|
||||||
|
|
||||||
# OS X specific source files
|
# OS X specific source files
|
||||||
set(client_SRCS ${client_SRCS} SDLMain.m OSX.mm Info.plist vcmi.icns ../osx/vcmi_dsa_public.pem)
|
set(client_SRCS ${client_SRCS} SDLMain.m OSX.mm Info.plist vcmi.icns ../osx/vcmi_dsa_public.pem)
|
||||||
add_executable(vcmiclient MACOSX_BUNDLE ${client_SRCS})
|
add_executable(vcmiclient MACOSX_BUNDLE ${client_SRCS} ${client_HEADERS})
|
||||||
|
|
||||||
# OS X specific libraries
|
# OS X specific libraries
|
||||||
target_link_libraries(vcmiclient ${SPARKLE_FRAMEWORK})
|
target_link_libraries(vcmiclient ${SPARKLE_FRAMEWORK})
|
||||||
@ -93,7 +102,7 @@ elseif(APPLE)
|
|||||||
|
|
||||||
add_custom_command(TARGET vcmiclient POST_BUILD COMMAND ${MakeVCMIBundle})
|
add_custom_command(TARGET vcmiclient POST_BUILD COMMAND ${MakeVCMIBundle})
|
||||||
else()
|
else()
|
||||||
add_executable(vcmiclient ${client_SRCS})
|
add_executable(vcmiclient ${client_SRCS} ${client_HEADERS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(vcmiclient vcmi ${Boost_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLMIXER_LIBRARY} ${SDLTTF_LIBRARY} ${ZLIB_LIBRARIES} ${FFMPEG_LIBRARIES} ${RT_LIB} ${DL_LIB})
|
target_link_libraries(vcmiclient vcmi ${Boost_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLMIXER_LIBRARY} ${SDLTTF_LIBRARY} ${ZLIB_LIBRARIES} ${FFMPEG_LIBRARIES} ${RT_LIB} ${DL_LIB})
|
||||||
|
@ -1022,6 +1022,21 @@ void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPlayerInterface::showInfoDialogAndWait(std::vector<Component> & components, const MetaString & text)
|
||||||
|
{
|
||||||
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
|
std::vector<Component*> comps;
|
||||||
|
for(auto & elem : components)
|
||||||
|
{
|
||||||
|
comps.push_back(&elem);
|
||||||
|
}
|
||||||
|
std::string str;
|
||||||
|
text.toString(str);
|
||||||
|
|
||||||
|
showInfoDialog(str,comps, 0);
|
||||||
|
waitWhileDialog();
|
||||||
|
}
|
||||||
|
|
||||||
void CPlayerInterface::showYesNoDialog(const std::string &text, CFunctionList<void()> onYes, CFunctionList<void()> onNo, bool DelComps, const std::vector<CComponent*> & components)
|
void CPlayerInterface::showYesNoDialog(const std::string &text, CFunctionList<void()> onYes, CFunctionList<void()> onNo, bool DelComps, const std::vector<CComponent*> & components)
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||||
@ -1031,6 +1046,27 @@ void CPlayerInterface::showYesNoDialog(const std::string &text, CFunctionList<vo
|
|||||||
CInfoWindow::showYesNoDialog(text, &components, onYes, onNo, DelComps, playerID);
|
CInfoWindow::showYesNoDialog(text, &components, onYes, onNo, DelComps, playerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPlayerInterface::showOkDialog(std::vector<Component> & components, const MetaString & text, const boost::function<void()> & onOk)
|
||||||
|
{
|
||||||
|
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||||
|
|
||||||
|
std::vector<Component*> comps;
|
||||||
|
for(auto & elem : components)
|
||||||
|
{
|
||||||
|
comps.push_back(&elem);
|
||||||
|
}
|
||||||
|
std::string str;
|
||||||
|
text.toString(str);
|
||||||
|
|
||||||
|
stopMovement();
|
||||||
|
showingDialog->setn(true);
|
||||||
|
|
||||||
|
std::vector<CComponent*> intComps;
|
||||||
|
for(auto & component : comps)
|
||||||
|
intComps.push_back(new CComponent(*component));
|
||||||
|
CInfoWindow::showOkDialog(str, &intComps, onOk, true, playerID);
|
||||||
|
}
|
||||||
|
|
||||||
void CPlayerInterface::showBlockingDialog( const std::string &text, const std::vector<Component> &components, QueryID askID, int soundID, bool selection, bool cancel )
|
void CPlayerInterface::showBlockingDialog( const std::string &text, const std::vector<Component> &components, QueryID askID, int soundID, bool selection, bool cancel )
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
@ -2251,6 +2287,31 @@ void CPlayerInterface::acceptTurn()
|
|||||||
|
|
||||||
adventureInt->endTurn.callback();
|
adventureInt->endTurn.callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// warn player if he has no town
|
||||||
|
if(cb->howManyTowns() == 0)
|
||||||
|
{
|
||||||
|
auto playerColor = *cb->getPlayerID();
|
||||||
|
|
||||||
|
std::vector<Component> components;
|
||||||
|
components.push_back(Component(Component::FLAG, playerColor.getNum(), 0, 0));
|
||||||
|
MetaString text;
|
||||||
|
|
||||||
|
auto daysWithoutCastle = cb->getPlayer(playerColor)->daysWithoutCastle;
|
||||||
|
if(daysWithoutCastle == 6)
|
||||||
|
{
|
||||||
|
text.addTxt(MetaString::ARRAY_TXT,129); //%s, this is your last day to capture a town or you will be banished from this land.
|
||||||
|
text.addReplacement(MetaString::COLOR, playerColor.getNum());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
text.addTxt(MetaString::ARRAY_TXT,128); //%s, you only have %d days left to capture a town or you will be banished from this land.
|
||||||
|
text.addReplacement(MetaString::COLOR, playerColor.getNum());
|
||||||
|
text.addReplacement(7 - daysWithoutCastle);
|
||||||
|
}
|
||||||
|
|
||||||
|
showInfoDialogAndWait(components, text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::tryDiggging(const CGHeroInstance *h)
|
void CPlayerInterface::tryDiggging(const CGHeroInstance *h)
|
||||||
|
@ -229,9 +229,14 @@ public:
|
|||||||
void updateInfo(const CGObjectInstance * specific);
|
void updateInfo(const CGObjectInstance * specific);
|
||||||
void init(shared_ptr<CCallback> CB);
|
void init(shared_ptr<CCallback> CB);
|
||||||
int3 repairScreenPos(int3 pos); //returns position closest to pos we can center screen on
|
int3 repairScreenPos(int3 pos); //returns position closest to pos we can center screen on
|
||||||
|
|
||||||
|
// show dialogs
|
||||||
void showInfoDialog(const std::string &text, CComponent * component);
|
void showInfoDialog(const std::string &text, CComponent * component);
|
||||||
void showInfoDialog(const std::string &text, const std::vector<CComponent*> & components = std::vector<CComponent*>(), int soundID = 0, bool delComps = false);
|
void showInfoDialog(const std::string &text, const std::vector<CComponent*> & components = std::vector<CComponent*>(), int soundID = 0, bool delComps = false);
|
||||||
|
void showInfoDialogAndWait(std::vector<Component> & components, const MetaString & text);
|
||||||
|
void showOkDialog(std::vector<Component> & components, const MetaString & text, const boost::function<void()> & onOk);
|
||||||
void showYesNoDialog(const std::string &text, CFunctionList<void()> onYes, CFunctionList<void()> onNo, bool DelComps = false, const std::vector<CComponent*> & components = std::vector<CComponent*>()); //deactivateCur - whether current main interface should be deactivated; delComps - if components will be deleted on window close
|
void showYesNoDialog(const std::string &text, CFunctionList<void()> onYes, CFunctionList<void()> onNo, bool DelComps = false, const std::vector<CComponent*> & components = std::vector<CComponent*>()); //deactivateCur - whether current main interface should be deactivated; delComps - if components will be deleted on window close
|
||||||
|
|
||||||
void stopMovement();
|
void stopMovement();
|
||||||
bool moveHero(const CGHeroInstance *h, CGPath path);
|
bool moveHero(const CGHeroInstance *h, CGPath path);
|
||||||
void initMovement(const TryMoveHero &details, const CGHeroInstance * ho, const int3 &hp );//initializing objects and performing first step of move
|
void initMovement(const TryMoveHero &details, const CGHeroInstance * ho, const int3 &hp );//initializing objects and performing first step of move
|
||||||
|
@ -83,48 +83,3 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Signature>
|
|
||||||
class CFunctionList2
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::vector<boost::function<Signature> > funcs;
|
|
||||||
|
|
||||||
CFunctionList2(int){};
|
|
||||||
CFunctionList2(){};
|
|
||||||
template <typename Functor>
|
|
||||||
CFunctionList2(const Functor &f)
|
|
||||||
{
|
|
||||||
funcs.push_back(boost::function<Signature>(f));
|
|
||||||
}
|
|
||||||
CFunctionList2(const boost::function<Signature> &first)
|
|
||||||
{
|
|
||||||
funcs.push_back(first);
|
|
||||||
}
|
|
||||||
CFunctionList2(boost::function<Signature> &first)
|
|
||||||
{
|
|
||||||
funcs.push_back(first);
|
|
||||||
}
|
|
||||||
CFunctionList2 & operator+=(const boost::function<Signature> &first)
|
|
||||||
{
|
|
||||||
funcs.push_back(first);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
funcs.clear();
|
|
||||||
}
|
|
||||||
operator bool() const
|
|
||||||
{
|
|
||||||
return funcs.size();
|
|
||||||
}
|
|
||||||
template <typename Arg>
|
|
||||||
void operator()(const Arg & a) const
|
|
||||||
{
|
|
||||||
std::vector<boost::function<Signature> > funcs2 = funcs; //backup
|
|
||||||
for(size_t i=0;i<funcs2.size(); ++i)
|
|
||||||
{
|
|
||||||
funcs2[i](a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
@ -742,6 +742,16 @@ void CInfoWindow::showYesNoDialog(const std::string & text, const std::vector<CC
|
|||||||
GH.pushInt(temp);
|
GH.pushInt(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CInfoWindow::showOkDialog(const std::string & text, const std::vector<CComponent*> *components, const boost::function<void()> & onOk, bool delComps, PlayerColor player)
|
||||||
|
{
|
||||||
|
std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
|
||||||
|
pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0));
|
||||||
|
CInfoWindow * temp = new CInfoWindow(text, player, *components, pom, delComps);
|
||||||
|
temp->buttons[0]->callback += onOk;
|
||||||
|
|
||||||
|
GH.pushInt(temp);
|
||||||
|
}
|
||||||
|
|
||||||
CInfoWindow * CInfoWindow::create(const std::string &text, PlayerColor playerID /*= 1*/, const std::vector<CComponent*> *components /*= nullptr*/, bool DelComps)
|
CInfoWindow * CInfoWindow::create(const std::string &text, PlayerColor playerID /*= 1*/, const std::vector<CComponent*> *components /*= nullptr*/, bool DelComps)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
|
std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
|
||||||
|
@ -106,6 +106,7 @@ public:
|
|||||||
|
|
||||||
//use only before the game starts! (showYesNoDialog in LOCPLINT must be used then)
|
//use only before the game starts! (showYesNoDialog in LOCPLINT must be used then)
|
||||||
static void showInfoDialog( const std::string & text, const std::vector<CComponent*> *components, bool DelComps = true, PlayerColor player = PlayerColor(1));
|
static void showInfoDialog( const std::string & text, const std::vector<CComponent*> *components, bool DelComps = true, PlayerColor player = PlayerColor(1));
|
||||||
|
static void showOkDialog(const std::string & text, const std::vector<CComponent*> *components, const boost::function<void()> & onOk, bool delComps = true, PlayerColor player = PlayerColor(1));
|
||||||
static void showYesNoDialog( const std::string & text, const std::vector<CComponent*> *components, const CFunctionList<void( ) > &onYes, const CFunctionList<void()> &onNo, bool DelComps = true, PlayerColor player = PlayerColor(1));
|
static void showYesNoDialog( const std::string & text, const std::vector<CComponent*> *components, const CFunctionList<void( ) > &onYes, const CFunctionList<void()> &onNo, bool DelComps = true, PlayerColor player = PlayerColor(1));
|
||||||
static CInfoWindow *create(const std::string &text, PlayerColor playerID = PlayerColor(1), const std::vector<CComponent*> *components = nullptr, bool DelComps = false);
|
static CInfoWindow *create(const std::string &text, PlayerColor playerID = PlayerColor(1), const std::vector<CComponent*> *components = nullptr, bool DelComps = false);
|
||||||
|
|
||||||
|
@ -534,7 +534,7 @@ void CHighlightableButtonsGroup::addButton(const std::map<int,std::string> &tool
|
|||||||
buttons.push_back(bt);
|
buttons.push_back(bt);
|
||||||
}
|
}
|
||||||
|
|
||||||
CHighlightableButtonsGroup::CHighlightableButtonsGroup(const CFunctionList2<void(int)> &OnChange, bool musicLikeButtons)
|
CHighlightableButtonsGroup::CHighlightableButtonsGroup(const CFunctionList<void(int)> &OnChange, bool musicLikeButtons)
|
||||||
: onChange(OnChange), musicLike(musicLikeButtons)
|
: onChange(OnChange), musicLike(musicLikeButtons)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -171,14 +171,14 @@ public:
|
|||||||
class CHighlightableButtonsGroup : public CIntObject
|
class CHighlightableButtonsGroup : public CIntObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CFunctionList2<void(int)> onChange; //called when changing selected button with new button's id
|
CFunctionList<void(int)> onChange; //called when changing selected button with new button's id
|
||||||
std::vector<CHighlightableButton*> buttons;
|
std::vector<CHighlightableButton*> buttons;
|
||||||
bool musicLike; //determines the behaviour of this group
|
bool musicLike; //determines the behaviour of this group
|
||||||
|
|
||||||
//void addButton(const std::map<int,std::string> &tooltip, const std::string &HelpBox, const std::string &defName, int x, int y, int uid);
|
//void addButton(const std::map<int,std::string> &tooltip, const std::string &HelpBox, const std::string &defName, int x, int y, int uid);
|
||||||
void addButton(CHighlightableButton* bt);//add existing button, it'll be deleted by CHighlightableButtonsGroup destructor
|
void addButton(CHighlightableButton* bt);//add existing button, it'll be deleted by CHighlightableButtonsGroup destructor
|
||||||
void addButton(const std::map<int,std::string> &tooltip, const std::string &HelpBox, const std::string &defName, int x, int y, int uid, const CFunctionList<void()> &OnSelect=0, int key=0); //creates new button
|
void addButton(const std::map<int,std::string> &tooltip, const std::string &HelpBox, const std::string &defName, int x, int y, int uid, const CFunctionList<void()> &OnSelect=0, int key=0); //creates new button
|
||||||
CHighlightableButtonsGroup(const CFunctionList2<void(int)> &OnChange, bool musicLikeButtons = false);
|
CHighlightableButtonsGroup(const CFunctionList<void(int)> & OnChange, bool musicLikeButtons = false);
|
||||||
~CHighlightableButtonsGroup();
|
~CHighlightableButtonsGroup();
|
||||||
void select(int id, bool mode); //mode==0: id is serial; mode==1: id is unique button id
|
void select(int id, bool mode); //mode==0: id is serial; mode==1: id is unique button id
|
||||||
void selectionChanged(int to);
|
void selectionChanged(int to);
|
||||||
|
@ -3327,15 +3327,19 @@ bool EVictoryLossCheckResult::loss() const
|
|||||||
return !victory();
|
return !victory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string EVictoryLossCheckResult::toString() const
|
||||||
|
{
|
||||||
|
if(*this == EVictoryLossCheckResult::NO_VICTORY_OR_LOSS) return "No victory or loss";
|
||||||
|
else if(*this == EVictoryLossCheckResult::VICTORY_STANDARD) return "Victory standard";
|
||||||
|
else if(*this == EVictoryLossCheckResult::VICTORY_SPECIAL) return "Victory special";
|
||||||
|
else if(*this == EVictoryLossCheckResult::LOSS_STANDARD_HEROES_AND_TOWNS) return "Loss standard heroes and towns";
|
||||||
|
else if(*this == EVictoryLossCheckResult::LOSS_STANDARD_TOWNS_AND_TIME_OVER) return "Loss standard towns and time over";
|
||||||
|
else if(*this == EVictoryLossCheckResult::LOSS_SPECIAL) return "Loss special";
|
||||||
|
else return "Unknown type";
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream & os, const EVictoryLossCheckResult & victoryLossCheckResult)
|
std::ostream & operator<<(std::ostream & os, const EVictoryLossCheckResult & victoryLossCheckResult)
|
||||||
{
|
{
|
||||||
if(victoryLossCheckResult == EVictoryLossCheckResult::NO_VICTORY_OR_LOSS) os << "No victory or loss";
|
os << victoryLossCheckResult.toString();
|
||||||
else if(victoryLossCheckResult == EVictoryLossCheckResult::VICTORY_STANDARD) os << "Victory standard";
|
|
||||||
else if(victoryLossCheckResult == EVictoryLossCheckResult::VICTORY_SPECIAL) os << "Victory special";
|
|
||||||
else if(victoryLossCheckResult == EVictoryLossCheckResult::LOSS_STANDARD_HEROES_AND_TOWNS) os << "Loss standard heroes and towns";
|
|
||||||
else if(victoryLossCheckResult == EVictoryLossCheckResult::LOSS_STANDARD_TOWNS_AND_TIME_OVER) os << "Loss standard towns and time over";
|
|
||||||
else if(victoryLossCheckResult == EVictoryLossCheckResult::LOSS_SPECIAL) os << "Loss special";
|
|
||||||
else os << "Unknown type";
|
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
@ -371,6 +371,7 @@ public:
|
|||||||
bool operator!=(EVictoryLossCheckResult const & other) const;
|
bool operator!=(EVictoryLossCheckResult const & other) const;
|
||||||
bool victory() const;
|
bool victory() const;
|
||||||
bool loss() const;
|
bool loss() const;
|
||||||
|
std::string toString() const;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "BattleHex.h"
|
#include "BattleHex.h"
|
||||||
#include "../client/FunctionList.h"
|
|
||||||
#include "ResourceSet.h"
|
#include "ResourceSet.h"
|
||||||
#include "int3.h"
|
#include "int3.h"
|
||||||
#include "GameConstants.h"
|
#include "GameConstants.h"
|
||||||
|
@ -685,7 +685,9 @@ void CGameHandler::battleAfterLevelUp( const BattleResult &result )
|
|||||||
}
|
}
|
||||||
visitObjectAfterVictory = false;
|
visitObjectAfterVictory = false;
|
||||||
|
|
||||||
winLoseHandle(1<<finishingBattle->loser.getNum() | 1<<finishingBattle->victor.getNum()); //handle victory/loss of engaged players
|
//handle victory/loss of engaged players
|
||||||
|
std::set<PlayerColor> playerColors = boost::assign::list_of(finishingBattle->loser)(finishingBattle->victor);
|
||||||
|
checkVictoryLossConditions(playerColors);
|
||||||
|
|
||||||
if(result.result == BattleResult::SURRENDER || result.result == BattleResult::ESCAPE) //loser has escaped or surrendered
|
if(result.result == BattleResult::SURRENDER || result.result == BattleResult::ESCAPE) //loser has escaped or surrendered
|
||||||
{
|
{
|
||||||
@ -1411,39 +1413,7 @@ void CGameHandler::newTurn()
|
|||||||
elem->newTurn();
|
elem->newTurn();
|
||||||
}
|
}
|
||||||
|
|
||||||
winLoseHandle(0xff);
|
checkVictoryLossConditionsForAll();
|
||||||
|
|
||||||
//warn players without town
|
|
||||||
if(gs->day)
|
|
||||||
{
|
|
||||||
for (auto i=gs->players.cbegin() ; i!=gs->players.cend();i++)
|
|
||||||
{
|
|
||||||
if(i->second.status || i->second.towns.size() || i->second.color >= PlayerColor::PLAYER_LIMIT)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
InfoWindow iw;
|
|
||||||
iw.player = i->first;
|
|
||||||
iw.components.push_back(Component(Component::FLAG, i->first.getNum(), 0, 0));
|
|
||||||
|
|
||||||
if(!i->second.daysWithoutCastle)
|
|
||||||
{
|
|
||||||
iw.text.addTxt(MetaString::GENERAL_TXT,6); //%s, you have lost your last town. If you do not conquer another town in the next week, you will be eliminated.
|
|
||||||
iw.text.addReplacement(MetaString::COLOR, i->first.getNum());
|
|
||||||
}
|
|
||||||
else if(i->second.daysWithoutCastle == 6)
|
|
||||||
{
|
|
||||||
iw.text.addTxt(MetaString::ARRAY_TXT,129); //%s, this is your last day to capture a town or you will be banished from this land.
|
|
||||||
iw.text.addReplacement(MetaString::COLOR, i->first.getNum());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iw.text.addTxt(MetaString::ARRAY_TXT,128); //%s, you only have %d days left to capture a town or you will be banished from this land.
|
|
||||||
iw.text.addReplacement(MetaString::COLOR, i->first.getNum());
|
|
||||||
iw.text.addReplacement(7 - i->second.daysWithoutCastle);
|
|
||||||
}
|
|
||||||
sendAndApply(&iw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronizeArtifactHandlerLists(); //new day events may have changed them. TODO better of managing that
|
synchronizeArtifactHandlerLists(); //new day events may have changed them. TODO better of managing that
|
||||||
}
|
}
|
||||||
@ -1515,19 +1485,13 @@ void CGameHandler::run(bool resume)
|
|||||||
resume = false;
|
resume = false;
|
||||||
for(; i != gs->players.end(); i++)
|
for(; i != gs->players.end(); i++)
|
||||||
{
|
{
|
||||||
if((i->second.towns.size()==0 && i->second.heroes.size()==0)
|
if(i->second.status == EPlayerStatus::INGAME)
|
||||||
|| i->first>=PlayerColor::PLAYER_LIMIT
|
|
||||||
|| i->second.status)
|
|
||||||
{
|
{
|
||||||
continue;
|
|
||||||
}
|
|
||||||
states.setFlag(i->first,&PlayerStatus::makingTurn,true);
|
states.setFlag(i->first,&PlayerStatus::makingTurn,true);
|
||||||
|
|
||||||
{
|
|
||||||
YourTurn yt;
|
YourTurn yt;
|
||||||
yt.player = i->first;
|
yt.player = i->first;
|
||||||
applyAndSend(&yt);
|
applyAndSend(&yt);
|
||||||
}
|
|
||||||
|
|
||||||
//wait till turn is done
|
//wait till turn is done
|
||||||
boost::unique_lock<boost::mutex> lock(states.mx);
|
boost::unique_lock<boost::mutex> lock(states.mx);
|
||||||
@ -1535,7 +1499,7 @@ void CGameHandler::run(bool resume)
|
|||||||
{
|
{
|
||||||
static time_duration p = milliseconds(200);
|
static time_duration p = milliseconds(200);
|
||||||
states.cv.timed_wait(lock,p);
|
states.cv.timed_wait(lock,p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1608,7 +1572,7 @@ bool CGameHandler::removeObject( const CGObjectInstance * obj )
|
|||||||
ro.id = obj->id;
|
ro.id = obj->id;
|
||||||
sendAndApply(&ro);
|
sendAndApply(&ro);
|
||||||
|
|
||||||
winLoseHandle(255); //eg if monster escaped (removing objs after battle is done dircetly by endBattle, not this function)
|
checkVictoryLossConditionsForAll(); //eg if monster escaped (removing objs after battle is done dircetly by endBattle, not this function)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1811,7 +1775,9 @@ void CGameHandler::setOwner(const CGObjectInstance * obj, PlayerColor owner)
|
|||||||
SetObjectProperty sop(obj->id, 1, owner.getNum());
|
SetObjectProperty sop(obj->id, 1, owner.getNum());
|
||||||
sendAndApply(&sop);
|
sendAndApply(&sop);
|
||||||
|
|
||||||
winLoseHandle(1<<owner.getNum() | 1<<oldOwner.getNum());
|
std::set<PlayerColor> playerColors = boost::assign::list_of(owner)(oldOwner);
|
||||||
|
checkVictoryLossConditions(playerColors);
|
||||||
|
|
||||||
if(owner < PlayerColor::PLAYER_LIMIT && dynamic_cast<const CGTownInstance *>(obj)) //town captured
|
if(owner < PlayerColor::PLAYER_LIMIT && dynamic_cast<const CGTownInstance *>(obj)) //town captured
|
||||||
{
|
{
|
||||||
const CGTownInstance * town = dynamic_cast<const CGTownInstance *>(obj);
|
const CGTownInstance * town = dynamic_cast<const CGTownInstance *>(obj);
|
||||||
@ -1933,7 +1899,7 @@ void CGameHandler::heroVisitCastle(const CGTownInstance * obj, const CGHeroInsta
|
|||||||
giveSpells (obj, hero);
|
giveSpells (obj, hero);
|
||||||
|
|
||||||
if(gs->map->victoryCondition.condition == EVictoryConditionType::TRANSPORTITEM)
|
if(gs->map->victoryCondition.condition == EVictoryConditionType::TRANSPORTITEM)
|
||||||
checkLossVictory(hero->tempOwner); //transported artifact?
|
checkVictoryLossConditionsForPlayer(hero->tempOwner); //transported artifact?
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameHandler::vistiCastleObjects (const CGTownInstance *t, const CGHeroInstance *h)
|
void CGameHandler::vistiCastleObjects (const CGTownInstance *t, const CGHeroInstance *h)
|
||||||
@ -2178,28 +2144,28 @@ void CGameHandler::sendAndApply(CGarrisonOperationPack * info)
|
|||||||
{
|
{
|
||||||
sendAndApply(static_cast<CPackForClient*>(info));
|
sendAndApply(static_cast<CPackForClient*>(info));
|
||||||
if(gs->map->victoryCondition.condition == EVictoryConditionType::GATHERTROOP)
|
if(gs->map->victoryCondition.condition == EVictoryConditionType::GATHERTROOP)
|
||||||
winLoseHandle();
|
checkVictoryLossConditionsForAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameHandler::sendAndApply( SetResource * info )
|
void CGameHandler::sendAndApply( SetResource * info )
|
||||||
{
|
{
|
||||||
sendAndApply(static_cast<CPackForClient*>(info));
|
sendAndApply(static_cast<CPackForClient*>(info));
|
||||||
if(gs->map->victoryCondition.condition == EVictoryConditionType::GATHERRESOURCE)
|
if(gs->map->victoryCondition.condition == EVictoryConditionType::GATHERRESOURCE)
|
||||||
checkLossVictory(info->player);
|
checkVictoryLossConditionsForPlayer(info->player);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameHandler::sendAndApply( SetResources * info )
|
void CGameHandler::sendAndApply( SetResources * info )
|
||||||
{
|
{
|
||||||
sendAndApply(static_cast<CPackForClient*>(info));
|
sendAndApply(static_cast<CPackForClient*>(info));
|
||||||
if(gs->map->victoryCondition.condition == EVictoryConditionType::GATHERRESOURCE)
|
if(gs->map->victoryCondition.condition == EVictoryConditionType::GATHERRESOURCE)
|
||||||
checkLossVictory(info->player);
|
checkVictoryLossConditionsForPlayer(info->player);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameHandler::sendAndApply( NewStructures * info )
|
void CGameHandler::sendAndApply( NewStructures * info )
|
||||||
{
|
{
|
||||||
sendAndApply(static_cast<CPackForClient*>(info));
|
sendAndApply(static_cast<CPackForClient*>(info));
|
||||||
if(gs->map->victoryCondition.condition == EVictoryConditionType::BUILDCITY)
|
if(gs->map->victoryCondition.condition == EVictoryConditionType::BUILDCITY)
|
||||||
checkLossVictory(getTown(info->tid)->tempOwner);
|
checkVictoryLossConditionsForPlayer(getTown(info->tid)->tempOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameHandler::save(const std::string & filename )
|
void CGameHandler::save(const std::string & filename )
|
||||||
@ -2525,7 +2491,7 @@ bool CGameHandler::buildStructure( ObjectInstanceID tid, BuildingID requestedID,
|
|||||||
if(t->garrisonHero)
|
if(t->garrisonHero)
|
||||||
vistiCastleObjects (t, t->garrisonHero);
|
vistiCastleObjects (t, t->garrisonHero);
|
||||||
|
|
||||||
checkLossVictory(t->tempOwner);
|
checkVictoryLossConditionsForPlayer(t->tempOwner);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool CGameHandler::razeStructure (ObjectInstanceID tid, BuildingID bid)
|
bool CGameHandler::razeStructure (ObjectInstanceID tid, BuildingID bid)
|
||||||
@ -3927,7 +3893,7 @@ void CGameHandler::playerMessage( PlayerColor player, const std::string &message
|
|||||||
{
|
{
|
||||||
SystemMessage temp_message(VLC->generaltexth->allTexts.at(260));
|
SystemMessage temp_message(VLC->generaltexth->allTexts.at(260));
|
||||||
sendAndApply(&temp_message);
|
sendAndApply(&temp_message);
|
||||||
checkLossVictory(player);//Player enter win code or got required art\creature
|
checkVictoryLossConditionsForPlayer(player);//Player enter win code or got required art\creature
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5055,21 +5021,28 @@ void CGameHandler::engageIntoBattle( PlayerColor player )
|
|||||||
sendAndApply(&pb);
|
sendAndApply(&pb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameHandler::winLoseHandle(ui8 players )
|
void CGameHandler::checkVictoryLossConditions(const std::set<PlayerColor> & playerColors)
|
||||||
{
|
{
|
||||||
for(size_t i = 0; i < PlayerColor::PLAYER_LIMIT_I; i++)
|
for(auto playerColor : playerColors)
|
||||||
{
|
{
|
||||||
if(players & 1<<i && gs->getPlayer(PlayerColor(i)))
|
if(gs->getPlayer(playerColor)) checkVictoryLossConditionsForPlayer(playerColor);
|
||||||
{
|
|
||||||
checkLossVictory(PlayerColor(i));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameHandler::checkLossVictory( PlayerColor player )
|
void CGameHandler::checkVictoryLossConditionsForAll()
|
||||||
|
{
|
||||||
|
std::set<PlayerColor> playerColors;
|
||||||
|
for(int i = 0; i < PlayerColor::PLAYER_LIMIT_I; ++i)
|
||||||
|
{
|
||||||
|
playerColors.insert(PlayerColor(i));
|
||||||
|
}
|
||||||
|
checkVictoryLossConditions(playerColors);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGameHandler::checkVictoryLossConditionsForPlayer(PlayerColor player)
|
||||||
{
|
{
|
||||||
const PlayerState *p = gs->getPlayer(player);
|
const PlayerState *p = gs->getPlayer(player);
|
||||||
if(p->status == EPlayerStatus::WINNER || p->status == EPlayerStatus::LOSER || p->status == EPlayerStatus::WRONG) return;
|
if(p->status != EPlayerStatus::INGAME) return;
|
||||||
|
|
||||||
auto victoryLossCheckResult = gs->checkForVictoryAndLoss(player);
|
auto victoryLossCheckResult = gs->checkForVictoryAndLoss(player);
|
||||||
|
|
||||||
@ -5091,7 +5064,7 @@ void CGameHandler::checkLossVictory( PlayerColor player )
|
|||||||
|
|
||||||
for (auto i = gs->players.cbegin(); i!=gs->players.cend(); i++)
|
for (auto i = gs->players.cbegin(); i!=gs->players.cend(); i++)
|
||||||
{
|
{
|
||||||
if(i->first < PlayerColor::PLAYER_LIMIT && i->first != player)//FIXME: skip already eliminated players?
|
if(i->first != player && gs->getPlayer(i->first)->status == EPlayerStatus::INGAME)
|
||||||
{
|
{
|
||||||
iw.player = i->first;
|
iw.player = i->first;
|
||||||
sendAndApply(&iw);
|
sendAndApply(&iw);
|
||||||
@ -5150,7 +5123,13 @@ void CGameHandler::checkLossVictory( PlayerColor player )
|
|||||||
}
|
}
|
||||||
|
|
||||||
//eliminating one player may cause victory of another:
|
//eliminating one player may cause victory of another:
|
||||||
winLoseHandle(GameConstants::ALL_PLAYERS & ~(1<<player.getNum()));
|
std::set<PlayerColor> playerColors;
|
||||||
|
for(int i = 0; i < PlayerColor::PLAYER_LIMIT_I; ++i)
|
||||||
|
{
|
||||||
|
if(player.getNum() != i) playerColors.insert(PlayerColor(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
checkVictoryLossConditions(playerColors);
|
||||||
}
|
}
|
||||||
|
|
||||||
//If player making turn has lost his turn must be over as well
|
//If player making turn has lost his turn must be over as well
|
||||||
|
@ -106,8 +106,6 @@ public:
|
|||||||
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
|
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
|
||||||
int moveStack(int stack, BattleHex dest); //returned value - travelled distance
|
int moveStack(int stack, BattleHex dest); //returned value - travelled distance
|
||||||
void runBattle();
|
void runBattle();
|
||||||
void checkLossVictory(PlayerColor player);
|
|
||||||
void winLoseHandle(ui8 players=255); //players: bit field - colours of players to be checked; default: all
|
|
||||||
|
|
||||||
////used only in endBattle - don't touch elsewhere
|
////used only in endBattle - don't touch elsewhere
|
||||||
bool visitObjectAfterVictory;
|
bool visitObjectAfterVictory;
|
||||||
@ -293,6 +291,11 @@ public:
|
|||||||
private:
|
private:
|
||||||
void makeStackDoNothing(const CStack * next);
|
void makeStackDoNothing(const CStack * next);
|
||||||
void getVictoryLossMessage(PlayerColor player, EVictoryLossCheckResult victoryLossCheckResult, InfoWindow & out) const;
|
void getVictoryLossMessage(PlayerColor player, EVictoryLossCheckResult victoryLossCheckResult, InfoWindow & out) const;
|
||||||
|
|
||||||
|
// Check for victory and loss conditions
|
||||||
|
void checkVictoryLossConditionsForPlayer(PlayerColor player);
|
||||||
|
void checkVictoryLossConditions(const std::set<PlayerColor> & playerColors);
|
||||||
|
void checkVictoryLossConditionsForAll();
|
||||||
};
|
};
|
||||||
|
|
||||||
void makeStackDoNothing();
|
void makeStackDoNothing();
|
||||||
|
Reference in New Issue
Block a user