1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-03 13:01:33 +02:00

Merge remote-tracking branch 'upstream/develop' into develop

This commit is contained in:
Alexander Wilms 2023-10-29 13:35:37 +00:00
commit 5cbc75d3b7
168 changed files with 3890 additions and 3342 deletions

View File

@ -114,6 +114,23 @@ float AttackPossibility::attackValue() const
return damageDiff();
}
float hpFunction(uint64_t unitHealthStart, uint64_t unitHealthEnd, uint64_t maxHealth)
{
float ratioStart = static_cast<float>(unitHealthStart) / maxHealth;
float ratioEnd = static_cast<float>(unitHealthEnd) / maxHealth;
float base = 0.666666f;
// reduce from max to 0 must be 1.
// 10 hp from end costs bit more than 10 hp from start because our goal is to kill unit, not just hurt it
// ********** 2 * base - ratioStart *********
// * *
// * height = ratioStart - ratioEnd *
// * *
// ******************** 2 * base - ratioEnd ******
// S = (a + b) * h / 2
return (base * (4 - ratioStart - ratioEnd)) * (ratioStart - ratioEnd) / 2 ;
}
/// <summary>
/// How enemy damage will be reduced by this attack
/// Half bounty for kill, half for making damage equal to enemy health
@ -127,6 +144,7 @@ float AttackPossibility::calculateDamageReduce(
std::shared_ptr<CBattleInfoCallback> state)
{
const float HEALTH_BOUNTY = 0.5;
const float KILL_BOUNTY = 0.5;
// FIXME: provide distance info for Jousting bonus
auto attackerUnitForMeasurement = attacker;
@ -157,13 +175,20 @@ float AttackPossibility::calculateDamageReduce(
auto enemyDamageBeforeAttack = damageCache.getOriginalDamage(defender, attackerUnitForMeasurement, state);
auto enemiesKilled = damageDealt / maxHealth + (damageDealt % maxHealth >= defender->getFirstHPleft() ? 1 : 0);
auto damagePerEnemy = enemyDamageBeforeAttack / (double)defender->getCount();
auto exceedingDamage = (damageDealt % maxHealth);
float hpValue = (damageDealt / maxHealth);
// lets use cached maxHealth here instead of getAvailableHealth
auto firstUnitHpLeft = (availableHealth - damageDealt) % maxHealth;
auto firstUnitHealthRatio = firstUnitHpLeft == 0 ? 1 : static_cast<float>(firstUnitHpLeft) / maxHealth;
auto firstUnitKillValue = (1 - firstUnitHealthRatio) * (1 - firstUnitHealthRatio);
if(defender->getFirstHPleft() >= exceedingDamage)
{
hpValue += hpFunction(defender->getFirstHPleft(), defender->getFirstHPleft() - exceedingDamage, maxHealth);
}
else
{
hpValue += hpFunction(defender->getFirstHPleft(), 0, maxHealth);
hpValue += hpFunction(maxHealth, maxHealth + defender->getFirstHPleft() - exceedingDamage, maxHealth);
}
return damagePerEnemy * (enemiesKilled + firstUnitKillValue * HEALTH_BOUNTY);
return damagePerEnemy * (enemiesKilled * KILL_BOUNTY + hpValue * HEALTH_BOUNTY);
}
int64_t AttackPossibility::evaluateBlockedShootersDmg(

View File

@ -149,7 +149,7 @@ BattleAction BattleEvaluator::selectStackAction(const CStack * stack)
bestAttack.attack.attacker->speed(0, true),
bestAttack.defenderDamageReduce,
bestAttack.attackerDamageReduce,
bestAttack.attackValue()
score
);
if (moveTarget.scorePerTurn <= score)
@ -190,6 +190,14 @@ BattleAction BattleEvaluator::selectStackAction(const CStack * stack)
if(stack->waited())
{
logAi->debug(
"Moving %s towards hex %s[%d], score: %2f/%2f",
stack->getDescription(),
moveTarget.cachedAttack->attack.defender->getDescription(),
moveTarget.cachedAttack->attack.defender->getPosition().hex,
moveTarget.score,
moveTarget.scorePerTurn);
return goTowardsNearest(stack, moveTarget.positions);
}
else
@ -572,7 +580,7 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack)
}
else
{
ps.value = scoreEvaluator.calculateExchange(*cachedAttack, *targets, innerCache, state);
ps.value = scoreEvaluator.evaluateExchange(*cachedAttack, 0, *targets, innerCache, state);
}
for(auto unit : allUnits)

View File

@ -18,10 +18,8 @@ AttackerValue::AttackerValue()
}
MoveTarget::MoveTarget()
: positions(), cachedAttack()
: positions(), cachedAttack(), score(EvaluationResult::INEFFECTIVE_SCORE), scorePerTurn(EvaluationResult::INEFFECTIVE_SCORE)
{
score = EvaluationResult::INEFFECTIVE_SCORE;
scorePerTurn = EvaluationResult::INEFFECTIVE_SCORE;
turnsToRich = 1;
}
@ -58,7 +56,7 @@ float BattleExchangeVariant::trackAttack(
auto attackerDamageReduce = AttackPossibility::calculateDamageReduce(defender.get(), unitToUpdate.get(), retaliationDamage, damageCache, hb);
attackValue -= attackerDamageReduce;
dpsScore -= attackerDamageReduce * negativeEffectMultiplier;
dpsScore.ourDamageReduce += attackerDamageReduce;
attackerValue[unitToUpdate->unitId()].isRetalitated = true;
unitToUpdate->damage(retaliationDamage);
@ -80,7 +78,7 @@ float BattleExchangeVariant::trackAttack(
auto collateralDamageReduce = AttackPossibility::calculateDamageReduce(attacker.get(), unitToUpdate.get(), collateralDamage, damageCache, hb);
attackValue -= collateralDamageReduce;
dpsScore -= collateralDamageReduce * negativeEffectMultiplier;
dpsScore.ourDamageReduce += collateralDamageReduce;
unitToUpdate->damage(collateralDamage);
@ -101,7 +99,7 @@ float BattleExchangeVariant::trackAttack(
float defenderDamageReduce = AttackPossibility::calculateDamageReduce(attacker.get(), unitToUpdate.get(), attackDamage, damageCache, hb);
attackValue += defenderDamageReduce;
dpsScore += defenderDamageReduce * positiveEffectMultiplier;
dpsScore.enemyDamageReduce += defenderDamageReduce;
attackerValue[attacker->unitId()].value += defenderDamageReduce;
unitToUpdate->damage(attackDamage);
@ -118,8 +116,12 @@ float BattleExchangeVariant::trackAttack(
}
}
#if BATTLE_TRACE_LEVEL >= 1
logAi->trace("ap shooters blocking: %lld", ap.shootersBlockedDmg);
#endif
attackValue += ap.shootersBlockedDmg;
dpsScore += ap.shootersBlockedDmg * positiveEffectMultiplier;
dpsScore.enemyDamageReduce += ap.shootersBlockedDmg;
attacker->afterAttack(ap.attack.shooting, false);
return attackValue;
@ -156,11 +158,11 @@ float BattleExchangeVariant::trackAttack(
if(isOurAttack)
{
dpsScore += defenderDamageReduce * positiveEffectMultiplier;
dpsScore.enemyDamageReduce += defenderDamageReduce;
attackerValue[attacker->unitId()].value += defenderDamageReduce;
}
else
dpsScore -= defenderDamageReduce * negativeEffectMultiplier;
dpsScore.ourDamageReduce += defenderDamageReduce;
defender->damage(attackDamage);
attacker->afterAttack(shooting, false);
@ -182,12 +184,12 @@ float BattleExchangeVariant::trackAttack(
if(isOurAttack)
{
dpsScore -= attackerDamageReduce * negativeEffectMultiplier;
dpsScore.ourDamageReduce += attackerDamageReduce;
attackerValue[attacker->unitId()].isRetalitated = true;
}
else
{
dpsScore += attackerDamageReduce * positiveEffectMultiplier;
dpsScore.enemyDamageReduce += attackerDamageReduce;
attackerValue[defender->unitId()].value += attackerDamageReduce;
}
@ -200,13 +202,18 @@ float BattleExchangeVariant::trackAttack(
#if BATTLE_TRACE_LEVEL>=1
if(!score)
{
logAi->trace("Attack has zero score d:%2f a:%2f", defenderDamageReduce, attackerDamageReduce);
logAi->trace("Attack has zero score def:%2f att:%2f", defenderDamageReduce, attackerDamageReduce);
}
#endif
return score;
}
float BattleExchangeEvaluator::scoreValue(const BattleScore & score) const
{
return score.enemyDamageReduce * getPositiveEffectMultiplier() - score.ourDamageReduce * getNegativeEffectMultiplier();
}
EvaluationResult BattleExchangeEvaluator::findBestTarget(
const battle::Unit * activeStack,
PotentialTargets & targets,
@ -215,7 +222,7 @@ EvaluationResult BattleExchangeEvaluator::findBestTarget(
{
EvaluationResult result(targets.bestAction());
if(!activeStack->waited())
if(!activeStack->waited() && !activeStack->acquireState()->hadMorale)
{
#if BATTLE_TRACE_LEVEL>=1
logAi->trace("Evaluating waited attack for %s", activeStack->getDescription());
@ -230,13 +237,17 @@ EvaluationResult BattleExchangeEvaluator::findBestTarget(
for(auto & ap : targets.possibleAttacks)
{
float score = calculateExchange(ap, targets, damageCache, hbWaited);
float score = evaluateExchange(ap, 0, targets, damageCache, hbWaited);
if(score > result.score)
{
result.score = score;
result.bestAttack = ap;
result.wait = true;
#if BATTLE_TRACE_LEVEL >= 1
logAi->trace("New high score %2f", result.score);
#endif
}
}
}
@ -247,15 +258,25 @@ EvaluationResult BattleExchangeEvaluator::findBestTarget(
updateReachabilityMap(hb);
if(result.bestAttack.attack.shooting && hb->battleHasShootingPenalty(activeStack, result.bestAttack.dest))
{
if(!canBeHitThisTurn(result.bestAttack))
return result; // lets wait
}
for(auto & ap : targets.possibleAttacks)
{
float score = calculateExchange(ap, targets, damageCache, hb);
float score = evaluateExchange(ap, 0, targets, damageCache, hb);
if(score >= result.score)
if(score > result.score || (score == result.score && result.wait))
{
result.score = score;
result.bestAttack = ap;
result.wait = false;
#if BATTLE_TRACE_LEVEL >= 1
logAi->trace("New high score %2f", result.score);
#endif
}
}
@ -269,7 +290,7 @@ MoveTarget BattleExchangeEvaluator::findMoveTowardsUnreachable(
std::shared_ptr<HypotheticBattle> hb)
{
MoveTarget result;
BattleExchangeVariant ev(getPositiveEffectMultiplier(), getNegativeEffectMultiplier());
BattleExchangeVariant ev;
if(targets.unreachableEnemies.empty())
return result;
@ -301,6 +322,12 @@ MoveTarget BattleExchangeEvaluator::findMoveTowardsUnreachable(
auto turnsToRich = (distance - 1) / speed + 1;
auto hexes = closestStack->getSurroundingHexes();
auto enemySpeed = closestStack->speed();
auto speedRatio = speed / static_cast<float>(enemySpeed);
auto multiplier = speedRatio > 1 ? 1 : speedRatio;
if(enemy->canShoot())
multiplier *= 1.5f;
for(auto hex : hexes)
{
@ -310,13 +337,13 @@ MoveTarget BattleExchangeEvaluator::findMoveTowardsUnreachable(
attack.shootersBlockedDmg = 0; // we do not want to count on it, it is not for sure
auto score = calculateExchange(attack, targets, damageCache, hb);
auto scorePerTurn = score / turnsToRich;
auto score = calculateExchange(attack, turnsToRich, targets, damageCache, hb);
auto scorePerTurn = BattleScore(score.enemyDamageReduce * std::sqrt(multiplier / turnsToRich), score.ourDamageReduce);
if(result.scorePerTurn < scorePerTurn)
if(result.scorePerTurn < scoreValue(scorePerTurn))
{
result.scorePerTurn = scorePerTurn;
result.score = score;
result.scorePerTurn = scoreValue(scorePerTurn);
result.score = scoreValue(score);
result.positions = closestStack->getAttackableHexes(activeStack);
result.cachedAttack = attack;
result.turnsToRich = turnsToRich;
@ -357,21 +384,23 @@ std::vector<const battle::Unit *> BattleExchangeEvaluator::getAdjacentUnits(cons
return checkedStacks;
}
std::vector<const battle::Unit *> BattleExchangeEvaluator::getExchangeUnits(
ReachabilityData BattleExchangeEvaluator::getExchangeUnits(
const AttackPossibility & ap,
uint8_t turn,
PotentialTargets & targets,
std::shared_ptr<HypotheticBattle> hb)
{
auto hexes = ap.attack.defender->getHexes();
ReachabilityData result;
auto hexes = ap.attack.defender->getSurroundingHexes();
if(!ap.attack.shooting) hexes.push_back(ap.from);
std::vector<const battle::Unit *> exchangeUnits;
std::vector<const battle::Unit *> allReachableUnits;
for(auto hex : hexes)
{
vstd::concatenate(allReachableUnits, reachabilityMap[hex]);
vstd::concatenate(allReachableUnits, turn == 0 ? reachabilityMap[hex] : getOneTurnReachableUnits(turn, hex));
}
vstd::removeDuplicates(allReachableUnits);
@ -404,7 +433,28 @@ std::vector<const battle::Unit *> BattleExchangeEvaluator::getExchangeUnits(
logAi->trace("Reachability map contains only %d stacks", allReachableUnits.size());
#endif
return exchangeUnits;
return result;
}
for(auto unit : allReachableUnits)
{
auto accessible = !unit->canShoot();
if(!accessible)
{
for(auto hex : unit->getSurroundingHexes())
{
if(ap.attack.defender->coversPos(hex))
{
accessible = true;
}
}
}
if(accessible)
result.melleeAccessible.push_back(unit);
else
result.shooters.push_back(unit);
}
for(int turn = 0; turn < turnOrder.size(); turn++)
@ -412,20 +462,47 @@ std::vector<const battle::Unit *> BattleExchangeEvaluator::getExchangeUnits(
for(auto unit : turnOrder[turn])
{
if(vstd::contains(allReachableUnits, unit))
exchangeUnits.push_back(unit);
result.units.push_back(unit);
}
}
vstd::erase_if(exchangeUnits, [&](const battle::Unit * u) -> bool
vstd::erase_if(result.units, [&](const battle::Unit * u) -> bool
{
return !hb->battleGetUnitByID(u->unitId())->alive();
});
return exchangeUnits;
return result;
}
float BattleExchangeEvaluator::calculateExchange(
float BattleExchangeEvaluator::evaluateExchange(
const AttackPossibility & ap,
uint8_t turn,
PotentialTargets & targets,
DamageCache & damageCache,
std::shared_ptr<HypotheticBattle> hb)
{
if(ap.from.hex == 127)
{
logAi->trace("x");
}
BattleScore score = calculateExchange(ap, turn, targets, damageCache, hb);
#if BATTLE_TRACE_LEVEL >= 1
logAi->trace(
"calculateExchange score +%2f -%2fx%2f = %2f",
score.enemyDamageReduce,
score.ourDamageReduce,
getNegativeEffectMultiplier(),
scoreValue(score));
#endif
return scoreValue(score);
}
BattleScore BattleExchangeEvaluator::calculateExchange(
const AttackPossibility & ap,
uint8_t turn,
PotentialTargets & targets,
DamageCache & damageCache,
std::shared_ptr<HypotheticBattle> hb)
@ -438,7 +515,7 @@ float BattleExchangeEvaluator::calculateExchange(
&& cb->battleGetGateState() == EGateState::BLOCKED
&& ap.attack.defender->coversPos(BattleHex::GATE_BRIDGE))
{
return EvaluationResult::INEFFECTIVE_SCORE;
return BattleScore(EvaluationResult::INEFFECTIVE_SCORE, 0);
}
std::vector<const battle::Unit *> ourStacks;
@ -447,27 +524,32 @@ float BattleExchangeEvaluator::calculateExchange(
if(hb->battleGetUnitByID(ap.attack.defender->unitId())->alive())
enemyStacks.push_back(ap.attack.defender);
std::vector<const battle::Unit *> exchangeUnits = getExchangeUnits(ap, targets, hb);
ReachabilityData exchangeUnits = getExchangeUnits(ap, turn, targets, hb);
if(exchangeUnits.empty())
if(exchangeUnits.units.empty())
{
return 0;
return BattleScore();
}
auto exchangeBattle = std::make_shared<HypotheticBattle>(env.get(), hb);
BattleExchangeVariant v(getPositiveEffectMultiplier(), getNegativeEffectMultiplier());
BattleExchangeVariant v;
for(auto unit : exchangeUnits)
for(auto unit : exchangeUnits.units)
{
if(unit->isTurret())
continue;
bool isOur = exchangeBattle->battleMatchOwner(ap.attack.attacker, unit, true);
auto & attackerQueue = isOur ? ourStacks : enemyStacks;
auto u = exchangeBattle->getForUpdate(unit->unitId());
if(exchangeBattle->getForUpdate(unit->unitId())->alive() && !vstd::contains(attackerQueue, unit))
if(u->alive() && !vstd::contains(attackerQueue, unit))
{
attackerQueue.push_back(unit);
#if BATTLE_TRACE_LEVEL
logAi->trace("Exchanging: %s", u->getDescription());
#endif
}
}
@ -476,12 +558,12 @@ float BattleExchangeEvaluator::calculateExchange(
vstd::removeDuplicates(melleeAttackers);
vstd::erase_if(melleeAttackers, [&](const battle::Unit * u) -> bool
{
return !cb->battleCanShoot(u);
return cb->battleCanShoot(u);
});
bool canUseAp = true;
for(auto activeUnit : exchangeUnits)
for(auto activeUnit : exchangeUnits.units)
{
bool isOur = exchangeBattle->battleMatchOwner(ap.attack.attacker, activeUnit, true);
battle::Units & attackerQueue = isOur ? ourStacks : enemyStacks;
@ -515,15 +597,22 @@ float BattleExchangeEvaluator::calculateExchange(
true);
#if BATTLE_TRACE_LEVEL>=1
logAi->trace("Best target selector %s->%s score = %2f", attacker->getDescription(), u->getDescription(), score);
logAi->trace("Best target selector %s->%s score = %2f", attacker->getDescription(), stackWithBonuses->getDescription(), score);
#endif
return score;
};
if(!oppositeQueue.empty())
auto unitsInOppositeQueueExceptInaccessible = oppositeQueue;
vstd::erase_if(unitsInOppositeQueueExceptInaccessible, [&](const battle::Unit * u)->bool
{
return vstd::contains(exchangeUnits.shooters, u);
});
if(!unitsInOppositeQueueExceptInaccessible.empty())
{
targetUnit = *vstd::maxElementByFun(oppositeQueue, estimateAttack);
targetUnit = *vstd::maxElementByFun(unitsInOppositeQueueExceptInaccessible, estimateAttack);
}
else
{
@ -591,10 +680,20 @@ float BattleExchangeEvaluator::calculateExchange(
// avoid blocking path for stronger stack by weaker stack
// the method checks if all stacks can be placed around enemy
v.adjustPositions(melleeAttackers, ap, reachabilityMap);
std::map<BattleHex, battle::Units> reachabilityMap;
auto hexes = ap.attack.defender->getSurroundingHexes();
for(auto hex : hexes)
reachabilityMap[hex] = getOneTurnReachableUnits(turn, hex);
if(!ap.attack.shooting)
{
v.adjustPositions(melleeAttackers, ap, reachabilityMap);
}
#if BATTLE_TRACE_LEVEL>=1
logAi->trace("Exchange score: %2f", v.getScore());
logAi->trace("Exchange score: enemy: %2f, our -%2f", v.getScore().enemyDamageReduce, v.getScore().ourDamageReduce);
#endif
return v.getScore();
@ -618,11 +717,8 @@ void BattleExchangeVariant::adjustPositions(
return attackerValue[u1->unitId()].value > attackerValue[u2->unitId()].value;
});
if(!ap.attack.shooting)
{
vstd::erase_if_present(hexes, ap.from);
vstd::erase_if_present(hexes, ap.attack.attacker->occupiedHex(ap.attack.attackerPos));
}
vstd::erase_if_present(hexes, ap.from);
vstd::erase_if_present(hexes, ap.attack.attacker->occupiedHex(ap.attack.attackerPos));
float notRealizedDamage = 0;
@ -662,22 +758,58 @@ void BattleExchangeVariant::adjustPositions(
if(notRealizedDamage > ap.attackValue() && notRealizedDamage > attackerValue[ap.attack.attacker->unitId()].value)
{
dpsScore = EvaluationResult::INEFFECTIVE_SCORE;
dpsScore = BattleScore(EvaluationResult::INEFFECTIVE_SCORE, 0);
}
}
void BattleExchangeEvaluator::updateReachabilityMap( std::shared_ptr<HypotheticBattle> hb)
bool BattleExchangeEvaluator::canBeHitThisTurn(const AttackPossibility & ap)
{
for(auto pos : ap.attack.attacker->getSurroundingHexes())
{
for(auto u : reachabilityMap[pos])
{
if(u->unitSide() != ap.attack.attacker->unitSide())
{
return true;
}
}
}
return false;
}
void BattleExchangeEvaluator::updateReachabilityMap(std::shared_ptr<HypotheticBattle> hb)
{
const int TURN_DEPTH = 2;
turnOrder.clear();
hb->battleGetTurnOrder(turnOrder, std::numeric_limits<int>::max(), TURN_DEPTH);
reachabilityMap.clear();
for(int turn = 0; turn < turnOrder.size(); turn++)
hb->battleGetTurnOrder(turnOrder, std::numeric_limits<int>::max(), TURN_DEPTH);
for(auto turn : turnOrder)
{
auto & turnQueue = turnOrder[turn];
for(auto u : turn)
{
if(!vstd::contains(reachabilityCache, u->unitId()))
{
reachabilityCache[u->unitId()] = hb->getReachability(u);
}
}
}
for(BattleHex hex = BattleHex::TOP_LEFT; hex.isValid(); hex = hex + 1)
{
reachabilityMap[hex] = getOneTurnReachableUnits(0, hex);
}
}
std::vector<const battle::Unit *> BattleExchangeEvaluator::getOneTurnReachableUnits(uint8_t turn, BattleHex hex)
{
std::vector<const battle::Unit *> result;
for(int i = 0; i < turnOrder.size(); i++, turn++)
{
auto & turnQueue = turnOrder[i];
HypotheticBattle turnBattle(env.get(), cb);
for(const battle::Unit * unit : turnQueue)
@ -685,46 +817,49 @@ void BattleExchangeEvaluator::updateReachabilityMap( std::shared_ptr<HypotheticB
if(unit->isTurret())
continue;
auto unitSpeed = unit->speed(turn);
if(turnBattle.battleCanShoot(unit))
{
for(BattleHex hex = BattleHex::TOP_LEFT; hex.isValid(); hex = hex + 1)
{
reachabilityMap[hex].push_back(unit);
}
result.push_back(unit);
continue;
}
auto unitReachability = turnBattle.getReachability(unit);
auto unitSpeed = unit->speed(turn);
auto radius = unitSpeed * (turn + 1);
for(BattleHex hex = BattleHex::TOP_LEFT; hex.isValid(); hex = hex + 1)
{
bool reachable = unitReachability.distances[hex] <= unitSpeed;
if(!reachable && unitReachability.accessibility[hex] == EAccessibility::ALIVE_STACK)
ReachabilityInfo unitReachability = vstd::getOrCompute(
reachabilityCache,
unit->unitId(),
[&](ReachabilityInfo & data)
{
const battle::Unit * hexStack = cb->battleGetUnitByPos(hex);
data = turnBattle.getReachability(unit);
});
if(hexStack && cb->battleMatchOwner(unit, hexStack, false))
bool reachable = unitReachability.distances[hex] <= radius;
if(!reachable && unitReachability.accessibility[hex] == EAccessibility::ALIVE_STACK)
{
const battle::Unit * hexStack = cb->battleGetUnitByPos(hex);
if(hexStack && cb->battleMatchOwner(unit, hexStack, false))
{
for(BattleHex neighbor : hex.neighbouringTiles())
{
for(BattleHex neighbor : hex.neighbouringTiles())
{
reachable = unitReachability.distances[neighbor] <= unitSpeed;
reachable = unitReachability.distances[neighbor] <= radius;
if(reachable) break;
}
if(reachable) break;
}
}
}
if(reachable)
{
reachabilityMap[hex].push_back(unit);
}
if(reachable)
{
result.push_back(unit);
}
}
}
return result;
}
// avoid blocking path for stronger stack by weaker stack

View File

@ -14,6 +14,34 @@
#include "PotentialTargets.h"
#include "StackWithBonuses.h"
struct BattleScore
{
float ourDamageReduce;
float enemyDamageReduce;
BattleScore(float enemyDamageReduce, float ourDamageReduce)
:enemyDamageReduce(enemyDamageReduce), ourDamageReduce(ourDamageReduce)
{
}
BattleScore() : BattleScore(0, 0) {}
float value()
{
return enemyDamageReduce - ourDamageReduce;
}
BattleScore operator+(BattleScore & other)
{
BattleScore result = *this;
result.ourDamageReduce += other.ourDamageReduce;
result.enemyDamageReduce += other.enemyDamageReduce;
return result;
}
};
struct AttackerValue
{
float value;
@ -59,8 +87,8 @@ struct EvaluationResult
class BattleExchangeVariant
{
public:
BattleExchangeVariant(float positiveEffectMultiplier, float negativeEffectMultiplier)
: dpsScore(0), positiveEffectMultiplier(positiveEffectMultiplier), negativeEffectMultiplier(negativeEffectMultiplier) {}
BattleExchangeVariant()
: dpsScore() {}
float trackAttack(
const AttackPossibility & ap,
@ -76,7 +104,7 @@ public:
std::shared_ptr<HypotheticBattle> hb,
bool evaluateOnly = false);
float getScore() const { return dpsScore; }
const BattleScore & getScore() const { return dpsScore; }
void adjustPositions(
std::vector<const battle::Unit *> attackers,
@ -84,27 +112,48 @@ public:
std::map<BattleHex, battle::Units> & reachabilityMap);
private:
float positiveEffectMultiplier;
float negativeEffectMultiplier;
float dpsScore;
BattleScore dpsScore;
std::map<uint32_t, AttackerValue> attackerValue;
};
struct ReachabilityData
{
std::vector<const battle::Unit *> units;
// shooters which are within mellee attack and mellee units
std::vector<const battle::Unit *> melleeAccessible;
// far shooters
std::vector<const battle::Unit *> shooters;
};
class BattleExchangeEvaluator
{
private:
std::shared_ptr<CBattleInfoCallback> cb;
std::shared_ptr<Environment> env;
std::map<uint32_t, ReachabilityInfo> reachabilityCache;
std::map<BattleHex, std::vector<const battle::Unit *>> reachabilityMap;
std::vector<battle::Units> turnOrder;
float negativeEffectMultiplier;
float scoreValue(const BattleScore & score) const;
BattleScore calculateExchange(
const AttackPossibility & ap,
uint8_t turn,
PotentialTargets & targets,
DamageCache & damageCache,
std::shared_ptr<HypotheticBattle> hb);
bool canBeHitThisTurn(const AttackPossibility & ap);
public:
BattleExchangeEvaluator(
std::shared_ptr<CBattleInfoCallback> cb,
std::shared_ptr<Environment> env,
float strengthRatio): cb(cb), env(env) {
negativeEffectMultiplier = strengthRatio;
negativeEffectMultiplier = strengthRatio >= 1 ? 1 : strengthRatio;
}
EvaluationResult findBestTarget(
@ -113,14 +162,22 @@ public:
DamageCache & damageCache,
std::shared_ptr<HypotheticBattle> hb);
float calculateExchange(
float evaluateExchange(
const AttackPossibility & ap,
uint8_t turn,
PotentialTargets & targets,
DamageCache & damageCache,
std::shared_ptr<HypotheticBattle> hb);
std::vector<const battle::Unit *> getOneTurnReachableUnits(uint8_t turn, BattleHex hex);
void updateReachabilityMap(std::shared_ptr<HypotheticBattle> hb);
std::vector<const battle::Unit *> getExchangeUnits(const AttackPossibility & ap, PotentialTargets & targets, std::shared_ptr<HypotheticBattle> hb);
ReachabilityData getExchangeUnits(
const AttackPossibility & ap,
uint8_t turn,
PotentialTargets & targets,
std::shared_ptr<HypotheticBattle> hb);
bool checkPositionBlocksOurStacks(HypotheticBattle & hb, const battle::Unit * unit, BattleHex position);
MoveTarget findMoveTowardsUnreachable(
@ -131,6 +188,6 @@ public:
std::vector<const battle::Unit *> getAdjacentUnits(const battle::Unit * unit) const;
float getPositiveEffectMultiplier() { return 1; }
float getNegativeEffectMultiplier() { return negativeEffectMultiplier; }
float getPositiveEffectMultiplier() const { return 1; }
float getNegativeEffectMultiplier() const { return negativeEffectMultiplier; }
};

View File

@ -12,9 +12,10 @@
#include <vcmi/events/EventBus.h>
#include "../../lib/NetPacks.h"
#include "../../lib/CStack.h"
#include "../../lib/ScriptHandler.h"
#include "../../lib/networkPacks/PacksForClientBattle.h"
#include "../../lib/networkPacks/SetStackEffect.h"
#if SCRIPTING_ENABLED
using scripting::Pool;

View File

@ -12,14 +12,18 @@
#include "../../lib/UnlockGuard.h"
#include "../../lib/mapObjects/MapObjects.h"
#include "../../lib/mapObjects/ObjectTemplate.h"
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/CConfigHandler.h"
#include "../../lib/CHeroHandler.h"
#include "../../lib/GameSettings.h"
#include "../../lib/gameState/CGameState.h"
#include "../../lib/NetPacks.h"
#include "../../lib/serializer/CTypeList.h"
#include "../../lib/serializer/BinarySerializer.h"
#include "../../lib/serializer/BinaryDeserializer.h"
#include "../../lib/networkPacks/PacksForClient.h"
#include "../../lib/networkPacks/PacksForClientBattle.h"
#include "../../lib/networkPacks/PacksForServer.h"
#include "../../lib/networkPacks/StackLocation.h"
#include "../../lib/battle/BattleStateInfoForRetreat.h"
#include "../../lib/battle/BattleInfo.h"

View File

@ -274,6 +274,7 @@ void Nullkiller::makeTurn()
bestTask = choseBestTask(bestTasks);
std::string taskDescription = bestTask->toString();
HeroPtr hero = bestTask->getHero();
HeroRole heroRole = HeroRole::MAIN;
@ -292,7 +293,7 @@ void Nullkiller::makeTurn()
logAi->trace(
"Goal %s has low priority %f so decreasing scan depth to gain performance.",
bestTask->toString(),
taskDescription,
bestTask->priority);
}
@ -308,7 +309,7 @@ void Nullkiller::makeTurn()
{
logAi->trace(
"Goal %s has too low priority %f so increasing scan depth to full.",
bestTask->toString(),
taskDescription,
bestTask->priority);
scanDepth = ScanDepth::ALL_FULL;
@ -316,7 +317,7 @@ void Nullkiller::makeTurn()
continue;
}
logAi->trace("Goal %s has too low priority. It is not worth doing it. Ending turn.", bestTask->toString());
logAi->trace("Goal %s has too low priority. It is not worth doing it. Ending turn.", taskDescription);
return;
}
@ -325,7 +326,7 @@ void Nullkiller::makeTurn()
if(i == MAXPASS)
{
logAi->error("Goal %s exceeded maxpass. Terminating AI turn.", bestTask->toString());
logAi->error("Goal %s exceeded maxpass. Terminating AI turn.", taskDescription);
}
}
}

View File

@ -21,12 +21,13 @@
#include "../../lib/CHeroHandler.h"
#include "../../lib/GameSettings.h"
#include "../../lib/gameState/CGameState.h"
#include "../../lib/NetPacksBase.h"
#include "../../lib/NetPacks.h"
#include "../../lib/bonuses/CBonusSystemNode.h"
#include "../../lib/bonuses/Limiters.h"
#include "../../lib/bonuses/Updaters.h"
#include "../../lib/bonuses/Propagators.h"
#include "../../lib/networkPacks/PacksForClient.h"
#include "../../lib/networkPacks/PacksForClientBattle.h"
#include "../../lib/networkPacks/PacksForServer.h"
#include "../../lib/serializer/CTypeList.h"
#include "../../lib/serializer/BinarySerializer.h"
#include "../../lib/serializer/BinaryDeserializer.h"

View File

@ -15,15 +15,16 @@
#include "client/CPlayerInterface.h"
#include "client/Client.h"
#include "lib/mapping/CMap.h"
#include "lib/mapObjects/CGHeroInstance.h"
#include "lib/CBuildingHandler.h"
#include "lib/CGeneralTextHandler.h"
#include "lib/CHeroHandler.h"
#include "lib/NetPacks.h"
#include "lib/CArtHandler.h"
#include "lib/GameConstants.h"
#include "lib/CPlayerState.h"
#include "lib/UnlockGuard.h"
#include "lib/battle/BattleInfo.h"
#include "lib/networkPacks/PacksForServer.h"
bool CCallback::teleportHero(const CGHeroInstance *who, const CGTownInstance *where)
{

View File

@ -22,7 +22,9 @@ public class Storage
public static boolean testH3DataFolder(final File baseDir)
{
final File testH3Data = new File(baseDir, "Data");
return testH3Data.exists();
final File testH3data = new File(baseDir, "data");
final File testH3DATA = new File(baseDir, "DATA");
return testH3Data.exists() || testH3data.exists() || testH3DATA.exists();
}
public static String getH3DataFolder(Context context){

View File

@ -127,9 +127,21 @@ public class CopyDataController extends LauncherSettingController<Void, Void>
for (DocumentFile child : sourceDir.listFiles())
{
if (allowed != null && !allowed.contains(child.getName()))
if (allowed != null)
{
continue;
boolean fileAllowed = false;
for (String str : allowed)
{
if (str.equalsIgnoreCase(child.getName()))
{
fileAllowed = true;
break;
}
}
if (!fileAllowed)
continue;
}
File exported = new File(targetDir, child.getName());

View File

@ -73,8 +73,6 @@
#include "../lib/CondSh.h"
#include "../lib/GameConstants.h"
#include "../lib/JsonNode.h"
#include "../lib/NetPacks.h" //todo: remove
#include "../lib/NetPacksBase.h"
#include "../lib/RoadHandler.h"
#include "../lib/StartInfo.h"
#include "../lib/TerrainHandler.h"
@ -95,6 +93,10 @@
#include "../lib/mapping/CMapHeader.h"
#include "../lib/networkPacks/PacksForClient.h"
#include "../lib/networkPacks/PacksForClientBattle.h"
#include "../lib/networkPacks/PacksForServer.h"
#include "../lib/pathfinder/CGPathNode.h"
#include "../lib/serializer/BinaryDeserializer.h"

View File

@ -38,7 +38,6 @@
#include "../lib/CConfigHandler.h"
#include "../lib/CGeneralTextHandler.h"
#include "../lib/CThreadHelper.h"
#include "../lib/NetPackVisitor.h"
#include "../lib/StartInfo.h"
#include "../lib/TurnTimerInfo.h"
#include "../lib/VCMIDirs.h"

View File

@ -18,7 +18,6 @@
#include "gui/CGuiHandler.h"
#include "gui/WindowHandler.h"
#include "render/IRenderHandler.h"
#include "../lib/NetPacks.h"
#include "ClientNetPackVisitors.h"
#include "../lib/CConfigHandler.h"
#include "../lib/gameState/CGameState.h"
@ -28,6 +27,7 @@
#include "../lib/mapping/CMapService.h"
#include "../lib/mapping/CMap.h"
#include "windows/CCastleInterface.h"
#include "../lib/mapObjects/CGHeroInstance.h"
#include "render/CAnimation.h"
#include "../CCallback.h"
#include "../lib/CGeneralTextHandler.h"

View File

@ -9,7 +9,7 @@
*/
#pragma once
#include "../lib/NetPackVisitor.h"
#include "../lib/networkPacks/NetPackVisitor.h"
class CClient;

View File

@ -24,9 +24,9 @@
#include "../lib/pathfinder/CGPathNode.h"
#include "../lib/mapObjects/CGHeroInstance.h"
#include "../lib/networkPacks/PacksForClient.h"
#include "../lib/RoadHandler.h"
#include "../lib/TerrainHandler.h"
#include "../lib/NetPacks.h"
bool HeroMovementController::isHeroMovingThroughGarrison(const CGHeroInstance * hero, const CArmedInstance * garrison) const
{

View File

@ -9,9 +9,11 @@
*/
#pragma once
#include "../lib/NetPackVisitor.h"
#include "../lib/networkPacks/NetPackVisitor.h"
#include "../lib/networkPacks/PacksForLobby.h"
class CClient;
class CLobbyScreen;
VCMI_LIB_NAMESPACE_BEGIN
class CGameState;
VCMI_LIB_NAMESPACE_END

View File

@ -27,7 +27,6 @@
#include "../lib/CConfigHandler.h"
#include "../lib/CGeneralTextHandler.h"
#include "../lib/NetPacksLobby.h"
#include "../lib/serializer/Connection.h"
void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientConnected(LobbyClientConnected & pack)

View File

@ -12,6 +12,7 @@
#include "../gui/CIntObject.h"
#include "CConfigHandler.h"
#include "../../lib/filesystem/ResourcePath.h"
#include "../../lib/networkPacks/Component.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -28,7 +28,7 @@
#include "../../CCallback.h"
#include "../../lib/battle/BattleAction.h"
#include "../../lib/filesystem/ResourcePath.h"
#include "../../lib/NetPacks.h"
#include "../../lib/networkPacks/PacksForClientBattle.h"
#include "../../lib/CStack.h"
#include "../../lib/IGameEventsReceiver.h"
#include "../../lib/CGeneralTextHandler.h"

View File

@ -40,7 +40,7 @@
#include "../../lib/CondSh.h"
#include "../../lib/gameState/InfoAboutArmy.h"
#include "../../lib/mapObjects/CGTownInstance.h"
#include "../../lib/NetPacks.h"
#include "../../lib/networkPacks/PacksForClientBattle.h"
#include "../../lib/UnlockGuard.h"
#include "../../lib/TerrainHandler.h"
#include "../../lib/CThreadHelper.h"

View File

@ -48,10 +48,10 @@
#include "../../lib/CGeneralTextHandler.h"
#include "../../lib/CTownHandler.h"
#include "../../lib/CHeroHandler.h"
#include "../../lib/NetPacks.h"
#include "../../lib/StartInfo.h"
#include "../../lib/CondSh.h"
#include "../../lib/mapObjects/CGTownInstance.h"
#include "../../lib/networkPacks/PacksForClientBattle.h"
#include "../../lib/TextOperations.h"
void BattleConsole::showAll(Canvas & to)

View File

@ -26,9 +26,9 @@
#include "../render/IRenderHandler.h"
#include "../../CCallback.h"
#include "../../lib/NetPacks.h"
#include "../../lib/CStack.h"
#include "../../lib/mapObjects/CGTownInstance.h"
#include "../../lib/networkPacks/PacksForClientBattle.h"
ImagePath BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisual what, EWallState state) const
{

View File

@ -25,7 +25,7 @@
#include "../../CCallback.h"
#include "../CGameInfo.h"
#include "../../lib/NetPacksLobby.h"
#include "../../lib/networkPacks/PacksForLobby.h"
#include "../../lib/CGeneralTextHandler.h"
#include "../../lib/campaign/CampaignHandler.h"
#include "../../lib/mapping/CMapInfo.h"

View File

@ -41,7 +41,6 @@
#include "../render/IFont.h"
#include "../render/IRenderHandler.h"
#include "../../lib/NetPacksLobby.h"
#include "../../lib/CGeneralTextHandler.h"
#include "../../lib/CHeroHandler.h"
#include "../../lib/CThreadHelper.h"

View File

@ -34,7 +34,7 @@
#include "../eventsSDL/InputHandler.h"
#include "../../lib/filesystem/Filesystem.h"
#include "../../lib/NetPacksLobby.h"
#include "../../lib/networkPacks/PacksForLobby.h"
#include "../../lib/CGeneralTextHandler.h"
#include "../../lib/CArtHandler.h"
#include "../../lib/CTownHandler.h"

View File

@ -34,7 +34,6 @@
#include "../../CCallback.h"
#include "../../lib/NetPacksLobby.h"
#include "../../lib/CGeneralTextHandler.h"
#include "../../lib/CConfigHandler.h"
#include "../../lib/GameSettings.h"

View File

@ -51,7 +51,6 @@
#include "../../lib/mapping/CMapInfo.h"
#include "../../lib/VCMIDirs.h"
#include "../../lib/CStopWatch.h"
#include "../../lib/NetPacksLobby.h"
#include "../../lib/CThreadHelper.h"
#include "../../lib/CConfigHandler.h"
#include "../../lib/GameConstants.h"

View File

@ -26,6 +26,7 @@
#include "../../lib/CGeneralTextHandler.h"
#include "../../lib/ArtifactUtils.h"
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/networkPacks/ArtifactLocation.h"
#include "../../lib/CConfigHandler.h"
void CArtPlace::setInternals(const CArtifactInstance * artInst)

View File

@ -16,6 +16,7 @@
#include "../../lib/ArtifactUtils.h"
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/networkPacks/ArtifactLocation.h"
CArtifactsOfHeroAltar::CArtifactsOfHeroAltar(const Point & position)
: visibleArtSet(ArtBearer::ArtBearer::HERO)
@ -109,4 +110,4 @@ void CArtifactsOfHeroAltar::deleteFromVisible(const CArtifactInstance * artInst)
getArtPlace(part.slot)->setArtifact(nullptr);
}
}
}
}

View File

@ -18,6 +18,7 @@
#include "../CPlayerInterface.h"
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/networkPacks/ArtifactLocation.h"
#include "../../CCallback.h"

View File

@ -22,6 +22,7 @@
#include "../../lib/ArtifactUtils.h"
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/networkPacks/ArtifactLocation.h"
CArtifactsOfHeroBase::CArtifactsOfHeroBase()
: backpackPos(0),

View File

@ -15,6 +15,7 @@
#include "../CPlayerInterface.h"
#include "../../CCallback.h"
#include "../../lib/networkPacks/ArtifactLocation.h"
CArtifactsOfHeroKingdom::CArtifactsOfHeroKingdom(ArtPlaceMap ArtWorn, std::vector<ArtPlacePtr> Backpack,
std::shared_ptr<CButton> leftScroll, std::shared_ptr<CButton> rightScroll)

View File

@ -13,6 +13,7 @@
#include "../CPlayerInterface.h"
#include "../../CCallback.h"
#include "../../lib/networkPacks/ArtifactLocation.h"
CArtifactsOfHeroMain::CArtifactsOfHeroMain(const Point & position)
{
@ -37,4 +38,4 @@ void CArtifactsOfHeroMain::pickUpArtifact(CHeroArtPlace & artPlace)
{
LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero, artPlace.slot),
ArtifactLocation(curHero, ArtifactPosition::TRANSITION_POS));
}
}

View File

@ -31,11 +31,11 @@
#include "../../lib/ArtifactUtils.h"
#include "../../lib/CTownHandler.h"
#include "../../lib/CHeroHandler.h"
#include "../../lib/networkPacks/Component.h"
#include "../../lib/spells/CSpellHandler.h"
#include "../../lib/CCreatureHandler.h"
#include "../../lib/CSkillHandler.h"
#include "../../lib/CGeneralTextHandler.h"
#include "../../lib/NetPacksBase.h"
#include "../../lib/CArtHandler.h"
#include "../../lib/CArtifactInstance.h"

View File

@ -30,6 +30,7 @@
#include "../../lib/CCreatureHandler.h"
#include "../../lib/CConfigHandler.h"
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/networkPacks/ArtifactLocation.h"
#include "../../lib/TextOperations.h"
#include "../../lib/gameState/CGameState.h"

View File

@ -29,6 +29,7 @@
#include "../../lib/ArtifactUtils.h"
#include "../../lib/CGeneralTextHandler.h"
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/networkPacks/ArtifactLocation.h"
#include "../../lib/CConfigHandler.h"
void CWindowWithArtifacts::addSet(CArtifactsOfHeroPtr artSet)

View File

@ -33,6 +33,7 @@
#include "../../lib/GameSettings.h"
#include "../../lib/CHeroHandler.h"
#include "../../lib/gameState/CGameState.h"
#include "../../lib/networkPacks/ArtifactLocation.h"
#include "../../lib/TextOperations.h"
class CCreatureArtifactInstance;

View File

@ -39,7 +39,7 @@
#include "../lib/CHeroHandler.h"
#include "../lib/CSkillHandler.h"
#include "../lib/mapObjects/CGHeroInstance.h"
#include "../lib/NetPacksBase.h"
#include "../../lib/networkPacks/ArtifactLocation.h"
void CHeroSwitcher::clickPressed(const Point & cursorPosition)
{

View File

@ -35,6 +35,7 @@
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/mapObjects/CGTownInstance.h"
#include "../../lib/mapObjects/CGMarket.h"
#include "../../lib/networkPacks/ArtifactLocation.h"
CTradeWindow::CTradeableItem::CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial)
: CIntObject(LCLICK | HOVER | SHOW_POPUP, pos),

View File

@ -123,6 +123,8 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/modding/IdentifierStorage.cpp
${MAIN_LIB_DIR}/modding/ModUtility.cpp
${MAIN_LIB_DIR}/networkPacks/NetPacksLib.cpp
${MAIN_LIB_DIR}/pathfinder/CGPathNode.cpp
${MAIN_LIB_DIR}/pathfinder/CPathfinder.cpp
${MAIN_LIB_DIR}/pathfinder/NodeStorage.cpp
@ -255,7 +257,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/JsonRandom.cpp
${MAIN_LIB_DIR}/LoadProgress.cpp
${MAIN_LIB_DIR}/LogicalExpression.cpp
${MAIN_LIB_DIR}/NetPacksLib.cpp
${MAIN_LIB_DIR}/MetaString.cpp
${MAIN_LIB_DIR}/ObstacleHandler.cpp
${MAIN_LIB_DIR}/StartInfo.cpp
@ -475,6 +476,21 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/modding/ModScope.h
${MAIN_LIB_DIR}/modding/ModUtility.h
${MAIN_LIB_DIR}/networkPacks/ArtifactLocation.h
${MAIN_LIB_DIR}/networkPacks/BattleChanges.h
${MAIN_LIB_DIR}/networkPacks/Component.h
${MAIN_LIB_DIR}/networkPacks/EInfoWindowMode.h
${MAIN_LIB_DIR}/networkPacks/EntityChanges.h
${MAIN_LIB_DIR}/networkPacks/EOpenWindowMode.h
${MAIN_LIB_DIR}/networkPacks/NetPacksBase.h
${MAIN_LIB_DIR}/networkPacks/NetPackVisitor.h
${MAIN_LIB_DIR}/networkPacks/PacksForClient.h
${MAIN_LIB_DIR}/networkPacks/PacksForClientBattle.h
${MAIN_LIB_DIR}/networkPacks/PacksForLobby.h
${MAIN_LIB_DIR}/networkPacks/PacksForServer.h
${MAIN_LIB_DIR}/networkPacks/SetStackEffect.h
${MAIN_LIB_DIR}/networkPacks/StackLocation.h
${MAIN_LIB_DIR}/pathfinder/INodeStorage.h
${MAIN_LIB_DIR}/pathfinder/CGPathNode.h
${MAIN_LIB_DIR}/pathfinder/CPathfinder.h
@ -615,10 +631,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/LoadProgress.h
${MAIN_LIB_DIR}/LogicalExpression.h
${MAIN_LIB_DIR}/MetaString.h
${MAIN_LIB_DIR}/NetPacksBase.h
${MAIN_LIB_DIR}/NetPacks.h
${MAIN_LIB_DIR}/NetPacksLobby.h
${MAIN_LIB_DIR}/NetPackVisitor.h
${MAIN_LIB_DIR}/ObstacleHandler.h
${MAIN_LIB_DIR}/Point.h
${MAIN_LIB_DIR}/Rect.h

View File

@ -63,7 +63,7 @@ If you are interested in providing builds for other distributions, please let us
## Compiling from source
Please check following developer guide: [How to build VCMI (Linux)]((../developers/Building_Linux.md))
Please check following developer guide: [How to build VCMI (Linux)](../developers/Building_Linux.md)
# Step 2: Installing Heroes III data files

View File

@ -13,7 +13,7 @@
#include "ArtifactUtils.h"
#include "CArtHandler.h"
#include "NetPacksBase.h"
#include "networkPacks/ArtifactLocation.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -23,7 +23,6 @@
#include "CHeroHandler.h"
#include "IBonusTypeHandler.h"
#include "serializer/JsonSerializeFormat.h"
#include "NetPacksBase.h"
#include <vcmi/FactionService.h>
#include <vcmi/Faction.h>

View File

@ -14,10 +14,11 @@
#include "gameState/InfoAboutArmy.h"
#include "gameState/SThievesGuildInfo.h"
#include "gameState/TavernHeroesPool.h"
#include "gameState/QuestInfo.h"
#include "mapObjects/CGHeroInstance.h"
#include "CGeneralTextHandler.h"
#include "StartInfo.h" // for StartInfo
#include "battle/BattleInfo.h" // for BattleInfo
#include "NetPacks.h" // for InfoWindow
#include "GameSettings.h"
#include "TerrainHandler.h"
#include "spells/CSpellHandler.h"

View File

@ -18,7 +18,7 @@
#include "CGeneralTextHandler.h"
#include "battle/BattleInfo.h"
#include "spells/CSpellHandler.h"
#include "NetPacks.h"
#include "networkPacks/PacksForClientBattle.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -13,7 +13,6 @@
#include "CHeroHandler.h" // for CHeroHandler
#include "spells/CSpellHandler.h"// for CSpell
#include "CSkillHandler.h"// for CSkill
#include "NetPacks.h"
#include "CBonusTypeHandler.h"
#include "BattleFieldHandler.h"
#include "ObstacleHandler.h"
@ -36,6 +35,7 @@
#include "gameState/CGameState.h"
#include "gameState/CGameStateCampaign.h"
#include "gameState/TavernHeroesPool.h"
#include "gameState/QuestInfo.h"
#include "mapping/CMap.h"
#include "modding/CModHandler.h"
#include "modding/CModInfo.h"

View File

@ -9,8 +9,7 @@
*/
#pragma once
#include "NetPacksBase.h"
#include "networkPacks/EInfoWindowMode.h"
#include "battle/BattleHex.h"
#include "GameConstants.h"
#include "int3.h"

View File

@ -1156,7 +1156,7 @@ CSelector JsonUtils::parseSelector(const JsonNode & ability)
{
CSelector base = Selector::none;
for(const auto & andN : value->Vector())
base.Or(parseSelector(andN));
base = base.Or(parseSelector(andN));
ret = ret.And(base);
}
@ -1166,7 +1166,7 @@ CSelector JsonUtils::parseSelector(const JsonNode & ability)
{
CSelector base = Selector::none;
for(const auto & andN : value->Vector())
base.Or(parseSelector(andN));
base = base.Or(parseSelector(andN));
ret = ret.And(base.Not());
}

File diff suppressed because it is too large Load Diff

View File

@ -1,286 +0,0 @@
/*
* NetPacksBase.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 <vcmi/Metatype.h>
#include "ConstTransitivePtr.h"
#include "GameConstants.h"
#include "JsonNode.h"
class CClient;
class CGameHandler;
class CLobbyScreen;
class CServerHandler;
class CVCMIServer;
VCMI_LIB_NAMESPACE_BEGIN
class CGameState;
class CConnection;
class CStackBasicDescriptor;
class CGHeroInstance;
class CStackInstance;
class CArmedInstance;
class CArtifactSet;
class CBonusSystemNode;
struct ArtSlotInfo;
class ICPackVisitor;
enum class EInfoWindowMode : uint8_t
{
AUTO,
MODAL,
INFO
};
enum class EOpenWindowMode : uint8_t
{
EXCHANGE_WINDOW,
RECRUITMENT_FIRST,
RECRUITMENT_ALL,
SHIPYARD_WINDOW,
THIEVES_GUILD,
UNIVERSITY_WINDOW,
HILL_FORT_WINDOW,
MARKET_WINDOW,
PUZZLE_MAP,
TAVERN_WINDOW
};
struct DLL_LINKAGE CPack
{
std::shared_ptr<CConnection> c; // Pointer to connection that pack received from
CPack() = default;
virtual ~CPack() = default;
template <typename Handler> void serialize(Handler &h, const int version)
{
logNetwork->error("CPack serialized... this should not happen!");
assert(false && "CPack serialized");
}
void applyGs(CGameState * gs)
{}
void visit(ICPackVisitor & cpackVisitor);
protected:
/// <summary>
/// For basic types of netpacks hierarchy like CPackForClient. Called first.
/// </summary>
virtual void visitBasic(ICPackVisitor & cpackVisitor);
/// <summary>
/// For leaf types of netpacks hierarchy. Called after visitBasic.
/// </summary>
virtual void visitTyped(ICPackVisitor & cpackVisitor);
};
struct DLL_LINKAGE CPackForClient : public CPack
{
protected:
virtual void visitBasic(ICPackVisitor & cpackVisitor) override;
};
struct DLL_LINKAGE CPackForServer : public CPack
{
mutable PlayerColor player = PlayerColor::NEUTRAL;
mutable si32 requestID;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & player;
h & requestID;
}
protected:
virtual void visitBasic(ICPackVisitor & cpackVisitor) override;
};
struct DLL_LINKAGE CPackForLobby : public CPack
{
virtual bool isForServer() const;
protected:
virtual void visitBasic(ICPackVisitor & cpackVisitor) override;
};
struct Component
{
enum class EComponentType : uint8_t
{
PRIM_SKILL,
SEC_SKILL,
RESOURCE,
CREATURE,
ARTIFACT,
EXPERIENCE,
SPELL,
MORALE,
LUCK,
BUILDING,
HERO_PORTRAIT,
FLAG,
INVALID //should be last
};
EComponentType id = EComponentType::INVALID;
ui16 subtype = 0; //id==EXPPERIENCE subtype==0 means exp points and subtype==1 levels
si32 val = 0; // + give; - take
si16 when = 0; // 0 - now; +x - within x days; -x - per x days
template <typename Handler> void serialize(Handler &h, const int version)
{
h & id;
h & subtype;
h & val;
h & when;
}
Component() = default;
DLL_LINKAGE explicit Component(const CStackBasicDescriptor &stack);
Component(Component::EComponentType Type, ui16 Subtype, si32 Val, si16 When)
:id(Type),subtype(Subtype),val(Val),when(When)
{
}
};
using TArtHolder = std::variant<ConstTransitivePtr<CGHeroInstance>, ConstTransitivePtr<CStackInstance>>;
struct ArtifactLocation
{
TArtHolder artHolder;//TODO: identify holder by id
ArtifactPosition slot = ArtifactPosition::PRE_FIRST;
ArtifactLocation()
: artHolder(ConstTransitivePtr<CGHeroInstance>())
{
}
template<typename T>
ArtifactLocation(const T * ArtHolder, ArtifactPosition Slot)
: artHolder(const_cast<T *>(ArtHolder)) //we are allowed here to const cast -> change will go through one of our packages... do not abuse!
, slot(Slot)
{
}
ArtifactLocation(TArtHolder ArtHolder, const ArtifactPosition & Slot)
: artHolder(std::move(std::move(ArtHolder)))
, slot(Slot)
{
}
template <typename T>
bool isHolder(const T *t) const
{
if(auto ptrToT = std::get<ConstTransitivePtr<T>>(artHolder))
{
return ptrToT == t;
}
return false;
}
DLL_LINKAGE void removeArtifact(); // BE CAREFUL, this operation modifies holder (gs)
DLL_LINKAGE const CArmedInstance *relatedObj() const; //hero or the stack owner
DLL_LINKAGE PlayerColor owningPlayer() const;
DLL_LINKAGE CArtifactSet *getHolderArtSet();
DLL_LINKAGE CBonusSystemNode *getHolderNode();
DLL_LINKAGE CArtifactSet *getHolderArtSet() const;
DLL_LINKAGE const CBonusSystemNode *getHolderNode() const;
DLL_LINKAGE const CArtifactInstance *getArt() const;
DLL_LINKAGE CArtifactInstance *getArt();
DLL_LINKAGE const ArtSlotInfo *getSlot() const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & artHolder;
h & slot;
}
};
class EntityChanges
{
public:
Metatype metatype = Metatype::UNKNOWN;
int32_t entityIndex = 0;
JsonNode data;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & metatype;
h & entityIndex;
h & data;
}
};
class BattleChanges
{
public:
enum class EOperation : si8
{
ADD,
RESET_STATE,
UPDATE,
REMOVE,
};
JsonNode data;
EOperation operation = EOperation::RESET_STATE;
BattleChanges() = default;
BattleChanges(EOperation operation_)
: operation(operation_)
{
}
};
class UnitChanges : public BattleChanges
{
public:
uint32_t id = 0;
int64_t healthDelta = 0;
UnitChanges() = default;
UnitChanges(uint32_t id_, EOperation operation_)
: BattleChanges(operation_)
, id(id_)
{
}
template <typename Handler> void serialize(Handler & h, const int version)
{
h & id;
h & healthDelta;
h & data;
h & operation;
}
};
class ObstacleChanges : public BattleChanges
{
public:
uint32_t id = 0;
ObstacleChanges() = default;
ObstacleChanges(uint32_t id_, EOperation operation_)
: BattleChanges(operation_),
id(id_)
{
}
template <typename Handler> void serialize(Handler & h, const int version)
{
h & id;
h & data;
h & operation;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -9,11 +9,11 @@
*/
#include "StdInc.h"
#include "BattleInfo.h"
#include "CObstacleInstance.h"
#include "bonuses/Limiters.h"
#include "bonuses/Updaters.h"
#include "../CStack.h"
#include "../CHeroHandler.h"
#include "../NetPacks.h"
#include "../filesystem/Filesystem.h"
#include "../mapObjects/CGTownInstance.h"
#include "../CGeneralTextHandler.h"

View File

@ -17,12 +17,12 @@
#include "CObstacleInstance.h"
#include "DamageCalculator.h"
#include "PossiblePlayerBattleAction.h"
#include "../NetPacks.h"
#include "../spells/ObstacleCasterProxy.h"
#include "../spells/ISpellMechanics.h"
#include "../spells/Problem.h"
#include "../spells/CSpellHandler.h"
#include "../mapObjects/CGTownInstance.h"
#include "../networkPacks/PacksForClientBattle.h"
#include "../BattleFieldHandler.h"
#include "../Rect.h"

View File

@ -11,9 +11,10 @@
#include "CBattleInfoEssentials.h"
#include "../CStack.h"
#include "BattleInfo.h"
#include "../NetPacks.h"
#include "CObstacleInstance.h"
#include "../mapObjects/CGTownInstance.h"
#include "../gameState/InfoAboutArmy.h"
#include "../constants/EntityIdentifiers.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -13,7 +13,6 @@
#include "../CTownHandler.h"
#include "../ObstacleHandler.h"
#include "../VCMI_Lib.h"
#include "../NetPacksBase.h"
#include "../serializer/JsonDeserializer.h"
#include "../serializer/JsonSerializer.h"

View File

@ -9,8 +9,9 @@
*/
#pragma once
#include "BattleHex.h"
#include "NetPacksBase.h"
#include "../filesystem/ResourcePath.h"
#include "../networkPacks/BattleChanges.h"
#include "../constants/EntityIdentifiers.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -13,8 +13,8 @@
#include <vcmi/spells/Spell.h>
#include "../NetPacks.h"
#include "../CCreatureHandler.h"
#include "../MetaString.h"
#include "../serializer/JsonDeserializer.h"
#include "../serializer/JsonSerializer.h"

View File

@ -14,7 +14,6 @@
#include "../VCMI_Lib.h"
#include "../CGeneralTextHandler.h"
#include "../MetaString.h"
#include "../NetPacksBase.h"
#include "../serializer/JsonDeserializer.h"
#include "../serializer/JsonSerializer.h"

View File

@ -12,8 +12,7 @@
#include <vcmi/Environment.h>
#include "ApplyDamage.h"
#include "../../lib/NetPacks.h"
#include "../networkPacks/PacksForClientBattle.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -193,13 +193,16 @@ TObjectTypeHandler CObjectClassesHandler::loadSubObjectFromJson(const std::strin
assert(identifier.find(':') == std::string::npos);
assert(!scope.empty());
if(!handlerConstructors.count(obj->handlerName))
std::string handler = obj->handlerName;
if(!handlerConstructors.count(handler))
{
logGlobal->error("Handler with name %s was not found!", obj->handlerName);
return nullptr;
logMod->error("Handler with name %s was not found!", handler);
// workaround for potential crash - if handler does not exists, continue with generic handler that is used for objects without any custom logc
handler = "generic";
assert(handlerConstructors.count(handler) != 0);
}
auto createdObject = handlerConstructors.at(obj->handlerName)();
auto createdObject = handlerConstructors.at(handler)();
createdObject->modScope = scope;
createdObject->typeName = obj->identifier;;

View File

@ -14,13 +14,17 @@
#include <vcmi/spells/Spell.h>
#include <vcmi/spells/Service.h>
#include "../NetPacks.h"
#include "../CGeneralTextHandler.h"
#include "../CSoundBase.h"
#include "../GameSettings.h"
#include "../CPlayerState.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../mapObjectConstructors/CBankInstanceConstructor.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../networkPacks/Component.h"
#include "../networkPacks/PacksForClient.h"
#include "../networkPacks/PacksForClientBattle.h"
#include "../MetaString.h"
#include "../IGameCallback.h"
#include "../gameState/CGameState.h"

View File

@ -10,12 +10,15 @@
#include "StdInc.h"
#include "CGCreature.h"
#include "CGHeroInstance.h"
#include "../NetPacks.h"
#include "../CGeneralTextHandler.h"
#include "../CConfigHandler.h"
#include "../GameSettings.h"
#include "../IGameCallback.h"
#include "../networkPacks/PacksForClient.h"
#include "../networkPacks/PacksForClientBattle.h"
#include "../networkPacks/StackLocation.h"
#include "../serializer/JsonSerializeFormat.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -13,11 +13,14 @@
#include "../serializer/JsonSerializeFormat.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../networkPacks/StackLocation.h"
#include "../networkPacks/PacksForClient.h"
#include "../networkPacks/PacksForClientBattle.h"
#include "../CTownHandler.h"
#include "../IGameCallback.h"
#include "../gameState/CGameState.h"
#include "../CPlayerState.h"
#include "../NetPacks.h"
#include "../GameSettings.h"
#include "../CConfigHandler.h"

View File

@ -14,7 +14,6 @@
#include <vcmi/ServerCallback.h>
#include <vcmi/spells/Spell.h>
#include "../NetPacks.h"
#include "../CGeneralTextHandler.h"
#include "../ArtifactUtils.h"
#include "../CHeroHandler.h"
@ -35,6 +34,8 @@
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../modding/ModScope.h"
#include "../networkPacks/PacksForClient.h"
#include "../networkPacks/PacksForClientBattle.h"
#include "../constants/StringConstants.h"
#include "../battle/Unit.h"

View File

@ -11,7 +11,6 @@
#include "StdInc.h"
#include "CGMarket.h"
#include "../NetPacks.h"
#include "../CGeneralTextHandler.h"
#include "../IGameCallback.h"
#include "../CCreatureHandler.h"
@ -20,6 +19,7 @@
#include "../CSkillHandler.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../networkPacks/PacksForClient.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -17,12 +17,12 @@
#include "../gameState/CGameState.h"
#include "../CGeneralTextHandler.h"
#include "../IGameCallback.h"
#include "../NetPacks.h"
#include "../constants/StringConstants.h"
#include "../TerrainHandler.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../mapping/CMap.h"
#include "../networkPacks/PacksForClient.h"
#include "../serializer/JsonSerializeFormat.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -10,11 +10,14 @@
#pragma once
#include "IObjectInterface.h"
#include "../constants/EntityIdentifiers.h"
#include "../filesystem/ResourcePath.h"
#include "../int3.h"
#include "../bonuses/BonusEnum.h"
VCMI_LIB_NAMESPACE_BEGIN
struct Component;
class JsonSerializeFormat;
class ObjectTemplate;
class CMap;

View File

@ -14,13 +14,15 @@
#include <vcmi/spells/Spell.h>
#include <vcmi/spells/Service.h>
#include "../NetPacks.h"
#include "../CSoundBase.h"
#include "../CSkillHandler.h"
#include "../StartInfo.h"
#include "../IGameCallback.h"
#include "../constants/StringConstants.h"
#include "../networkPacks/PacksForClient.h"
#include "../networkPacks/PacksForClientBattle.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../serializer/JsonSerializeFormat.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -12,9 +12,10 @@
#include "CGTownBuilding.h"
#include "CGTownInstance.h"
#include "../CGeneralTextHandler.h"
#include "../NetPacks.h"
#include "../IGameCallback.h"
#include "../gameState/CGameState.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../networkPacks/PacksForClient.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -14,7 +14,6 @@
#include "../spells/CSpellHandler.h"
#include "../bonuses/Bonus.h"
#include "../battle/IBattleInfoCallback.h"
#include "../NetPacks.h"
#include "../CConfigHandler.h"
#include "../CGeneralTextHandler.h"
#include "../IGameCallback.h"
@ -24,7 +23,11 @@
#include "../TerrainHandler.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../modding/ModScope.h"
#include "../networkPacks/StackLocation.h"
#include "../networkPacks/PacksForClient.h"
#include "../networkPacks/PacksForClientBattle.h"
#include "../serializer/JsonSerializeFormat.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -13,6 +13,7 @@
#include "CGObjectInstance.h"
#include "../filesystem/ResourcePath.h"
#include "../JsonNode.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -14,7 +14,6 @@
#include <vcmi/spells/Spell.h>
#include "../ArtifactUtils.h"
#include "../NetPacks.h"
#include "../CSoundBase.h"
#include "../CGeneralTextHandler.h"
#include "../CHeroHandler.h"
@ -26,8 +25,10 @@
#include "../constants/StringConstants.h"
#include "../CSkillHandler.h"
#include "../mapping/CMap.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../modding/ModScope.h"
#include "../modding/ModUtility.h"
#include "../networkPacks/PacksForClient.h"
#include "../spells/CSpellHandler.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -14,9 +14,10 @@
#include "../CGeneralTextHandler.h"
#include "../CPlayerState.h"
#include "../IGameCallback.h"
#include "../NetPacks.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../networkPacks/PacksForClient.h"
#include "../serializer/JsonSerializeFormat.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -14,9 +14,10 @@
#include "CGTownInstance.h"
#include "MiscObjects.h"
#include "../NetPacks.h"
#include "../IGameCallback.h"
#include "../TerrainHandler.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../networkPacks/PacksForClient.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -9,18 +9,22 @@
*/
#pragma once
#include "../NetPacksBase.h"
#include "../networkPacks/EInfoWindowMode.h"
VCMI_LIB_NAMESPACE_BEGIN
struct BattleResult;
struct UpgradeInfo;
class BoatId;
class CGObjectInstance;
class CRandomGenerator;
class CStackInstance;
class CGHeroInstance;
class IGameCallback;
class ResourceSet;
class int3;
class MetaString;
class PlayerColor;
class DLL_LINKAGE IObjectInterface
{

View File

@ -12,7 +12,6 @@
#include "MiscObjects.h"
#include "../constants/StringConstants.h"
#include "../NetPacks.h"
#include "../CGeneralTextHandler.h"
#include "../CSoundBase.h"
#include "../CSkillHandler.h"
@ -24,7 +23,11 @@
#include "../serializer/JsonSerializeFormat.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../modding/ModScope.h"
#include "../networkPacks/PacksForClient.h"
#include "../networkPacks/PacksForClientBattle.h"
#include "../networkPacks/StackLocation.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -36,6 +36,8 @@
#include "../mapObjects/MapObjects.h"
#include "../mapObjects/ObjectTemplate.h"
#include "../modding/ModScope.h"
#include "../networkPacks/Component.h"
#include "../networkPacks/ArtifactLocation.h"
#include "../spells/CSpellHandler.h"
#include <boost/crc.hpp>

View File

@ -86,17 +86,28 @@ std::vector <TModID> CModHandler::validateAndSortDependencies(std::vector <TModI
std::set <TModID> resolvedModIDs; // Use a set for validation for performance reason, but set does not keep order of elements
// Mod is resolved if it has not dependencies or all its dependencies are already resolved
auto isResolved = [&](const CModInfo & mod) -> CModInfo::EValidationStatus
auto isResolved = [&](const CModInfo & mod) -> bool
{
if(mod.dependencies.size() > resolvedModIDs.size())
return CModInfo::PENDING;
return false;
for(const TModID & dependency : mod.dependencies)
{
if(!vstd::contains(resolvedModIDs, dependency))
return CModInfo::PENDING;
return false;
}
return CModInfo::PASSED;
for(const TModID & conflict : mod.conflicts)
{
if(vstd::contains(resolvedModIDs, conflict))
return false;
}
for(const TModID & reverseConflict : resolvedModIDs)
{
if (vstd::contains(allMods.at(reverseConflict).conflicts, mod.identifier))
return false;
}
return true;
};
while(true)
@ -104,7 +115,7 @@ std::vector <TModID> CModHandler::validateAndSortDependencies(std::vector <TModI
std::set <TModID> resolvedOnCurrentTreeLevel;
for(auto it = modsToResolve.begin(); it != modsToResolve.end();) // One iteration - one level of mods tree
{
if(isResolved(allMods.at(*it)) == CModInfo::PASSED)
if(isResolved(allMods.at(*it)))
{
resolvedOnCurrentTreeLevel.insert(*it); // Not to the resolvedModIDs, so current node childs will be resolved on the next iteration
sortedValidMods.push_back(*it);
@ -131,6 +142,16 @@ std::vector <TModID> CModHandler::validateAndSortDependencies(std::vector <TModI
if(!vstd::contains(resolvedModIDs, dependency) && brokenMod.config["modType"].String() != "Compatibility")
logMod->error("Mod '%s' has been disabled: dependency '%s' is missing.", brokenMod.getVerificationInfo().name, dependency);
}
for(const TModID & conflict : brokenMod.conflicts)
{
if(vstd::contains(resolvedModIDs, conflict))
logMod->error("Mod '%s' has been disabled: conflicts with enabled mod '%s'.", brokenMod.getVerificationInfo().name, conflict);
}
for(const TModID & reverseConflict : resolvedModIDs)
{
if (vstd::contains(allMods.at(reverseConflict).conflicts, brokenModID))
logMod->error("Mod '%s' has been disabled: conflicts with enabled mod '%s'.", brokenMod.getVerificationInfo().name, reverseConflict);
}
}
return sortedValidMods;
}

View File

@ -104,7 +104,16 @@ bool ContentTypeHandler::loadMod(const std::string & modName, bool validate)
JsonNode & data = entry.second;
if (data.meta != modName)
logMod->warn("Mod %s is attempting to inject object %s into mod %s! This may not be supported in future versions!", data.meta, name, modName);
{
// in this scenario, entire object record comes from another mod
// normally, this is used to "patch" object from another mod (which is legal)
// however in this case there is no object to patch. This might happen in such cases:
// - another mod attempts to add object into this mod (technically can be supported, but might lead to weird edge cases)
// - another mod attempts to edit object from this mod that no longer exist - DANGER since such patch likely has very incomplete data
// so emit warning and skip such case
logMod->warn("Mod %s attempts to edit object %s from mod %s but no such object exist!", data.meta, name, modName);
continue;
}
if (vstd::contains(data.Struct(), "index") && !data["index"].isNull())
{

View File

@ -0,0 +1,76 @@
/*
* ArtifactLocation.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 "../ConstTransitivePtr.h"
#include "../constants/EntityIdentifiers.h"
VCMI_LIB_NAMESPACE_BEGIN
class CGHeroInstance;
class CStackInstance;
class CArmedInstance;
class CArtifactSet;
class CBonusSystemNode;
struct ArtSlotInfo;
using TArtHolder = std::variant<ConstTransitivePtr<CGHeroInstance>, ConstTransitivePtr<CStackInstance>>;
struct ArtifactLocation
{
TArtHolder artHolder;//TODO: identify holder by id
ArtifactPosition slot = ArtifactPosition::PRE_FIRST;
ArtifactLocation()
: artHolder(ConstTransitivePtr<CGHeroInstance>())
{
}
template<typename T>
ArtifactLocation(const T * ArtHolder, ArtifactPosition Slot)
: artHolder(const_cast<T *>(ArtHolder)) //we are allowed here to const cast -> change will go through one of our packages... do not abuse!
, slot(Slot)
{
}
ArtifactLocation(TArtHolder ArtHolder, const ArtifactPosition & Slot)
: artHolder(std::move(std::move(ArtHolder)))
, slot(Slot)
{
}
template <typename T>
bool isHolder(const T *t) const
{
if(auto ptrToT = std::get<ConstTransitivePtr<T>>(artHolder))
{
return ptrToT == t;
}
return false;
}
DLL_LINKAGE void removeArtifact(); // BE CAREFUL, this operation modifies holder (gs)
DLL_LINKAGE const CArmedInstance *relatedObj() const; //hero or the stack owner
DLL_LINKAGE PlayerColor owningPlayer() const;
DLL_LINKAGE CArtifactSet *getHolderArtSet();
DLL_LINKAGE CBonusSystemNode *getHolderNode();
DLL_LINKAGE CArtifactSet *getHolderArtSet() const;
DLL_LINKAGE const CBonusSystemNode *getHolderNode() const;
DLL_LINKAGE const CArtifactInstance *getArt() const;
DLL_LINKAGE CArtifactInstance *getArt();
DLL_LINKAGE const ArtSlotInfo *getSlot() const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & artHolder;
h & slot;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,81 @@
/*
* BattleChanges.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 "JsonNode.h"
VCMI_LIB_NAMESPACE_BEGIN
class BattleChanges
{
public:
enum class EOperation : si8
{
ADD,
RESET_STATE,
UPDATE,
REMOVE,
};
JsonNode data;
EOperation operation = EOperation::RESET_STATE;
BattleChanges() = default;
explicit BattleChanges(EOperation operation_)
: operation(operation_)
{
}
};
class UnitChanges : public BattleChanges
{
public:
uint32_t id = 0;
int64_t healthDelta = 0;
UnitChanges() = default;
UnitChanges(uint32_t id_, EOperation operation_)
: BattleChanges(operation_)
, id(id_)
{
}
template <typename Handler> void serialize(Handler & h, const int version)
{
h & id;
h & healthDelta;
h & data;
h & operation;
}
};
class ObstacleChanges : public BattleChanges
{
public:
uint32_t id = 0;
ObstacleChanges() = default;
ObstacleChanges(uint32_t id_, EOperation operation_)
: BattleChanges(operation_),
id(id_)
{
}
template <typename Handler> void serialize(Handler & h, const int version)
{
h & id;
h & data;
h & operation;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,54 @@
/*
* Component.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
VCMI_LIB_NAMESPACE_BEGIN
class CStackBasicDescriptor;
struct Component
{
enum class EComponentType : uint8_t
{
PRIM_SKILL,
SEC_SKILL,
RESOURCE,
CREATURE,
ARTIFACT,
EXPERIENCE,
SPELL,
MORALE,
LUCK,
BUILDING,
HERO_PORTRAIT,
FLAG,
INVALID //should be last
};
EComponentType id = EComponentType::INVALID;
ui16 subtype = 0; //id==EXPPERIENCE subtype==0 means exp points and subtype==1 levels
si32 val = 0; // + give; - take
si16 when = 0; // 0 - now; +x - within x days; -x - per x days
template <typename Handler> void serialize(Handler &h, const int version)
{
h & id;
h & subtype;
h & val;
h & when;
}
Component() = default;
DLL_LINKAGE explicit Component(const CStackBasicDescriptor &stack);
Component(Component::EComponentType Type, ui16 Subtype, si32 Val, si16 When)
:id(Type),subtype(Subtype),val(Val),when(When)
{
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,22 @@
/*
* EInfoWindowMode.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
VCMI_LIB_NAMESPACE_BEGIN
enum class EInfoWindowMode : uint8_t
{
AUTO,
MODAL,
INFO
};
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,28 @@
/*
* EOpenWindowMode.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
VCMI_LIB_NAMESPACE_BEGIN
enum class EOpenWindowMode : uint8_t
{
EXCHANGE_WINDOW,
RECRUITMENT_FIRST,
RECRUITMENT_ALL,
SHIPYARD_WINDOW,
THIEVES_GUILD,
UNIVERSITY_WINDOW,
HILL_FORT_WINDOW,
MARKET_WINDOW,
PUZZLE_MAP,
TAVERN_WINDOW
};
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,33 @@
/*
* EInfoWindowMode.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 <vcmi/Metatype.h>
#include "../JsonNode.h"
VCMI_LIB_NAMESPACE_BEGIN
class EntityChanges
{
public:
Metatype metatype = Metatype::UNKNOWN;
int32_t entityIndex = 0;
JsonNode data;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & metatype;
h & entityIndex;
h & data;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -9,8 +9,11 @@
*/
#pragma once
#include "NetPacks.h"
#include "NetPacksLobby.h"
#include "PacksForClient.h"
#include "PacksForClientBattle.h"
#include "PacksForServer.h"
#include "PacksForLobby.h"
#include "SetStackEffect.h"
VCMI_LIB_NAMESPACE_BEGIN

View File

@ -0,0 +1,85 @@
/*
* NetPacksBase.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 "../constants/EntityIdentifiers.h"
VCMI_LIB_NAMESPACE_BEGIN
class CGameState;
class CConnection;
class ICPackVisitor;
struct DLL_LINKAGE CPack
{
std::shared_ptr<CConnection> c; // Pointer to connection that pack received from
CPack() = default;
virtual ~CPack() = default;
template <typename Handler> void serialize(Handler &h, const int version)
{
logNetwork->error("CPack serialized... this should not happen!");
assert(false && "CPack serialized");
}
void applyGs(CGameState * gs)
{}
void visit(ICPackVisitor & cpackVisitor);
protected:
/// <summary>
/// For basic types of netpacks hierarchy like CPackForClient. Called first.
/// </summary>
virtual void visitBasic(ICPackVisitor & cpackVisitor);
/// <summary>
/// For leaf types of netpacks hierarchy. Called after visitBasic.
/// </summary>
virtual void visitTyped(ICPackVisitor & cpackVisitor);
};
struct DLL_LINKAGE CPackForClient : public CPack
{
protected:
void visitBasic(ICPackVisitor & cpackVisitor) override;
};
struct DLL_LINKAGE Query : public CPackForClient
{
QueryID queryID; // equals to -1 if it is not an actual query (and should not be answered)
};
struct DLL_LINKAGE CPackForServer : public CPack
{
mutable PlayerColor player = PlayerColor::NEUTRAL;
mutable si32 requestID;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & player;
h & requestID;
}
protected:
void visitBasic(ICPackVisitor & cpackVisitor) override;
};
struct DLL_LINKAGE CPackForLobby : public CPack
{
virtual bool isForServer() const;
protected:
void visitBasic(ICPackVisitor & cpackVisitor) override;
};
VCMI_LIB_NAMESPACE_END

View File

@ -9,7 +9,12 @@
*/
#include "StdInc.h"
#include "ArtifactUtils.h"
#include "NetPacks.h"
#include "PacksForClient.h"
#include "PacksForClientBattle.h"
#include "PacksForServer.h"
#include "StackLocation.h"
#include "PacksForLobby.h"
#include "SetStackEffect.h"
#include "NetPackVisitor.h"
#include "CGeneralTextHandler.h"
#include "CArtHandler.h"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,557 @@
/*
* 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 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

View File

@ -1,5 +1,5 @@
/*
* NetPacksLobby.h, part of VCMI engine
* PacksForLobby.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
@ -9,9 +9,8 @@
*/
#pragma once
#include "NetPacksBase.h"
#include "StartInfo.h"
#include "NetPacksBase.h"
class CServerHandler;
class CVCMIServer;
@ -43,7 +42,7 @@ struct DLL_LINKAGE LobbyClientConnected : public CLobbyPackToPropagate
int clientId = -1;
int hostClientId = -1;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
@ -62,7 +61,7 @@ struct DLL_LINKAGE LobbyClientDisconnected : public CLobbyPackToPropagate
bool shutdownServer = false;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -75,7 +74,7 @@ struct DLL_LINKAGE LobbyChatMessage : public CLobbyPackToPropagate
{
std::string playerName, message;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -91,7 +90,7 @@ struct DLL_LINKAGE LobbyGuiAction : public CLobbyPackToPropagate
} action = NONE;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -103,7 +102,7 @@ struct DLL_LINKAGE LobbyLoadProgress : public CLobbyPackToPropagate
{
unsigned char progress;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -115,7 +114,7 @@ struct DLL_LINKAGE LobbyEndGame : public CLobbyPackToPropagate
{
bool closeConnection = false, restart = false;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -131,7 +130,7 @@ struct DLL_LINKAGE LobbyStartGame : public CLobbyPackToPropagate
CGameState * initializedGameState = nullptr;
int clientId = -1; //-1 means to all clients
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -148,7 +147,7 @@ struct DLL_LINKAGE LobbyChangeHost : public CLobbyPackToPropagate
{
int newHostConnectionId = -1;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
@ -161,7 +160,7 @@ struct DLL_LINKAGE LobbyUpdateState : public CLobbyPackToPropagate
LobbyState state;
bool hostChanged = false; // Used on client-side only
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -176,7 +175,7 @@ struct DLL_LINKAGE LobbySetMap : public CLobbyPackToServer
LobbySetMap() : mapInfo(nullptr), mapGenOpts(nullptr) {}
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -189,7 +188,7 @@ struct DLL_LINKAGE LobbySetCampaign : public CLobbyPackToServer
{
std::shared_ptr<CampaignState> ourCampaign;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -201,7 +200,7 @@ struct DLL_LINKAGE LobbySetCampaignMap : public CLobbyPackToServer
{
CampaignScenarioID mapId = CampaignScenarioID::NONE;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -213,7 +212,7 @@ struct DLL_LINKAGE LobbySetCampaignBonus : public CLobbyPackToServer
{
int bonusId = -1;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -228,7 +227,7 @@ struct DLL_LINKAGE LobbyChangePlayerOption : public CLobbyPackToServer
int32_t value = 0;
PlayerColor color = PlayerColor::CANNOT_DETERMINE;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -242,7 +241,7 @@ struct DLL_LINKAGE LobbySetPlayer : public CLobbyPackToServer
{
PlayerColor clickedColor = PlayerColor::CANNOT_DETERMINE;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -255,7 +254,7 @@ struct DLL_LINKAGE LobbySetPlayerName : public CLobbyPackToServer
PlayerColor color = PlayerColor::CANNOT_DETERMINE;
std::string name = "";
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -268,7 +267,7 @@ struct DLL_LINKAGE LobbySetSimturns : public CLobbyPackToServer
{
SimturnsInfo simturnsInfo;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -280,7 +279,7 @@ struct DLL_LINKAGE LobbySetTurnTime : public CLobbyPackToServer
{
TurnTimerInfo turnTimerInfo;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -292,7 +291,7 @@ struct DLL_LINKAGE LobbySetDifficulty : public CLobbyPackToServer
{
ui8 difficulty = 0;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -305,7 +304,7 @@ struct DLL_LINKAGE LobbyForceSetPlayer : public CLobbyPackToServer
ui8 targetConnectedPlayer = -1;
PlayerColor targetPlayerColor = PlayerColor::CANNOT_DETERMINE;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
@ -318,7 +317,7 @@ struct DLL_LINKAGE LobbyShowMessage : public CLobbyPackToPropagate
{
std::string message;
virtual void visitTyped(ICPackVisitor & visitor) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{

View File

@ -0,0 +1,669 @@
/*
* PacksForServer.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 "ArtifactLocation.h"
#include "NetPacksBase.h"
#include "../int3.h"
#include "../battle/BattleAction.h"
VCMI_LIB_NAMESPACE_BEGIN
struct DLL_LINKAGE GamePause : public CPackForServer
{
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
}
};
struct DLL_LINKAGE EndTurn : public CPackForServer
{
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
}
};
struct DLL_LINKAGE DismissHero : public CPackForServer
{
DismissHero() = default;
DismissHero(const ObjectInstanceID & HID)
: hid(HID)
{
}
ObjectInstanceID hid;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & hid;
}
};
struct DLL_LINKAGE MoveHero : public CPackForServer
{
MoveHero() = default;
MoveHero(const int3 & Dest, const ObjectInstanceID & HID, bool Transit)
: dest(Dest)
, hid(HID)
, transit(Transit)
{
}
int3 dest;
ObjectInstanceID hid;
bool transit = false;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & dest;
h & hid;
h & transit;
}
};
struct DLL_LINKAGE CastleTeleportHero : public CPackForServer
{
CastleTeleportHero() = default;
CastleTeleportHero(const ObjectInstanceID & HID, const ObjectInstanceID & Dest, ui8 Source)
: dest(Dest)
, hid(HID)
, source(Source)
{
}
ObjectInstanceID dest;
ObjectInstanceID hid;
si8 source = 0; //who give teleporting, 1=castle gate
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & dest;
h & hid;
}
};
struct DLL_LINKAGE ArrangeStacks : public CPackForServer
{
ArrangeStacks() = default;
ArrangeStacks(ui8 W, const SlotID & P1, const SlotID & P2, const ObjectInstanceID & ID1, const ObjectInstanceID & ID2, si32 VAL)
: what(W)
, p1(P1)
, p2(P2)
, id1(ID1)
, id2(ID2)
, val(VAL)
{
}
ui8 what = 0; //1 - swap; 2 - merge; 3 - split
SlotID p1, p2; //positions of first and second stack
ObjectInstanceID id1, id2; //ids of objects with garrison
si32 val = 0;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & what;
h & p1;
h & p2;
h & id1;
h & id2;
h & val;
}
};
struct DLL_LINKAGE BulkMoveArmy : public CPackForServer
{
SlotID srcSlot;
ObjectInstanceID srcArmy;
ObjectInstanceID destArmy;
BulkMoveArmy() = default;
BulkMoveArmy(const ObjectInstanceID & srcArmy, const ObjectInstanceID & destArmy, const SlotID & srcSlot)
: srcArmy(srcArmy)
, destArmy(destArmy)
, srcSlot(srcSlot)
{
}
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler>
void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & srcSlot;
h & srcArmy;
h & destArmy;
}
};
struct DLL_LINKAGE BulkSplitStack : public CPackForServer
{
SlotID src;
ObjectInstanceID srcOwner;
si32 amount = 0;
BulkSplitStack() = default;
BulkSplitStack(const ObjectInstanceID & srcOwner, const SlotID & src, si32 howMany)
: src(src)
, srcOwner(srcOwner)
, amount(howMany)
{
}
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler>
void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & src;
h & srcOwner;
h & amount;
}
};
struct DLL_LINKAGE BulkMergeStacks : public CPackForServer
{
SlotID src;
ObjectInstanceID srcOwner;
BulkMergeStacks() = default;
BulkMergeStacks(const ObjectInstanceID & srcOwner, const SlotID & src)
: src(src)
, srcOwner(srcOwner)
{
}
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler>
void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & src;
h & srcOwner;
}
};
struct DLL_LINKAGE BulkSmartSplitStack : public CPackForServer
{
SlotID src;
ObjectInstanceID srcOwner;
BulkSmartSplitStack() = default;
BulkSmartSplitStack(const ObjectInstanceID & srcOwner, const SlotID & src)
: src(src)
, srcOwner(srcOwner)
{
}
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler>
void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & src;
h & srcOwner;
}
};
struct DLL_LINKAGE DisbandCreature : public CPackForServer
{
DisbandCreature() = default;
DisbandCreature(const SlotID & Pos, const ObjectInstanceID & ID)
: pos(Pos)
, id(ID)
{
}
SlotID pos; //stack pos
ObjectInstanceID id; //object id
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & pos;
h & id;
}
};
struct DLL_LINKAGE BuildStructure : public CPackForServer
{
BuildStructure() = default;
BuildStructure(const ObjectInstanceID & TID, const BuildingID & BID)
: tid(TID)
, bid(BID)
{
}
ObjectInstanceID tid; //town id
BuildingID bid; //structure id
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & tid;
h & bid;
}
};
struct DLL_LINKAGE RazeStructure : public BuildStructure
{
void visitTyped(ICPackVisitor & visitor) override;
};
struct DLL_LINKAGE RecruitCreatures : public CPackForServer
{
RecruitCreatures() = default;
RecruitCreatures(const ObjectInstanceID & TID, const ObjectInstanceID & DST, const CreatureID & CRID, si32 Amount, si32 Level)
: tid(TID)
, dst(DST)
, crid(CRID)
, amount(Amount)
, level(Level)
{
}
ObjectInstanceID tid; //dwelling id, or town
ObjectInstanceID dst; //destination ID, e.g. hero
CreatureID crid;
ui32 amount = 0; //creature amount
si32 level = 0; //dwelling level to buy from, -1 if any
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & tid;
h & dst;
h & crid;
h & amount;
h & level;
}
};
struct DLL_LINKAGE UpgradeCreature : public CPackForServer
{
UpgradeCreature() = default;
UpgradeCreature(const SlotID & Pos, const ObjectInstanceID & ID, const CreatureID & CRID)
: pos(Pos)
, id(ID)
, cid(CRID)
{
}
SlotID pos; //stack pos
ObjectInstanceID id; //object id
CreatureID cid; //id of type to which we want make upgrade
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & pos;
h & id;
h & cid;
}
};
struct DLL_LINKAGE GarrisonHeroSwap : public CPackForServer
{
GarrisonHeroSwap() = default;
GarrisonHeroSwap(const ObjectInstanceID & TID)
: tid(TID)
{
}
ObjectInstanceID tid;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & tid;
}
};
struct DLL_LINKAGE ExchangeArtifacts : public CPackForServer
{
ArtifactLocation src, dst;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & src;
h & dst;
}
};
struct DLL_LINKAGE BulkExchangeArtifacts : public CPackForServer
{
ObjectInstanceID srcHero;
ObjectInstanceID dstHero;
bool swap = false;
bool equipped = true;
bool backpack = true;
BulkExchangeArtifacts() = default;
BulkExchangeArtifacts(const ObjectInstanceID & srcHero, const ObjectInstanceID & dstHero, bool swap, bool equipped, bool backpack)
: srcHero(srcHero)
, dstHero(dstHero)
, swap(swap)
, equipped(equipped)
, backpack(backpack)
{
}
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & srcHero;
h & dstHero;
h & swap;
h & equipped;
h & backpack;
}
};
struct DLL_LINKAGE AssembleArtifacts : public CPackForServer
{
AssembleArtifacts() = default;
AssembleArtifacts(const ObjectInstanceID & _heroID, const ArtifactPosition & _artifactSlot, bool _assemble, const ArtifactID & _assembleTo)
: heroID(_heroID)
, artifactSlot(_artifactSlot)
, assemble(_assemble)
, assembleTo(_assembleTo)
{
}
ObjectInstanceID heroID;
ArtifactPosition artifactSlot;
bool assemble = false; // True to assemble artifact, false to disassemble.
ArtifactID assembleTo; // Artifact to assemble into.
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & heroID;
h & artifactSlot;
h & assemble;
h & assembleTo;
}
};
struct DLL_LINKAGE EraseArtifactByClient : public CPackForServer
{
EraseArtifactByClient() = default;
EraseArtifactByClient(const ArtifactLocation & al)
: al(al)
{
}
ArtifactLocation al;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer&>(*this);
h & al;
}
};
struct DLL_LINKAGE BuyArtifact : public CPackForServer
{
BuyArtifact() = default;
BuyArtifact(const ObjectInstanceID & HID, const ArtifactID & AID)
: hid(HID)
, aid(AID)
{
}
ObjectInstanceID hid;
ArtifactID aid;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & hid;
h & aid;
}
};
struct DLL_LINKAGE TradeOnMarketplace : public CPackForServer
{
ObjectInstanceID marketId;
ObjectInstanceID heroId;
EMarketMode mode = EMarketMode::RESOURCE_RESOURCE;
std::vector<ui32> r1, r2; //mode 0: r1 - sold resource, r2 - bought res (exception: when sacrificing art r1 is art id [todo: make r2 preferred slot?]
std::vector<ui32> val; //units of sold resource
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & marketId;
h & heroId;
h & mode;
h & r1;
h & r2;
h & val;
}
};
struct DLL_LINKAGE SetFormation : public CPackForServer
{
SetFormation() = default;
;
SetFormation(const ObjectInstanceID & HID, ui8 Formation)
: hid(HID)
, formation(Formation)
{
}
ObjectInstanceID hid;
ui8 formation = 0;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & hid;
h & formation;
}
};
struct DLL_LINKAGE HireHero : public CPackForServer
{
HireHero() = default;
HireHero(HeroTypeID HID, const ObjectInstanceID & TID)
: hid(HID)
, tid(TID)
{
}
HeroTypeID hid; //available hero serial
ObjectInstanceID tid; //town (tavern) id
PlayerColor player;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & hid;
h & tid;
h & player;
}
};
struct DLL_LINKAGE BuildBoat : public CPackForServer
{
ObjectInstanceID objid; //where player wants to buy a boat
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & objid;
}
};
struct DLL_LINKAGE QueryReply : public CPackForServer
{
QueryReply() = default;
QueryReply(const QueryID & QID, std::optional<int32_t> Reply)
: qid(QID)
, reply(Reply)
{
}
QueryID qid;
PlayerColor player;
std::optional<int32_t> reply;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & qid;
h & player;
h & reply;
}
};
struct DLL_LINKAGE MakeAction : public CPackForServer
{
MakeAction() = default;
MakeAction(BattleAction BA)
: ba(std::move(BA))
{
}
BattleAction ba;
BattleID battleID;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & ba;
h & battleID;
}
};
struct DLL_LINKAGE DigWithHero : public CPackForServer
{
ObjectInstanceID id; //digging hero id
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & id;
}
};
struct DLL_LINKAGE CastAdvSpell : public CPackForServer
{
ObjectInstanceID hid; //hero id
SpellID sid; //spell id
int3 pos; //selected tile (not always used)
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & hid;
h & sid;
h & pos;
}
};
/***********************************************************************************************************/
struct DLL_LINKAGE SaveGame : public CPackForServer
{
SaveGame() = default;
SaveGame(std::string Fname)
: fname(std::move(Fname))
{
}
std::string fname;
void applyGs(CGameState * gs) {};
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & fname;
}
};
struct DLL_LINKAGE PlayerMessage : public CPackForServer
{
PlayerMessage() = default;
PlayerMessage(std::string Text, const ObjectInstanceID & obj)
: text(std::move(Text))
, currObj(obj)
{
}
void applyGs(CGameState * gs) {};
void visitTyped(ICPackVisitor & visitor) override;
std::string text;
ObjectInstanceID currObj; // optional parameter that specifies current object. For cheats :)
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CPackForServer &>(*this);
h & text;
h & currObj;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,42 @@
/*
* SetStackEffect.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 "../bonuses/Bonus.h"
VCMI_LIB_NAMESPACE_BEGIN
class IBattleState;
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);
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,40 @@
/*
* StackLocation.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 "../ConstTransitivePtr.h"
#include "../GameConstants.h"
VCMI_LIB_NAMESPACE_BEGIN
class CArmedInstance;
class CStackInstance;
struct StackLocation
{
ConstTransitivePtr<CArmedInstance> army;
SlotID slot;
StackLocation() = default;
StackLocation(const CArmedInstance * Army, const SlotID & Slot)
: army(const_cast<CArmedInstance *>(Army)) //we are allowed here to const cast -> change will go through one of our packages... do not abuse!
, slot(Slot)
{
}
DLL_LINKAGE const CStackInstance * getStack();
template <typename Handler> void serialize(Handler & h, const int version)
{
h & army;
h & slot;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -9,8 +9,11 @@
*/
#pragma once
#include "../NetPacks.h"
#include "../NetPacksLobby.h"
#include "../networkPacks/PacksForClient.h"
#include "../networkPacks/PacksForClientBattle.h"
#include "../networkPacks/PacksForServer.h"
#include "../networkPacks/PacksForLobby.h"
#include "../networkPacks/SetStackEffect.h"
#include "../VCMI_Lib.h"
#include "../CArtHandler.h"
#include "../CCreatureSet.h"

View File

@ -18,7 +18,6 @@
#include "../CHeroHandler.h"
#include "../spells/CSpellHandler.h"
#include "../CTownHandler.h"
#include "../NetPacks.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"

View File

@ -20,7 +20,6 @@
#include "../CHeroHandler.h"
#include "../spells/CSpellHandler.h"
#include "../CTownHandler.h"
#include "../NetPacks.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"

View File

@ -27,7 +27,6 @@
#include "../RiverHandler.h"
#include "../TerrainHandler.h"
#include "../campaign/CampaignState.h"
#include "../NetPacks.h"
#include "../rmg/CMapGenOptions.h"
#include "../serializer/BinaryDeserializer.h"

View File

@ -18,7 +18,6 @@
#include "../CHeroHandler.h"
#include "../spells/CSpellHandler.h"
#include "../CTownHandler.h"
#include "../NetPacks.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"

View File

@ -20,7 +20,6 @@
#include "../CHeroHandler.h"
#include "../spells/CSpellHandler.h"
#include "../CTownHandler.h"
#include "../NetPacks.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"

Some files were not shown because too many files have changed in this diff Show More