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

Cloned stack dissapear when killed.

Fixed #864
This commit is contained in:
DjWarmonger 2012-02-18 17:39:47 +00:00
parent 0867451f26
commit 5c86d32903
7 changed files with 48 additions and 27 deletions

View File

@ -946,18 +946,21 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
{
if ((int)creatureSpellToCast > -1) //use randomized spell (Faerie Dragon), or only avaliable spell (Archangel)
{
const CSpell * spell = CGI->spellh->spells[creatureSpellToCast];
if (curInt->cb->battleCanCastThisSpell(spell, BattleHex(myNumber)) == ESpellCastProblem::OK)
if (shere != sactive) //can't cast on itself
{
if ((!spell->isNegative() && ourStack) || (!spell->isPositive() && !ourStack))
const CSpell * spell = CGI->spellh->spells[creatureSpellToCast];
if (curInt->cb->battleCanCastThisSpell(spell, BattleHex(myNumber)) == ESpellCastProblem::OK)
{
CCS->curh->changeGraphic(3, 0);
stackCastsSpell = true;
std::string buf = CGI->generaltexth->allTexts[27]; //cast %s on &s
boost::replace_first (buf, "%s", spell->name);
boost::replace_first (buf, "%s", shere->getName());
console->alterTxt = buf;
console->whoSetAlter = 0;
if ((!spell->isNegative() && ourStack) || (!spell->isPositive() && !ourStack))
{
CCS->curh->changeGraphic(3, 0);
stackCastsSpell = true;
std::string buf = CGI->generaltexth->allTexts[27]; //cast %s on &s
boost::replace_first (buf, "%s", spell->name);
boost::replace_first (buf, "%s", shere->getName());
console->alterTxt = buf;
console->whoSetAlter = 0;
}
}
}
}
@ -1503,7 +1506,7 @@ void CBattleInterface::bConsoleDownf()
void CBattleInterface::newStack(const CStack * stack)
{
Point coords = CClickableHex::getXYUnitAnim(stack->position, stack->owner == attackingHeroInstance->tempOwner, stack, this);;
Point coords = CClickableHex::getXYUnitAnim(stack->position, stack->owner == attackingHeroInstance->tempOwner, stack, this);
if(stack->position < 0) //turret
{
@ -1538,6 +1541,7 @@ void CBattleInterface::newStack(const CStack * stack)
creAnims[stack->ID]->setType(CCreatureAnim::HOLDING);
creAnims[stack->ID]->pos = Rect(coords.x, coords.y, creAnims[stack->ID]->fullWidth, creAnims[stack->ID]->fullHeight);
creDir[stack->ID] = stack->attackerOwned;
}
void CBattleInterface::stackRemoved(int stackID)
@ -1551,7 +1555,8 @@ void CBattleInterface::stackActivated(const CStack * stack) //TODO: check it all
{
//givenCommand = NULL;
stackToActivate = stack;
if(pendingAnims.size() == 0)
waitForAnims();
//if(pendingAnims.size() == 0)
activateStack();
}
@ -1563,9 +1568,10 @@ void CBattleInterface::stackMoved(const CStack * stack, std::vector<BattleHex> d
void CBattleInterface::stacksAreAttacked(std::vector<StackAttackedInfo> attackedInfos)
{
for(size_t h = 0; h < attackedInfos.size(); ++h)
for (size_t h = 0; h < attackedInfos.size(); ++h)
{
addNewAnim(new CDefenceAnimation(attackedInfos[h], this));
if (!attackedInfos[h].cloneKilled) //FIXME: play dead animation for cloned creature before it vanishes
addNewAnim(new CDefenceAnimation(attackedInfos[h], this));
if (attackedInfos[h].rebirth)
{
displayEffect(50, attackedInfos[h].defender->position); //TODO: play reverse death animation
@ -1580,6 +1586,8 @@ void CBattleInterface::stacksAreAttacked(std::vector<StackAttackedInfo> attacked
killed += attackedInfos[h].killed;
damage += attackedInfos[h].dmg;
}
if (attackedInfos.front().cloneKilled) //FIXME: cloned stack is already removed
return;
if (targets > 1)
printConsoleAttacked(attackedInfos.front().defender, damage, killed, attackedInfos.front().attacker, true); //creatures perish
else
@ -1589,6 +1597,8 @@ void CBattleInterface::stacksAreAttacked(std::vector<StackAttackedInfo> attacked
{
if (attackedInfos[h].rebirth)
creAnims[attackedInfos[h].defender->ID]->setType(CCreatureAnim::HOLDING);
if (attackedInfos[h].cloneKilled)
stackRemoved(attackedInfos[h].defender->ID);
}
}

View File

@ -62,6 +62,7 @@ struct StackAttackedInfo
bool byShooting; //if true, stack has been attacked by shooting
bool killed; //if true, stack has been killed
bool rebirth; //if true, play rebirth animation after all
bool cloneKilled;
};
/// Struct for battle effect animation e.g. morale, prayer, armageddon, bless,...

View File

@ -640,10 +640,8 @@ void CPlayerInterface::battleNewStackAppeared(const CStack * stack)
{ //another local interface should do this
return;
}
//changing necessary things in battle interface
//boost::unique_lock<boost::recursive_mutex> un(*pim);
battleInt->newStack(stack);
//battleInt->addNewAnim(new CDummyAnim(battleInt, 2)); //wait a moment
}
void CPlayerInterface::battleObstaclesRemoved(const std::set<si32> & removedObstacles)
@ -686,7 +684,7 @@ void CPlayerInterface::battleStacksRemoved(const BattleStacksRemoved & bsr)
return;
}
//boost::unique_lock<boost::recursive_mutex> un(*pim); //fixme: this one caused deadlock
boost::unique_lock<boost::recursive_mutex> un(*pim); //fixme: this one caused deadlock
for(std::set<ui32>::const_iterator it = bsr.stackIDs.begin(); it != bsr.stackIDs.end(); ++it) //for each removed stack
{
battleInt->stackRemoved(*it);
@ -820,9 +818,8 @@ void CPlayerInterface::battleStacksAttacked(const std::vector<BattleStackAttacke
if (defender && !i->isSecondary())
battleInt->displayEffect(i->effect, defender->position);
}
StackAttackedInfo to_put = {defender, i->damageAmount, i->killedAmount, attacker, LOCPLINT->curAction->actionType==7, i->killed(), i->willRebirth()};
StackAttackedInfo to_put = {defender, i->damageAmount, i->killedAmount, attacker, LOCPLINT->curAction->actionType==7, i->killed(), i->willRebirth(), i->cloneKilled()};
arg.push_back(to_put);
}
if(bsa.begin()->isEffect() && bsa.begin()->effect == 12) //for armageddon - I hope this condition is enough

View File

@ -603,7 +603,8 @@ void BattleStackMoved::applyFirstCl( CClient *cl )
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleStackMoved,movedStack,tilesToMove,distance);
}
void BattleStackAttacked::applyCl( CClient *cl )
//void BattleStackAttacked::( CClient *cl )
void BattleStackAttacked::applyFirstCl( CClient *cl )
{
std::vector<BattleStackAttacked> bsa;
bsa.push_back(*this);

View File

@ -1299,7 +1299,7 @@ si8 BattleInfo::hasWallPenalty( const CStack* stack, BattleHex destHex ) const
if (stackLeft && destRight) //shooting from outside to inside
{
int row = (stack->position + destHex) / (2 * GameConstants::BFIELD_WIDTH);
if (stack->position > destHex && ((destHex & GameConstants::BFIELD_WIDTH - stack->position % GameConstants::BFIELD_WIDTH) < 2)) //shooting up high
if (stack->position > destHex && ((destHex % GameConstants::BFIELD_WIDTH - stack->position % GameConstants::BFIELD_WIDTH) < 2)) //shooting up high
row -= 2;
int wallPos = lineToWallHex(row);
if (hexToWallPart(wallPos) != -1) //wall still exists or is indestructible
@ -2732,7 +2732,7 @@ void CStack::prepareAttacked(BattleStackAttacked &bsa) const
if (bsa.damageAmount && vstd::contains(state, EBattleStackState::CLONED)) // block ability should not kill clone (0 damage)
{
bsa.killedAmount = count;
bsa.flags |= BattleStackAttacked::KILLED;
bsa.flags |= BattleStackAttacked::CLONE_KILLED;
return; // no rebirth I believe
}

View File

@ -1270,12 +1270,13 @@ struct StacksHealedOrResurrected : public CPackForClient //3013
struct BattleStackAttacked : public CPackForClient//3005
{
BattleStackAttacked(){flags = 0; type = 3005;};
void applyCl(CClient *cl);
void applyFirstCl(CClient * cl);
//void applyCl(CClient *cl);
DLL_LINKAGE void applyGs(CGameState *gs);
ui32 stackAttacked, attackerID;
ui32 newAmount, newHP, killedAmount, damageAmount;
enum EFlags {KILLED = 1, EFFECT = 2, SECONDARY = 4, REBIRTH = 8};
enum EFlags {KILLED = 1, EFFECT = 2, SECONDARY = 4, REBIRTH = 8, CLONE_KILLED = 16};
ui8 flags; //uses EFlags (above)
ui32 effect; //set only if flag EFFECT is set
std::vector<StacksHealedOrResurrected> healedStacks; //used when life drain
@ -1283,7 +1284,11 @@ struct BattleStackAttacked : public CPackForClient//3005
bool killed() const//if target stack was killed
{
return flags & KILLED;
return flags & KILLED || flags & CLONE_KILLED;
}
bool cloneKilled() const
{
return flags & CLONE_KILLED;
}
bool isEffect() const//if stack has been attacked by a spell
{

View File

@ -972,6 +972,12 @@ DLL_LINKAGE void BattleStackAttacked::applyGs( CGameState *gs )
at->casts--;
at->state.insert(EBattleStackState::ALIVE); //hmm?
}
if (cloneKilled())
{
BattleStacksRemoved bsr; //remove body
bsr.stackIDs.insert(at->ID);
bsr.applyGs(gs);
}
}
DLL_LINKAGE void BattleAttack::applyGs( CGameState *gs )
@ -1006,7 +1012,8 @@ DLL_LINKAGE void BattleAttack::applyGs( CGameState *gs )
for(std::vector<BattleStackAttacked>::const_iterator it = bsa.begin(); it != bsa.end(); ++it)
{
CStack * stack = gs->curB->getStack(it->stackAttacked, false);
stack->getBonusList().remove_if(Bonus::UntilBeingAttacked);
if (stack) //cloned stack is already gone
stack->getBonusList().remove_if(Bonus::UntilBeingAttacked);
}
}