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

Revert "Merge pull request #124 from vcmi/issue/1372"

This reverts commit da01af319b, reversing
changes made to 8b6b4e2e0b.
This commit is contained in:
AlexVinS 2015-11-07 11:35:02 +03:00
parent bd12989ad6
commit e645b46aed
6 changed files with 31 additions and 105 deletions

View File

@ -2163,15 +2163,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
break; break;
case RISE_DEMONS: case RISE_DEMONS:
if (shere && ourStack && !shere->alive()) if (shere && ourStack && !shere->alive())
{ legalAction = true;
if(!(shere->hasBonusOfType(Bonus::UNDEAD)
|| shere->hasBonusOfType(Bonus::NON_LIVING)
|| vstd::contains(shere->state, EBattleStackState::SUMMONED)
|| vstd::contains(shere->state, EBattleStackState::CLONED)
|| shere->hasBonusOfType(Bonus::SIEGE_WEAPON)
))
legalAction = true;
}
break; break;
} }
if (legalAction) if (legalAction)
@ -2328,10 +2320,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
break; break;
case RISE_DEMONS: case RISE_DEMONS:
cursorType = ECursor::SPELLBOOK; cursorType = ECursor::SPELLBOOK;
realizeAction = [=] realizeAction = [=]{ giveCommand(Battle::DAEMON_SUMMONING, myNumber, activeStack->ID); };
{
giveCommand(Battle::DAEMON_SUMMONING, myNumber, activeStack->ID);
};
break; break;
case CATAPULT: case CATAPULT:
cursorFrame = ECursor::COMBAT_SHOOT_CATAPULT; cursorFrame = ECursor::COMBAT_SHOOT_CATAPULT;

View File

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

View File

@ -216,7 +216,6 @@ class SlotID : public BaseForID<SlotID, si32>
friend class CNonConstInfoCallback; friend class CNonConstInfoCallback;
DLL_LINKAGE static const SlotID COMMANDER_SLOT_PLACEHOLDER; DLL_LINKAGE static const SlotID COMMANDER_SLOT_PLACEHOLDER;
DLL_LINKAGE static const SlotID SUMMONED_SLOT_PLACEHOLDER; ///<for all summoned creatures, only during battle
bool validSlot() const bool validSlot() const
{ {

View File

@ -1567,7 +1567,7 @@ DLL_LINKAGE void BattleStackAdded::applyGs(CGameState *gs)
} }
CStackBasicDescriptor csbd(creID, amount); CStackBasicDescriptor csbd(creID, amount);
CStack * addedStack = gs->curB->generateNewStack(csbd, attacker, SlotID::SUMMONED_SLOT_PLACEHOLDER, pos); //TODO: netpacks? CStack * addedStack = gs->curB->generateNewStack(csbd, attacker, SlotID(255), pos); //TODO: netpacks?
if (summoned) if (summoned)
addedStack->state.insert(EBattleStackState::SUMMONED); addedStack->state.insert(EBattleStackState::SUMMONED);

View File

@ -651,8 +651,8 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
sendAndApply(&cs); sendAndApply(&cs);
} }
cab1.updateArmy(this); cab1.takeFromArmy(this);
cab2.updateArmy(this); //take casualties after battle is deleted cab2.takeFromArmy(this); //take casualties after battle is deleted
//if one hero has lost we will erase him //if one hero has lost we will erase him
if(battleResult.data->winner!=0 && hero1) if(battleResult.data->winner!=0 && hero1)
@ -3848,16 +3848,18 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
//TODO: From Strategija: //TODO: From Strategija:
//Summon Demon is a level 2 spell. //Summon Demon is a level 2 spell.
{ {
StartAction start_action(ba);
sendAndApply(&start_action);
const CStack *summoner = gs->curB->battleGetStackByID(ba.stackNumber), const CStack *summoner = gs->curB->battleGetStackByID(ba.stackNumber),
*destStack = gs->curB->battleGetStackByPos(ba.destinationTile, false); *destStack = gs->curB->battleGetStackByPos(ba.destinationTile, false);
CreatureID summonedType(summoner->getBonusLocalFirst(Selector::type(Bonus::DAEMON_SUMMONING))->subtype);//in case summoner can summon more than one type of monsters... scream!
BattleStackAdded bsa; BattleStackAdded bsa;
bsa.attacker = summoner->attackerOwned; bsa.attacker = summoner->attackerOwned;
bsa.creID = summonedType; bsa.creID = CreatureID(summoner->getBonusLocalFirst(Selector::type(Bonus::DAEMON_SUMMONING))->subtype); //in case summoner can summon more than one type of monsters... scream!
ui64 risedHp = summoner->count * summoner->valOfBonuses(Bonus::DAEMON_SUMMONING, bsa.creID.toEnum()); ui64 risedHp = summoner->count * summoner->valOfBonuses(Bonus::DAEMON_SUMMONING, bsa.creID.toEnum());
ui64 targetHealth = destStack->getCreature()->MaxHealth() * destStack->baseAmount;//todo: ignore AGE effect ui64 targetHealth = destStack->getCreature()->MaxHealth() * destStack->baseAmount;
ui64 canRiseHp = std::min(targetHealth, risedHp); ui64 canRiseHp = std::min(targetHealth, risedHp);
ui32 canRiseAmount = canRiseHp / VLC->creh->creatures.at(bsa.creID)->MaxHealth(); ui32 canRiseAmount = canRiseHp / VLC->creh->creatures.at(bsa.creID)->MaxHealth();
@ -3869,9 +3871,6 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
if (bsa.amount) //there's rare possibility single creature cannot rise desired type if (bsa.amount) //there's rare possibility single creature cannot rise desired type
{ {
StartAction start_action(ba);
sendAndApply(&start_action);
BattleStacksRemoved bsr; //remove body BattleStacksRemoved bsr; //remove body
bsr.stackIDs.insert(destStack->ID); bsr.stackIDs.insert(destStack->ID);
sendAndApply(&bsr); sendAndApply(&bsr);
@ -3883,9 +3882,9 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
ssp.val = -1; ssp.val = -1;
ssp.absolute = false; ssp.absolute = false;
sendAndApply(&ssp); sendAndApply(&ssp);
sendAndApply(&end_action);
} }
sendAndApply(&end_action);
break; break;
} }
case Battle::MONSTER_SPELL: case Battle::MONSTER_SPELL:
@ -5805,8 +5804,7 @@ void CGameHandler::duelFinished()
return; return;
} }
CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, BattleInfo *bat): CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleInfo *bat)
army(_army)
{ {
heroWithDeadCommander = ObjectInstanceID(); heroWithDeadCommander = ObjectInstanceID();
@ -5814,44 +5812,6 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, Battl
if(color == PlayerColor::UNFLAGGABLE) if(color == PlayerColor::UNFLAGGABLE)
color = PlayerColor::NEUTRAL; color = PlayerColor::NEUTRAL;
auto killStack = [&, this](const SlotID slot, const CStackInstance * instance)
{
StackLocation sl(army, slot);
newStackCounts.push_back(TStackAndItsNewCount(sl, 0));
if(nullptr == instance)
return;
auto c = dynamic_cast <const CCommanderInstance *>(instance);
if (c) //switch commander status to dead
{
auto h = dynamic_cast <const CGHeroInstance *>(army);
if (h && h->commander == c)
heroWithDeadCommander = army->id; //TODO: unify commander handling
}
};
//1. Find removed stacks.
for(const auto & slotInfo : army->stacks)
{
const SlotID slot = slotInfo.first;
const CStackInstance * instance = slotInfo.second;
if(nullptr != instance)//just in case
{
bool found = false;
for(const CStack * sta : bat->stacks)
{
if(sta->base == instance)
{
found = true;
break;
}
}
//stack in this slot was removed == it is dead
if(!found)
killStack(slot, instance);
}
}
for(CStack *st : bat->stacks) 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 summoned stacks
@ -5862,7 +5822,7 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, Battl
//FIXME: this info is also used in BattleInfo::calculateCasualties, refactor //FIXME: this info is also used in BattleInfo::calculateCasualties, refactor
st->count = std::max (0, st->count - st->resurrected); 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->count && !st->base) //we can imagine stacks of war mahcines that are not spawned by artifacts?
{ {
auto warMachine = VLC->arth->creatureToMachineID(st->type->idNumber); auto warMachine = VLC->arth->creatureToMachineID(st->type->idNumber);
if (warMachine != ArtifactID::NONE) if (warMachine != ArtifactID::NONE)
@ -5873,31 +5833,28 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, Battl
} }
} }
if(army->slotEmpty(st->slot)) if(!army->slotEmpty(st->slot) && st->count < army->getStackCount(st->slot))
{ {
if(st->slot == SlotID::SUMMONED_SLOT_PLACEHOLDER && !vstd::contains(st->state, EBattleStackState::SUMMONED) && st->alive() && st->count > 0) StackLocation sl(army, st->slot);
{ if(st->alive())
//this stack was permanently summoned newStackCounts.push_back(std::pair<StackLocation, int>(sl, st->count));
const CreatureID summonedType = st->type->idNumber; else
summoned[summonedType] += st->count; newStackCounts.push_back(std::pair<StackLocation, int>(sl, 0));
}
} }
else if (st->base && !st->count)
{ {
if(st->count == 0 || !st->alive()) auto c = dynamic_cast <const CCommanderInstance *>(st->base);
if (c) //switch commander status to dead
{ {
killStack(st->slot, st->base); auto h = dynamic_cast <const CGHeroInstance *>(army);
} if (h && h->commander == c)
else if(st->count < army->getStackCount(st->slot)) heroWithDeadCommander = army->id; //TODO: unify commander handling
{
StackLocation sl(army, st->slot);
newStackCounts.push_back(TStackAndItsNewCount(sl, st->count));
} }
} }
} }
} }
void CasualtiesAfterBattle::updateArmy(CGameHandler *gh) void CasualtiesAfterBattle::takeFromArmy(CGameHandler *gh)
{ {
for(TStackAndItsNewCount &ncount : newStackCounts) for(TStackAndItsNewCount &ncount : newStackCounts)
{ {
@ -5906,21 +5863,6 @@ void CasualtiesAfterBattle::updateArmy(CGameHandler *gh)
else else
gh->eraseStack(ncount.first, true); gh->eraseStack(ncount.first, true);
} }
for(auto summoned_iter : summoned)
{
SlotID slot = army->getSlotFor(summoned_iter.first);
if(slot.validSlot())
{
StackLocation location(army, slot);
gh->addToSlot(location, summoned_iter.first.toCreature(), summoned_iter.second);
}
else
{
//even if it will be possible to summon anything permanently it should be checked for free slot
//necromancy is handled separately
gh->complain("No free slot to put summoned creature");
}
}
for (auto al : removedWarMachines) for (auto al : removedWarMachines)
{ {
gh->removeArtifact(al); gh->removeArtifact(al);

View File

@ -71,16 +71,13 @@ public:
struct CasualtiesAfterBattle struct CasualtiesAfterBattle
{ {
typedef std::pair<StackLocation, int> TStackAndItsNewCount; typedef std::pair<StackLocation, int> TStackAndItsNewCount;
typedef std::map<CreatureID, TQuantity> TSummoned;
enum {ERASE = -1}; enum {ERASE = -1};
const CArmedInstance * army;
std::vector<TStackAndItsNewCount> newStackCounts; std::vector<TStackAndItsNewCount> newStackCounts;
std::vector<ArtifactLocation> removedWarMachines; std::vector<ArtifactLocation> removedWarMachines;
TSummoned summoned; ObjectInstanceID heroWithDeadCommander; //TODO: unify stack loactions
ObjectInstanceID heroWithDeadCommander; //TODO: unify stack locations
CasualtiesAfterBattle(const CArmedInstance * _army, BattleInfo *bat); CasualtiesAfterBattle(const CArmedInstance *army, BattleInfo *bat);
void updateArmy(CGameHandler *gh); void takeFromArmy(CGameHandler *gh);
}; };
class CGameHandler : public IGameCallback, CBattleInfoCallback class CGameHandler : public IGameCallback, CBattleInfoCallback