1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

- No battle actions will be available during tactics phase

- Fixed moving stacks during tactics
- Fixed Genie spell targeting
- Fixed AI getting stuck at Tree of Knowledge when no resources
This commit is contained in:
DjWarmonger 2012-04-28 13:01:39 +00:00
parent 82f3bc8135
commit d6873d7570
4 changed files with 75 additions and 71 deletions

View File

@ -2666,6 +2666,12 @@ bool shouldVisit (const CGHeroInstance * h, const CGObjectInstance * obj)
case Obj::LIBRARY_OF_ENLIGHTENMENT: case Obj::LIBRARY_OF_ENLIGHTENMENT:
if (h->level < 12) if (h->level < 12)
return false; return false;
case Obj::TREE_OF_KNOWLEDGE:
{
TResources myRes = ai->myCb->getResourceAmount();
if (myRes[Res::GOLD] - GOLD_RESERVE < 2000 || myRes[Res::GEMS] < 10)
return false;
}
break; break;
} }

View File

@ -1941,14 +1941,9 @@ void CBattleInterface::activateStack()
{ {
stackCanCastSpell = true; stackCanCastSpell = true;
if(randomSpellcaster) if(randomSpellcaster)
creatureSpellToCast = -1;
else
creatureSpellToCast = curInt->cb->battleGetRandomStackSpell(s, CBattleInfoCallback::RANDOM_AIMED); //faerie dragon can cast only one spell until their next move creatureSpellToCast = curInt->cb->battleGetRandomStackSpell(s, CBattleInfoCallback::RANDOM_AIMED); //faerie dragon can cast only one spell until their next move
else
creatureSpellToCast = spellcaster->subtype;
if(creatureSpellToCast < 0) //TODO proper way of detecting casters of positive spells
spellSelMode = FRIENDLY_CREATURE_SPELL;
else
spellSelMode = selectionTypeByPositiveness(*CGI->spellh->spells[creatureSpellToCast]);
} }
else else
{ {
@ -1996,63 +1991,69 @@ void CBattleInterface::endCastingSpell()
void CBattleInterface::getPossibleActionsForStack(const CStack * stack) void CBattleInterface::getPossibleActionsForStack(const CStack * stack)
{ {
possibleActions.clear(); possibleActions.clear();
//first action will be prioritized over later ones if (tacticsMode)
if (stack->casts) //TODO: check for battlefield effects that prevent casting?
{ {
if (stack->hasBonusOfType (Bonus::SPELLCASTER)) possibleActions += MOVE_TACTICS, CHOOSE_TACTICS_STACK;
{
//TODO: poll possible spells
const CSpell * spell;
BonusList spellBonuses = *stack->getBonuses (Selector::type(Bonus::SPELLCASTER));
BOOST_FOREACH (Bonus * spellBonus, spellBonuses)
{
spell = CGI->spellh->spells[spellBonus->subtype];
if (spell->isRisingSpell())
{
possibleActions.push_back (RISING_SPELL);
}
//possibleActions.push_back (NO_LOCATION);
//possibleActions.push_back (ANY_LOCATION);
//possibleActions.push_back (OTHER_SPELL);
else
{
switch (spellBonus->subtype)
{
case Spells::REMOVE_OBSTACLE:
possibleActions.push_back (OBSTACLE);
break;
default:
possibleActions.push_back (selectionTypeByPositiveness (*spell));
break;
}
}
}
std::sort(possibleActions.begin(), possibleActions.end());
auto it = std::unique (possibleActions.begin(), possibleActions.end());
possibleActions.erase (it, possibleActions.end());
}
if (stack->hasBonusOfType (Bonus::RANDOM_SPELLCASTER))
possibleActions.push_back (RANDOM_GENIE_SPELL);
if (stack->hasBonusOfType (Bonus::DAEMON_SUMMONING))
possibleActions.push_back (RISE_DEMONS);
} }
if (stack->shots && stack->hasBonusOfType (Bonus::SHOOTER)) else
possibleActions.push_back (SHOOT); {
if (stack->hasBonusOfType (Bonus::RETURN_AFTER_STRIKE)) //first action will be prioritized over later ones
possibleActions.push_back (ATTACK_AND_RETURN); if (stack->casts) //TODO: check for battlefield effects that prevent casting?
{
if (stack->hasBonusOfType (Bonus::SPELLCASTER))
{
//TODO: poll possible spells
const CSpell * spell;
BonusList spellBonuses = *stack->getBonuses (Selector::type(Bonus::SPELLCASTER));
BOOST_FOREACH (Bonus * spellBonus, spellBonuses)
{
spell = CGI->spellh->spells[spellBonus->subtype];
if (spell->isRisingSpell())
{
possibleActions.push_back (RISING_SPELL);
}
//possibleActions.push_back (NO_LOCATION);
//possibleActions.push_back (ANY_LOCATION);
//possibleActions.push_back (OTHER_SPELL);
else
{
switch (spellBonus->subtype)
{
case Spells::REMOVE_OBSTACLE:
possibleActions.push_back (OBSTACLE);
break;
default:
possibleActions.push_back (selectionTypeByPositiveness (*spell));
break;
}
}
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 std::sort(possibleActions.begin(), possibleActions.end());
auto it = std::unique (possibleActions.begin(), possibleActions.end());
possibleActions.erase (it, possibleActions.end());
}
if (stack->hasBonusOfType (Bonus::RANDOM_SPELLCASTER))
possibleActions.push_back (RANDOM_GENIE_SPELL);
if (stack->hasBonusOfType (Bonus::DAEMON_SUMMONING))
possibleActions.push_back (RISE_DEMONS);
}
if (stack->shots && stack->hasBonusOfType (Bonus::SHOOTER))
possibleActions.push_back (SHOOT);
if (stack->hasBonusOfType (Bonus::RETURN_AFTER_STRIKE))
possibleActions.push_back (ATTACK_AND_RETURN);
if (stack->canMove() && stack->Speed()); //probably no reason to try move war machines or bound stacks possibleActions.push_back(ATTACK); //all active stacks can attack
possibleActions.push_back (MOVE_STACK); //all active stacks can attack possibleActions.push_back(WALK_AND_ATTACK); //not all stacks can always walk, but we will check this elsewhere
if (siegeH && stack->hasBonusOfType (Bonus::CATAPULT)) //TODO: check shots if (stack->canMove() && stack->Speed()); //probably no reason to try move war machines or bound stacks
possibleActions.push_back (CATAPULT); possibleActions.push_back (MOVE_STACK); //all active stacks can attack
if (stack->hasBonusOfType (Bonus::HEALER))
possibleActions.push_back (HEAL);
if (siegeH && stack->hasBonusOfType (Bonus::CATAPULT)) //TODO: check shots
possibleActions.push_back (CATAPULT);
if (stack->hasBonusOfType (Bonus::HEALER))
possibleActions.push_back (HEAL);
}
} }
void CBattleInterface::showAliveStack(const CStack *stack, SDL_Surface * to) void CBattleInterface::showAliveStack(const CStack *stack, SDL_Surface * to)
@ -2602,8 +2603,6 @@ void CBattleInterface::bTacticNextStack(const CStack *current /*= NULL*/)
else else
stackActivated(stacksOfMine.front()); stackActivated(stacksOfMine.front());
possibleActions.clear();
possibleActions += MOVE_TACTICS, CHOOSE_TACTICS_STACK;
} }
CBattleInterface::PossibleActions CBattleInterface::selectionTypeByPositiveness(const CSpell & spell) CBattleInterface::PossibleActions CBattleInterface::selectionTypeByPositiveness(const CSpell & spell)
@ -2702,17 +2701,14 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
switch (action) switch (action)
{ {
case MOVE_TACTICS:
break;
case CHOOSE_TACTICS_STACK: case CHOOSE_TACTICS_STACK:
if (shere && ourStack) if (shere && ourStack)
legalAction = true; legalAction = true;
break; break;
case MOVE_TACTICS:
case MOVE_STACK: case MOVE_STACK:
{ if (canStackMoveHere (sactive, myNumber) && !shere)
if (canStackMoveHere (sactive, myNumber))
legalAction = true; legalAction = true;
}
break; break;
case ATTACK: case ATTACK:
case WALK_AND_ATTACK: case WALK_AND_ATTACK:
@ -2749,7 +2745,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
break; break;
case RANDOM_GENIE_SPELL: case RANDOM_GENIE_SPELL:
{ {
if (shere) if (shere && ourStack && shere != sactive) //only positive spells for other allied creatures
{ {
int spellID = curInt->cb->battleGetRandomStackSpell(shere, CBattleInfoCallback::RANDOM_GENIE); int spellID = curInt->cb->battleGetRandomStackSpell(shere, CBattleInfoCallback::RANDOM_GENIE);
if (spellID > -1) if (spellID > -1)
@ -2829,8 +2825,9 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
consoleMsg = (boost::format(CGI->generaltexth->allTexts[481]) % shere->getName()).str(); //Select %s consoleMsg = (boost::format(CGI->generaltexth->allTexts[481]) % shere->getName()).str(); //Select %s
realizeAction = [=]{ stackActivated(shere); }; realizeAction = [=]{ stackActivated(shere); };
break; break;
case MOVE_TACTICS:
case MOVE_STACK: case MOVE_STACK:
if(activeStack->hasBonusOfType(Bonus::FLYING)) if (activeStack->hasBonusOfType(Bonus::FLYING))
{ {
cursorFrame = ECursor::COMBAT_FLY; cursorFrame = ECursor::COMBAT_FLY;
consoleMsg = (boost::format(CGI->generaltexth->allTexts[295]) % activeStack->getName()).str(); //Fly %s here consoleMsg = (boost::format(CGI->generaltexth->allTexts[295]) % activeStack->getName()).str(); //Fly %s here
@ -2843,7 +2840,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
realizeAction = [=] realizeAction = [=]
{ {
if(activeStack->doubleWide()) if (activeStack->doubleWide())
{ {
std::vector<BattleHex> acc = curInt->cb->battleGetAvailableHexes(activeStack, false); std::vector<BattleHex> acc = curInt->cb->battleGetAvailableHexes(activeStack, false);
int shiftedDest = myNumber + (activeStack->attackerOwned ? 1 : -1); int shiftedDest = myNumber + (activeStack->attackerOwned ? 1 : -1);
@ -2854,7 +2851,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
} }
else else
{ {
giveCommand(BattleAction::WALK, myNumber, activeStack->ID); giveCommand (BattleAction::WALK, myNumber, activeStack->ID);
} }
}; };
break; break;
@ -2867,7 +2864,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
realizeAction = [=] realizeAction = [=]
{ {
BattleHex attackFromHex = fromWhichHexAttack(myNumber); BattleHex attackFromHex = fromWhichHexAttack(myNumber);
if(attackFromHex >= 0) //we can be in this line when unreachable creature is L - clicked (as of revision 1308) if (attackFromHex >= 0) //we can be in this line when unreachable creature is L - clicked (as of revision 1308)
{ {
giveCommand(BattleAction::WALK_AND_ATTACK, attackFromHex, activeStack->ID, myNumber); giveCommand(BattleAction::WALK_AND_ATTACK, attackFromHex, activeStack->ID, myNumber);
} }

View File

@ -959,7 +959,7 @@ CCommanderInstance::CCommanderInstance (TCreature id)
name = "Commando"; //TODO - parse them name = "Commando"; //TODO - parse them
} }
void CCommanderInstance::init() //called only after CStackInstance::init was executed void CCommanderInstance::init()
{ {
alive = true; alive = true;
experience = 0; experience = 0;

View File

@ -205,6 +205,7 @@ namespace Obj
SHIPWRECK = 85, SHIPWRECK = 85,
STABLES = 94, STABLES = 94,
TRADING_POST = 99, TRADING_POST = 99,
TREE_OF_KNOWLEDGE = 102,
SUBTERRANEAN_GATE = 103, SUBTERRANEAN_GATE = 103,
UNIVERSITY = 104, UNIVERSITY = 104,
SCHOOL_OF_WAR = 107, SCHOOL_OF_WAR = 107,