mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-15 01:24:45 +02:00
Merge remote-tracking branch 'origin/issue/2306' into develop
This commit is contained in:
@ -2735,24 +2735,13 @@ void VCAI::finish()
|
|||||||
|
|
||||||
void VCAI::requestActionASAP(std::function<void()> whatToDo)
|
void VCAI::requestActionASAP(std::function<void()> whatToDo)
|
||||||
{
|
{
|
||||||
boost::mutex mutex;
|
boost::thread newThread([this,whatToDo]()
|
||||||
mutex.lock();
|
|
||||||
|
|
||||||
boost::thread newThread([&mutex,this,whatToDo]()
|
|
||||||
{
|
{
|
||||||
setThreadName("VCAI::requestActionASAP::helper");
|
setThreadName("VCAI::requestActionASAP::whatToDo");
|
||||||
SET_GLOBAL_STATE(this);
|
SET_GLOBAL_STATE(this);
|
||||||
boost::shared_lock<boost::shared_mutex> gsLock(cb->getGsMutex());
|
boost::shared_lock<boost::shared_mutex> gsLock(cb->getGsMutex());
|
||||||
// unlock mutex and allow parent function to exit
|
|
||||||
mutex.unlock();
|
|
||||||
whatToDo();
|
whatToDo();
|
||||||
});
|
});
|
||||||
|
|
||||||
// wait for mutex to unlock and for thread to initialize properly
|
|
||||||
mutex.lock();
|
|
||||||
|
|
||||||
// unlock mutex - boost dislikes destruction of locked mutexes
|
|
||||||
mutex.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCAI::lostHero(HeroPtr h)
|
void VCAI::lostHero(HeroPtr h)
|
||||||
|
@ -247,21 +247,14 @@ void CClient::endGame( bool closeConnection /*= true*/ )
|
|||||||
void CClient::loadGame(const std::string & fname, const bool server, const std::vector<int>& humanplayerindices, const int loadNumPlayers, int player_, const std::string & ipaddr, const std::string & port)
|
void CClient::loadGame(const std::string & fname, const bool server, const std::vector<int>& humanplayerindices, const int loadNumPlayers, int player_, const std::string & ipaddr, const std::string & port)
|
||||||
{
|
{
|
||||||
PlayerColor player(player_); //intentional shadowing
|
PlayerColor player(player_); //intentional shadowing
|
||||||
logNetwork->infoStream() << "Loading procedure started!";
|
|
||||||
|
|
||||||
std::string realPort;
|
logNetwork->infoStream() <<"Loading procedure started!";
|
||||||
if(settings["testing"]["enabled"].Bool())
|
|
||||||
realPort = settings["testing"]["port"].String();
|
|
||||||
else if(port.size())
|
|
||||||
realPort = port;
|
|
||||||
else
|
|
||||||
realPort = boost::lexical_cast<std::string>(settings["server"]["port"].Float());
|
|
||||||
|
|
||||||
CServerHandler sh;
|
CServerHandler sh;
|
||||||
if(server)
|
if(server)
|
||||||
sh.startServer();
|
sh.startServer();
|
||||||
else
|
else
|
||||||
serv = sh.justConnectToServer(ipaddr, realPort);
|
serv = sh.justConnectToServer(ipaddr,port=="" ? "3030" : port);
|
||||||
|
|
||||||
CStopWatch tmh;
|
CStopWatch tmh;
|
||||||
unique_ptr<CLoadFile> loader;
|
unique_ptr<CLoadFile> loader;
|
||||||
@ -974,9 +967,6 @@ CServerHandler::CServerHandler(bool runServer /*= false*/)
|
|||||||
{
|
{
|
||||||
serverThread = nullptr;
|
serverThread = nullptr;
|
||||||
shared = nullptr;
|
shared = nullptr;
|
||||||
if(settings["testing"]["enabled"].Bool())
|
|
||||||
port = settings["testing"]["port"].String();
|
|
||||||
else
|
|
||||||
port = boost::lexical_cast<std::string>(settings["server"]["port"].Float());
|
port = boost::lexical_cast<std::string>(settings["server"]["port"].Float());
|
||||||
verbose = true;
|
verbose = true;
|
||||||
|
|
||||||
|
@ -1538,7 +1538,10 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
|
|||||||
}
|
}
|
||||||
else if(const CGHeroInstance * h = curHero())
|
else if(const CGHeroInstance * h = curHero())
|
||||||
{
|
{
|
||||||
const CGPathNode * pnode = LOCPLINT->cb->getPathsInfo(h)->getPathInfo(mapPos);
|
int3 mapPosCopy = mapPos;
|
||||||
|
const CGPathNode * pnode = LOCPLINT->cb->getPathsInfo(h)->getPathInfo(mapPosCopy);
|
||||||
|
assert(pnode);
|
||||||
|
|
||||||
int turns = pnode->turns;
|
int turns = pnode->turns;
|
||||||
vstd::amin(turns, 3);
|
vstd::amin(turns, 3);
|
||||||
switch(pnode->action)
|
switch(pnode->action)
|
||||||
@ -1800,4 +1803,3 @@ void CAdvMapInt::WorldViewOptions::adjustDrawingInfo(MapDrawingInfo& info)
|
|||||||
|
|
||||||
info.additionalIcons = &iconPositions;
|
info.additionalIcons = &iconPositions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,18 +450,19 @@ CTypeList::TypeInfoPtr CTypeList::registerType( const std::type_info *type )
|
|||||||
return newType;
|
return newType;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui16 CTypeList::getTypeID( const std::type_info *type )
|
ui16 CTypeList::getTypeID( const std::type_info *type, bool throws ) const
|
||||||
|
{
|
||||||
|
auto descriptor = getTypeDescriptor(type, throws);
|
||||||
|
if (descriptor == nullptr)
|
||||||
{
|
{
|
||||||
auto i = typeInfos.find(type);
|
|
||||||
if(i != typeInfos.end())
|
|
||||||
return i->second->typeID;
|
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
return descriptor->typeID;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, TypeInfoPtr to)
|
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, TypeInfoPtr to) const
|
||||||
{
|
{
|
||||||
if(from == to)
|
if(!strcmp(from->name, to->name))
|
||||||
return std::vector<CTypeList::TypeInfoPtr>();
|
return std::vector<CTypeList::TypeInfoPtr>();
|
||||||
|
|
||||||
// Perform a simple BFS in the class hierarchy.
|
// Perform a simple BFS in the class hierarchy.
|
||||||
@ -512,17 +513,17 @@ std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, Ty
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(const std::type_info *from, const std::type_info *to)
|
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(const std::type_info *from, const std::type_info *to) const
|
||||||
{
|
{
|
||||||
//This additional if is needed because getTypeDescriptor might fail if type is not registered
|
//This additional if is needed because getTypeDescriptor might fail if type is not registered
|
||||||
// (and if casting is not needed, then registereing should no be required)
|
// (and if casting is not needed, then registereing should no be required)
|
||||||
if(*from == *to)
|
if(!strcmp(from->name(), to->name()))
|
||||||
return std::vector<CTypeList::TypeInfoPtr>();
|
return std::vector<CTypeList::TypeInfoPtr>();
|
||||||
|
|
||||||
return castSequence(getTypeDescriptor(from), getTypeDescriptor(to));
|
return castSequence(getTypeDescriptor(from), getTypeDescriptor(to));
|
||||||
}
|
}
|
||||||
|
|
||||||
CTypeList::TypeInfoPtr CTypeList::getTypeDescriptor(const std::type_info *type, bool throws)
|
CTypeList::TypeInfoPtr CTypeList::getTypeDescriptor(const std::type_info *type, bool throws) const
|
||||||
{
|
{
|
||||||
auto i = typeInfos.find(type);
|
auto i = typeInfos.find(type);
|
||||||
if(i != typeInfos.end())
|
if(i != typeInfos.end())
|
||||||
@ -646,4 +647,3 @@ CMemorySerializer::CMemorySerializer(): iser(this), oser(this)
|
|||||||
registerTypes(iser);
|
registerTypes(iser);
|
||||||
registerTypes(oser);
|
registerTypes(oser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
126
lib/Connection.h
126
lib/Connection.h
@ -83,7 +83,11 @@ struct TypeComparer
|
|||||||
{
|
{
|
||||||
bool operator()(const std::type_info *a, const std::type_info *b) const
|
bool operator()(const std::type_info *a, const std::type_info *b) const
|
||||||
{
|
{
|
||||||
|
#ifndef __APPLE__
|
||||||
return a->before(*b);
|
return a->before(*b);
|
||||||
|
#else
|
||||||
|
return strcmp(a->name(), b->name()) < 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -102,6 +106,11 @@ struct PointerCaster : IPointerCaster
|
|||||||
{
|
{
|
||||||
From * from = (From*)boost::any_cast<void*>(ptr);
|
From * from = (From*)boost::any_cast<void*>(ptr);
|
||||||
To * ret = dynamic_cast<To*>(from);
|
To * ret = dynamic_cast<To*>(from);
|
||||||
|
if (ret == nullptr)
|
||||||
|
{
|
||||||
|
// Last resort when RTTI goes mad
|
||||||
|
ret = static_cast<To*>(from);
|
||||||
|
}
|
||||||
return (void*)ret;
|
return (void*)ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +122,11 @@ struct PointerCaster : IPointerCaster
|
|||||||
{
|
{
|
||||||
auto from = boost::any_cast<SmartPt>(ptr);
|
auto from = boost::any_cast<SmartPt>(ptr);
|
||||||
auto ret = std::dynamic_pointer_cast<To>(from);
|
auto ret = std::dynamic_pointer_cast<To>(from);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
// Last resort when RTTI goes mad
|
||||||
|
ret = std::static_pointer_cast<To>(from);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
@ -136,7 +150,7 @@ struct PointerCaster : IPointerCaster
|
|||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CTypeList
|
class DLL_LINKAGE CTypeList: public boost::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct TypeDescriptor;
|
struct TypeDescriptor;
|
||||||
@ -147,33 +161,53 @@ public:
|
|||||||
const char *name;
|
const char *name;
|
||||||
std::vector<TypeInfoPtr> children, parents;
|
std::vector<TypeInfoPtr> children, parents;
|
||||||
};
|
};
|
||||||
|
typedef boost::shared_mutex TMutex;
|
||||||
|
typedef boost::unique_lock<TMutex> TUniqueLock;
|
||||||
|
typedef boost::shared_lock<TMutex> TSharedLock;
|
||||||
private:
|
private:
|
||||||
|
mutable TMutex mx;
|
||||||
|
|
||||||
std::map<const std::type_info *, TypeInfoPtr, TypeComparer> typeInfos;
|
std::map<const std::type_info *, TypeInfoPtr, TypeComparer> typeInfos;
|
||||||
std::map<std::pair<TypeInfoPtr, TypeInfoPtr>, std::unique_ptr<const IPointerCaster>> casters; //for each pair <Base, Der> we provide a caster (each registered relations creates a single entry here)
|
std::map<std::pair<TypeInfoPtr, TypeInfoPtr>, std::unique_ptr<const IPointerCaster>> casters; //for each pair <Base, Der> we provide a caster (each registered relations creates a single entry here)
|
||||||
|
|
||||||
CTypeList(CTypeList &)
|
/// Returns sequence of types starting from "from" and ending on "to". Every next type is derived from the previous.
|
||||||
{
|
/// Throws if there is no link registered.
|
||||||
// This type is non-copyable.
|
std::vector<TypeInfoPtr> castSequence(TypeInfoPtr from, TypeInfoPtr to) const;
|
||||||
// Unfortunately on Windows it is required for DLL_EXPORT-ed type to provide copy c-tor, so we can't =delete it.
|
std::vector<TypeInfoPtr> castSequence(const std::type_info *from, const std::type_info *to) const;
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
CTypeList &operator=(CTypeList &)
|
|
||||||
{
|
|
||||||
// As above.
|
|
||||||
assert(0);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
|
|
||||||
CTypeList();
|
|
||||||
|
template<boost::any(IPointerCaster::*CastingFunction)(const boost::any &) const>
|
||||||
|
boost::any castHelper(boost::any inputPtr, const std::type_info *fromArg, const std::type_info *toArg) const
|
||||||
|
{
|
||||||
|
TSharedLock lock(mx);
|
||||||
|
auto typesSequence = castSequence(fromArg, toArg);
|
||||||
|
|
||||||
|
boost::any ptr = inputPtr;
|
||||||
|
for(int i = 0; i < static_cast<int>(typesSequence.size()) - 1; i++)
|
||||||
|
{
|
||||||
|
auto &from = typesSequence[i];
|
||||||
|
auto &to = typesSequence[i + 1];
|
||||||
|
auto castingPair = std::make_pair(from, to);
|
||||||
|
if(!casters.count(castingPair))
|
||||||
|
THROW_FORMAT("Cannot find caster for conversion %s -> %s which is needed to cast %s -> %s", from->name % to->name % fromArg->name() % toArg->name());
|
||||||
|
|
||||||
|
auto &caster = casters.at(castingPair);
|
||||||
|
ptr = (*caster.*CastingFunction)(ptr); //Why does unique_ptr not have operator->* ..?
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeInfoPtr getTypeDescriptor(const std::type_info *type, bool throws = true) const; //if not throws, failure returns nullptr
|
||||||
|
|
||||||
TypeInfoPtr registerType(const std::type_info *type);
|
TypeInfoPtr registerType(const std::type_info *type);
|
||||||
|
public:
|
||||||
|
CTypeList();
|
||||||
|
|
||||||
template <typename Base, typename Derived>
|
template <typename Base, typename Derived>
|
||||||
void registerType(const Base * b = nullptr, const Derived * d = nullptr)
|
void registerType(const Base * b = nullptr, const Derived * d = nullptr)
|
||||||
{
|
{
|
||||||
|
TUniqueLock lock(mx);
|
||||||
static_assert(std::is_base_of<Base, Derived>::value, "First registerType template parameter needs to ba a base class of the second one.");
|
static_assert(std::is_base_of<Base, Derived>::value, "First registerType template parameter needs to ba a base class of the second one.");
|
||||||
static_assert(std::has_virtual_destructor<Base>::value, "Base class needs to have a virtual destructor.");
|
static_assert(std::has_virtual_destructor<Base>::value, "Base class needs to have a virtual destructor.");
|
||||||
static_assert(!std::is_same<Base, Derived>::value, "Parameters of registerTypes should be two diffrenet types.");
|
static_assert(!std::is_same<Base, Derived>::value, "Parameters of registerTypes should be two diffrenet types.");
|
||||||
@ -187,77 +221,52 @@ public:
|
|||||||
casters[std::make_pair(dti, bti)] = make_unique<const PointerCaster<Derived, Base>>();
|
casters[std::make_pair(dti, bti)] = make_unique<const PointerCaster<Derived, Base>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ui16 getTypeID(const std::type_info *type);
|
ui16 getTypeID(const std::type_info *type, bool throws = false) const;
|
||||||
TypeInfoPtr getTypeDescriptor(const std::type_info *type, bool throws = true); //if not throws, failure returns nullptr
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
ui16 getTypeID(const T * t = nullptr)
|
ui16 getTypeID(const T * t = nullptr, bool throws = false) const
|
||||||
{
|
{
|
||||||
return getTypeID(getTypeInfo(t));
|
return getTypeID(getTypeInfo(t), throws);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Returns sequence of types starting from "from" and ending on "to". Every next type is derived from the previous.
|
|
||||||
// Throws if there is no link registered.
|
|
||||||
std::vector<TypeInfoPtr> castSequence(TypeInfoPtr from, TypeInfoPtr to);
|
|
||||||
std::vector<TypeInfoPtr> castSequence(const std::type_info *from, const std::type_info *to);
|
|
||||||
|
|
||||||
template<boost::any(IPointerCaster::*CastingFunction)(const boost::any &) const>
|
|
||||||
boost::any castHelper(boost::any inputPtr, const std::type_info *fromArg, const std::type_info *toArg)
|
|
||||||
{
|
|
||||||
auto typesSequence = castSequence(fromArg, toArg);
|
|
||||||
|
|
||||||
boost::any ptr = inputPtr;
|
|
||||||
for(int i = 0; i < (int)typesSequence.size() - 1; i++)
|
|
||||||
{
|
|
||||||
auto &from = typesSequence[i];
|
|
||||||
auto &to = typesSequence[i + 1];
|
|
||||||
auto castingPair = std::make_pair(from, to);
|
|
||||||
if(!casters.count(castingPair))
|
|
||||||
THROW_FORMAT("Cannot find caster for conversion %s -> %s which is needed to cast %s -> %s", from->name % to->name % fromArg->name() % toArg->name());
|
|
||||||
|
|
||||||
auto &caster = casters.at(castingPair);
|
|
||||||
ptr = (*caster.*CastingFunction)(ptr); //Why does unique_ptr does not have operator->* ..?
|
|
||||||
}
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TInput>
|
template<typename TInput>
|
||||||
void *castToMostDerived(const TInput *inputPtr)
|
void * castToMostDerived(const TInput * inputPtr) const
|
||||||
{
|
{
|
||||||
auto &baseType = typeid(typename std::remove_cv<TInput>::type);
|
auto &baseType = typeid(typename std::remove_cv<TInput>::type);
|
||||||
auto derivedType = getTypeInfo(inputPtr);
|
auto derivedType = getTypeInfo(inputPtr);
|
||||||
|
|
||||||
if(baseType == *derivedType)
|
if (!strcmp(baseType.name(), derivedType->name()))
|
||||||
return (void*)inputPtr;
|
{
|
||||||
|
return const_cast<void*>(reinterpret_cast<const void*>(inputPtr));
|
||||||
|
}
|
||||||
|
|
||||||
return boost::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>((void*)inputPtr, &baseType, derivedType));
|
return boost::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>(
|
||||||
|
const_cast<void*>(reinterpret_cast<const void*>(inputPtr)), &baseType,
|
||||||
|
derivedType));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TInput>
|
template<typename TInput>
|
||||||
boost::any castSharedToMostDerived(const std::shared_ptr<TInput> inputPtr)
|
boost::any castSharedToMostDerived(const std::shared_ptr<TInput> inputPtr) const
|
||||||
{
|
{
|
||||||
auto &baseType = typeid(typename std::remove_cv<TInput>::type);
|
auto &baseType = typeid(typename std::remove_cv<TInput>::type);
|
||||||
auto derivedType = getTypeInfo(inputPtr.get());
|
auto derivedType = getTypeInfo(inputPtr.get());
|
||||||
|
|
||||||
if(baseType == *derivedType)
|
if (!strcmp(baseType.name(), derivedType->name()))
|
||||||
return inputPtr;
|
return inputPtr;
|
||||||
|
|
||||||
return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, &baseType, derivedType);
|
return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, &baseType, derivedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* castRaw(void *inputPtr, const std::type_info *from, const std::type_info *to)
|
void * castRaw(void *inputPtr, const std::type_info *from, const std::type_info *to) const
|
||||||
{
|
{
|
||||||
return boost::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>(inputPtr, from, to));
|
return boost::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>(inputPtr, from, to));
|
||||||
}
|
}
|
||||||
boost::any castShared(boost::any inputPtr, const std::type_info *from, const std::type_info *to)
|
boost::any castShared(boost::any inputPtr, const std::type_info *from, const std::type_info *to) const
|
||||||
{
|
{
|
||||||
return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, from, to);
|
return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T> const std::type_info * getTypeInfo(const T * t = nullptr) const
|
||||||
template <typename T> const std::type_info * getTypeInfo(const T * t = nullptr)
|
|
||||||
{
|
{
|
||||||
if(t)
|
if(t)
|
||||||
return &typeid(*t);
|
return &typeid(*t);
|
||||||
@ -665,9 +674,8 @@ public:
|
|||||||
{
|
{
|
||||||
COSer &s = static_cast<COSer&>(ar);
|
COSer &s = static_cast<COSer&>(ar);
|
||||||
const T *ptr = static_cast<const T*>(data);
|
const T *ptr = static_cast<const T*>(data);
|
||||||
|
|
||||||
//T is most derived known type, it's time to call actual serialize
|
//T is most derived known type, it's time to call actual serialize
|
||||||
const_cast<T&>(*ptr).serialize(s,version);
|
const_cast<T*>(ptr)->serialize(s,version);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -331,9 +331,6 @@ struct SetAvailableHeroes : public CPackForClient //113
|
|||||||
for (int i = 0; i < GameConstants::AVAILABLE_HEROES_PER_PLAYER; i++)
|
for (int i = 0; i < GameConstants::AVAILABLE_HEROES_PER_PLAYER; i++)
|
||||||
army[i].clear();
|
army[i].clear();
|
||||||
}
|
}
|
||||||
~SetAvailableHeroes()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void applyCl(CClient *cl);
|
void applyCl(CClient *cl);
|
||||||
DLL_LINKAGE void applyGs(CGameState *gs);
|
DLL_LINKAGE void applyGs(CGameState *gs);
|
||||||
|
|
||||||
|
@ -917,7 +917,7 @@ void CGameHandler::handleConnection(std::set<PlayerColor> players, CConnection &
|
|||||||
c << &applied;
|
c << &applied;
|
||||||
};
|
};
|
||||||
|
|
||||||
CBaseForGHApply *apply = applier->apps[packType]; //and appropriae applier object
|
CBaseForGHApply *apply = applier->apps[packType]; //and appropriate applier object
|
||||||
if(isBlockedByQueries(pack, player))
|
if(isBlockedByQueries(pack, player))
|
||||||
{
|
{
|
||||||
sendPackageResponse(false);
|
sendPackageResponse(false);
|
||||||
@ -5368,7 +5368,6 @@ void CGameHandler::runBattle()
|
|||||||
const CStack *next;
|
const CStack *next;
|
||||||
while(!battleResult.get() && (next = curB.getNextStack()) && next->willMove())
|
while(!battleResult.get() && (next = curB.getNextStack()) && next->willMove())
|
||||||
{
|
{
|
||||||
|
|
||||||
//check for bad morale => freeze
|
//check for bad morale => freeze
|
||||||
int nextStackMorale = next->MoraleVal();
|
int nextStackMorale = next->MoraleVal();
|
||||||
if( nextStackMorale < 0 &&
|
if( nextStackMorale < 0 &&
|
||||||
@ -5710,7 +5709,7 @@ bool CGameHandler::isValidObject(const CGObjectInstance *obj) const
|
|||||||
|
|
||||||
bool CGameHandler::isBlockedByQueries(const CPack *pack, PlayerColor player)
|
bool CGameHandler::isBlockedByQueries(const CPack *pack, PlayerColor player)
|
||||||
{
|
{
|
||||||
if(dynamic_cast<const PlayerMessage*>(pack))
|
if(!strcmp(typeid(*pack).name(), typeid(PlayerMessage).name()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto query = queries.topQuery(player);
|
auto query = queries.topQuery(player);
|
||||||
@ -5849,7 +5848,7 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleI
|
|||||||
//catapult artifact remain even if "creature" killed in siege
|
//catapult artifact remain even if "creature" killed in siege
|
||||||
if(warMachine != ArtifactID::NONE && warMachine != ArtifactID::CATAPULT)
|
if(warMachine != ArtifactID::NONE && warMachine != ArtifactID::CATAPULT)
|
||||||
{
|
{
|
||||||
auto hero = dynamic_cast<const CGHeroInstance*> (army);
|
auto hero = dynamic_ptr_cast<CGHeroInstance> (army);
|
||||||
if (hero)
|
if (hero)
|
||||||
removedWarMachines.push_back (ArtifactLocation(hero, hero->getArtPos(warMachine, true)));
|
removedWarMachines.push_back (ArtifactLocation(hero, hero->getArtPos(warMachine, true)));
|
||||||
}
|
}
|
||||||
@ -5955,4 +5954,3 @@ bool ServerSpellCastEnvironment::moveHero(ObjectInstanceID hid, int3 dst, ui8 te
|
|||||||
{
|
{
|
||||||
return gh->moveHero(hid, dst, teleporting, false, asker);
|
return gh->moveHero(hid, dst, teleporting, false, asker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +245,8 @@ CBattleQuery::CBattleQuery()
|
|||||||
|
|
||||||
bool CBattleQuery::blocksPack(const CPack *pack) const
|
bool CBattleQuery::blocksPack(const CPack *pack) const
|
||||||
{
|
{
|
||||||
return !dynamic_cast<const MakeAction*>(pack) && !dynamic_cast<const MakeCustomAction*>(pack);
|
const char * name = typeid(*pack).name();
|
||||||
|
return strcmp(name, typeid(MakeAction).name()) && strcmp(name, typeid(MakeCustomAction).name());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
void CBattleQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
||||||
@ -273,12 +274,12 @@ bool CGarrisonDialogQuery::blocksPack(const CPack *pack) const
|
|||||||
ourIds.insert(this->exchangingArmies[0]->id);
|
ourIds.insert(this->exchangingArmies[0]->id);
|
||||||
ourIds.insert(this->exchangingArmies[1]->id);
|
ourIds.insert(this->exchangingArmies[1]->id);
|
||||||
|
|
||||||
|
if (auto stacks = dynamic_ptr_cast<ArrangeStacks>(pack))
|
||||||
if (auto stacks = dynamic_cast<const ArrangeStacks*>(pack))
|
|
||||||
{
|
{
|
||||||
return !vstd::contains(ourIds, stacks->id1) || !vstd::contains(ourIds, stacks->id2);
|
return !vstd::contains(ourIds, stacks->id1) || !vstd::contains(ourIds, stacks->id2);
|
||||||
}
|
}
|
||||||
if (auto arts = dynamic_cast<const ExchangeArtifacts*>(pack))
|
|
||||||
|
if (auto arts = dynamic_ptr_cast<ExchangeArtifacts>(pack))
|
||||||
{
|
{
|
||||||
if(auto id1 = boost::apply_visitor(GetEngagedHeroIds(), arts->src.artHolder))
|
if(auto id1 = boost::apply_visitor(GetEngagedHeroIds(), arts->src.artHolder))
|
||||||
if(!vstd::contains(ourIds, *id1))
|
if(!vstd::contains(ourIds, *id1))
|
||||||
@ -289,17 +290,17 @@ bool CGarrisonDialogQuery::blocksPack(const CPack *pack) const
|
|||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (auto dismiss = dynamic_cast<const DisbandCreature*>(pack))
|
if (auto dismiss = dynamic_ptr_cast<DisbandCreature>(pack))
|
||||||
{
|
{
|
||||||
return !vstd::contains(ourIds, dismiss->id);
|
return !vstd::contains(ourIds, dismiss->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto dismiss = dynamic_cast<const AssembleArtifacts*>(pack))
|
if (auto dismiss = dynamic_ptr_cast<AssembleArtifacts>(pack))
|
||||||
{
|
{
|
||||||
return !vstd::contains(ourIds, dismiss->heroID);
|
return !vstd::contains(ourIds, dismiss->heroID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(auto upgrade = dynamic_cast<const UpgradeCreature*>(pack))
|
if(auto upgrade = dynamic_ptr_cast<UpgradeCreature>(pack))
|
||||||
{
|
{
|
||||||
return !vstd::contains(ourIds, upgrade->id);
|
return !vstd::contains(ourIds, upgrade->id);
|
||||||
}
|
}
|
||||||
@ -320,7 +321,7 @@ CBlockingDialogQuery::CBlockingDialogQuery(const BlockingDialog &bd)
|
|||||||
|
|
||||||
void CTeleportDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
void CTeleportDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||||
{
|
{
|
||||||
auto obj = dynamic_cast<const CGTeleport *>(objectVisit.visitedObject);
|
auto obj = dynamic_ptr_cast<const CGTeleport>(objectVisit.visitedObject);
|
||||||
obj->teleportDialogAnswered(objectVisit.visitingHero, *answer, td.exits);
|
obj->teleportDialogAnswered(objectVisit.visitingHero, *answer, td.exits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,7 +375,7 @@ bool CDialogQuery::endsByPlayerAnswer() const
|
|||||||
bool CDialogQuery::blocksPack(const CPack *pack) const
|
bool CDialogQuery::blocksPack(const CPack *pack) const
|
||||||
{
|
{
|
||||||
//We accept only query replies from correct player
|
//We accept only query replies from correct player
|
||||||
if(auto reply = dynamic_cast<const QueryReply *>(pack))
|
if(auto reply = dynamic_ptr_cast<QueryReply>(pack))
|
||||||
{
|
{
|
||||||
return !vstd::contains(players, reply->player);
|
return !vstd::contains(players, reply->player);
|
||||||
}
|
}
|
||||||
|
@ -86,8 +86,8 @@ void CPregameServer::handleConnection(CConnection *cpc)
|
|||||||
logNetwork->infoStream() << "Got package to announce " << typeid(*cpfs).name() << " from " << *cpc;
|
logNetwork->infoStream() << "Got package to announce " << typeid(*cpfs).name() << " from " << *cpc;
|
||||||
|
|
||||||
boost::unique_lock<boost::recursive_mutex> queueLock(mx);
|
boost::unique_lock<boost::recursive_mutex> queueLock(mx);
|
||||||
bool quitting = dynamic_cast<QuitMenuWithoutStarting*>(cpfs),
|
bool quitting = dynamic_ptr_cast<QuitMenuWithoutStarting>(cpfs),
|
||||||
startingGame = dynamic_cast<StartWithCurrentSettings*>(cpfs);
|
startingGame = dynamic_ptr_cast<StartWithCurrentSettings>(cpfs);
|
||||||
if(quitting || startingGame) //host leaves main menu or wants to start game -> we end
|
if(quitting || startingGame) //host leaves main menu or wants to start game -> we end
|
||||||
{
|
{
|
||||||
cpc->receivedStop = true;
|
cpc->receivedStop = true;
|
||||||
@ -258,11 +258,11 @@ void CPregameServer::sendPack(CConnection * pc, const CPackForSelectionScreen &
|
|||||||
*pc << &pack;
|
*pc << &pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dynamic_cast<const QuitMenuWithoutStarting*>(&pack))
|
if(dynamic_ptr_cast<QuitMenuWithoutStarting>(&pack))
|
||||||
{
|
{
|
||||||
pc->sendStop = true;
|
pc->sendStop = true;
|
||||||
}
|
}
|
||||||
else if(dynamic_cast<const StartWithCurrentSettings*>(&pack))
|
else if(dynamic_ptr_cast<StartWithCurrentSettings>(&pack))
|
||||||
{
|
{
|
||||||
pc->sendStop = true;
|
pc->sendStop = true;
|
||||||
}
|
}
|
||||||
@ -270,25 +270,25 @@ void CPregameServer::sendPack(CConnection * pc, const CPackForSelectionScreen &
|
|||||||
|
|
||||||
void CPregameServer::processPack(CPackForSelectionScreen * pack)
|
void CPregameServer::processPack(CPackForSelectionScreen * pack)
|
||||||
{
|
{
|
||||||
if(dynamic_cast<CPregamePackToHost*>(pack))
|
if(dynamic_ptr_cast<CPregamePackToHost>(pack))
|
||||||
{
|
{
|
||||||
sendPack(host, *pack);
|
sendPack(host, *pack);
|
||||||
}
|
}
|
||||||
else if(SelectMap *sm = dynamic_cast<SelectMap*>(pack))
|
else if(SelectMap *sm = dynamic_ptr_cast<SelectMap>(pack))
|
||||||
{
|
{
|
||||||
vstd::clear_pointer(curmap);
|
vstd::clear_pointer(curmap);
|
||||||
curmap = sm->mapInfo;
|
curmap = sm->mapInfo;
|
||||||
sm->free = false;
|
sm->free = false;
|
||||||
announcePack(*pack);
|
announcePack(*pack);
|
||||||
}
|
}
|
||||||
else if(UpdateStartOptions *uso = dynamic_cast<UpdateStartOptions*>(pack))
|
else if(UpdateStartOptions *uso = dynamic_ptr_cast<UpdateStartOptions>(pack))
|
||||||
{
|
{
|
||||||
vstd::clear_pointer(curStartInfo);
|
vstd::clear_pointer(curStartInfo);
|
||||||
curStartInfo = uso->options;
|
curStartInfo = uso->options;
|
||||||
uso->free = false;
|
uso->free = false;
|
||||||
announcePack(*pack);
|
announcePack(*pack);
|
||||||
}
|
}
|
||||||
else if(dynamic_cast<const StartWithCurrentSettings*>(pack))
|
else if(dynamic_ptr_cast<StartWithCurrentSettings>(pack))
|
||||||
{
|
{
|
||||||
state = ENDING_AND_STARTING_GAME;
|
state = ENDING_AND_STARTING_GAME;
|
||||||
announcePack(*pack);
|
announcePack(*pack);
|
||||||
|
@ -209,7 +209,7 @@ bool SetFormation::applyGh( CGameHandler *gh )
|
|||||||
bool HireHero::applyGh( CGameHandler *gh )
|
bool HireHero::applyGh( CGameHandler *gh )
|
||||||
{
|
{
|
||||||
const CGObjectInstance *obj = gh->getObj(tid);
|
const CGObjectInstance *obj = gh->getObj(tid);
|
||||||
const CGTownInstance *town = dynamic_cast<const CGTownInstance *>(obj);
|
const CGTownInstance *town = dynamic_ptr_cast<CGTownInstance>(obj);
|
||||||
if(town && PlayerRelations::ENEMIES == gh->getPlayerRelations(obj->tempOwner, gh->getPlayerAt(c)))
|
if(town && PlayerRelations::ENEMIES == gh->getPlayerRelations(obj->tempOwner, gh->getPlayerAt(c)))
|
||||||
COMPLAIN_AND_RETURN("Can't buy hero in enemy town!");
|
COMPLAIN_AND_RETURN("Can't buy hero in enemy town!");
|
||||||
|
|
||||||
|
@ -8,3 +8,31 @@
|
|||||||
#include <boost/random/mersenne_twister.hpp>
|
#include <boost/random/mersenne_twister.hpp>
|
||||||
#include <boost/random/variate_generator.hpp>
|
#include <boost/random/variate_generator.hpp>
|
||||||
#include <boost/system/system_error.hpp>
|
#include <boost/system/system_error.hpp>
|
||||||
|
|
||||||
|
template<class T, class F>
|
||||||
|
inline const T * dynamic_ptr_cast(const F * ptr)
|
||||||
|
{
|
||||||
|
#ifndef __APPLE__
|
||||||
|
return dynamic_cast<const T*>(ptr);
|
||||||
|
#else
|
||||||
|
if (!strcmp(typeid(*ptr).name(), typeid(T).name()))
|
||||||
|
{
|
||||||
|
return static_cast<const T*>(ptr);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class F>
|
||||||
|
inline T * dynamic_ptr_cast(F * ptr)
|
||||||
|
{
|
||||||
|
#ifndef __APPLE__
|
||||||
|
return dynamic_cast<T*>(ptr);
|
||||||
|
#else
|
||||||
|
if (!strcmp(typeid(*ptr).name(), typeid(T).name()))
|
||||||
|
{
|
||||||
|
return static_cast<T*>(ptr);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user