mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
- Battle interface fixes. It's possible to move stacks & attack
- Creature window allows to pass stack artifact to hero - Fixes for Mana Drain, including #916
This commit is contained in:
parent
cd4c93318d
commit
f720038ca5
@ -1946,6 +1946,8 @@ void CBattleInterface::activateStack()
|
||||
|
||||
if(!pendingAnims.size() && !active)
|
||||
activate();
|
||||
|
||||
getPossibleActionsForStack (activeStack);
|
||||
}
|
||||
|
||||
double CBattleInterface::getAnimSpeedMultiplier() const
|
||||
@ -1986,7 +1988,8 @@ void CBattleInterface::getPossibleActionsForStack(const CStack * stack)
|
||||
{
|
||||
//TODO: poll possible spells
|
||||
const CSpell * spell;
|
||||
BOOST_FOREACH (Bonus * spellBonus, *stack->getBonuses (Selector::type(Bonus::SPELLCASTER)))
|
||||
BonusList spellBonuses = *stack->getBonuses (Selector::type(Bonus::SPELLCASTER));
|
||||
BOOST_FOREACH (Bonus * spellBonus, spellBonuses)
|
||||
{
|
||||
spell = CGI->spellh->spells[spellBonus->subtype];
|
||||
if (spell->isRisingSpell())
|
||||
@ -2018,12 +2021,15 @@ void CBattleInterface::getPossibleActionsForStack(const CStack * stack)
|
||||
}
|
||||
if (stack->shots && stack->hasBonusOfType (Bonus::SHOOTER))
|
||||
possibleActions.push_back (SHOOT);
|
||||
if (stack->hasBonusOfType (Bonus::RETURN_AFTER_STRIKE));
|
||||
if (stack->hasBonusOfType (Bonus::RETURN_AFTER_STRIKE))
|
||||
possibleActions.push_back (ATTACK_AND_RETURN);
|
||||
|
||||
possibleActions.push_back(ATTACK); //all active stacks can attack
|
||||
possibleActions.push_back(WALK_AND_ATTACK); //not all stacks can always walk, but we will check this elsewhere
|
||||
|
||||
if (stack->canMove() && stack->Speed()); //probably no reason to try move war machines or bound stacks
|
||||
possibleActions.push_back (MOVE_STACK); //all active stacks can attack
|
||||
|
||||
if (siegeH && stack->hasBonusOfType (Bonus::CATAPULT)) //TODO: check shots
|
||||
possibleActions.push_back (CATAPULT);
|
||||
if (stack->hasBonusOfType (Bonus::HEALER))
|
||||
@ -2664,19 +2670,28 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
legalAction = true;
|
||||
break;
|
||||
case MOVE_STACK:
|
||||
if (vstd::contains(occupyableHexes, myNumber) || activeStack->coversPos(myNumber))
|
||||
//TODO
|
||||
{
|
||||
std::vector<BattleHex> acc = curInt->cb->battleGetAvailableHexes (activeStack, false);
|
||||
int shiftedDest = myNumber + (activeStack->attackerOwned ? 1 : -1);
|
||||
|
||||
if (vstd::contains(acc, myNumber))
|
||||
legalAction = true;
|
||||
else if (sactive->doubleWide() && vstd::contains(acc, shiftedDest))
|
||||
legalAction = true;
|
||||
}
|
||||
break;
|
||||
case ATTACK:
|
||||
case WALK_AND_ATTACK:
|
||||
case ATTACK_AND_RETURN:
|
||||
{
|
||||
std::vector<BattleHex> acc = curInt->cb->battleGetAvailableHexes (activeStack, false);
|
||||
if (shere && shere->alive())
|
||||
{
|
||||
setBattleCursor(myNumber); // temporary - needed for following function :(
|
||||
BattleHex attackFromHex = fromWhichHexAttack(myNumber);
|
||||
|
||||
BattleHex attackFromHex = fromWhichHexAttack(myNumber);
|
||||
if(shere->alive() && isTileAttackable(myNumber) && attackFromHex >= 0) //we can be in this line when unreachable creature is L - clicked (as of revision 1308)
|
||||
legalAction = true;
|
||||
if (isTileAttackable(myNumber) && attackFromHex >= 0) //we can be in this line when unreachable creature is L - clicked (as of revision 1308)
|
||||
legalAction = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SHOOT:
|
||||
@ -2773,7 +2788,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
consoleMsg = (boost::format(CGI->generaltexth->allTexts[481]) % shere->getName()).str(); //Select %s
|
||||
realizeAction = [=]{ stackActivated(shere); };
|
||||
break;
|
||||
case MOVE:
|
||||
case MOVE_STACK:
|
||||
if(activeStack->hasBonusOfType(Bonus::FLYING))
|
||||
{
|
||||
cursorFrame = ECursor::COMBAT_FLY;
|
||||
@ -2807,7 +2822,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
case ATTACK_AND_RETURN: //TODO: allow to disable return
|
||||
{
|
||||
setBattleCursor(myNumber); //handle direction of cursor and attackable tile
|
||||
setCursor = false; //don't overwrite settings from the call above
|
||||
setCursor = false; //don't overwrite settings from the call above //TODO: what does it mean?
|
||||
realizeAction = [=]
|
||||
{
|
||||
BattleHex attackFromHex = fromWhichHexAttack(myNumber);
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "../lib/BattleState.h"
|
||||
#include "../lib/CSpellHandler.h"
|
||||
#include "../lib/CArtHandler.h"
|
||||
#include "../lib/NetPacks.h" //ArtifactLocation
|
||||
|
||||
#include "UIFramework/CGuiHandler.h"
|
||||
#include "UIFramework/CIntObjectClasses.h"
|
||||
@ -258,15 +259,15 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
|
||||
|
||||
if (GameConstants::STACK_ARTIFACT)
|
||||
{
|
||||
creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT);
|
||||
if (type > BATTLE) //artifact buttons inactive in battle
|
||||
{
|
||||
//TODO: disable buttons if no artifact is equipped
|
||||
leftArtRoll = new CAdventureMapButton(std::string(), std::string(), boost::bind (&CCreatureWindow::scrollArt, this, -1), 437, 98, "hsbtns3.def", SDLK_LEFT);
|
||||
rightArtRoll = new CAdventureMapButton(std::string(), std::string(), boost::bind (&CCreatureWindow::scrollArt, this, +1), 516, 98, "hsbtns5.def", SDLK_RIGHT);
|
||||
if (heroOwner)
|
||||
passArtToHero = new CAdventureMapButton(std::string(), std::string(), boost::bind (&CCreatureWindow::scrollArt, this, 0), 437, 148, "OVBUTN1.DEF", SDLK_HOME);
|
||||
passArtToHero = new CAdventureMapButton(std::string(), std::string(), boost::bind (&CCreatureWindow::passArtifactToHero, this), 437, 148, "OVBUTN1.DEF", SDLK_HOME);
|
||||
}
|
||||
if ((creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT)))
|
||||
blitAt(graphics->artDefs->ourImages[creatureArtifact->artType->id].bitmap, 466, 100, *bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
@ -379,6 +380,12 @@ void CCreatureWindow::showAll(SDL_Surface * to)
|
||||
|
||||
BOOST_FOREACH(CBonusItem* b, bonusItems)
|
||||
b->showAll (to);
|
||||
|
||||
if (GameConstants::STACK_ARTIFACT)
|
||||
{
|
||||
if (creatureArtifact)
|
||||
blitAt(graphics->artDefs->ourImages[creatureArtifact->artType->id].bitmap, 466 + pos.x, 100 + pos.y, to);
|
||||
}
|
||||
}
|
||||
|
||||
void CCreatureWindow::show(SDL_Surface * to)
|
||||
@ -402,7 +409,26 @@ void CCreatureWindow::scrollArt(int dir)
|
||||
|
||||
void CCreatureWindow::passArtifactToHero()
|
||||
{
|
||||
//creatureArtifact->artType; //FIXME
|
||||
const CGHeroInstance * h = dynamic_cast<const CGHeroInstance *>(stack->armyObj);
|
||||
if (h && creatureArtifact)
|
||||
{
|
||||
LOCPLINT->cb->swapArtifacts (ArtifactLocation (stack, ArtifactPosition::CREATURE_SLOT), ArtifactLocation(h, creatureArtifact->firstBackpackSlot(h)));
|
||||
}
|
||||
else
|
||||
tlog2 << "Pass artifact to hero should be disabled, no hero or no artifact!\n";
|
||||
|
||||
//redraw is handled via CArtifactHolder interface
|
||||
}
|
||||
|
||||
void CCreatureWindow::artifactRemoved (const ArtifactLocation &artLoc)
|
||||
{
|
||||
creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT); //TODO: select next from the list (for Commanders)
|
||||
redraw();
|
||||
}
|
||||
void CCreatureWindow::artifactMoved (const ArtifactLocation &artLoc, const ArtifactLocation &destLoc)
|
||||
{
|
||||
creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT); //TODO: select next from the list (for Commanders)
|
||||
redraw();
|
||||
}
|
||||
|
||||
void CCreatureWindow::clickRight(tribool down, bool previousState)
|
||||
@ -413,18 +439,6 @@ void CCreatureWindow::clickRight(tribool down, bool previousState)
|
||||
close();
|
||||
}
|
||||
|
||||
//void CCreatureWindow::activate()
|
||||
//{
|
||||
// CIntObject::activate();
|
||||
// if(type < 3)
|
||||
// activateRClick();
|
||||
//}
|
||||
|
||||
//void CCreatureWindow::deactivate()
|
||||
//{
|
||||
//
|
||||
//}
|
||||
|
||||
void CCreatureWindow::close()
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
|
@ -18,6 +18,7 @@ struct Bonus;
|
||||
class CCreature;
|
||||
class CStackInstance;
|
||||
class CStack;
|
||||
class ArtifactLocation;
|
||||
class CCreatureArtifactInstance;
|
||||
class CAdventureMapButton;
|
||||
class CBonusItem;
|
||||
@ -35,7 +36,7 @@ class CLabel;
|
||||
class CAnimImage;
|
||||
|
||||
// New creature window
|
||||
class CCreatureWindow : public CIntObject
|
||||
class CCreatureWindow : public CArtifactHolder
|
||||
{
|
||||
public:
|
||||
enum CreWinType {OTHER = 0, BATTLE = 1, ARMY = 2, HERO = 3}; //only last one should open permanently
|
||||
@ -62,6 +63,11 @@ public:
|
||||
CAdventureMapButton * leftArtRoll, * rightArtRoll; //artifact selection
|
||||
CAdventureMapButton * passArtToHero;
|
||||
|
||||
void artifactRemoved (const ArtifactLocation &artLoc);
|
||||
void artifactMoved (const ArtifactLocation &artLoc, const ArtifactLocation &destLoc);
|
||||
void artifactDisassembled (const ArtifactLocation &artLoc) {return;};
|
||||
void artifactAssembled (const ArtifactLocation &artLoc) {return;};
|
||||
|
||||
boost::function<void()> dsm; //dismiss button callback
|
||||
boost::function<void()> Upg; //upgrade button callback
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
{ "id": "SPELL_IMMUNITY", "name": "Immune to %s", "description": "" },
|
||||
{ "id": "CHARGE_IMMUNITY", "name": "Immune to Charge", "description": "Immune to Champion charge" },
|
||||
{ "id": "MANA_CHANNELING", "name": "Magic Channel %d%", "description": "Gives mana spent by enemy" },
|
||||
{ "id": "MANA_DRAIN", "name": "Mana Drain", "description": "Drains %d mana every turn" },
|
||||
{ "id": "CHANGES_SPELL_COST_FOR_ENEMY", "name": "Magic Damper (%d)", "description": "Increase Cost of enemy spells" },
|
||||
{ "id": "MAGIC_MIRROR", "name": "Magic Mirror (%d%)", "description": "Redirects offensive spell to enemy" },
|
||||
{ "id": "MAGIC_RESISTANCE", "name": "Magic Resistance", "description": "%d% chance to resist enemy spell" },
|
||||
|
@ -583,7 +583,7 @@ std::string CStackInstance::bonusToString(Bonus *bonus, bool description) const
|
||||
case Bonus::DRAGON_NATURE:
|
||||
case Bonus::NON_LIVING:
|
||||
case Bonus::UNDEAD:
|
||||
case Bonus::FIRE_IMMUNITY: //TODO: what about direct, hostile and total immunity?
|
||||
case Bonus::FIRE_IMMUNITY:
|
||||
case Bonus::WATER_IMMUNITY:
|
||||
case Bonus::AIR_IMMUNITY:
|
||||
case Bonus::EARTH_IMMUNITY:
|
||||
|
@ -171,7 +171,8 @@ namespace EMarketMode
|
||||
|
||||
namespace EBattleStackState
|
||||
{
|
||||
enum EBattleStackState{ALIVE = 180, SUMMONED, CLONED, HAD_MORALE, WAITING, MOVED, DEFENDING, FEAR};
|
||||
enum EBattleStackState{ALIVE = 180, SUMMONED, CLONED, HAD_MORALE, WAITING, MOVED, DEFENDING, FEAR,
|
||||
DRAINED_MANA /*remember to drain mana only once per turn*/};
|
||||
}
|
||||
|
||||
namespace ECommander
|
||||
|
@ -922,6 +922,7 @@ DLL_LINKAGE void BattleNextRound::applyGs( CGameState *gs )
|
||||
s->state -= EBattleStackState::MOVED;
|
||||
s->state -= EBattleStackState::HAD_MORALE;
|
||||
s->state -= EBattleStackState::FEAR;
|
||||
s->state -= EBattleStackState::DRAINED_MANA;
|
||||
s->counterAttacks = 1 + s->valOfBonuses(Bonus::ADDITIONAL_RETALIATION);
|
||||
// new turn effects
|
||||
s->battleTurnPassed();
|
||||
@ -952,6 +953,7 @@ DLL_LINKAGE void BattleTriggerEffect::applyGs( CGameState *gs )
|
||||
case Bonus::MANA_DRAIN:
|
||||
{
|
||||
CGHeroInstance * h = gs->getHero(additionalInfo);
|
||||
st->state.insert (EBattleStackState::DRAINED_MANA);
|
||||
h->mana -= val;
|
||||
vstd::amax(h->mana, 0);
|
||||
break;
|
||||
|
@ -4096,7 +4096,7 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
|
||||
}
|
||||
}
|
||||
}
|
||||
if(st->hasBonusOfType(Bonus::MANA_DRAIN))
|
||||
if (st->hasBonusOfType(Bonus::MANA_DRAIN) && !vstd::contains(st->state, EBattleStackState::DRAINED_MANA))
|
||||
{
|
||||
const CGHeroInstance * enemy = gs->curB->getHero(gs->curB->theOtherPlayer(st->owner));
|
||||
if (enemy)
|
||||
|
Loading…
Reference in New Issue
Block a user