mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* Client is able to await for answers for multiple queries at the same time
* Hackish solution allowing AI undertaking actions from event-handling thread * Fixed crash when death stare or acid breath activated on stack that was just killed * minor fixes
This commit is contained in:
parent
a3f36ccc71
commit
13f26fc3cb
@ -793,7 +793,7 @@ void VCAI::heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16
|
||||
NET_EVENT_HANDLER;
|
||||
LOG_ENTRY;
|
||||
status.addQuery();
|
||||
callback(0);
|
||||
requestActionASAP(boost::bind(callback, 0));
|
||||
}
|
||||
|
||||
void VCAI::showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, const int soundID, bool selection, bool cancel)
|
||||
@ -809,7 +809,10 @@ void VCAI::showBlockingDialog(const std::string &text, const std::vector<Compone
|
||||
if(!selection && cancel) //yes&no -> always answer yes, we are a brave AI :)
|
||||
sel = 1;
|
||||
|
||||
cb->selectionMade(sel, askID);
|
||||
requestActionASAP([&]()
|
||||
{
|
||||
cb->selectionMade(sel, askID);
|
||||
});
|
||||
}
|
||||
|
||||
void VCAI::showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd)
|
||||
@ -819,8 +822,11 @@ void VCAI::showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *do
|
||||
status.addQuery();
|
||||
|
||||
//you can't request action from action-response thread
|
||||
//pickBestCreatures (down, up);
|
||||
onEnd();
|
||||
requestActionASAP([=,this]()
|
||||
{
|
||||
pickBestCreatures (down, up);
|
||||
onEnd();
|
||||
});
|
||||
}
|
||||
|
||||
void VCAI::serialize(COSer<CSaveFile> &h, const int version)
|
||||
@ -1352,6 +1358,7 @@ bool VCAI::moveHeroToTile(int3 dst, const CGHeroInstance * h)
|
||||
if(h->tempOwner != playerID) //we lost hero
|
||||
{
|
||||
remove_if_present(lockedHeroes, h);
|
||||
throw std::runtime_error("Hero was lost!"); //we need to throw, otherwise hero will be assigned to sth again
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1653,7 +1660,15 @@ void VCAI::performTypicalActions()
|
||||
INDENT;
|
||||
makePossibleUpgrades(h);
|
||||
cb->setSelection(h);
|
||||
wander(h);
|
||||
try
|
||||
{
|
||||
wander(h);
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
BNLOG("Cannot use this hero anymore, received exception: %s", e.what());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1787,6 +1802,20 @@ void VCAI::finish()
|
||||
makingTurn->interrupt();
|
||||
}
|
||||
|
||||
void VCAI::requestActionASAP(boost::function<void()> whatToDo)
|
||||
{
|
||||
boost::barrier b(2);
|
||||
boost::thread newThread([&b,this,whatToDo]()
|
||||
{
|
||||
setThreadName(-1, "VCAI::requestActionASAP::helper");
|
||||
SET_GLOBAL_STATE(this);
|
||||
boost::shared_lock<boost::shared_mutex> gsLock(cb->getGsMutex());
|
||||
b.wait();
|
||||
whatToDo();
|
||||
});
|
||||
b.wait();
|
||||
}
|
||||
|
||||
AIStatus::AIStatus()
|
||||
{
|
||||
battle = NO_BATTLE;
|
||||
|
@ -284,6 +284,9 @@ public:
|
||||
const CGHeroInstance *primaryHero() const;
|
||||
TResources estimateIncome() const;
|
||||
bool containsSavedRes(const TResources &cost) const;
|
||||
|
||||
//special function that can be called ONLY from game events handling thread and will send request ASAP
|
||||
void requestActionASAP(boost::function<void()> whatToDo);
|
||||
};
|
||||
|
||||
|
||||
|
@ -59,7 +59,7 @@ void CCallback::selectionMade(int selection, int asker)
|
||||
{
|
||||
QueryReply pack(asker,selection);
|
||||
pack.player = player;
|
||||
cl->serv->sendPackToServer(pack, player);
|
||||
sendRequest(&pack);
|
||||
}
|
||||
void CCallback::recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount, si32 level/*=-1*/)
|
||||
{
|
||||
@ -222,21 +222,15 @@ int CBattleCallback::battleMakeAction(BattleAction* action)
|
||||
|
||||
void CBattleCallback::sendRequest(const CPack* request)
|
||||
{
|
||||
|
||||
//TODO should be part of CClient (client owns connection, not CB)
|
||||
//but it would have to be very tricky cause template/serialization issues
|
||||
if(waitTillRealize)
|
||||
cl->waitingRequest.set(typeList.getTypeID(request));
|
||||
|
||||
cl->serv->sendPackToServer(*request, player);
|
||||
|
||||
int requestID = cl->sendRequest(request, player);
|
||||
if(waitTillRealize)
|
||||
{
|
||||
tlog5 << boost::format("We'll wait till request %d is answered.\n") % requestID;
|
||||
unique_ptr<vstd::unlock_shared_guard> unlocker; //optional, if flag set
|
||||
if(unlockGsWhenWaiting)
|
||||
unlocker = make_unique<vstd::unlock_shared_guard>(vstd::makeUnlockSharedGuard(getGsMutex()));
|
||||
unlocker = make_unique<vstd::unlock_shared_guard>(getGsMutex());
|
||||
|
||||
cl->waitingRequest.waitWhileTrue();
|
||||
cl->waitingRequest.waitWhileContains(requestID);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,13 +96,11 @@ void CClient::init()
|
||||
}
|
||||
|
||||
CClient::CClient(void)
|
||||
:waitingRequest(0)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
CClient::CClient(CConnection *con, StartInfo *si)
|
||||
:waitingRequest(0)
|
||||
{
|
||||
init();
|
||||
newGame(con,si);
|
||||
@ -121,7 +119,7 @@ void CClient::waitForMoveAndSend(int color)
|
||||
assert(vstd::contains(battleints, color));
|
||||
BattleAction ba = battleints[color]->activeStack(gs->curB->getStack(gs->curB->activeStack, false));
|
||||
MakeAction temp_action(ba);
|
||||
serv->sendPackToServer(temp_action, color);
|
||||
sendRequest(&temp_action, color);
|
||||
return;
|
||||
}
|
||||
catch(boost::thread_interrupted&)
|
||||
@ -175,7 +173,7 @@ void CClient::save(const std::string & fname)
|
||||
}
|
||||
|
||||
SaveGame save_game(fname);
|
||||
serv->sendPackToServer((CPackForClient&)save_game, getCurrentPlayer());
|
||||
sendRequest((CPackForClient*)&save_game, 255);
|
||||
}
|
||||
|
||||
void CClient::endGame( bool closeConnection /*= true*/ )
|
||||
@ -530,7 +528,7 @@ void CClient::stopConnection()
|
||||
tlog0 << "Connection has been requested to be closed.\n";
|
||||
boost::unique_lock<boost::mutex>(*serv->wmx);
|
||||
CloseServer close_server;
|
||||
serv->sendPackToServer(close_server, 255);
|
||||
sendRequest(&close_server, 255);
|
||||
tlog0 << "Sent closing signal to the server\n";
|
||||
}
|
||||
|
||||
@ -599,7 +597,7 @@ void CClient::commitPackage( CPackForClient *pack )
|
||||
CommitPackage cp;
|
||||
cp.freePack = false;
|
||||
cp.packToCommit = pack;
|
||||
serv->sendPackToServer(cp, 255);
|
||||
sendRequest(&cp, 255);
|
||||
}
|
||||
|
||||
int CClient::getLocalPlayer() const
|
||||
@ -625,7 +623,7 @@ void CClient::commenceTacticPhaseForInt(CBattleGameInterface *battleInt)
|
||||
if(gs && !!gs->curB && gs->curB->tacticDistance) //while awaiting for end of tactics phase, many things can happen (end of battle... or game)
|
||||
{
|
||||
MakeAction ma(BattleAction::makeEndOFTacticPhase(battleInt->playerID));
|
||||
serv->sendPackToServer(ma, battleInt->playerID);
|
||||
sendRequest(&ma, battleInt->playerID);
|
||||
}
|
||||
} HANDLE_EXCEPTION
|
||||
}
|
||||
@ -636,6 +634,19 @@ void CClient::invalidatePaths(const CGHeroInstance *h /*= NULL*/)
|
||||
pathInfo->isValid = false;
|
||||
}
|
||||
|
||||
int CClient::sendRequest(const CPack *request, int player)
|
||||
{
|
||||
static ui32 requestCounter = 0;
|
||||
|
||||
ui32 requestID = requestCounter++;
|
||||
tlog5 << boost::format("Sending a request \"%s\". It'll have an ID=%d.\n")
|
||||
% typeid(*request).name() % requestID;
|
||||
|
||||
waitingRequest.pushBack(requestID);
|
||||
serv->sendPackToServer(*request, player, requestID);
|
||||
return requestID;
|
||||
}
|
||||
|
||||
template void CClient::serialize( CISer<CLoadFile> &h, const int version );
|
||||
template void CClient::serialize( COSer<CSaveFile> &h, const int version );
|
||||
|
||||
|
@ -56,6 +56,58 @@ public:
|
||||
~CServerHandler();
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class ThreadSafeVector
|
||||
{
|
||||
typedef std::vector<T> TVector;
|
||||
typedef boost::unique_lock<boost::mutex> TLock;
|
||||
TVector items;
|
||||
boost::mutex mx;
|
||||
boost::condition_variable cond;
|
||||
|
||||
public:
|
||||
|
||||
void pushBack(const T &item)
|
||||
{
|
||||
TLock lock(mx);
|
||||
items.push_back(item);
|
||||
cond.notify_all();
|
||||
}
|
||||
|
||||
// //to access list, caller must present a lock used to lock mx
|
||||
// TVector &getList(TLock &lockedLock)
|
||||
// {
|
||||
// assert(lockedLock.owns_lock() && lockedLock.mutex() == &mx);
|
||||
// return items;
|
||||
// }
|
||||
|
||||
TLock getLock()
|
||||
{
|
||||
return TLock(mx);
|
||||
}
|
||||
|
||||
void waitWhileContains(const T &item)
|
||||
{
|
||||
auto lock = getLock();
|
||||
while(vstd::contains(items, item))
|
||||
cond.wait(lock);
|
||||
}
|
||||
|
||||
bool tryRemovingElement(const T&item) //returns false if element was not present
|
||||
{
|
||||
auto lock = getLock();
|
||||
auto itr = vstd::find(items, item);
|
||||
if(itr == items.end()) //not in container
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
items.erase(itr);
|
||||
cond.notify_all();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/// Class which handles client - server logic
|
||||
class CClient : public IGameCallback
|
||||
{
|
||||
@ -75,7 +127,7 @@ public:
|
||||
|
||||
CScriptingModule *erm;
|
||||
|
||||
CondSh<int> waitingRequest;
|
||||
ThreadSafeVector<int> waitingRequest;
|
||||
|
||||
std::queue<CPack *> packs;
|
||||
boost::mutex packsM;
|
||||
@ -162,6 +214,8 @@ public:
|
||||
friend class CBattleCallback; //handling players actions
|
||||
friend void processCommand(const std::string &message, CClient *&client); //handling console
|
||||
|
||||
int sendRequest(const CPack *request, int player); //returns ID given to that request
|
||||
|
||||
void handlePack( CPack * pack ); //applies the given pack and deletes it
|
||||
void battleStarted(const BattleInfo * info);
|
||||
void commenceTacticPhaseForInt(CBattleGameInterface *battleInt); //will be called as separate thread
|
||||
|
@ -717,9 +717,7 @@ void EndAction::applyCl( CClient *cl )
|
||||
void PackageApplied::applyCl( CClient *cl )
|
||||
{
|
||||
INTERFACE_CALL_IF_PRESENT(player, requestRealized, this);
|
||||
if(cl->waitingRequest.get() == packType)
|
||||
cl->waitingRequest.setn(false);
|
||||
else if(cl->waitingRequest.get())
|
||||
if(!cl->waitingRequest.tryRemovingElement(requestID))
|
||||
tlog3 << "Surprising server message!\n";
|
||||
}
|
||||
|
||||
|
@ -240,11 +240,11 @@ CPack * CConnection::retreivePack()
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CConnection::sendPackToServer(const CPack &pack, ui8 player)
|
||||
void CConnection::sendPackToServer(const CPack &pack, ui8 player, ui32 requestID)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(*wmx);
|
||||
tlog5 << "Sending to server a pack of type " << typeid(pack).name() << std::endl;
|
||||
*this << player << &pack; //packs has to be sent as polymorphic pointers!
|
||||
*this << player << requestID << &pack; //packs has to be sent as polymorphic pointers!
|
||||
}
|
||||
|
||||
CSaveFile::CSaveFile( const std::string &fname )
|
||||
|
@ -916,7 +916,7 @@ public:
|
||||
~CConnection(void);
|
||||
|
||||
CPack *retreivePack(); //gets from server next pack (allocates it with new)
|
||||
void sendPackToServer(const CPack &pack, ui8 player);
|
||||
void sendPackToServer(const CPack &pack, ui8 player, ui32 requestID);
|
||||
};
|
||||
|
||||
DLL_LINKAGE std::ostream &operator<<(std::ostream &str, const CConnection &cpc);
|
||||
|
@ -172,11 +172,12 @@ struct PackageApplied : public CPackForClient //94
|
||||
|
||||
ui8 result; //0 - something went wrong, request hasn't been realized; 1 - OK
|
||||
ui32 packType; //type id of applied package
|
||||
ui32 requestID; //an ID given by client to the request that was applied
|
||||
ui8 player;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & result & packType & player;
|
||||
h & result & packType & requestID & player;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -627,29 +627,36 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
{
|
||||
setThreadName(-1, "CGameHandler::handleConnection");
|
||||
srand(time(NULL));
|
||||
CPack *pack = NULL;
|
||||
ui8 player = 255;
|
||||
|
||||
try
|
||||
{
|
||||
while(1)//server should never shut connection first //was: while(!end2)
|
||||
{
|
||||
CPack *pack = NULL;
|
||||
ui8 player = 255;
|
||||
si32 requestID = -999;
|
||||
int packType = 0;
|
||||
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(*c.rmx);
|
||||
c >> player >> pack; //get the package
|
||||
tlog5 << "Received client message of type " << typeid(*pack).name() << std::endl;
|
||||
c >> player >> requestID >> pack; //get the package
|
||||
packType = typeList.getTypeID(pack); //get the id of type
|
||||
|
||||
tlog5 << boost::format("Received client message (request %d by player %d) of type with ID=%d (%s).\n")
|
||||
% requestID % player % packType % typeid(*pack).name();
|
||||
}
|
||||
|
||||
int packType = typeList.getTypeID(pack); //get the id of type
|
||||
//prepare struct informing that action was applied
|
||||
PackageApplied applied;
|
||||
applied.player = player;
|
||||
applied.result = false;
|
||||
applied.packType = packType;
|
||||
applied.requestID = requestID;
|
||||
|
||||
CBaseForGHApply *apply = applier->apps[packType]; //and appropriae applier object
|
||||
if(packType != typeList.getTypeID<QueryReply>()
|
||||
&& (packType != typeList.getTypeID<ArrangeStacks>() || !isAllowedArrangePack((ArrangeStacks*)pack)) // for dialogs like garrison
|
||||
&& states.getQueriesCount(player))
|
||||
if(isBlockedByQueries(pack, packType, player))
|
||||
{
|
||||
complain(boost::str(boost::format("Player %d has to answer queries before attempting any further actions (count=%d)!") % (int)player % states.getQueriesCount(player)));
|
||||
PackageApplied applied;
|
||||
applied.player = player;
|
||||
applied.result = false;
|
||||
applied.packType = packType;
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(*c.wmx);
|
||||
c << &applied;
|
||||
@ -661,10 +668,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
tlog5 << "Message successfully applied (result=" << result << ")!\n";
|
||||
|
||||
//send confirmation that we've applied the package
|
||||
PackageApplied applied;
|
||||
applied.player = player;
|
||||
applied.result = result;
|
||||
applied.packType = packType;
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(*c.wmx);
|
||||
c << &applied;
|
||||
@ -674,9 +678,8 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
{
|
||||
tlog1 << "Message cannot be applied, cannot find applier (unregistered type)!\n";
|
||||
}
|
||||
delete pack;
|
||||
pack = NULL;
|
||||
player = 255;
|
||||
|
||||
vstd::clear_pointer(pack);
|
||||
}
|
||||
}
|
||||
catch(boost::system::system_error &e) //for boost errors just log, not crash - probably client shut down connection
|
||||
@ -4793,6 +4796,12 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
|
||||
const CStack * attacker = gs->curB->getStack(bat.stackAttacking);
|
||||
attackCasting(bat, Bonus::SPELL_AFTER_ATTACK, attacker);
|
||||
|
||||
if(bat.bsa[0].newAmount <= 0)
|
||||
{
|
||||
//don't try death stare or acid breath on dead stack (crash!)
|
||||
return;
|
||||
}
|
||||
|
||||
if (attacker->hasBonusOfType(Bonus::DEATH_STARE)) // spell id 79
|
||||
{
|
||||
int staredCreatures = 0;
|
||||
@ -4815,6 +4824,7 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
|
||||
!attacker->attackerOwned, attacker->owner, NULL, NULL, staredCreatures, ECastingMode::AFTER_ATTACK_CASTING, attacker);
|
||||
}
|
||||
}
|
||||
|
||||
int acidDamage = 0;
|
||||
TBonusListPtr acidBreath = attacker->getBonuses(Selector::type(Bonus::ACID_BREATH));
|
||||
BOOST_FOREACH(const Bonus *b, *acidBreath)
|
||||
@ -5621,6 +5631,22 @@ void CGameHandler::spawnWanderingMonsters(int creatureID)
|
||||
}
|
||||
}
|
||||
|
||||
bool CGameHandler::isBlockedByQueries(const CPack *pack, int packType, ui8 player)
|
||||
{
|
||||
//it's always legal to send query reply (we'll check later if it makes sense)
|
||||
if(packType == typeList.getTypeID<QueryReply>())
|
||||
return false;
|
||||
|
||||
if(packType == typeList.getTypeID<ArrangeStacks>() && isAllowedArrangePack((const ArrangeStacks*)pack))
|
||||
return false;
|
||||
|
||||
//if there are no queries, nothing is blocking
|
||||
if(states.getQueriesCount(player) == 0)
|
||||
return false;
|
||||
|
||||
return true; //block package
|
||||
}
|
||||
|
||||
CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleInfo *bat)
|
||||
{
|
||||
int color = army->tempOwner;
|
||||
|
@ -98,6 +98,7 @@ public:
|
||||
std::map<ui32, boost::function<void()> > garrisonCallbacks; //query id => callback - for garrison dialogs
|
||||
std::map<ui32, std::pair<si32,si32> > allowedExchanges;
|
||||
|
||||
bool isBlockedByQueries(const CPack *pack, int packType, ui8 player);
|
||||
bool isAllowedExchange(int id1, int id2);
|
||||
bool isAllowedArrangePack(const ArrangeStacks *pack);
|
||||
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
|
||||
|
@ -62,17 +62,12 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)_VC9\</IntDir>
|
||||
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)_VC9\</IntDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">..\..\RD</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">$(Configuration)_VC9\</IntDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">G:\Programowanie\VCMI\RD</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">$(SolutionDir)$(Configuration)\bin\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='RD|x64'">$(SolutionDir)$(Configuration)\bin\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">$(Configuration)\</IntDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='RD|x64'">$(Configuration)\</IntDir>
|
||||
@ -112,8 +107,8 @@
|
||||
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>VCMI_lib.lib;zdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>../..;../../libs;../;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>VCMI_lib.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
@ -160,14 +155,13 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>VCMI_lib.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>G:\Programowanie\VCMI\libs;$(OutDir);G:\Programowanie\VCMI\RD;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<Profile>true</Profile>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RD|x64'">
|
||||
@ -178,7 +172,7 @@
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>false</OmitFramePointers>
|
||||
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
|
||||
<AdditionalIncludeDirectories>F:\Programowanie\VCMI\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||
@ -191,12 +185,13 @@
|
||||
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>VCMI_lib.lib;zdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>F:\Programowanie\VCMI\libs;F:\Programowanie\VCMI\RD;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>VCMI_lib.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<Profile>true</Profile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
@ -220,7 +215,6 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\lib\VCMI_lib.vcxproj">
|
||||
<Project>{b952ffc5-3039-4de1-9f08-90acda483d8f}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
Loading…
Reference in New Issue
Block a user