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

Creature spells are now functional.

It includes Master Genie, Archangel, Faerie Dragon & Elementals
This commit is contained in:
DjWarmonger 2011-10-08 09:11:36 +00:00
parent 47740cd683
commit f4fc77ccb8
6 changed files with 95 additions and 20 deletions

View File

@ -2140,8 +2140,8 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
std::ostringstream estDmg;
estDmg << estimatedDmg.first << " - " << estimatedDmg.second;
//printing
sprintf(buf, CGI->generaltexth->allTexts[36].c_str(), shere->count == 1 ? shere->getCreature()->nameSing.c_str() : shere->getCreature()->namePl.c_str(),
estDmg.str().c_str());
sprintf(buf, CGI->generaltexth->allTexts[36].c_str(),
shere->count == 1 ? shere->getCreature()->nameSing.c_str() : shere->getCreature()->namePl.c_str(), estDmg.str().c_str());
console->alterTxt = buf;
console->whoSetAlter = 0;
}
@ -2170,19 +2170,20 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
else //available tile
{
//setting console text and cursor
const CStack *sactive = activeStack;
if(sactive) //there can be a moment when stack is dead ut next is not yet activated
if(activeStack) //there can be a moment when stack is dead ut next is not yet activated
{
char buf[500];
if(sactive->hasBonusOfType(Bonus::FLYING))
if(activeStack->hasBonusOfType(Bonus::FLYING))
{
CCS->curh->changeGraphic(1,2);
sprintf(buf, CGI->generaltexth->allTexts[295].c_str(), sactive->count == 1 ? sactive->getCreature()->nameSing.c_str() : sactive->getCreature()->namePl.c_str());
sprintf(buf, CGI->generaltexth->allTexts[295].c_str(),
activeStack->count == 1 ? activeStack->getCreature()->nameSing.c_str() : activeStack->getCreature()->namePl.c_str());
}
else
{
CCS->curh->changeGraphic(1,1);
sprintf(buf, CGI->generaltexth->allTexts[294].c_str(), sactive->count == 1 ? sactive->getCreature()->nameSing.c_str() : sactive->getCreature()->namePl.c_str());
sprintf(buf, CGI->generaltexth->allTexts[294].c_str(),
activeStack->count == 1 ? activeStack->getCreature()->nameSing.c_str() : activeStack->getCreature()->namePl.c_str());
}
console->alterTxt = buf;
@ -2894,11 +2895,42 @@ void CBattleInterface::hexLclicked(int whichOne)
endCastingSpell();
}
}
else //we don't aim for spell target
else //we don't aim for spell target area
{
bool walkableTile = false;
if (dest)
{
bool ourStack = actSt->owner == dest->owner;
//try to cast stack spell first
if (stackCanCastSpell && spellSelMode > STACK_SPELL_CANCELLED) //player did not decide to cancel this spell
{
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, THex(whichOne)) == SpellCasting::OK)
{
if (spell->positiveness > -1 && ourStack || spell->positiveness < 1 && !ourStack)
{
giveCommand(BattleAction::MONSTER_SPELL, whichOne, actSt->ID, creatureSpellToCast);
}
}
}
else if (ourStack) //must have only random positive spell (genie)
{
if (dest != actSt) //can't cast on itself
{
int spellID = curInt->cb->battleGetRandomStackSpell(dest, CBattleInfoCallback::RANDOM_GENIE);
if (spellID > -1) //can cast any spell on target stack
{
giveCommand(BattleAction::MONSTER_SPELL, whichOne, actSt->ID, spellID); //use randomized spell
}
}
}
creatureSpellToCast = -1;
return; //no further action after cast
}
if (dest->alive())
{
if(dest->owner != actSt->owner && curInt->cb->battleCanShoot(activeStack, whichOne)) //shooting
@ -2906,7 +2938,7 @@ void CBattleInterface::hexLclicked(int whichOne)
CCS->curh->changeGraphic(1, 6); //cursor should be changed
giveCommand (BattleAction::SHOOT, whichOne, activeStack->ID);
}
else if(dest->owner != actSt->owner) //attacking
else if(!ourStack) //attacking
{
const CStack * actStack = activeStack;
int attackFromHex = -1; //hex from which we will attack chosen stack

View File

@ -396,8 +396,8 @@
"level": 5,
"name": [ "Caliph" ],
"faction": 2,
"ability_add": [ [ "CREATURE_ENCHANT_POWER", 5, 0, 0 ], //spells last 6 turns
[ "RANDOM_SPELLCASTER", 0, 0, 0 ], //master genies cast spells
"ability_add": [ [ "CREATURE_ENCHANT_POWER", 5, 0, 0 ], //spells last 5 turns
[ "RANDOM_SPELLCASTER", 2, 0, 0 ], //master genies cast spells on advanced level
[ "CASTS", 3, 0, 0],
[ "HATE", 50, 53, 0 ],
[ "HATE", 50, 52, 0 ] ], //master genies hate efreet sultans
@ -1293,7 +1293,7 @@
"faction": 8,
"ability_add": [ [ "NON_LIVING", 0, 0, 0 ],
[ "DOUBLE_WIDE", 0, 0, 0 ], //ice elemental should be treated as double-wide
[ "CREATURE_ENCHANT_POWER", 5, 0, 0 ],
[ "CREATURE_ENCHANT_POWER", 6, 0, 0 ],
[ "CASTS", 3, 0, 0 ],
[ "SPELLCASTER", 2, 32, 0 ]],
"defname": "CICEE.DEF",
@ -1307,7 +1307,7 @@
"name": [ "StoneElemental" ],
"faction": 8,
"ability_add": [ [ "NON_LIVING", 0, 0, 0 ], //magma elementals shouldn't get morale
[ "CREATURE_ENCHANT_POWER", 5, 0, 0 ],
[ "CREATURE_ENCHANT_POWER", 6, 0, 0 ],
[ "CASTS", 3, 0, 0 ],
[ "SPELLCASTER", 2, 33, 0 ]],
"defname": "CSTONE.DEF"
@ -1319,7 +1319,7 @@
"name": [ "StormElemental" ],
"faction": 8,
"ability_add": [ [ "NON_LIVING", 0, 0, 0 ], //storm elementals shouldn't get morale
[ "CREATURE_ENCHANT_POWER", 5, 0, 0 ],
[ "CREATURE_ENCHANT_POWER", 6, 0, 0 ],
[ "CASTS", 3, 0, 0 ],
[ "SPELLCASTER", 2, 30, 0 ]],
"defname": "CSTORM.DEF",
@ -1334,7 +1334,7 @@
"name": [ "ElectricityElemental" ],
"faction": 8,
"ability_add": [ [ "NON_LIVING", 0, 0, 0 ] , //energy elementals shouldn't get morale //Crystal Dragons do not fly
[ "CREATURE_ENCHANT_POWER", 5, 0, 0 ],
[ "CREATURE_ENCHANT_POWER", 6, 0, 0 ],
[ "CASTS", 3, 0, 0 ],
[ "SPELLCASTER", 2, 31, 0 ]],
"defname": "CNRG.DEF"

View File

@ -2007,6 +2007,9 @@ TSpell BattleInfo::getRandomBeneficialSpell(const CStack * subject) const
continue;
}
break;
case 65: //clone - not allowed
continue;
break;
}
possibleSpells.push_back(i);
}

View File

@ -102,7 +102,7 @@ namespace PrimarySkill
BONUS_NAME(SPELL_DAMAGE_REDUCTION) /*eg. golems; value - reduction in %, subtype - spell school; -1 - all, 0 - air, 1 - fire, 2 - water, 3 - earth*/ \
BONUS_NAME(NO_WALL_PENALTY) \
BONUS_NAME(NON_LIVING) /*eg. gargoyle*/ \
BONUS_NAME(RANDOM_SPELLCASTER) /*eg. master genie, For Genie spells, subtype - spell id */ \
BONUS_NAME(RANDOM_SPELLCASTER) /*eg. master genie, val - level*/ \
BONUS_NAME(BLOCKS_RETALIATION) /*eg. naga*/ \
BONUS_NAME(SPELL_IMMUNITY) /*subid - spell id*/ \
BONUS_NAME(MANA_CHANNELING) /*value in %, eg. familiar*/ \

View File

@ -1278,15 +1278,16 @@ DLL_EXPORT void BattleStackAdded::applyGs(CGameState *gs)
DLL_EXPORT void BattleSetStackProperty::applyGs(CGameState *gs)
{
CStack * stack = gs->curB->getStack(stackID);
switch (which)
{
case CASTS:
{
if (absolute)
gs->curB->stacks[stackID]->casts = val;
stack->casts = val;
else
gs->curB->stacks[stackID]->casts--;
amax(gs->curB->stacks[stackID]->casts, 0);
stack->casts += val;
amax(stack->casts, 0);
break;
}
}

View File

@ -3312,12 +3312,45 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
BattleSetStackProperty ssp;
ssp.stackID = ba.stackNumber;
ssp.which = BattleSetStackProperty::CASTS;
ssp.which = BattleSetStackProperty::CASTS; //reduce number of casts
ssp.val = -1;
ssp.absolute = false;
sendAndApply(&ssp);
}
sendAndApply(&end_action);
break;
}
case BattleAction::MONSTER_SPELL:
{
StartAction start_action(ba);
sendAndApply(&start_action);
CStack * stack = gs->curB->getStack(ba.stackNumber);
int spellID = ba.additionalInfo;
THex destination(ba.destinationTile);
int spellLvl = 0;
Bonus * bonus = stack->getBonus(Selector::typeSubtype(Bonus::SPELLCASTER, spellID));
if (bonus)
amax(spellLvl, bonus->val);
bonus = stack->getBonus(Selector::type(Bonus::RANDOM_SPELLCASTER));
if (bonus)
amax(spellLvl, bonus->val);
amin (spellLvl, 3);
int casterSide = gs->curB->whatSide(stack->owner);
const CGHeroInstance * secHero = gs->curB->getHero(gs->curB->theOtherPlayer(stack->owner));
handleSpellCasting(spellID, spellLvl, destination, casterSide, stack->owner, NULL, secHero, 0, SpellCasting::CREATURE_ACTIVE_CASTING, stack);
BattleSetStackProperty ssp;
ssp.stackID = ba.stackNumber;
ssp.which = BattleSetStackProperty::CASTS; //reduce number of casts
ssp.val = -1;
ssp.absolute = false;
sendAndApply(&ssp);
sendAndApply(&end_action);
break;
}
@ -3520,7 +3553,10 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, THex destinati
if (unitSpellPower)
sc.dmgToDisplay = spellDamage = stack->count * unitSpellPower; //TODO: handle immunities
else //Faerie Dragon
{
usedSpellPower = stack->valOfBonuses(Bonus::CREATURE_SPELL_POWER) * stack->count / 100;
sc.dmgToDisplay = 0;
}
}
for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it)
{
@ -3536,7 +3572,10 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, THex destinati
if (spellDamage)
bsa.damageAmount = spellDamage;
else
{
bsa.damageAmount = gs->curB->calculateSpellDmg(spell, caster, *it, spellLvl, usedSpellPower);
sc.dmgToDisplay += bsa.damageAmount;
}
bsa.stackAttacked = (*it)->ID;
bsa.attackerID = -1;
(*it)->prepareAttacked(bsa);