1
0
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:
DjWarmonger 2012-04-17 14:50:23 +00:00
parent cd4c93318d
commit f720038ca5
8 changed files with 69 additions and 30 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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" },

View File

@ -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:

View File

@ -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

View File

@ -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;

View File

@ -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)