1
0
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:
mateuszb 2009-05-16 14:49:06 +00:00
parent cc78c2d350
commit 38226c1056
5 changed files with 173 additions and 20 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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
};

View File

@ -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