1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-25 21:38:59 +02:00

* jousting support

This commit is contained in:
mateuszb 2009-08-22 15:29:30 +00:00
parent ef8f2e695f
commit 56fe3b0547
4 changed files with 28 additions and 15 deletions

@ -1898,7 +1898,7 @@ bool CGameState::checkForVisitableDir(const int3 & src, const int3 & dst) const
return true;
}
int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting)
int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge)
{
int attackDefenseBonus,
minDmg = attacker->creature->damageMin * attacker->amount,
@ -1986,6 +1986,10 @@ int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, con
float dmgBonusMultiplier = 1.0f;
//applying jousting bonus
if( attacker->hasFeatureOfType(StackFeature::JOUSTING) && !defender->hasFeatureOfType(StackFeature::CHARGE_IMMUNITY) )
dmgBonusMultiplier += charge * 0.05f;
//bonus from attack/defense skills
if(attackDefenseBonus < 0) //decreasing dmg
{

@ -136,7 +136,7 @@ struct DLL_EXPORT BattleInfo
bool isStackBlocked(int ID); //returns true if there is neighbouring enemy stack
static signed char mutualPosition(int hex1, int hex2); //returns info about mutual position of given hexes (-1 - they're distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left)
static std::vector<int> neighbouringTiles(int hex);
static int calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting); //TODO: add additional conditions and require necessary data
static int calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge); //charge - number of hexes travelled before attack (for champion's jousting) //TODO: add additional conditions and require necessary data
void calculateCasualties(std::set<std::pair<ui32,si32> > *casualties);
std::set<CStack*> getAttackedCreatures(const CSpell * s, const CGHeroInstance * caster, int destinationTile); //calculates stack affected by given spell
static int calculateSpellDuration(const CSpell * spell, const CGHeroInstance * caster);

@ -451,6 +451,7 @@ askInterfaceForMove:
sendAndApply(&resultsApplied);
}
void CGameHandler::prepareAttacked(BattleStackAttacked &bsa, CStack *def)
{
bsa.killedAmount = bsa.damageAmount / def->MaxHealth();
@ -478,7 +479,7 @@ void CGameHandler::prepareAttacked(BattleStackAttacked &bsa, CStack *def)
}
}
void CGameHandler::prepareAttack(BattleAttack &bat, CStack *att, CStack *def)
void CGameHandler::prepareAttack(BattleAttack &bat, CStack *att, CStack *def, int distance)
{
bat.bsa.clear();
bat.stackAttacking = att->ID;
@ -490,7 +491,7 @@ void CGameHandler::prepareAttack(BattleAttack &bat, CStack *att, CStack *def)
#endif
bsa->stackAttacked = def->ID;
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
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(), distance);//counting dealt damage
if(att->Luck() > 0 && rand()%24 < att->Luck())
{
bsa->damageAmount *= 2;
@ -546,8 +547,11 @@ handleConEnd:
#undef SPELL_CAST_TEMPLATE_1
#undef SPELL_CAST_TEMPLATE_2
}
void CGameHandler::moveStack(int stack, int dest)
{
int CGameHandler::moveStack(int stack, int dest)
{
int ret = 0;
CStack *curStack = gs->curB->getStack(stack),
*stackAtEnd = gs->curB->getStackT(dest);
@ -579,7 +583,7 @@ void CGameHandler::moveStack(int stack, int dest)
}
if((stackAtEnd && stackAtEnd!=curStack && stackAtEnd->alive()) || !accessibility[dest])
return;
return 0;
bool accessibilityWithOccupyable[BFIELD_SIZE];
std::vector<int> accOc = gs->curB->getAccessibility(curStack->ID, true);
@ -596,6 +600,9 @@ void CGameHandler::moveStack(int stack, int dest)
// return false;
std::pair< std::vector<int>, int > path = gs->curB->getPath(curStack->position, dest, accessibilityWithOccupyable, curStack->hasFeatureOfType(StackFeature::FLYING), curStack->hasFeatureOfType(StackFeature::DOUBLE_WIDE), curStack->attackerOwned);
ret = path.second;
if(curStack->hasFeatureOfType(StackFeature::FLYING))
{
if(path.second <= curStack->Speed() && path.first.size() > 0)
@ -623,6 +630,8 @@ void CGameHandler::moveStack(int stack, int dest)
sendAndApply(&sm);
}
}
return ret;
}
CGameHandler::CGameHandler(void)
{
@ -2323,7 +2332,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
case 6: //walk or attack
{
sendAndApply(&StartAction(ba)); //start movement and attack
moveStack(ba.stackNumber,ba.destinationTile);
int distance = moveStack(ba.stackNumber, ba.destinationTile);
CStack *curStack = gs->curB->getStack(ba.stackNumber),
*stackAtEnd = gs->curB->getStackT(ba.additionalInfo);
@ -2380,7 +2389,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
//attack
BattleAttack bat;
prepareAttack(bat,curStack,stackAtEnd);
prepareAttack(bat, curStack, stackAtEnd, distance);
sendAndApply(&bat);
//counterattack
@ -2390,7 +2399,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
&& !stackAtEnd->hasFeatureOfType(StackFeature::SIEGE_WEAPON)
&& !stackAtEnd->hasFeatureOfType(StackFeature::HYPNOTIZED))
{
prepareAttack(bat,stackAtEnd,curStack);
prepareAttack(bat, stackAtEnd, curStack, 0);
bat.flags |= 2;
sendAndApply(&bat);
}
@ -2402,7 +2411,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
&& stackAtEnd->alive() )
{
bat.flags = 0;
prepareAttack(bat,curStack,stackAtEnd);
prepareAttack(bat, curStack, stackAtEnd, 0);
sendAndApply(&bat);
}
sendAndApply(&EndAction());
@ -2430,7 +2439,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
sendAndApply(&StartAction(ba)); //start shooting
BattleAttack bat;
prepareAttack(bat,curStack,destStack);
prepareAttack(bat, curStack, destStack, 0);
bat.flags |= 1;
sendAndApply(&bat);
@ -2440,7 +2449,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
&& curStack->shots
)
{
prepareAttack(bat,curStack,destStack);
prepareAttack(bat, curStack, destStack, 0);
sendAndApply(&bat);
}

@ -83,9 +83,9 @@ public:
bool isAllowedExchange(int id1, int id2);
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
void moveStack(int stack, int dest);
int moveStack(int stack, int dest); //returned value - travelled distance
void startBattle(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town = NULL); //use hero=NULL for no hero
void prepareAttack(BattleAttack &bat, CStack *att, CStack *def); //if last parameter is true, attack is by shooting, if false it's a melee attack
void prepareAttack(BattleAttack &bat, CStack *att, CStack *def, int distance); //distance - number of hexes travelled before attacking
void prepareAttacked(BattleStackAttacked &bsa, CStack *def);
void checkForBattleEnd( std::vector<CStack*> &stacks );
void setupBattle( BattleInfo * curB, int3 tile, const CCreatureSet &army1, const CCreatureSet &army2, const CGHeroInstance * hero1, const CGHeroInstance * hero2, bool creatureBank, const CGTownInstance *town);