From 27ffad3580d1b952c4b568ccd43b418e220e2c04 Mon Sep 17 00:00:00 2001 From: mateuszb Date: Sun, 17 May 2009 15:24:50 +0000 Subject: [PATCH] * next part of stack bonus system * stacks can shoot again --- CBattleInterface.cpp | 16 ++++---- CGameState.cpp | 85 +++++++++++++++++------------------------ CGameState.h | 10 ++--- lib/NetPacksLib.cpp | 67 +++++++++++++++++++++----------- lib/StackFeature.h | 2 +- server/CGameHandler.cpp | 12 +++--- 6 files changed, 99 insertions(+), 93 deletions(-) diff --git a/CBattleInterface.cpp b/CBattleInterface.cpp index fe2276776..ced9317b9 100644 --- a/CBattleInterface.cpp +++ b/CBattleInterface.cpp @@ -2582,21 +2582,19 @@ void CBattleHex::clickRight(boost::logic::tribool down) int stID = LOCPLINT->cb->battleGetStack(myNumber); //id of stack being on this tile if(hovered && strictHovered && stID!=-1) { - CStack myst = *LOCPLINT->cb->battleGetStackByID(stID); //stack info + const CStack & myst = *LOCPLINT->cb->battleGetStackByID(stID); //stack info if(!myst.alive()) return; StackState *pom = NULL; if(down) { pom = new StackState(); const CGHeroInstance *h = myst.owner == myInterface->attackingHeroInstance->tempOwner ? myInterface->attackingHeroInstance : myInterface->defendingHeroInstance; - if(h) - { - pom->attackBonus = h->getPrimSkillLevel(0); - pom->defenseBonus = h->getPrimSkillLevel(1); - pom->luck = myst.Luck(); - pom->morale = myst.Morale(); - pom->speedBonus = myst.Speed() - myst.creature->speed; - } + + pom->attackBonus = myst.Attack() - myst.creature->attack; + pom->defenseBonus = myst.Defense() - myst.creature->defence; + pom->luck = myst.Luck(); + pom->morale = myst.Morale(); + pom->speedBonus = myst.Speed() - myst.creature->speed; pom->shotsLeft = myst.shots; for(int vb=0; vbhitPoints), owner(O), slot(S), attackerOwned(AO), position(-1), - counterAttacks(1), shots(C->shots), speed(creature->speed), features(C->abilities), attack(C->attack), defense(C->defence) + counterAttacks(1), shots(C->shots), features(C->abilities) { state.insert(ALIVE); } ui32 CStack::Speed() const { - int premy=0; - const StackEffect *effect = 0; - //haste effect check - effect = getEffect(53); - if(effect) - premy += VLC->spellh->spells[effect->id].powers[effect->level]; - //slow effect check - effect = getEffect(54); - if(effect) - premy -= (creature->speed * VLC->spellh->spells[effect->id].powers[effect->level])/100; - //prayer effect check - effect = getEffect(48); - if(effect) - premy += VLC->spellh->spells[effect->id].powers[effect->level]; - //bind effect check - effect = getEffect(72); - if(effect) + int speed = creature->speed; + + speed += valOfFeatures(StackFeature::SPEED_BONUS); + + int percentBonus = 0; + for(int g=0; gspeed; //don't use '- creature->speed' - speed is unsigned! - premy = -premy; + if(features[g].type == StackFeature::SPEED_BONUS) + { + percentBonus += features[g].additionalInfo; + } } - return speed + premy; + + if(percentBonus < 0) + { + speed = (abs(percentBonus) * speed)/100; + } + else + { + speed = ((100 + percentBonus) * speed)/100; + } + + //bind effect check + if(getEffect(72)) + { + return 0; + } + + return speed; } const CStack::StackEffect * CStack::getEffect(ui16 id) const @@ -564,48 +571,28 @@ si8 CStack::Luck() const si32 CStack::Attack() const { - si32 ret = attack; //value to be returned + si32 ret = creature->attack; //value to be returned - if(getEffect(56)) //frenzy for attacker + if(hasFeatureOfType(StackFeature::IN_FRENZY)) //frenzy for attacker { - ret += (VLC->spellh->spells[56].powers[getEffect(56)->level]/100.0) * defense; + ret += (VLC->spellh->spells[56].powers[getEffect(56)->level]/100.0) * Defense(false); } - if(getEffect(48)) //attacker's prayer handling - { - ret += VLC->spellh->spells[48].powers[getEffect(48)->level]; - } - - if(getEffect(45)) //weakness handling - { - ret -= VLC->spellh->spells[45].powers[getEffect(45)->level]; - } + ret += valOfFeatures(StackFeature::ATTACK_BONUS); return ret; } -si32 CStack::Defense() const +si32 CStack::Defense(bool withFrenzy /*= true*/) const { - si32 ret = defense; + si32 ret = creature->defence; - if(getEffect(56)) //frenzy for defender + if(withFrenzy && getEffect(56)) //frenzy for defender { return 0; } - if(getEffect(48)) //defender's prayer handling - { - ret += VLC->spellh->spells[48].powers[getEffect(48)->level]; - } - if(getEffect(47)) //defender's disrupting ray handling - { - int howMany = howManyEffectsSet(47); - ret -= VLC->spellh->spells[47].powers[getEffect(47)->level] * howMany; - } - if(getEffect(46)) //stone skin handling - { - ret += VLC->spellh->spells[46].powers[getEffect(46)->level]; - } + ret += valOfFeatures(StackFeature::DEFENCE_BONUS); return ret; } diff --git a/CGameState.h b/CGameState.h index b2555c745..671a61bc5 100644 --- a/CGameState.h +++ b/CGameState.h @@ -154,9 +154,9 @@ public: ui16 position; //position on battlefield ui8 counterAttacks; //how many counter attacks can be performed more in this turn (by default set at the beginning of the round to 1) si16 shots; //how many shots left - ui8 speed; //speed of stack with hero bonus - si32 attack; //attack of stack with hero bonus - si32 defense; //defense of stack with hero bonus + //ui8 speed; //speed of stack with hero bonus + //si32 attack; //attack of stack with hero bonus + //si32 defense; //defense of stack with hero bonus si8 morale, luck; //base stack luck/morale std::vector features; @@ -185,7 +185,7 @@ public: si8 Morale() const; //get morale of stack with all modificators si8 Luck() const; //get luck of stack with all modificators si32 Attack() const; //get attack of stack with all modificators - si32 Defense() const; //get defense of stack with all modificators + si32 Defense(bool withFrenzy = true) const; //get defense of stack with all modificators template void save(Handler &h, const int version) { h & creature->idNumber; @@ -200,7 +200,7 @@ public: template void serialize(Handler &h, const int version) { h & ID & amount & baseAmount & firstHPleft & owner & slot & attackerOwned & position & state & counterAttacks - & shots & morale & luck & speed & attack & defense; + & shots & morale & luck; if(h.saving) save(h,version); else diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index f44e12aac..3f6633954 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -479,7 +479,7 @@ DLL_EXPORT void BattleNextRound::applyGs( CGameState *gs ) //the same as above for features std::vector tmpFeatures = s->features; s->features.clear(); - for(int i=0; i < tmpEffects.size(); i++) + for(int i=0; i < tmpFeatures.size(); i++) { if(tmpFeatures[i].duration == StackFeature::N_TURNS) { @@ -681,6 +681,41 @@ std::vector stackEffectToFeature(const CStack::StackEffect & sse) return sf; } +void actualizeEffect(CStack * s, CStack::StackEffect & ef) +{ + //actualizing effects vector + for(int g=0; geffects.size(); ++g) + { + if(s->effects[g].id == ef.id) + { + s->effects[g].turnsRemain = std::max(s->effects[g].turnsRemain, ef.turnsRemain); + } + } + //actualizing features vector + std::vector sf = stackEffectToFeature(ef); + for(int b=0; bfeatures.size(); ++g) + { + if(s->features[g].source == StackFeature::SPELL_EFFECT && s->features[g].type == sf[b].type && s->features[g].subtype == sf[b].subtype) + { + s->features[g].turnsRemain = std::max(s->features[g].turnsRemain, ef.turnsRemain); + } + } + } + +} + +bool containsEff(const std::vector & vec, int effectId) +{ + for(int g=0; gcurB->getStack(id); if(s) { - s->effects.push_back(effect); //adding effect - std::vector sf = stackEffectToFeature(effect); - for(int n=0; neffects, effect.id))//disrupting ray or not on the list - just add { - if(effect.id == 42) //disrupting ray + s->effects.push_back(effect); + std::vector sf = stackEffectToFeature(effect); + for(int n=0; nfeatures.push_back(sf[n]); } - else - { - //don't add multiple instances of the same feature from spell source - bool added = false; - for(int f=0; ffeatures.size(); ++f) - { - if(s->features[f].source == StackFeature::SPELL_EFFECT && s->features[f].type == sf[n].type) - { - s->features[f].turnsRemain = std::max(s->features[f].turnsRemain, effect.turnsRemain); - added = true; - break; - } - } - if(!added) - { - s->features.push_back(sf[n]); - } - } + } + else //just actualize + { + actualizeEffect(s, effect); } } else diff --git a/lib/StackFeature.h b/lib/StackFeature.h index eb4938387..bc55943a0 100644 --- a/lib/StackFeature.h +++ b/lib/StackFeature.h @@ -47,7 +47,7 @@ struct StackFeature SELF_LUCK /*halfling*/, ATTACK_BONUS /*subtype: -1 - any attack, 0 - melee, 1 - ranged*/, DEFENCE_BONUS /*subtype: -1 - any attack, 0 - melee, 1 - ranged*/, - SPEED_BONUS /*additional info - percent of speed bonus applied after direct bonuses; >0 - added, <0 - substracted*/, + SPEED_BONUS /*additional info - percent of speed bonus applied after direct bonuses; >0 - added, <0 - substracted to this part*/, HP_BONUS, ENCHANTER, HEALER, SIEGE_WEAPON, LUCK_BONUS, MORALE_BONUS, HYPNOTIZED, ADDITIONAL_RETAILATION /*value - number of additional retailations*/, MAGIC_MIRROR /* value - chance of redirecting in %*/, diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 4a2e94f2a..706886d0b 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -841,13 +841,13 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army stacks.push_back(new CStack(&VLC->creh->creatures[i->second.first],i->second.second,hero1->tempOwner, stacks.size(), true,i->first)); if(hero1) { - stacks.back()->speed += hero1->valOfBonuses(HeroBonus::STACKS_SPEED); + stacks.back()->features.push_back(makeFeature(StackFeature::SPEED_BONUS, StackFeature::WHOLE_BATTLE, 0, hero1->valOfBonuses(HeroBonus::STACKS_SPEED), StackFeature::BONUS_FROM_HERO)); //base luck/morale calculations //TODO: check if terrain is native, add bonuses for neutral stacks, bonuses from town stacks.back()->morale = hero1->getCurrentMorale(i->first,false); stacks.back()->luck = hero1->getCurrentLuck(i->first,false); - stacks.back()->attack += hero1->getPrimSkillLevel(0); - stacks.back()->defense += hero1->getPrimSkillLevel(1); + stacks.back()->features.push_back(makeFeature(StackFeature::ATTACK_BONUS, StackFeature::WHOLE_BATTLE, 0, hero1->getPrimSkillLevel(0), StackFeature::BONUS_FROM_HERO)); + stacks.back()->features.push_back(makeFeature(StackFeature::DEFENCE_BONUS, StackFeature::WHOLE_BATTLE, 0, hero1->getPrimSkillLevel(1), StackFeature::BONUS_FROM_HERO)); } else { @@ -894,11 +894,11 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army //TODO: check if terrain is native, add bonuses for neutral stacks, bonuses from town if(hero2) { - stacks.back()->speed += hero2->valOfBonuses(HeroBonus::STACKS_SPEED); + stacks.back()->features.push_back(makeFeature(StackFeature::SPEED_BONUS, StackFeature::WHOLE_BATTLE, 0, hero2->valOfBonuses(HeroBonus::STACKS_SPEED), StackFeature::BONUS_FROM_HERO)); stacks.back()->morale = hero2->getCurrentMorale(i->first,false); stacks.back()->luck = hero2->getCurrentLuck(i->first,false); - stacks.back()->attack += hero2->getPrimSkillLevel(0); - stacks.back()->defense += hero2->getPrimSkillLevel(1); + stacks.back()->features.push_back(makeFeature(StackFeature::ATTACK_BONUS, StackFeature::WHOLE_BATTLE, 0, hero2->getPrimSkillLevel(0), StackFeature::BONUS_FROM_HERO)); + stacks.back()->features.push_back(makeFeature(StackFeature::DEFENCE_BONUS, StackFeature::WHOLE_BATTLE, 0, hero2->getPrimSkillLevel(1), StackFeature::BONUS_FROM_HERO)); } else {