1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-15 00:05:02 +02:00

* morale/luck support in battles

* minor improvements/fixes
* updated changelog
More objects supported:
 *	Faerie Ring
 *	Swan Pond
 *	Idol of Fortune
 *	Fountain of Fortune
 *	Rally Flag
 *	Oasis
 *	Temple
 *	Watering Hole
 *	Fountain of Youth
This commit is contained in:
Michał W. Urbańczyk
2009-02-05 09:49:45 +00:00
parent 218a3beaf6
commit e1d6ff54d7
15 changed files with 325 additions and 113 deletions

View File

@ -311,14 +311,49 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile
CStack *next;
while(!battleResult.get() && (next=gs->curB->getNextStack()))
{
BattleSetActiveStack sas;
sas.stack = next->ID;
sendAndApply(&sas);
boost::unique_lock<boost::mutex> lock(battleMadeAction.mx);
while(!battleMadeAction.data && !battleResult.get()) //active stack hasn't made its action and battle is still going
battleMadeAction.cond.wait(lock);
battleMadeAction.data = false;
next->state -= WAITING; //if stack was waiting it'll now make move, so it won't be "waiting" anymore
//check for bad morale => freeze
if(next->Morale() < 0)
{
if( rand()%24 < (-next->Morale())*2 )
{
//unit loses its turn - empty freeze action
BattleAction ba;
ba.actionType = 11;
ba.additionalInfo = 1;
ba.side = !next->attackerOwned;
ba.stackNumber = next->ID;
sendAndApply(&StartAction(ba));
sendDataToClients(ui16(3008));
checkForBattleEnd(stacks); //check if this "action" ended the battle (not likely but who knows...)
continue;
}
}
askInterfaceForMove:
//ask interface and wait for answer
{
BattleSetActiveStack sas;
sas.stack = next->ID;
sendAndApply(&sas);
boost::unique_lock<boost::mutex> lock(battleMadeAction.mx);
while(!battleMadeAction.data && !battleResult.get()) //active stack hasn't made its action and battle is still going
battleMadeAction.cond.wait(lock);
battleMadeAction.data = false;
}
//we're after action, all results applied
checkForBattleEnd(stacks); //check if this action ended the battle
//check for good morale
if(!vstd::contains(next->state,HAD_MORALE) //only one extra move per turn possible
&& !vstd::contains(next->state,DEFENDING)
&& !vstd::contains(next->state,WAITING)
&& next->alive()
&& next->Morale() > 0
)
if(rand()%24 < next->Morale()) //this stack hasn't got morale this turn
goto askInterfaceForMove; //move this stack once more
}
}
@ -395,6 +430,11 @@ void CGameHandler::prepareAttack(BattleAttack &bat, CStack *att, CStack *def)
bat.stackAttacking = att->ID;
bat.bsa.stackAttacked = def->ID;
bat.bsa.damageAmount = BattleInfo::calculateDmg(att, def, gs->getHero(att->attackerOwned ? gs->curB->hero1 : gs->curB->hero2), gs->getHero(def->attackerOwned ? gs->curB->hero1 : gs->curB->hero2), bat.shot());//counting dealt damage
if(att->Luck() > 0 && rand()%24 < att->Luck())
{
bat.bsa.damageAmount *= 2;
bat.bsa.flags |= 4;
}
prepareAttacked(bat.bsa,def);
}
void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
@ -2035,6 +2075,20 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
for(std::map<si32,std::pair<ui32,si32> >::iterator i = army1.slots.begin(); i!=army1.slots.end(); i++)
{
stacks.push_back(new CStack(&VLC->creh->creatures[i->second.first],i->second.second,hero1->tempOwner, stacks.size(), true,i->first));
//base luck/morale calculations
//TODO: check if terrain is native, add bonuses for neutral stacks, bonuses from town
if(hero1)
{
stacks.back()->morale = hero1->getCurrentMorale(i->first,false);
stacks.back()->luck = hero1->getCurrentLuck(i->first,false);
}
else
{
stacks.back()->morale = 0;
stacks.back()->luck = 0;
}
stacks[stacks.size()-1]->ID = stacks.size()-1;
}
//initialization of positions
@ -2068,7 +2122,21 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
stacks[b]->position = attackerLoose[army1.slots.size()-1][b];
}
for(std::map<si32,std::pair<ui32,si32> >::iterator i = army2.slots.begin(); i!=army2.slots.end(); i++)
{
stacks.push_back(new CStack(&VLC->creh->creatures[i->second.first],i->second.second,hero2 ? hero2->tempOwner : 255, stacks.size(), false, i->first));
//base luck/morale calculations
//TODO: check if terrain is native, add bonuses for neutral stacks, bonuses from town
if(hero2)
{
stacks.back()->morale = hero2->getCurrentMorale(i->first,false);
stacks.back()->luck = hero2->getCurrentLuck(i->first,false);
}
else
{
stacks.back()->morale = 0;
stacks.back()->luck = 0;
}
}
if(army2.formation)
for(int b=0; b<army2.slots.size(); ++b) //tight