mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
parent
0867451f26
commit
5c86d32903
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,...
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user