mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Towards duel support.
This commit is contained in:
parent
6383c9a013
commit
2cf6729eee
@ -261,7 +261,7 @@ BattleAction CBattleLogic::MakeDecision(int stackID)
|
||||
const CStack *currentStack = m_cb->battleGetStackByID(stackID);
|
||||
if(currentStack->position < 0 || currentStack->getCreature()->idNumber == 147) //turret or first aid kit
|
||||
{
|
||||
return MakeDefend(stackID);
|
||||
return BattleAction::makeDefend(currentStack);
|
||||
}
|
||||
MakeStatistics(stackID);
|
||||
|
||||
@ -285,11 +285,11 @@ BattleAction CBattleLogic::MakeDecision(int stackID)
|
||||
if (additionalInfo == -1 || creatures.empty())
|
||||
{
|
||||
// defend
|
||||
return MakeDefend(stackID);
|
||||
return BattleAction::makeDefend(currentStack);
|
||||
}
|
||||
else if (additionalInfo == -2)
|
||||
{
|
||||
return MakeWait(stackID);
|
||||
return BattleAction::makeWait(currentStack);
|
||||
}
|
||||
|
||||
list<int>::iterator it, eit;
|
||||
@ -472,26 +472,6 @@ std::vector<int> CBattleLogic::GetAvailableHexesForAttacker(const CStack *defend
|
||||
return fields;
|
||||
}
|
||||
|
||||
BattleAction CBattleLogic::MakeDefend(int stackID)
|
||||
{
|
||||
BattleAction ba;
|
||||
ba.side = m_side;
|
||||
ba.actionType = action_defend;
|
||||
ba.stackNumber = stackID;
|
||||
ba.additionalInfo = -1;
|
||||
return ba;
|
||||
}
|
||||
|
||||
BattleAction CBattleLogic::MakeWait(int stackID)
|
||||
{
|
||||
BattleAction ba;
|
||||
ba.side = m_side;
|
||||
ba.actionType = action_wait;
|
||||
ba.stackNumber = stackID;
|
||||
ba.additionalInfo = -1;
|
||||
return ba;
|
||||
}
|
||||
|
||||
BattleAction CBattleLogic::MakeAttack(int attackerID, int destinationID)
|
||||
{
|
||||
const CStack *attackerStack = m_cb->battleGetStackByID(attackerID),
|
||||
@ -501,19 +481,12 @@ BattleAction CBattleLogic::MakeAttack(int attackerID, int destinationID)
|
||||
//don't attack ourselves
|
||||
if(destinationStack->attackerOwned == !m_side)
|
||||
{
|
||||
return MakeDefend(attackerID);
|
||||
return BattleAction::makeDefend(attackerStack);
|
||||
}
|
||||
|
||||
if (m_cb->battleCanShoot(attackerID, m_cb->battleGetPos(destinationID)))
|
||||
if (m_cb->battleCanShoot(attackerID, m_cb->battleGetPos(destinationID))) // shoot
|
||||
{
|
||||
// shoot
|
||||
BattleAction ba;
|
||||
ba.side = m_side;
|
||||
ba.additionalInfo = -1;
|
||||
ba.actionType = action_shoot; // shoot
|
||||
ba.stackNumber = attackerID;
|
||||
ba.destinationTile = (ui16)m_cb->battleGetPos(destinationID);
|
||||
return ba;
|
||||
return BattleAction::makeShotAttack(attackerStack, destinationStack);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -522,7 +495,7 @@ BattleAction CBattleLogic::MakeAttack(int attackerID, int destinationID)
|
||||
std::vector<int> av_tiles = GetAvailableHexesForAttacker(m_cb->battleGetStackByID(destinationID), m_cb->battleGetStackByID(attackerID));
|
||||
if (av_tiles.size() < 1)
|
||||
{
|
||||
return MakeDefend(attackerID);
|
||||
return BattleAction::makeDefend(attackerStack);
|
||||
}
|
||||
|
||||
// get the best tile - now the nearest
|
||||
@ -549,7 +522,7 @@ BattleAction CBattleLogic::MakeAttack(int attackerID, int destinationID)
|
||||
|
||||
if(fields.size() == 0)
|
||||
{
|
||||
return MakeDefend(attackerID);
|
||||
return BattleAction::makeDefend(attackerStack);
|
||||
}
|
||||
|
||||
BattleAction ba;
|
||||
@ -566,7 +539,7 @@ BattleAction CBattleLogic::MakeAttack(int attackerID, int destinationID)
|
||||
else if(BattleInfo::mutualPosition(dest_tile, destStackPos-1) != -1)
|
||||
ba.additionalInfo = destStackPos-1;
|
||||
else
|
||||
MakeDefend(attackerID);
|
||||
return BattleAction::makeDefend(attackerStack);
|
||||
|
||||
int nearest_dist = m_battleHelper.InfiniteDistance;
|
||||
int nearest_pos = -1;
|
||||
|
@ -106,14 +106,6 @@ private:
|
||||
* Helper function. It's used for performing an attack action.
|
||||
*/
|
||||
std::vector<int> GetAvailableHexesForAttacker(const CStack *defender, const CStack *attacker = NULL);
|
||||
/**
|
||||
* Just make defend action.
|
||||
*/
|
||||
BattleAction MakeDefend(int stackID);
|
||||
/**
|
||||
* Just make wait action.
|
||||
*/
|
||||
BattleAction MakeWait(int stackID);
|
||||
/**
|
||||
* Make an attack action if it's possible.
|
||||
* If it's not possible then function returns defend action.
|
||||
|
@ -3,33 +3,122 @@
|
||||
#include "../../lib/CGameState.h"
|
||||
|
||||
CStupidAI::CStupidAI(void)
|
||||
: side(-1), cb(NULL)
|
||||
{
|
||||
print("created");
|
||||
}
|
||||
|
||||
|
||||
CStupidAI::~CStupidAI(void)
|
||||
{
|
||||
print("destroyed");
|
||||
}
|
||||
|
||||
void CStupidAI::init( IBattleCallback * CB )
|
||||
{
|
||||
|
||||
print("init called, saving ptr to IBattleCallback");
|
||||
cb = CB;
|
||||
}
|
||||
|
||||
void CStupidAI::actionFinished( const BattleAction *action )
|
||||
{
|
||||
|
||||
print("actionFinished called");
|
||||
}
|
||||
|
||||
void CStupidAI::actionStarted( const BattleAction *action )
|
||||
{
|
||||
|
||||
print("actionStarted called");
|
||||
}
|
||||
|
||||
BattleAction CStupidAI::activeStack( const CStack * stack )
|
||||
{
|
||||
BattleAction ba;
|
||||
ba.actionType = BattleAction::DEFEND;
|
||||
ba.stackNumber = stack->ID;
|
||||
return ba;
|
||||
print("activeStack called");
|
||||
return BattleAction::makeDefend(stack);
|
||||
if(stack->position % 17 < 5) //move army little towards enemy
|
||||
{
|
||||
THex dest = stack->position + side*2 - 1;
|
||||
print(stack->nodeName() << "will be moved to " + boost::lexical_cast<std::string>(dest));
|
||||
return BattleAction::makeMove(stack, );
|
||||
}
|
||||
}
|
||||
|
||||
void CStupidAI::battleAttack(const BattleAttack *ba)
|
||||
{
|
||||
print("battleAttack called");
|
||||
}
|
||||
|
||||
void CStupidAI::battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa)
|
||||
{
|
||||
print("battleStacksAttacked called");
|
||||
}
|
||||
|
||||
void CStupidAI::battleEnd(const BattleResult *br)
|
||||
{
|
||||
print("battleEnd called");
|
||||
}
|
||||
|
||||
void CStupidAI::battleResultsApplied()
|
||||
{
|
||||
print("battleResultsApplied called");
|
||||
}
|
||||
|
||||
void CStupidAI::battleNewRoundFirst(int round)
|
||||
{
|
||||
print("battleNewRoundFirst called");
|
||||
}
|
||||
|
||||
void CStupidAI::battleNewRound(int round)
|
||||
{
|
||||
print("battleNewRound called");
|
||||
}
|
||||
|
||||
void CStupidAI::battleStackMoved(const CStack * stack, THex dest, int distance, bool end)
|
||||
{
|
||||
print("battleStackMoved called");;
|
||||
}
|
||||
|
||||
void CStupidAI::battleSpellCast(const BattleSpellCast *sc)
|
||||
{
|
||||
print("battleSpellCast called");
|
||||
}
|
||||
|
||||
void CStupidAI::battleStacksEffectsSet(const SetStackEffect & sse)
|
||||
{
|
||||
print("battleStacksEffectsSet called");
|
||||
}
|
||||
|
||||
void CStupidAI::battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool Side)
|
||||
{
|
||||
print("battleStart called");
|
||||
side = Side;
|
||||
}
|
||||
|
||||
void CStupidAI::battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, si32 lifeDrainFrom)
|
||||
{
|
||||
print("battleStacksHealedRes called");
|
||||
}
|
||||
|
||||
void CStupidAI::battleNewStackAppeared(const CStack * stack)
|
||||
{
|
||||
print("battleNewStackAppeared called");
|
||||
}
|
||||
|
||||
void CStupidAI::battleObstaclesRemoved(const std::set<si32> & removedObstacles)
|
||||
{
|
||||
print("battleObstaclesRemoved called");
|
||||
}
|
||||
|
||||
void CStupidAI::battleCatapultAttacked(const CatapultAttack & ca)
|
||||
{
|
||||
print("battleCatapultAttacked called");
|
||||
}
|
||||
|
||||
void CStupidAI::battleStacksRemoved(const BattleStacksRemoved & bsr)
|
||||
{
|
||||
print("battleStacksRemoved called");
|
||||
}
|
||||
|
||||
void CStupidAI::print(const std::string &text) const
|
||||
{
|
||||
tlog0 << "CStupidAI [" << this <<"]: " << text << std::endl;
|
||||
}
|
@ -2,6 +2,10 @@
|
||||
|
||||
class CStupidAI : public CBattleGameInterface
|
||||
{
|
||||
int side;
|
||||
IBattleCallback *cb;
|
||||
|
||||
void print(const std::string &text) const;
|
||||
public:
|
||||
CStupidAI(void);
|
||||
~CStupidAI(void);
|
||||
@ -10,5 +14,22 @@ public:
|
||||
void actionFinished(const BattleAction *action) OVERRIDE;//occurs AFTER every action taken by any stack or by the hero
|
||||
void actionStarted(const BattleAction *action) OVERRIDE;//occurs BEFORE every action taken by any stack or by the hero
|
||||
BattleAction activeStack(const CStack * stack) OVERRIDE; //called when it's turn of that stack
|
||||
|
||||
void battleAttack(const BattleAttack *ba) OVERRIDE; //called when stack is performing attack
|
||||
void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa) OVERRIDE; //called when stack receives damage (after battleAttack())
|
||||
void battleEnd(const BattleResult *br) OVERRIDE;
|
||||
void battleResultsApplied() OVERRIDE; //called when all effects of last battle are applied
|
||||
void battleNewRoundFirst(int round) OVERRIDE; //called at the beginning of each turn before changes are applied;
|
||||
void battleNewRound(int round) OVERRIDE; //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
|
||||
void battleStackMoved(const CStack * stack, THex dest, int distance, bool end) OVERRIDE;
|
||||
void battleSpellCast(const BattleSpellCast *sc) OVERRIDE;
|
||||
void battleStacksEffectsSet(const SetStackEffect & sse) OVERRIDE;//called when a specific effect is set to stacks
|
||||
void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) OVERRIDE; //called by engine when battle starts; side=0 - left, side=1 - right
|
||||
void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, si32 lifeDrainFrom) OVERRIDE; //called when stacks are healed / resurrected first element of pair - stack id, second - healed hp
|
||||
void battleNewStackAppeared(const CStack * stack) OVERRIDE; //not called at the beginning of a battle or by resurrection; called eg. when elemental is summoned
|
||||
void battleObstaclesRemoved(const std::set<si32> & removedObstacles) OVERRIDE; //called when a certain set of obstacles is removed from batlefield; IDs of them are given
|
||||
void battleCatapultAttacked(const CatapultAttack & ca) OVERRIDE; //called when catapult makes an attack
|
||||
void battleStacksRemoved(const BattleStacksRemoved & bsr) OVERRIDE; //called when certain stack is completely removed from battlefield
|
||||
|
||||
};
|
||||
|
||||
|
@ -1,2 +1,3 @@
|
||||
#pragma once
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include "../../AI_Base.h"
|
@ -476,7 +476,14 @@ bool CCallback::buildBuilding(const CGTownInstance *town, si32 buildingID)
|
||||
int CBattleCallback::battleGetBattlefieldType()
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||
return gs->battleGetBattlefieldType();
|
||||
//return gs->battleGetBattlefieldType();
|
||||
|
||||
if(!gs->curB)
|
||||
{
|
||||
tlog2<<"battleGetBattlefieldType called when there is no battle!"<<std::endl;
|
||||
return -1;
|
||||
}
|
||||
return gs->curB->battlefieldType;
|
||||
}
|
||||
|
||||
int CBattleCallback::battleGetObstaclesAtTile(THex tile) //returns bitfield
|
||||
|
@ -2993,7 +2993,7 @@ void CBattleInterface::showAliveStack(const CStack *stack, SDL_Surface * to)
|
||||
}
|
||||
}
|
||||
|
||||
creAnims[ID]->nextFrame(to, creAnims[ID]->pos.x, creAnims[ID]->pos.y, creDir[ID], animCount, incrementFrame, ID==activeStack->ID, ID==mouseHoveredStack); //increment always when moving, never if stack died
|
||||
creAnims[ID]->nextFrame(to, creAnims[ID]->pos.x, creAnims[ID]->pos.y, creDir[ID], animCount, incrementFrame, activeStack && ID==activeStack->ID, ID==mouseHoveredStack); //increment always when moving, never if stack died
|
||||
|
||||
//printing amount
|
||||
if(stack->count > 0 //don't print if stack is not alive
|
||||
|
@ -279,6 +279,8 @@ int main(int argc, char** argv)
|
||||
{
|
||||
StartInfo *si = new StartInfo();
|
||||
si->mode = StartInfo::DUEL;
|
||||
si->playerInfos[0].color = 0;
|
||||
si->playerInfos[1].color = 1;
|
||||
startGame(si);
|
||||
}
|
||||
mainGUIThread = new boost::thread(&CGuiHandler::run, boost::ref(GH));
|
||||
|
@ -116,7 +116,8 @@ void CClient::waitForMoveAndSend(int color)
|
||||
{
|
||||
try
|
||||
{
|
||||
BattleAction ba = playerint[color]->activeStack(gs->curB->getStack(gs->curB->activeStack, false));
|
||||
assert(vstd::contains(battleints, color));
|
||||
BattleAction ba = battleints[color]->activeStack(gs->curB->getStack(gs->curB->activeStack, false));
|
||||
*serv << &MakeAction(ba);
|
||||
return;
|
||||
}HANDLE_EXCEPTION
|
||||
@ -402,13 +403,14 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
playerint[color] = new CPlayerInterface(color);
|
||||
humanPlayers++;
|
||||
}
|
||||
battleints[color] = playerint[color];
|
||||
|
||||
playerint[color]->init(cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
CBattleCallback * cbc = new CBattleCallback(gs, color, this);
|
||||
battleints[color] = CAIHandler::getNewBattleAI(cb,conf.cc.defaultAI);
|
||||
battleints[color] = CAIHandler::getNewBattleAI(cb,"StupidAI");
|
||||
battleints[color]->init(cbc);
|
||||
}
|
||||
}
|
||||
@ -417,16 +419,21 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
{
|
||||
CPlayerInterface *p = new CPlayerInterface(-1);
|
||||
p->observerInDuelMode = true;
|
||||
playerint[254] = p;
|
||||
battleints[254] = playerint[254] = p;
|
||||
GH.curInt = p;
|
||||
p->init(new CCallback(gs, -1, this));
|
||||
battleStarted(gs->curB);
|
||||
}
|
||||
else
|
||||
{
|
||||
playerint[255] = CAIHandler::getNewAI(cb,conf.cc.defaultAI);
|
||||
playerint[255]->init(new CCallback(gs,255,this));
|
||||
}
|
||||
|
||||
serv->addStdVecItems(const_cast<CGameInfo*>(CGI)->state);
|
||||
hotSeat = (humanPlayers > 1);
|
||||
|
||||
playerint[255] = CAIHandler::getNewAI(cb,conf.cc.defaultAI);
|
||||
playerint[255]->init(new CCallback(gs,255,this));
|
||||
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
@ -553,12 +560,12 @@ void CClient::battleStarted(const BattleInfo * info)
|
||||
|
||||
new CBattleInterface(info->belligerents[0], info->belligerents[1], info->heroes[0], info->heroes[1], Rect((conf.cc.resx - 800)/2, (conf.cc.resy - 600)/2, 800, 600), att, def);
|
||||
|
||||
if(vstd::contains(playerint,info->side1))
|
||||
playerint[info->side1]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 0);
|
||||
if(vstd::contains(playerint,info->side2))
|
||||
playerint[info->side2]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 1);
|
||||
if(vstd::contains(playerint,254))
|
||||
playerint[254]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 1);
|
||||
if(vstd::contains(battleints,info->side1))
|
||||
battleints[info->side1]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 0);
|
||||
if(vstd::contains(battleints,info->side2))
|
||||
battleints[info->side2]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 1);
|
||||
if(vstd::contains(battleints,254))
|
||||
battleints[254]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 1);
|
||||
}
|
||||
|
||||
template void CClient::serialize( CISer<CLoadFile> &h, const int version );
|
||||
|
@ -29,6 +29,14 @@
|
||||
if(vstd::contains(cl->playerint,player)) \
|
||||
cl->playerint[player]->function(__VA_ARGS__);
|
||||
|
||||
#define BATTLE_INTERFACE_CALL_IF_PRESENT(player,function,...) \
|
||||
if(vstd::contains(cl->battleints,player)) \
|
||||
cl->battleints[player]->function(__VA_ARGS__);
|
||||
|
||||
#define BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(function,...) \
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1, function, __VA_ARGS__) \
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2, function, __VA_ARGS__) \
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT(254, function, __VA_ARGS__)
|
||||
/*
|
||||
* NetPacksClient.cpp, part of VCMI engine
|
||||
*
|
||||
@ -486,14 +494,12 @@ void BattleStart::applyCl( CClient *cl )
|
||||
|
||||
void BattleNextRound::applyFirstCl(CClient *cl)
|
||||
{
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1,battleNewRoundFirst,round);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2,battleNewRoundFirst,round);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleNewRoundFirst,round);
|
||||
}
|
||||
|
||||
void BattleNextRound::applyCl( CClient *cl )
|
||||
{
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1,battleNewRound,round);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2,battleNewRound,round);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleNewRound,round);
|
||||
}
|
||||
|
||||
void BattleSetActiveStack::applyCl( CClient *cl )
|
||||
@ -508,23 +514,19 @@ void BattleSetActiveStack::applyCl( CClient *cl )
|
||||
{
|
||||
playerToCall = activated->owner;
|
||||
}
|
||||
if( vstd::contains(cl->playerint, playerToCall) )
|
||||
if( vstd::contains(cl->battleints, playerToCall) )
|
||||
boost::thread( boost::bind(&CClient::waitForMoveAndSend, cl, playerToCall) );
|
||||
}
|
||||
|
||||
void BattleResult::applyFirstCl( CClient *cl )
|
||||
{
|
||||
if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side1]->battleEnd(this);
|
||||
if(cl->playerint.find(GS(cl)->curB->side2) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side2]->battleEnd(this);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleEnd,this);
|
||||
}
|
||||
|
||||
void BattleStackMoved::applyFirstCl( CClient *cl )
|
||||
{
|
||||
const CStack * movedStack = GS(cl)->curB->getStack(stack);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1,battleStackMoved,movedStack,tile,distance,ending);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2,battleStackMoved,movedStack,tile,distance,ending);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleStackMoved,movedStack,tile,distance,ending);
|
||||
}
|
||||
|
||||
void BattleStackAttacked::applyCl( CClient *cl )
|
||||
@ -532,16 +534,12 @@ void BattleStackAttacked::applyCl( CClient *cl )
|
||||
std::vector<BattleStackAttacked> bsa;
|
||||
bsa.push_back(*this);
|
||||
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1,battleStacksAttacked,bsa);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2,battleStacksAttacked,bsa);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleStacksAttacked,bsa);
|
||||
}
|
||||
|
||||
void BattleAttack::applyFirstCl( CClient *cl )
|
||||
{
|
||||
if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side1]->battleAttack(this);
|
||||
if(cl->playerint.find(GS(cl)->curB->side2) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side2]->battleAttack(this);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleAttack,this);
|
||||
for (int g=0; g<bsa.size(); ++g)
|
||||
{
|
||||
for (int z=0; z<bsa[g].healedStacks.size(); ++z)
|
||||
@ -553,59 +551,39 @@ void BattleAttack::applyFirstCl( CClient *cl )
|
||||
|
||||
void BattleAttack::applyCl( CClient *cl )
|
||||
{
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1,battleStacksAttacked,bsa);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2,battleStacksAttacked,bsa);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleStacksAttacked,bsa);
|
||||
}
|
||||
|
||||
void StartAction::applyFirstCl( CClient *cl )
|
||||
{
|
||||
cl->curbaction = new BattleAction(ba);
|
||||
if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side1]->actionStarted(&ba);
|
||||
if(cl->playerint.find(GS(cl)->curB->side2) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side2]->actionStarted(&ba);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(actionStarted, &ba);
|
||||
}
|
||||
|
||||
void BattleSpellCast::applyCl( CClient *cl )
|
||||
{
|
||||
if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side1]->battleSpellCast(this);
|
||||
if(cl->playerint.find(GS(cl)->curB->side2) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side2]->battleSpellCast(this);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleSpellCast,this);
|
||||
|
||||
if(id >= 66 && id <= 69) //elemental summoning
|
||||
{
|
||||
if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side1]->battleNewStackAppeared(GS(cl)->curB->stacks[GS(cl)->curB->stacks.size() - 1]);
|
||||
if(cl->playerint.find(GS(cl)->curB->side2) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side2]->battleNewStackAppeared(GS(cl)->curB->stacks[GS(cl)->curB->stacks.size() - 1]);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleNewStackAppeared,GS(cl)->curB->stacks.back());
|
||||
}
|
||||
}
|
||||
|
||||
void SetStackEffect::applyCl( CClient *cl )
|
||||
{
|
||||
BattleSpellCast sc;
|
||||
sc.id = effect.id;
|
||||
sc.side = 3; //doesn't matter
|
||||
sc.skill = effect.val;
|
||||
|
||||
//informing about effects
|
||||
if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side1]->battleStacksEffectsSet(*this);
|
||||
if(cl->playerint.find(GS(cl)->curB->side2) != cl->playerint.end())
|
||||
cl->playerint[GS(cl)->curB->side2]->battleStacksEffectsSet(*this);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleStacksEffectsSet,*this);
|
||||
}
|
||||
|
||||
void StacksInjured::applyCl( CClient *cl )
|
||||
{
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1,battleStacksAttacked,stacks);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2,battleStacksAttacked,stacks);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleStacksAttacked,stacks);
|
||||
}
|
||||
|
||||
void BattleResultsApplied::applyCl( CClient *cl )
|
||||
{
|
||||
INTERFACE_CALL_IF_PRESENT(player1,battleResultsApplied);
|
||||
INTERFACE_CALL_IF_PRESENT(player2,battleResultsApplied);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleResultsApplied);
|
||||
}
|
||||
|
||||
void StacksHealedOrResurrected::applyCl( CClient *cl )
|
||||
@ -615,29 +593,25 @@ void StacksHealedOrResurrected::applyCl( CClient *cl )
|
||||
{
|
||||
shiftedHealed.push_back(std::make_pair(healedStacks[v].stackID, healedStacks[v].healedHP));
|
||||
}
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1, battleStacksHealedRes, shiftedHealed, lifeDrain, drainedFrom);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2, battleStacksHealedRes, shiftedHealed, lifeDrain, drainedFrom);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleStacksHealedRes, shiftedHealed, lifeDrain, drainedFrom);
|
||||
}
|
||||
|
||||
void ObstaclesRemoved::applyCl( CClient *cl )
|
||||
{
|
||||
//inform interfaces about removed obstacles
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1, battleObstaclesRemoved, obstacles);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2, battleObstaclesRemoved, obstacles);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleObstaclesRemoved, obstacles);
|
||||
}
|
||||
|
||||
void CatapultAttack::applyCl( CClient *cl )
|
||||
{
|
||||
//inform interfaces about catapult attack
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1, battleCatapultAttacked, *this);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2, battleCatapultAttacked, *this);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleCatapultAttacked, *this);
|
||||
}
|
||||
|
||||
void BattleStacksRemoved::applyCl( CClient *cl )
|
||||
{
|
||||
//inform interfaces about removed stacks
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1, battleStacksRemoved, *this);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2, battleStacksRemoved, *this);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleStacksRemoved, *this);
|
||||
}
|
||||
|
||||
CGameState* CPackForClient::GS( CClient *cl )
|
||||
@ -647,8 +621,7 @@ CGameState* CPackForClient::GS( CClient *cl )
|
||||
|
||||
void EndAction::applyCl( CClient *cl )
|
||||
{
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1,actionFinished,cl->curbaction);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2,actionFinished,cl->curbaction);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(actionFinished, cl->curbaction);
|
||||
|
||||
delete cl->curbaction;
|
||||
cl->curbaction = NULL;
|
||||
|
59
lib/BattleAction.cpp
Normal file
59
lib/BattleAction.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#define VCMI_DLL
|
||||
#include "BattleAction.h"
|
||||
#include "CGameState.h"
|
||||
|
||||
BattleAction::BattleAction()
|
||||
{
|
||||
side = -1;
|
||||
stackNumber = -1;
|
||||
actionType = INVALID;
|
||||
destinationTile = -1;
|
||||
additionalInfo = -1;
|
||||
}
|
||||
|
||||
BattleAction BattleAction::makeDefend(const CStack *stack)
|
||||
{
|
||||
BattleAction ba;
|
||||
ba.side = !stack->attackerOwned;
|
||||
ba.actionType = DEFEND;
|
||||
ba.stackNumber = stack->ID;
|
||||
return ba;
|
||||
}
|
||||
|
||||
BattleAction BattleAction::makeMeleeAttack(const CStack *stack) /*WARNING: stacks must be neighbouring! */
|
||||
{
|
||||
BattleAction ba;
|
||||
ba.side = !stack->attackerOwned;
|
||||
ba.actionType = WAIT;
|
||||
ba.stackNumber = stack->ID;
|
||||
return ba;
|
||||
}
|
||||
|
||||
BattleAction BattleAction::makeWait(const CStack *stack)
|
||||
{
|
||||
BattleAction ba;
|
||||
ba.side = !stack->attackerOwned;
|
||||
ba.actionType = WAIT;
|
||||
ba.stackNumber = stack->ID;
|
||||
return ba;
|
||||
}
|
||||
|
||||
BattleAction BattleAction::makeShotAttack(const CStack *shooter, const CStack *target)
|
||||
{
|
||||
BattleAction ba;
|
||||
ba.side = !shooter->attackerOwned;
|
||||
ba.actionType = SHOOT;
|
||||
ba.stackNumber = shooter->ID;
|
||||
ba.destinationTile = target->position;
|
||||
return ba;
|
||||
}
|
||||
|
||||
BattleAction BattleAction::makeMove(const CStack *stack, THex dest)
|
||||
{
|
||||
BattleAction ba;
|
||||
ba.side = !stack->attackerOwned;
|
||||
ba.actionType = WALK;
|
||||
ba.stackNumber = stack->ID;
|
||||
ba.destinationTile = dest;
|
||||
return ba;
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
#pragma once;
|
||||
#ifndef __BATTLEACTION_H__
|
||||
#define __BATTLEACTION_H__
|
||||
|
||||
#include "../global.h"
|
||||
/*
|
||||
* BattleAction.h, part of VCMI engine
|
||||
*
|
||||
@ -11,13 +13,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
struct BattleAction
|
||||
class CStack;
|
||||
|
||||
struct DLL_EXPORT BattleAction
|
||||
{
|
||||
ui8 side; //who made this action: false - left, true - right player
|
||||
ui32 stackNumber;//stack ID, -1 left hero, -2 right hero,
|
||||
enum ActionType
|
||||
{
|
||||
NO_ACTION = 0, HERO_SPELL, WALK, DEFEND, RETREAT, SURRENDER, WALK_AND_ATTACK, SHOOT, WAIT, CATAPULT, MONSTER_SPELL, BAD_MORALE, STACK_HEAL
|
||||
INVALID = -1, NO_ACTION = 0, HERO_SPELL, WALK, DEFEND, RETREAT, SURRENDER, WALK_AND_ATTACK, SHOOT, WAIT, CATAPULT, MONSTER_SPELL, BAD_MORALE, STACK_HEAL
|
||||
};
|
||||
ui8 actionType; // 0 = No action; 1 = Hero cast a spell 2 = Walk 3 = Defend 4 = Retreat from the battle
|
||||
//5 = Surrender 6 = Walk and Attack 7 = Shoot 8 = Wait 9 = Catapult
|
||||
@ -28,5 +32,13 @@ struct BattleAction
|
||||
{
|
||||
h & side & stackNumber & actionType & destinationTile & additionalInfo;
|
||||
}
|
||||
|
||||
BattleAction();
|
||||
|
||||
static BattleAction makeDefend(const CStack *stack);
|
||||
static BattleAction makeWait(const CStack *stack);
|
||||
static BattleAction makeMeleeAttack(const CStack *stack); //WARNING: stacks must be neighbouring!;
|
||||
static BattleAction makeShotAttack(const CStack *shooter, const CStack *target);
|
||||
static BattleAction makeMove(const CStack *stack, THex dest);
|
||||
};
|
||||
#endif // __BATTLEACTION_H__
|
||||
|
@ -60,6 +60,7 @@ public:
|
||||
|
||||
class DLL_EXPORT CArtifactInstance : public CBonusSystemNode
|
||||
{
|
||||
void init();
|
||||
public:
|
||||
ConstTransitivePtr<CArtifact> art;
|
||||
si32 id; //id of the instance
|
||||
@ -67,7 +68,6 @@ public:
|
||||
CArtifactInstance();
|
||||
CArtifactInstance(CArtifact *Art);
|
||||
|
||||
void init();
|
||||
std::string nodeName() const OVERRIDE;
|
||||
void setType(CArtifact *Art);
|
||||
|
||||
@ -80,6 +80,12 @@ public:
|
||||
static CArtifactInstance *createScroll(const CSpell *s);
|
||||
};
|
||||
|
||||
class DLL_EXPORT CCombinedArtifactInstance : public CArtifactInstance
|
||||
{
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
class DLL_EXPORT IModableArt : public CArtifact //artifact which can have different properties, such as scroll or banner
|
||||
{ //used only for dynamic cast :P
|
||||
public:
|
||||
|
@ -1041,7 +1041,7 @@ const CGHeroInstance * CStack::getMyHero() const
|
||||
std::string CStack::nodeName() const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Battle stack of " << count << " creatures of ";
|
||||
oss << "Battle stack [" << ID << "]: " << count << " creatures of ";
|
||||
if(type)
|
||||
oss << type->namePl;
|
||||
else
|
||||
@ -1486,6 +1486,7 @@ BattleInfo * setupBattle( int3 tile, int terrain, int terType, const CArmedInsta
|
||||
std::vector<CStack*> & stacks = (curB->stacks);
|
||||
|
||||
curB->tile = tile;
|
||||
curB->battlefieldType = terType;
|
||||
curB->belligerents[0] = const_cast<CArmedInstance*>(armies[0]);
|
||||
curB->belligerents[1] = const_cast<CArmedInstance*>(armies[1]);
|
||||
curB->heroes[0] = const_cast<CGHeroInstance*>(heroes[0]);
|
||||
@ -1930,12 +1931,14 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
|
||||
const CGHeroInstance *heroes[2];
|
||||
const CGTownInstance *town = NULL;
|
||||
CGHeroInstance *h = new CGHeroInstance();
|
||||
h->setOwner(0);
|
||||
h->subID = 1;
|
||||
h->initHero(1);
|
||||
h->initObj();
|
||||
//h->putStack(0, new CStackInstance(34, 5));
|
||||
|
||||
CGCreature *c = new CGCreature();
|
||||
c->setOwner(1);
|
||||
c->putStack(0, new CStackInstance(70, 6));
|
||||
c->subID = 34;
|
||||
c->initObj();
|
||||
|
@ -212,11 +212,12 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
|
||||
std::vector<CObstacleInstance> obstacles;
|
||||
ui8 castSpells[2]; //[0] - attacker, [1] - defender
|
||||
SiegeInfo si;
|
||||
si32 battlefieldType;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & side1 & side2 & round & activeStack & siege & tid & tile & stacks & belligerents & obstacles
|
||||
& castSpells & si;
|
||||
& castSpells & si & battlefieldType;
|
||||
h & heroes;
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user