mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* further changes in stack feature code
This commit is contained in:
parent
cc78c2d350
commit
38226c1056
@ -527,11 +527,13 @@ bool CCallback::battleCanShoot(int ID, int dest)
|
||||
CStack *our = battleGetStackByID(ID), *dst = battleGetStackByPos(dest);
|
||||
if(!our || !dst || !gs->curB) return false;
|
||||
|
||||
for(size_t g=0; g<our->effects.size(); ++g)
|
||||
{
|
||||
if(61 == our->effects[g].id) //forgetfulness
|
||||
//for(size_t g=0; g<our->effects.size(); ++g)
|
||||
//{
|
||||
// if(61 == our->effects[g].id) //forgetfulness
|
||||
// return false;
|
||||
//}
|
||||
if(our->hasFeatureOfType(StackFeature::FORGETFULL)) //forgetfulness
|
||||
return false;
|
||||
}
|
||||
|
||||
if(our->hasFeatureOfType(StackFeature::SHOOTER)//it's shooter
|
||||
&& our->owner != dst->owner
|
||||
|
@ -480,7 +480,7 @@ bool CStack::hasFeatureOfType(StackFeature::ECombatFeatures type, int subtype) c
|
||||
|
||||
CStack::CStack(CCreature * C, int A, int O, int I, bool AO, int S)
|
||||
:ID(I), creature(C), amount(A), baseAmount(A), firstHPleft(C->hitPoints), owner(O), slot(S), attackerOwned(AO), position(-1),
|
||||
counterAttacks(1), shots(C->shots), state(), effects(), speed(creature->speed), features(C->abilities), attack(C->attack), defense(C->defence)
|
||||
counterAttacks(1), shots(C->shots), speed(creature->speed), features(C->abilities), attack(C->attack), defense(C->defence)
|
||||
{
|
||||
state.insert(ALIVE);
|
||||
}
|
||||
|
@ -475,6 +475,23 @@ DLL_EXPORT void BattleNextRound::applyGs( CGameState *gs )
|
||||
if(tmpEffects[i].turnsRemain > 0)
|
||||
s->effects.push_back(tmpEffects[i]);
|
||||
}
|
||||
|
||||
//the same as above for features
|
||||
std::vector<StackFeature> tmpFeatures = s->features;
|
||||
s->features.clear();
|
||||
for(int i=0; i < tmpEffects.size(); i++)
|
||||
{
|
||||
if(tmpFeatures[i].duration == StackFeature::N_TURNS)
|
||||
{
|
||||
tmpFeatures[i].turnsRemain--;
|
||||
if(tmpEffects[i].turnsRemain > 0)
|
||||
s->features.push_back(tmpFeatures[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
s->features.push_back(tmpFeatures[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -564,8 +581,104 @@ DLL_EXPORT void SpellCast::applyGs( CGameState *gs )
|
||||
if(s)
|
||||
{
|
||||
s->effects.clear(); //removing all effects
|
||||
//removing all features from spells
|
||||
std::vector<StackFeature> tmpFeatures = s->features;
|
||||
s->features.clear();
|
||||
for(int i=0; i < tmpFeatures.size(); i++)
|
||||
{
|
||||
if(tmpFeatures[i].source != StackFeature::SPELL_EFFECT)
|
||||
{
|
||||
s->features.push_back(tmpFeatures[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StackFeature featureGenerator(StackFeature::ECombatFeatures type, si16 subtype, si32 value, ui16 turnsRemain, si32 additionalInfo = 0)
|
||||
{
|
||||
return makeFeature(type, StackFeature::N_TURNS, subtype, value, StackFeature::SPELL_EFFECT, turnsRemain, additionalInfo);
|
||||
}
|
||||
|
||||
std::vector<StackFeature> stackEffectToFeature(const CStack::StackEffect & sse)
|
||||
{
|
||||
std::vector<StackFeature> sf;
|
||||
switch(sse.id)
|
||||
{
|
||||
case 27: //shield
|
||||
sf.push_back(featureGenerator(StackFeature::GENERAL_DAMAGE_REDUCTION, 0, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 28: //air shield
|
||||
sf.push_back(featureGenerator(StackFeature::GENERAL_DAMAGE_REDUCTION, 1, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 30: //protection from air
|
||||
sf.push_back(featureGenerator(StackFeature::SPELL_DAMAGE_REDUCTION, 0, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 31: //protection from fire
|
||||
sf.push_back(featureGenerator(StackFeature::SPELL_DAMAGE_REDUCTION, 1, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 32: //protection from water
|
||||
sf.push_back(featureGenerator(StackFeature::SPELL_DAMAGE_REDUCTION, 2, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 33: //protection from earth
|
||||
sf.push_back(featureGenerator(StackFeature::SPELL_DAMAGE_REDUCTION, 3, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 41: //bless
|
||||
sf.push_back(featureGenerator(StackFeature::ALWAYS_MAXIMUM_DAMAGE, -1, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 42: //curse
|
||||
sf.push_back(featureGenerator(StackFeature::ALWAYS_MINUMUM_DAMAGE, -1, -1 * VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain, sse.level >= 2 ? 20 : 0));
|
||||
break;
|
||||
case 43: //bloodlust
|
||||
sf.push_back(featureGenerator(StackFeature::ATTACK_BONUS, 0, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 44: //precision
|
||||
sf.push_back(featureGenerator(StackFeature::ATTACK_BONUS, 1, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 45: //weakness
|
||||
sf.push_back(featureGenerator(StackFeature::ATTACK_BONUS, -1, -1 * VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 46: //stone skin
|
||||
sf.push_back(featureGenerator(StackFeature::DEFENCE_BONUS, -1, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 47: //disrupting ray
|
||||
sf.push_back(featureGenerator(StackFeature::DEFENCE_BONUS, -1, -1 * VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 48: //prayer
|
||||
sf.push_back(featureGenerator(StackFeature::ATTACK_BONUS, 0, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
sf.push_back(featureGenerator(StackFeature::DEFENCE_BONUS, 0, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
sf.push_back(featureGenerator(StackFeature::SPEED_BONUS, 0, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 49: //mirth
|
||||
sf.push_back(featureGenerator(StackFeature::MORALE_BONUS, 0, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 50: //sorrow
|
||||
sf.push_back(featureGenerator(StackFeature::MORALE_BONUS, 0, -1 * VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 51: //fortune
|
||||
sf.push_back(featureGenerator(StackFeature::LUCK_BONUS, 0, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 52: //misfortune
|
||||
sf.push_back(featureGenerator(StackFeature::LUCK_BONUS, 0, -1 * VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 53: //haste
|
||||
sf.push_back(featureGenerator(StackFeature::SPEED_BONUS, 0, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||
break;
|
||||
case 54: //slow
|
||||
sf.push_back(featureGenerator(StackFeature::SPEED_BONUS, 0, 0, sse.turnsRemain, -1 * VLC->spellh->spells[sse.id].powers[sse.level]));
|
||||
break;
|
||||
case 55: //slayer
|
||||
sf.push_back(featureGenerator(StackFeature::SLAYER, 0, sse.level, sse.turnsRemain));
|
||||
break;
|
||||
case 61: //forgetfulness
|
||||
sf.push_back(featureGenerator(StackFeature::SLAYER, 0, sse.level, sse.turnsRemain));
|
||||
break;
|
||||
case 56: //frenzy
|
||||
sf.push_back(featureGenerator(StackFeature::SLAYER, 0, sse.level, sse.turnsRemain));
|
||||
break;
|
||||
}
|
||||
|
||||
return sf;
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetStackEffect::applyGs( CGameState *gs )
|
||||
@ -576,6 +689,32 @@ DLL_EXPORT void SetStackEffect::applyGs( CGameState *gs )
|
||||
if(s)
|
||||
{
|
||||
s->effects.push_back(effect); //adding effect
|
||||
std::vector<StackFeature> sf = stackEffectToFeature(effect);
|
||||
for(int n=0; n<sf.size(); ++n)
|
||||
{
|
||||
if(effect.id == 42) //disrupting ray
|
||||
{
|
||||
s->features.push_back(sf[n]);
|
||||
}
|
||||
else
|
||||
{
|
||||
//don't add multiple instances of the same feature from spell source
|
||||
bool added = false;
|
||||
for(int f=0; f<s->features.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
|
||||
tlog1 << "Cannot find stack " << id << std::endl;
|
||||
|
@ -8,7 +8,8 @@ struct StackFeature
|
||||
{
|
||||
NO_TYPE,
|
||||
DOUBLE_WIDE, FLYING, SHOOTER, CHARGE_IMMUNITY, ADDITIONAL_ATTACK, UNLIMITED_RETAILATIONS,
|
||||
NO_MELEE_PENALTY, JOUSTING /*for champions*/,
|
||||
NO_MELEE_PENALTY,
|
||||
JOUSTING /*for champions*/,
|
||||
RAISING_MORALE /*value - how much raises*/,
|
||||
HATE /*eg. angels hate devils, subtype - ID of hated creature*/,
|
||||
KING1,
|
||||
@ -28,11 +29,15 @@ struct StackFeature
|
||||
SPELL_LIKE_ATTACK /*value - spell id; range is taken from spell, but damage from creature; eg. magog*/,
|
||||
THREE_HEADED_ATTACK /*eg. cerberus*/,
|
||||
DEAMON_SUMMONING /*pit lord*/,
|
||||
FIRE_IMMUNITY, FIRE_SHIELD, ENEMY_MORALE_DECREASING /*value - how much it decreases*/,
|
||||
ENEMY_LUCK_DECREASING, UNDEAD, REGENERATION, MANA_DRAIN /*value - spell points per turn*/, LIFE_DRAIN,
|
||||
FIRE_IMMUNITY, FIRE_SHIELD,
|
||||
ENEMY_MORALE_DECREASING /*value - how much it decreases*/,
|
||||
ENEMY_LUCK_DECREASING, UNDEAD,
|
||||
REGENERATION, MANA_DRAIN /*value - spell points per turn*/,
|
||||
LIFE_DRAIN,
|
||||
DOUBLE_DAMAGE_CHANCE /*value in %, eg. dread knight*/,
|
||||
RETURN_AFTER_STRIKE, SELF_MORALE /*eg. minotaur*/,
|
||||
SPELLCASTER /*subtype - spell id, value - level of school, additional info - spell power*/, CATAPULT,
|
||||
SPELLCASTER /*subtype - spell id, value - level of school, additional info - spell power*/,
|
||||
CATAPULT,
|
||||
ENEMY_DEFENCE_REDUCTION /*in % (value), eg. behemots*/,
|
||||
GENERAL_DAMAGE_REDUCTION /*eg. while stoned or blinded - in %, subtype: -1 - any damage, 0 - melee damage, 1 - ranged damage*/,
|
||||
ATTACKS_ALL_ADAJCENT /*eg. hydra*/,
|
||||
@ -40,14 +45,19 @@ struct StackFeature
|
||||
CASTS_SPELL_WHEN_KILLED /*similar to spell after attack*/,
|
||||
FEAR, FEARLESS, NO_DISTANCE_PENALTY, NO_OBSTACLES_PENALTY,
|
||||
SELF_LUCK /*halfling*/,
|
||||
ATTACK_BONUS, DEFENCE_BONUS, SPEED_BONUS, HP_BONUS, ENCHANTER, HEALER, SIEGE_WEAPON, LUCK_BONUS, MORALE_BONUS, HYPNOTIZED,
|
||||
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*/,
|
||||
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 %*/,
|
||||
SUMMONED, ALWAYS_MINUMUM_DAMAGE /*unit does its minimum damage from range; -1 - any attack, 0 - melee, 1 - ranged*/,
|
||||
ALWAYS_MAXIMUM_DAMAGE /*eg. bless effect, -1 - any attack, 0 - melee, 1 - ranged*/,
|
||||
ATTACKS_NEAREST_CREATURE /*while in berserk*/, IN_FRENZY,
|
||||
SUMMONED,
|
||||
ALWAYS_MINUMUM_DAMAGE /*unit does its minimum damage from range; subtype: -1 - any attack, 0 - melee, 1 - ranged, value: additional damage, additional info - multiplicative anti-bonus for dmg in % [eg 20 means that creature will inflict 80% of normal dmg]*/,
|
||||
ALWAYS_MAXIMUM_DAMAGE /*eg. bless effect, subtype: -1 - any attack, 0 - melee, 1 - ranged, value: additional damage, additional info - multiplicative bonus for dmg in %*/,
|
||||
ATTACKS_NEAREST_CREATURE /*while in berserk*/,
|
||||
IN_FRENZY /*value - level*/,
|
||||
SLAYER /*value - level*/,
|
||||
FORGETFULL /*forgetfullnes spell effect*/,
|
||||
FORGETFULL /*forgetfullnes spell effect, value - level*/,
|
||||
CLONED, NOT_ACTIVE
|
||||
};
|
||||
|
||||
|
@ -2130,11 +2130,13 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
|| !curStack->hasFeatureOfType(StackFeature::SHOOTER) //our stack is shooting unit
|
||||
)
|
||||
break;
|
||||
for(int g=0; g<curStack->effects.size(); ++g)
|
||||
{
|
||||
if(61 == curStack->effects[g].id) //forgetfulness
|
||||
//for(int g=0; g<curStack->effects.size(); ++g)
|
||||
//{
|
||||
// if(61 == curStack->effects[g].id) //forgetfulness
|
||||
// break;
|
||||
//}
|
||||
if(curStack->hasFeatureOfType(StackFeature::FORGETFULL)) //forgetfulness
|
||||
break;
|
||||
}
|
||||
|
||||
sendAndApply(&StartAction(ba)); //start shooting
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user