1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-29 21:56:54 +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

View File

@ -1898,7 +1898,7 @@ bool CGameState::checkForVisitableDir(const int3 & src, const int3 & dst) const
return true; 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, int attackDefenseBonus,
minDmg = attacker->creature->damageMin * attacker->amount, minDmg = attacker->creature->damageMin * attacker->amount,
@ -1986,6 +1986,10 @@ int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, con
float dmgBonusMultiplier = 1.0f; 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 //bonus from attack/defense skills
if(attackDefenseBonus < 0) //decreasing dmg if(attackDefenseBonus < 0) //decreasing dmg
{ {

View File

@ -136,7 +136,7 @@ struct DLL_EXPORT BattleInfo
bool isStackBlocked(int ID); //returns true if there is neighbouring enemy stack 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 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 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); 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 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); static int calculateSpellDuration(const CSpell * spell, const CGHeroInstance * caster);

View File

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

View File

@ -83,9 +83,9 @@ public:
bool isAllowedExchange(int id1, int id2); bool isAllowedExchange(int id1, int id2);
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h); 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 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 prepareAttacked(BattleStackAttacked &bsa, CStack *def);
void checkForBattleEnd( std::vector<CStack*> &stacks ); 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); void setupBattle( BattleInfo * curB, int3 tile, const CCreatureSet &army1, const CCreatureSet &army2, const CGHeroInstance * hero1, const CGHeroInstance * hero2, bool creatureBank, const CGTownInstance *town);