1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Added special slots for war machines and arrow towers

This commit is contained in:
AlexVinS 2016-01-30 00:53:53 +03:00
parent ba017c443d
commit 16e0d18880
4 changed files with 48 additions and 23 deletions

View File

@ -469,7 +469,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp
auto handleWarMachine= [&](int side, ArtifactPosition artslot, CreatureID cretype, BattleHex hex)
{
if(heroes[side] && heroes[side]->getArt(artslot))
stacks.push_back(curB->generateNewStack(CStackBasicDescriptor(cretype, 1), !side, SlotID(255), hex));
stacks.push_back(curB->generateNewStack(CStackBasicDescriptor(cretype, 1), !side, SlotID::WAR_MACHINES_SLOT, hex));
};
handleWarMachine(0, ArtifactPosition::MACH1, CreatureID::BALLISTA, 52);
@ -526,15 +526,15 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp
if (curB->town && curB->town->fortLevel() >= CGTownInstance::CITADEL)
{
// keep tower
CStack * stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, SlotID(255), -2);
CStack * stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, SlotID::ARROW_TOWERS_SLOT, -2);
stacks.push_back(stack);
if (curB->town->fortLevel() >= CGTownInstance::CASTLE)
{
// lower tower + upper tower
CStack * stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, SlotID(255), -4);
CStack * stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, SlotID::ARROW_TOWERS_SLOT, -4);
stacks.push_back(stack);
stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, SlotID(255), -3);
stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, SlotID::ARROW_TOWERS_SLOT, -3);
stacks.push_back(stack);
}
@ -712,7 +712,7 @@ std::shared_ptr<CObstacleInstance> BattleInfo::getObstacleOnTile(BattleHex tile)
BattlefieldBI::BattlefieldBI BattleInfo::battlefieldTypeToBI(BFieldType bfieldType)
{
static const std::map<BFieldType, BattlefieldBI::BattlefieldBI> theMap =
static const std::map<BFieldType, BattlefieldBI::BattlefieldBI> theMap =
{
{BFieldType::CLOVER_FIELD, BattlefieldBI::CLOVER_FIELD},
{BFieldType::CURSED_GROUND, BattlefieldBI::CURSED_GROUND},
@ -1141,7 +1141,7 @@ bool CStack::ableToRetaliate() const //FIXME: crash after clone is killed
ui8 CStack::counterAttacksTotal() const
{
//after dispell bonus should remain during current round
//after dispell bonus should remain during current round
ui8 val = 1 + valOfBonuses(Bonus::ADDITIONAL_RETALIATION);
vstd::amax(counterAttacksTotalCache, val);
return counterAttacksTotalCache;
@ -1183,9 +1183,9 @@ ui32 CStack::calculateHealedHealthPoints(ui32 toHeal, const bool resurrect) cons
ui8 CStack::getSpellSchoolLevel(const CSpell * spell, int * outSelectedSchool) const
{
int skill = valOfBonuses(Selector::typeSubtype(Bonus::SPELLCASTER, spell->id));
vstd::abetween(skill, 0, 3);
return skill;
}

View File

@ -19,7 +19,10 @@
#include "spells/CSpellHandler.h"
const SlotID SlotID::COMMANDER_SLOT_PLACEHOLDER = SlotID(-2);
const SlotID SlotID::SUMMONED_SLOT_PLACEHOLDER = SlotID(255);
const SlotID SlotID::SUMMONED_SLOT_PLACEHOLDER = SlotID(-3);
const SlotID SlotID::WAR_MACHINES_SLOT = SlotID(-4);
const SlotID SlotID::ARROW_TOWERS_SLOT = SlotID(-5);
const PlayerColor PlayerColor::CANNOT_DETERMINE = PlayerColor(253);
const PlayerColor PlayerColor::UNFLAGGABLE = PlayerColor(254);
const PlayerColor PlayerColor::NEUTRAL = PlayerColor(255);

View File

@ -237,6 +237,8 @@ class SlotID : public BaseForID<SlotID, si32>
DLL_LINKAGE static const SlotID COMMANDER_SLOT_PLACEHOLDER;
DLL_LINKAGE static const SlotID SUMMONED_SLOT_PLACEHOLDER; ///<for all summoned creatures, only during battle
DLL_LINKAGE static const SlotID WAR_MACHINES_SLOT; ///<for all war machines during battle
DLL_LINKAGE static const SlotID ARROW_TOWERS_SLOT; ///<for all arrow towers during battle
bool validSlot() const
{
@ -444,11 +446,11 @@ namespace ESpellCastProblem
namespace ECastingMode
{
enum ECastingMode
enum ECastingMode
{
HERO_CASTING, AFTER_ATTACK_CASTING, //also includes cast before attack
MAGIC_MIRROR, CREATURE_ACTIVE_CASTING, ENCHANTER_CASTING,
SPELL_LIKE_ATTACK,
SPELL_LIKE_ATTACK,
PASSIVE_CASTING//f.e. opening battle spells
};
}

View File

@ -3914,7 +3914,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
BattleStackAdded bsa;
bsa.attacker = summoner->attackerOwned;
bsa.creID = summonedType;
bsa.creID = summonedType;
ui64 risedHp = summoner->count * summoner->valOfBonuses(Bonus::DAEMON_SUMMONING, bsa.creID.toEnum());
ui64 targetHealth = destStack->getCreature()->MaxHealth() * destStack->baseAmount;//todo: ignore AGE effect
@ -5887,7 +5887,7 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, Battl
PlayerColor color = army->tempOwner;
if(color == PlayerColor::UNFLAGGABLE)
color = PlayerColor::NEUTRAL;
auto killStack = [&, this](const SlotID slot, const CStackInstance * instance)
{
StackLocation sl(army, slot);
@ -5928,47 +5928,67 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, Battl
for(CStack *st : bat->stacks)
{
if(vstd::contains(st->state, EBattleStackState::SUMMONED)) //don't take into account summoned stacks
if(vstd::contains(st->state, EBattleStackState::SUMMONED)) //don't take into account temporary summoned stacks
continue;
if (st->owner != color) //remove only our stacks
continue;
logGlobal->debugStream() << "Calculating casualties for " << st->nodeName();
//FIXME: this info is also used in BattleInfo::calculateCasualties, refactor
st->count = std::max (0, st->count - st->resurrected);
if (!st->count && !st->base) //we can imagine stacks of war machines that are not spawned by artifacts?
if(st->slot == SlotID::ARROW_TOWERS_SLOT)
{
//do nothing
logGlobal->debugStream() << "Ignored arrow towers stack";
}
else if(st->slot == SlotID::WAR_MACHINES_SLOT)
{
auto warMachine = VLC->arth->creatureToMachineID(st->type->idNumber);
//catapult artifact remain even if "creature" killed in siege
if(warMachine != ArtifactID::NONE && warMachine != ArtifactID::CATAPULT)
if(warMachine == ArtifactID::NONE)
{
logGlobal->errorStream() << "Invalid creature in war machine virtual slot: " << st->nodeName();
}
//catapult artifact remain even if "creature" killed in siege
else if(warMachine != ArtifactID::CATAPULT && !st->count)
{
logGlobal->debugStream() << "War machine has been destroyed";
auto hero = dynamic_ptr_cast<CGHeroInstance> (army);
if (hero)
removedWarMachines.push_back (ArtifactLocation(hero, hero->getArtPos(warMachine, true)));
else
logGlobal->errorStream() << "War machine in army without hero";
}
}
if(army->slotEmpty(st->slot))
else if(st->slot == SlotID::SUMMONED_SLOT_PLACEHOLDER)
{
if(st->slot == SlotID::SUMMONED_SLOT_PLACEHOLDER && !vstd::contains(st->state, EBattleStackState::SUMMONED) && st->alive() && st->count > 0)
if(st->alive() && st->count > 0)
{
logGlobal->debugStream() << "Stack has been permanently summoned";
//this stack was permanently summoned
const CreatureID summonedType = st->type->idNumber;
summoned[summonedType] += st->count;
}
}
}
else
else if(st->base && !army->slotEmpty(st->slot))
{
if(st->count == 0 || !st->alive())
{
killStack(st->slot, st->base);
logGlobal->debugStream() << "Stack has been destroyed";
}
else if(st->count < army->getStackCount(st->slot))
{
{
StackLocation sl(army, st->slot);
newStackCounts.push_back(TStackAndItsNewCount(sl, st->count));
}
}
else
{
logGlobal->warnStream() << "Unhandled stack " << st->nodeName();
}
}
}