1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-26 22:57:00 +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

@ -33,3 +33,8 @@ extern "C" DLL_F_EXPORT void ReleaseAI(CGlobalAI* i)
{ {
delete (CGeniusAI*)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) 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; bool alivenessMatches = s->alive() || !onlyAlive;
if(ownerMatches && alivenessMatches) if(ownerMatches && alivenessMatches)
ret.push_back(s); ret.push_back(s);

View File

@ -20,7 +20,7 @@
*/ */
template<typename rett> template<typename rett>
rett * createAnyAI(CCallback * cb, std::string dllname, std::string methodName) rett * createAnyAI(std::string dllname, std::string methodName)
{ {
char temp[50]; char temp[50];
rett * ret=NULL; rett * ret=NULL;
@ -62,14 +62,14 @@ rett * createAnyAI(CCallback * cb, std::string dllname, std::string methodName)
return ret; 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 ) BattleAction CGlobalAI::activeStack( const CStack * stack )

View File

@ -153,8 +153,8 @@ public:
class CAIHandler class CAIHandler
{ {
public: public:
static CGlobalAI * getNewAI(CCallback * cb, std::string dllname); static CGlobalAI * getNewAI(std::string dllname);
static CBattleGameInterface * getNewBattleAI(CCallback * cb, std::string dllname); static CBattleGameInterface * getNewBattleAI(std::string dllname);
}; };
class CGlobalAI : public CGameInterface // AI class (to derivate) class CGlobalAI : public CGameInterface // AI class (to derivate)
{ {

View File

@ -3334,6 +3334,9 @@ void CBattleInterface::endAction(const BattleAction* action)
} }
queue->update(); 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() void CBattleInterface::hideQueue()
@ -3461,9 +3464,11 @@ void CBattleInterface::waitForAnims()
void CBattleInterface::bEndTacticPhase() void CBattleInterface::bEndTacticPhase()
{ {
btactEnd->block(true);
bDefence->block(false);
bWait->block(false);
BattleAction endt = BattleAction::makeEndOFTacticPhase(curInt->cb->battleGetMySide()); BattleAction endt = BattleAction::makeEndOFTacticPhase(curInt->cb->battleGetMySide());
curInt->cb->battleMakeTacticAction(&endt); curInt->cb->battleMakeTacticAction(&endt);
btactEnd->block(true);
} }
void CBattleInterface::bTacticNextStack() 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("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("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("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: ")] | (+(anychar_p - '}'))[lerror2("Unrecognized client option: ")]
; ;
clientOptionsSequence = *(clientOption >> (';' | eps_p[lerror("Semicolon lacking after 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 pregameResx, pregameResy; //real screen resolution of preGame
int port, localInformation; int port, localInformation;
std::string server, //server address (e.g. 127.0.0.1) std::string server, //server address (e.g. 127.0.0.1)
defaultAI; //dll name defaultPlayerAI, defaultBattleAI; //dll names
}; };
struct ButtonInfo struct ButtonInfo

View File

@ -398,7 +398,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
CCallback *cb = new CCallback(gs,color,this); CCallback *cb = new CCallback(gs,color,this);
if(!it->second.human) 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 else
{ {
@ -412,7 +412,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
else else
{ {
CBattleCallback * cbc = new CBattleCallback(gs, color, this); CBattleCallback * cbc = new CBattleCallback(gs, color, this);
battleints[color] = CAIHandler::getNewBattleAI(cb,"StupidAI"); battleints[color] = CAIHandler::getNewBattleAI("StupidAI");
battleints[color]->init(cbc); battleints[color]->init(cbc);
} }
} }
@ -428,9 +428,10 @@ void CClient::newGame( CConnection *con, StartInfo *si )
} }
else else
{ {
playerint[255] = CAIHandler::getNewAI(cb,conf.cc.defaultAI); battleints[255] = CAIHandler::getNewBattleAI(conf.cc.defaultBattleAI);
playerint[255]->init(new CCallback(gs,255,this)); battleints[255]->init(new CBattleCallback(gs, 255, this));
battleints[255] = playerint[255]; // playerint[255]->init(new CCallback(gs,255,this));
// battleints[255] = playerint[255];
} }
serv->addStdVecItems(const_cast<CGameInfo*>(CGI)->state); serv->addStdVecItems(const_cast<CGameInfo*>(CGI)->state);
@ -465,16 +466,27 @@ void CClient::serialize( Handler &h, const int version )
ui8 pid; ui8 pid;
h & pid & dllname; h & pid & dllname;
CCallback *callback = new CCallback(gs,pid,this);
callbacks.insert(callback);
CGameInterface *nInt = NULL; CGameInterface *nInt = NULL;
if(dllname.length()) 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 else
nInt = new CPlayerInterface(pid); nInt = new CPlayerInterface(pid);
CCallback *callback = new CCallback(gs,pid,this);
callbacks.insert(callback);
battleints[pid] = playerint[pid] = nInt; battleints[pid] = playerint[pid] = nInt;
nInt->init(callback); nInt->init(callback);
nInt->serialize(h, version); nInt->serialize(h, version);

View File

@ -10,7 +10,8 @@ clientSettings
fullscreen=0; //0 - windowed mode, 1 - fullscreen fullscreen=0; //0 - windowed mode, 1 - fullscreen
server=127.0.0.1; //use 127.0.0.1 for localhost 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 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 GUISettings
{ {

View File

@ -685,6 +685,6 @@ static inline ui32 read_unaligned_u32(const void *p)
#define OVERRIDE //is there any working counterpart? #define OVERRIDE //is there any working counterpart?
#endif #endif
#define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving) deserializationFix(); #define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving && h.smartPointerSerialization) deserializationFix();
#endif // __GLOBAL_H__ #endif // __GLOBAL_H__

View File

@ -145,7 +145,6 @@ public:
PlayerState(); PlayerState();
std::string nodeName() const OVERRIDE; std::string nodeName() const OVERRIDE;
void deserializationFix();
//override //override
//void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const; //void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
@ -371,6 +370,7 @@ public:
{ {
loadTownDInfos(); loadTownDInfos();
} }
BONUS_TREE_DESERIALIZATION_FIX
} }
friend class CCallback; friend class CCallback;

View File

@ -386,10 +386,7 @@ void CBonusSystemNode::addNewBonus(Bonus *b)
{ {
assert(!vstd::contains(exportedBonuses,b)); assert(!vstd::contains(exportedBonuses,b));
exportedBonuses.push_back(b); exportedBonuses.push_back(b);
if(b->propagator) exportBonus(b);
propagateBonus(b);
else
bonuses.push_back(b);
} }
void CBonusSystemNode::removeBonus(Bonus *b) void CBonusSystemNode::removeBonus(Bonus *b)
@ -478,7 +475,8 @@ std::string CBonusSystemNode::nodeName() const
void CBonusSystemNode::deserializationFix() 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) 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*/) int NBonus::valOf(const CBonusSystemNode *obj, Bonus::BonusType type, int subtype /*= -1*/)
{ {
if(obj) if(obj)

View File

@ -55,6 +55,7 @@ namespace PrimarySkill
BONUS_NAME(EARTH_SPELL_DMG_PREMY) \ BONUS_NAME(EARTH_SPELL_DMG_PREMY) \
BONUS_NAME(FIRE_SPELL_DMG_PREMY) \ BONUS_NAME(FIRE_SPELL_DMG_PREMY) \
BONUS_NAME(WATER_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(WATER_WALKING) /*subtype 1 - without penalty, 2 - with penalty*/ \
BONUS_NAME(NO_SHOTING_PENALTY) /* duplicates NO_DISTANCE_PENALTY or FREE_SHOOTHING?*/\ BONUS_NAME(NO_SHOTING_PENALTY) /* duplicates NO_DISTANCE_PENALTY or FREE_SHOOTHING?*/\
BONUS_NAME(NEGATE_ALL_NATURAL_IMMUNITIES) \ BONUS_NAME(NEGATE_ALL_NATURAL_IMMUNITIES) \
@ -253,7 +254,7 @@ struct DLL_EXPORT Bonus
template <typename Handler> void serialize(Handler &h, const int version) 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) static bool OneDay(const Bonus *hb)
@ -448,15 +449,16 @@ public:
void popBonuses(const CSelector &s); void popBonuses(const CSelector &s);
virtual std::string nodeName() const; virtual std::string nodeName() const;
void deserializationFix(); void deserializationFix();
void exportBonus(Bonus * b);
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & bonuses & nodeType; h & /*bonuses & */nodeType;
h & exportedBonuses; h & exportedBonuses;
h & description; h & description;
BONUS_TREE_DESERIALIZATION_FIX
//h & parents & children; //h & parents & children;
} }
enum ENodeTypes enum ENodeTypes
{ {
UNKNOWN, STACK_INSTANCE, STACK_BATTLE, SPECIALITY, ARTIFACT, CREATURE, ARTIFACT_INSTANCE, HERO, PLAYER, TEAM UNKNOWN, STACK_INSTANCE, STACK_BATTLE, SPECIALITY, ARTIFACT, CREATURE, ARTIFACT_INSTANCE, HERO, PLAYER, TEAM