1
0
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:
Michał W. Urbańczyk 2011-02-23 03:57:45 +00:00
parent 9d313d3d2c
commit cab8f9e11d
13 changed files with 64 additions and 32 deletions

View File

@ -32,4 +32,9 @@ extern "C" DLL_F_EXPORT CGlobalAI* GetNewAI()
extern "C" DLL_F_EXPORT void ReleaseAI(CGlobalAI* i)
{
delete (CGeniusAI*)i;
}
extern "C" DLL_F_EXPORT CBattleGameInterface* GetNewBattleAI()
{
return new CGeniusAI();
}

View File

@ -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);

View File

@ -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 )

View File

@ -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)
{

View File

@ -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()

View File

@ -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!")]));

View File

@ -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

View File

@ -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);

View File

@ -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
{

View File

@ -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__

View File

@ -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;

View File

@ -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)

View File

@ -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