mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
AI for neutral creatures and battles and player AIs can be different. StupidAI will handle neutrals by default.
Fixes for issues with deserialization and handling Tactics secondary skill.
This commit is contained in:
parent
9d313d3d2c
commit
cab8f9e11d
@ -33,3 +33,8 @@ extern "C" DLL_F_EXPORT void ReleaseAI(CGlobalAI* i)
|
||||
{
|
||||
delete (CGeniusAI*)i;
|
||||
}
|
||||
|
||||
extern "C" DLL_F_EXPORT CBattleGameInterface* GetNewBattleAI()
|
||||
{
|
||||
return new CGeniusAI();
|
||||
}
|
@ -551,7 +551,7 @@ TStacks CBattleCallback::battleGetStacks(EStackOwnership whose /*= MINE_AND_ENEM
|
||||
|
||||
BOOST_FOREACH(const CStack *s, gs->curB->stacks)
|
||||
{
|
||||
bool ownerMatches = whose == MINE_AND_ENEMY || whose == ONLY_MINE && s->owner == player;
|
||||
bool ownerMatches = whose == MINE_AND_ENEMY || whose == ONLY_MINE && s->owner == player || whose == ONLY_ENEMY && s->owner != player;
|
||||
bool alivenessMatches = s->alive() || !onlyAlive;
|
||||
if(ownerMatches && alivenessMatches)
|
||||
ret.push_back(s);
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
template<typename rett>
|
||||
rett * createAnyAI(CCallback * cb, std::string dllname, std::string methodName)
|
||||
rett * createAnyAI(std::string dllname, std::string methodName)
|
||||
{
|
||||
char temp[50];
|
||||
rett * ret=NULL;
|
||||
@ -62,14 +62,14 @@ rett * createAnyAI(CCallback * cb, std::string dllname, std::string methodName)
|
||||
return ret;
|
||||
}
|
||||
|
||||
CGlobalAI * CAIHandler::getNewAI(CCallback * cb, std::string dllname)
|
||||
CGlobalAI * CAIHandler::getNewAI(std::string dllname)
|
||||
{
|
||||
return createAnyAI<CGlobalAI>(cb, dllname, "GetNewAI");
|
||||
return createAnyAI<CGlobalAI>(dllname, "GetNewAI");
|
||||
}
|
||||
|
||||
CBattleGameInterface * CAIHandler::getNewBattleAI( CCallback * cb, std::string dllname )
|
||||
CBattleGameInterface * CAIHandler::getNewBattleAI(std::string dllname )
|
||||
{
|
||||
return createAnyAI<CBattleGameInterface>(cb, dllname, "GetNewBattleAI");
|
||||
return createAnyAI<CBattleGameInterface>(dllname, "GetNewBattleAI");
|
||||
}
|
||||
|
||||
BattleAction CGlobalAI::activeStack( const CStack * stack )
|
||||
|
@ -153,8 +153,8 @@ public:
|
||||
class CAIHandler
|
||||
{
|
||||
public:
|
||||
static CGlobalAI * getNewAI(CCallback * cb, std::string dllname);
|
||||
static CBattleGameInterface * getNewBattleAI(CCallback * cb, std::string dllname);
|
||||
static CGlobalAI * getNewAI(std::string dllname);
|
||||
static CBattleGameInterface * getNewBattleAI(std::string dllname);
|
||||
};
|
||||
class CGlobalAI : public CGameInterface // AI class (to derivate)
|
||||
{
|
||||
|
@ -3334,6 +3334,9 @@ void CBattleInterface::endAction(const BattleAction* action)
|
||||
}
|
||||
|
||||
queue->update();
|
||||
|
||||
if(tacticsMode) //we have activated next stack after sending request that has been just realized -> blockmap due to movement has changed
|
||||
redrawBackgroundWithHexes(activeStack);
|
||||
}
|
||||
|
||||
void CBattleInterface::hideQueue()
|
||||
@ -3461,9 +3464,11 @@ void CBattleInterface::waitForAnims()
|
||||
|
||||
void CBattleInterface::bEndTacticPhase()
|
||||
{
|
||||
btactEnd->block(true);
|
||||
bDefence->block(false);
|
||||
bWait->block(false);
|
||||
BattleAction endt = BattleAction::makeEndOFTacticPhase(curInt->cb->battleGetMySide());
|
||||
curInt->cb->battleMakeTacticAction(&endt);
|
||||
btactEnd->block(true);
|
||||
}
|
||||
|
||||
void CBattleInterface::bTacticNextStack()
|
||||
|
@ -210,7 +210,8 @@ struct SettingsGrammar : public grammar<SettingsGrammar>
|
||||
| str_p("localInformation=") >> (uint_p[assign_a(conf.cc.localInformation)] | eps_p[lerror("Wrong localInformation!")])
|
||||
| str_p("fullscreen=") >> (uint_p[assign_a(conf.cc.fullscreen)] | eps_p[lerror("Wrong fullscreen!")])
|
||||
| str_p("server=") >> ( ( +digit_p >> *('.' >> +digit_p) )[assign_a(conf.cc.server)] | eps_p[lerror("Wrong server!")])
|
||||
| str_p("defaultAI=") >> ((+(anychar_p - ';'))[assign_a(conf.cc.defaultAI)] | eps_p[lerror("Wrong defaultAI!")])
|
||||
| str_p("defaultPlayerAI=") >> ((+(anychar_p - ';'))[assign_a(conf.cc.defaultPlayerAI)] | eps_p[lerror("Wrong defaultAI!")])
|
||||
| str_p("neutralBattleAI=") >> ((+(anychar_p - ';'))[assign_a(conf.cc.defaultBattleAI)] | eps_p[lerror("Wrong defaultAI!")])
|
||||
| (+(anychar_p - '}'))[lerror2("Unrecognized client option: ")]
|
||||
;
|
||||
clientOptionsSequence = *(clientOption >> (';' | eps_p[lerror("Semicolon lacking after client option!")]));
|
||||
|
@ -23,7 +23,7 @@ namespace config
|
||||
int pregameResx, pregameResy; //real screen resolution of preGame
|
||||
int port, localInformation;
|
||||
std::string server, //server address (e.g. 127.0.0.1)
|
||||
defaultAI; //dll name
|
||||
defaultPlayerAI, defaultBattleAI; //dll names
|
||||
};
|
||||
|
||||
struct ButtonInfo
|
||||
|
@ -398,7 +398,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
CCallback *cb = new CCallback(gs,color,this);
|
||||
if(!it->second.human)
|
||||
{
|
||||
playerint[color] = static_cast<CGameInterface*>(CAIHandler::getNewAI(cb,conf.cc.defaultAI));
|
||||
playerint[color] = static_cast<CGameInterface*>(CAIHandler::getNewAI(conf.cc.defaultPlayerAI));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -412,7 +412,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
else
|
||||
{
|
||||
CBattleCallback * cbc = new CBattleCallback(gs, color, this);
|
||||
battleints[color] = CAIHandler::getNewBattleAI(cb,"StupidAI");
|
||||
battleints[color] = CAIHandler::getNewBattleAI("StupidAI");
|
||||
battleints[color]->init(cbc);
|
||||
}
|
||||
}
|
||||
@ -428,9 +428,10 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
}
|
||||
else
|
||||
{
|
||||
playerint[255] = CAIHandler::getNewAI(cb,conf.cc.defaultAI);
|
||||
playerint[255]->init(new CCallback(gs,255,this));
|
||||
battleints[255] = playerint[255];
|
||||
battleints[255] = CAIHandler::getNewBattleAI(conf.cc.defaultBattleAI);
|
||||
battleints[255]->init(new CBattleCallback(gs, 255, this));
|
||||
// playerint[255]->init(new CCallback(gs,255,this));
|
||||
// battleints[255] = playerint[255];
|
||||
}
|
||||
|
||||
serv->addStdVecItems(const_cast<CGameInfo*>(CGI)->state);
|
||||
@ -465,16 +466,27 @@ void CClient::serialize( Handler &h, const int version )
|
||||
ui8 pid;
|
||||
h & pid & dllname;
|
||||
|
||||
CCallback *callback = new CCallback(gs,pid,this);
|
||||
callbacks.insert(callback);
|
||||
|
||||
CGameInterface *nInt = NULL;
|
||||
|
||||
|
||||
if(dllname.length())
|
||||
nInt = CAIHandler::getNewAI(callback,dllname);
|
||||
{
|
||||
if(pid == 255)
|
||||
{
|
||||
CBattleCallback * cbc = new CBattleCallback(gs, pid, this);
|
||||
CBattleGameInterface *cbgi = CAIHandler::getNewBattleAI(dllname);
|
||||
battleints[pid] = cbgi;
|
||||
cbgi->init(cb);
|
||||
//TODO? consider serialization
|
||||
continue;
|
||||
}
|
||||
else
|
||||
nInt = CAIHandler::getNewAI(dllname);
|
||||
}
|
||||
else
|
||||
nInt = new CPlayerInterface(pid);
|
||||
|
||||
CCallback *callback = new CCallback(gs,pid,this);
|
||||
callbacks.insert(callback);
|
||||
battleints[pid] = playerint[pid] = nInt;
|
||||
nInt->init(callback);
|
||||
nInt->serialize(h, version);
|
||||
|
@ -10,7 +10,8 @@ clientSettings
|
||||
fullscreen=0; //0 - windowed mode, 1 - fullscreen
|
||||
server=127.0.0.1; //use 127.0.0.1 for localhost
|
||||
localInformation=2; //0 - *all* information sent from server (safest and slowest); 1 - map information sent from server; 2 - all information local-storaged
|
||||
defaultAI=GeniusAI;
|
||||
defaultPlayerAI=GeniusAI;
|
||||
neutralBattleAI=StupidAI;
|
||||
}
|
||||
GUISettings
|
||||
{
|
||||
|
2
global.h
2
global.h
@ -685,6 +685,6 @@ static inline ui32 read_unaligned_u32(const void *p)
|
||||
#define OVERRIDE //is there any working counterpart?
|
||||
#endif
|
||||
|
||||
#define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving) deserializationFix();
|
||||
#define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving && h.smartPointerSerialization) deserializationFix();
|
||||
|
||||
#endif // __GLOBAL_H__
|
||||
|
@ -145,7 +145,6 @@ public:
|
||||
|
||||
PlayerState();
|
||||
std::string nodeName() const OVERRIDE;
|
||||
void deserializationFix();
|
||||
|
||||
//override
|
||||
//void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
|
||||
@ -371,6 +370,7 @@ public:
|
||||
{
|
||||
loadTownDInfos();
|
||||
}
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
}
|
||||
|
||||
friend class CCallback;
|
||||
|
@ -386,10 +386,7 @@ void CBonusSystemNode::addNewBonus(Bonus *b)
|
||||
{
|
||||
assert(!vstd::contains(exportedBonuses,b));
|
||||
exportedBonuses.push_back(b);
|
||||
if(b->propagator)
|
||||
propagateBonus(b);
|
||||
else
|
||||
bonuses.push_back(b);
|
||||
exportBonus(b);
|
||||
}
|
||||
|
||||
void CBonusSystemNode::removeBonus(Bonus *b)
|
||||
@ -478,7 +475,8 @@ std::string CBonusSystemNode::nodeName() const
|
||||
|
||||
void CBonusSystemNode::deserializationFix()
|
||||
{
|
||||
tlog2 << "Deserialization fix called on bare CBSN? Shouldn't be...\n";
|
||||
BOOST_FOREACH(Bonus *b, exportedBonuses)
|
||||
exportBonus(b);
|
||||
}
|
||||
|
||||
void CBonusSystemNode::getRedParents(TNodes &out)
|
||||
@ -567,6 +565,14 @@ void CBonusSystemNode::battleTurnPassed()
|
||||
}
|
||||
}
|
||||
|
||||
void CBonusSystemNode::exportBonus(Bonus * b)
|
||||
{
|
||||
if(b->propagator)
|
||||
propagateBonus(b);
|
||||
else
|
||||
bonuses.push_back(b);
|
||||
}
|
||||
|
||||
int NBonus::valOf(const CBonusSystemNode *obj, Bonus::BonusType type, int subtype /*= -1*/)
|
||||
{
|
||||
if(obj)
|
||||
|
@ -55,6 +55,7 @@ namespace PrimarySkill
|
||||
BONUS_NAME(EARTH_SPELL_DMG_PREMY) \
|
||||
BONUS_NAME(FIRE_SPELL_DMG_PREMY) \
|
||||
BONUS_NAME(WATER_SPELL_DMG_PREMY) \
|
||||
BONUS_NAME(BLOCK_SPELLS_ABOVE_LEVEL) \
|
||||
BONUS_NAME(WATER_WALKING) /*subtype 1 - without penalty, 2 - with penalty*/ \
|
||||
BONUS_NAME(NO_SHOTING_PENALTY) /* duplicates NO_DISTANCE_PENALTY or FREE_SHOOTHING?*/\
|
||||
BONUS_NAME(NEGATE_ALL_NATURAL_IMMUNITIES) \
|
||||
@ -253,7 +254,7 @@ struct DLL_EXPORT Bonus
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & duration & type & subtype & source & val & sid & description & additionalInfo & turnsRemain & valType & effectRange & limiter;
|
||||
h & duration & type & subtype & source & val & sid & description & additionalInfo & turnsRemain & valType & effectRange & limiter & propagator;
|
||||
}
|
||||
|
||||
static bool OneDay(const Bonus *hb)
|
||||
@ -448,15 +449,16 @@ public:
|
||||
void popBonuses(const CSelector &s);
|
||||
virtual std::string nodeName() const;
|
||||
void deserializationFix();
|
||||
void exportBonus(Bonus * b);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & bonuses & nodeType;
|
||||
h & /*bonuses & */nodeType;
|
||||
h & exportedBonuses;
|
||||
h & description;
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
//h & parents & children;
|
||||
}
|
||||
|
||||
enum ENodeTypes
|
||||
{
|
||||
UNKNOWN, STACK_INSTANCE, STACK_BATTLE, SPECIALITY, ARTIFACT, CREATURE, ARTIFACT_INSTANCE, HERO, PLAYER, TEAM
|
||||
|
Loading…
Reference in New Issue
Block a user