mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-14 10:12:59 +02:00
580 lines
13 KiB
C++
580 lines
13 KiB
C++
/*
|
|
* PacksForClientBattle.h, part of VCMI engine
|
|
*
|
|
* Authors: listed in file AUTHORS in main folder
|
|
*
|
|
* License: GNU General Public License v2.0 or later
|
|
* Full text of license available in license.txt file, in main folder
|
|
*
|
|
*/
|
|
#pragma once
|
|
|
|
#include "NetPacksBase.h"
|
|
#include "BattleChanges.h"
|
|
#include "../MetaString.h"
|
|
#include "../battle/BattleAction.h"
|
|
|
|
class CClient;
|
|
|
|
VCMI_LIB_NAMESPACE_BEGIN
|
|
|
|
class CGHeroInstance;
|
|
class CArmedInstance;
|
|
class IBattleState;
|
|
class BattleInfo;
|
|
|
|
struct DLL_LINKAGE BattleStart : public CPackForClient
|
|
{
|
|
void applyGs(CGameState * gs) const;
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
BattleInfo * info = nullptr;
|
|
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & info;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE BattleNextRound : public CPackForClient
|
|
{
|
|
void applyGs(CGameState * gs) const;
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE BattleSetActiveStack : public CPackForClient
|
|
{
|
|
void applyGs(CGameState * gs) const;
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
ui32 stack = 0;
|
|
ui8 askPlayerInterface = true;
|
|
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & stack;
|
|
h & askPlayerInterface;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE BattleCancelled: public CPackForClient
|
|
{
|
|
void applyGs(CGameState * gs) const;
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE BattleResultAccepted : public CPackForClient
|
|
{
|
|
void applyGs(CGameState * gs) const;
|
|
|
|
struct HeroBattleResults
|
|
{
|
|
HeroBattleResults()
|
|
: hero(nullptr), army(nullptr), exp(0) {}
|
|
|
|
CGHeroInstance * hero;
|
|
CArmedInstance * army;
|
|
TExpType exp;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & hero;
|
|
h & army;
|
|
h & exp;
|
|
}
|
|
};
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
std::array<HeroBattleResults, 2> heroResult;
|
|
ui8 winnerSide;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & heroResult;
|
|
h & winnerSide;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE BattleResult : public Query
|
|
{
|
|
void applyFirstCl(CClient * cl);
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
EBattleResult result = EBattleResult::NORMAL;
|
|
ui8 winner = 2; //0 - attacker, 1 - defender, [2 - draw (should be possible?)]
|
|
std::map<ui32, si32> casualties[2]; //first => casualties of attackers - map crid => number
|
|
TExpType exp[2] = {0, 0}; //exp for attacker and defender
|
|
std::set<ArtifactInstanceID> artifacts; //artifacts taken from loser to winner - currently unused
|
|
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & queryID;
|
|
h & result;
|
|
h & winner;
|
|
h & casualties[0];
|
|
h & casualties[1];
|
|
h & exp;
|
|
h & artifacts;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE BattleLogMessage : public CPackForClient
|
|
{
|
|
BattleID battleID = BattleID::NONE;
|
|
std::vector<MetaString> lines;
|
|
|
|
void applyGs(CGameState * gs);
|
|
void applyBattle(IBattleState * battleState);
|
|
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & lines;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE BattleStackMoved : public CPackForClient
|
|
{
|
|
BattleID battleID = BattleID::NONE;
|
|
ui32 stack = 0;
|
|
std::vector<BattleHex> tilesToMove;
|
|
int distance = 0;
|
|
bool teleporting = false;
|
|
|
|
void applyGs(CGameState * gs);
|
|
void applyBattle(IBattleState * battleState);
|
|
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & stack;
|
|
h & tilesToMove;
|
|
h & distance;
|
|
h & teleporting;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE BattleUnitsChanged : public CPackForClient
|
|
{
|
|
void applyGs(CGameState * gs);
|
|
void applyBattle(IBattleState * battleState);
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
std::vector<UnitChanges> changedStacks;
|
|
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & changedStacks;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct BattleStackAttacked
|
|
{
|
|
DLL_LINKAGE void applyGs(CGameState * gs);
|
|
DLL_LINKAGE void applyBattle(IBattleState * battleState);
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
ui32 stackAttacked = 0, attackerID = 0;
|
|
ui32 killedAmount = 0;
|
|
int64_t damageAmount = 0;
|
|
UnitChanges newState;
|
|
enum EFlags { KILLED = 1, SECONDARY = 2, REBIRTH = 4, CLONE_KILLED = 8, SPELL_EFFECT = 16, FIRE_SHIELD = 32, };
|
|
ui32 flags = 0; //uses EFlags (above)
|
|
SpellID spellID = SpellID::NONE; //only if flag SPELL_EFFECT is set
|
|
|
|
bool killed() const//if target stack was killed
|
|
{
|
|
return flags & KILLED || flags & CLONE_KILLED;
|
|
}
|
|
bool cloneKilled() const
|
|
{
|
|
return flags & CLONE_KILLED;
|
|
}
|
|
bool isSecondary() const//if stack was not a primary target (receives no spell effects)
|
|
{
|
|
return flags & SECONDARY;
|
|
}
|
|
///Attacked with spell (SPELL_LIKE_ATTACK)
|
|
bool isSpell() const
|
|
{
|
|
return flags & SPELL_EFFECT;
|
|
}
|
|
bool willRebirth() const//resurrection, e.g. Phoenix
|
|
{
|
|
return flags & REBIRTH;
|
|
}
|
|
bool fireShield() const
|
|
{
|
|
return flags & FIRE_SHIELD;
|
|
}
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & stackAttacked;
|
|
h & attackerID;
|
|
h & newState;
|
|
h & flags;
|
|
h & killedAmount;
|
|
h & damageAmount;
|
|
h & spellID;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
bool operator<(const BattleStackAttacked & b) const
|
|
{
|
|
return stackAttacked < b.stackAttacked;
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE BattleAttack : public CPackForClient
|
|
{
|
|
void applyGs(CGameState * gs);
|
|
BattleUnitsChanged attackerChanges;
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
std::vector<BattleStackAttacked> bsa;
|
|
ui32 stackAttacking = 0;
|
|
ui32 flags = 0; //uses Eflags (below)
|
|
enum EFlags { SHOT = 1, COUNTER = 2, LUCKY = 4, UNLUCKY = 8, BALLISTA_DOUBLE_DMG = 16, DEATH_BLOW = 32, SPELL_LIKE = 64, LIFE_DRAIN = 128 };
|
|
|
|
BattleHex tile;
|
|
SpellID spellID = SpellID::NONE; //for SPELL_LIKE
|
|
|
|
bool shot() const//distance attack - decrease number of shots
|
|
{
|
|
return flags & SHOT;
|
|
}
|
|
bool counter() const//is it counterattack?
|
|
{
|
|
return flags & COUNTER;
|
|
}
|
|
bool lucky() const
|
|
{
|
|
return flags & LUCKY;
|
|
}
|
|
bool unlucky() const
|
|
{
|
|
return flags & UNLUCKY;
|
|
}
|
|
bool ballistaDoubleDmg() const //if it's ballista attack and does double dmg
|
|
{
|
|
return flags & BALLISTA_DOUBLE_DMG;
|
|
}
|
|
bool deathBlow() const
|
|
{
|
|
return flags & DEATH_BLOW;
|
|
}
|
|
bool spellLike() const
|
|
{
|
|
return flags & SPELL_LIKE;
|
|
}
|
|
bool lifeDrain() const
|
|
{
|
|
return flags & LIFE_DRAIN;
|
|
}
|
|
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & bsa;
|
|
h & stackAttacking;
|
|
h & flags;
|
|
h & tile;
|
|
h & spellID;
|
|
h & attackerChanges;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE StartAction : public CPackForClient
|
|
{
|
|
StartAction() = default;
|
|
explicit StartAction(BattleAction act)
|
|
: ba(std::move(act))
|
|
{
|
|
}
|
|
void applyFirstCl(CClient * cl);
|
|
void applyGs(CGameState * gs);
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
BattleAction ba;
|
|
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & ba;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE EndAction : public CPackForClient
|
|
{
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE BattleSpellCast : public CPackForClient
|
|
{
|
|
void applyGs(CGameState * gs) const;
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
bool activeCast = true;
|
|
ui8 side = 0; //which hero did cast spell: 0 - attacker, 1 - defender
|
|
SpellID spellID; //id of spell
|
|
ui8 manaGained = 0; //mana channeling ability
|
|
BattleHex tile; //destination tile (may not be set in some global/mass spells
|
|
std::set<ui32> affectedCres; //ids of creatures affected by this spell, generally used if spell does not set any effect (like dispel or cure)
|
|
std::set<ui32> resistedCres; // creatures that resisted the spell (e.g. Dwarves)
|
|
std::set<ui32> reflectedCres; // creatures that reflected the spell (e.g. Magic Mirror spell)
|
|
si32 casterStack = -1; // -1 if not cated by creature, >=0 caster stack ID
|
|
bool castByHero = true; //if true - spell has been cast by hero, otherwise by a creature
|
|
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & side;
|
|
h & spellID;
|
|
h & manaGained;
|
|
h & tile;
|
|
h & affectedCres;
|
|
h & resistedCres;
|
|
h & reflectedCres;
|
|
h & casterStack;
|
|
h & castByHero;
|
|
h & activeCast;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE SetStackEffect : public CPackForClient
|
|
{
|
|
void applyGs(CGameState * gs);
|
|
void applyBattle(IBattleState * battleState);
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
std::vector<std::pair<ui32, std::vector<Bonus>>> toAdd;
|
|
std::vector<std::pair<ui32, std::vector<Bonus>>> toUpdate;
|
|
std::vector<std::pair<ui32, std::vector<Bonus>>> toRemove;
|
|
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & toAdd;
|
|
h & toUpdate;
|
|
h & toRemove;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE StacksInjured : public CPackForClient
|
|
{
|
|
void applyGs(CGameState * gs);
|
|
void applyBattle(IBattleState * battleState);
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
std::vector<BattleStackAttacked> stacks;
|
|
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & stacks;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE BattleResultsApplied : public CPackForClient
|
|
{
|
|
BattleID battleID = BattleID::NONE;
|
|
PlayerColor player1, player2;
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & player1;
|
|
h & player2;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE BattleObstaclesChanged : public CPackForClient
|
|
{
|
|
void applyGs(CGameState * gs);
|
|
void applyBattle(IBattleState * battleState);
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
std::vector<ObstacleChanges> changes;
|
|
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & changes;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE CatapultAttack : public CPackForClient
|
|
{
|
|
struct AttackInfo
|
|
{
|
|
si16 destinationTile;
|
|
EWallPart attackedPart;
|
|
ui8 damageDealt;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & destinationTile;
|
|
h & attackedPart;
|
|
h & damageDealt;
|
|
}
|
|
};
|
|
|
|
CatapultAttack();
|
|
~CatapultAttack() override;
|
|
|
|
void applyGs(CGameState * gs);
|
|
void applyBattle(IBattleState * battleState);
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
std::vector< AttackInfo > attackedParts;
|
|
int attacker = -1; //if -1, then a spell caused this
|
|
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & attackedParts;
|
|
h & attacker;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
};
|
|
|
|
struct DLL_LINKAGE BattleSetStackProperty : public CPackForClient
|
|
{
|
|
enum BattleStackProperty { CASTS, ENCHANTER_COUNTER, UNBIND, CLONED, HAS_CLONE };
|
|
|
|
void applyGs(CGameState * gs) const;
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
int stackID = 0;
|
|
BattleStackProperty which = CASTS;
|
|
int val = 0;
|
|
int absolute = 0;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & stackID;
|
|
h & which;
|
|
h & val;
|
|
h & absolute;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
|
|
protected:
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
};
|
|
|
|
///activated at the beginning of turn
|
|
struct DLL_LINKAGE BattleTriggerEffect : public CPackForClient
|
|
{
|
|
void applyGs(CGameState * gs) const; //effect
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
int stackID = 0;
|
|
int effect = 0; //use corresponding Bonus type
|
|
int val = 0;
|
|
int additionalInfo = 0;
|
|
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & stackID;
|
|
h & effect;
|
|
h & val;
|
|
h & additionalInfo;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
|
|
protected:
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
};
|
|
|
|
struct DLL_LINKAGE BattleUpdateGateState : public CPackForClient
|
|
{
|
|
void applyGs(CGameState * gs) const;
|
|
|
|
BattleID battleID = BattleID::NONE;
|
|
EGateState state = EGateState::NONE;
|
|
template <typename Handler> void serialize(Handler & h, const int version)
|
|
{
|
|
h & battleID;
|
|
h & state;
|
|
assert(battleID != BattleID::NONE);
|
|
}
|
|
|
|
protected:
|
|
void visitTyped(ICPackVisitor & visitor) override;
|
|
};
|
|
|
|
VCMI_LIB_NAMESPACE_END
|