mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
- Fixed serialization of limiters
- Hero can now can have several separate specialty nodes - Fixed typo (speciality->specialty) - Fixed several crashes related to commanders - Improvements to specialty handling, bugfixes and temporary solutions for upcoming hero specialties in mods
This commit is contained in:
parent
36469f406c
commit
ce15eb37c2
@ -553,7 +553,7 @@ void CCreatureWindow::showAll(SDL_Surface * to)
|
||||
skillPictures[i]->showAll (to);
|
||||
}
|
||||
|
||||
if (type == COMMANDER_LEVEL_UP && upgradeOptions[selectedOption] >= 100) //add frame to selected skill
|
||||
if (upgradeOptions.size() && (type == COMMANDER_LEVEL_UP && upgradeOptions[selectedOption] >= 100)) //add frame to selected skill
|
||||
{
|
||||
int index = selectedOption - selectableSkills.size(); //this is screwed
|
||||
CSDL_Ext::drawBorder(to, Rect::around(selectableBonuses[index]->pos), int3(Colors::METALLIC_GOLD.r, Colors::METALLIC_GOLD.g, Colors::METALLIC_GOLD.b));
|
||||
|
@ -65,7 +65,7 @@ class CHeroWindow: public CWindowObject, public CWindowWithGarrison, public CWin
|
||||
std::vector<LRClickableAreaWTextComp *> primSkillAreas;
|
||||
LRClickableAreaWText * expArea;
|
||||
LRClickableAreaWText * spellPointsArea;
|
||||
LRClickableAreaWText * specArea;//speciality
|
||||
LRClickableAreaWText * specArea;//specialty
|
||||
CAnimImage *specImage;
|
||||
MoraleLuckBox * morale, * luck;
|
||||
std::vector<LRClickableAreaWTextComp *> secSkillAreas;
|
||||
|
@ -570,7 +570,7 @@ void CKingdomInterface::generateMinesList(const std::vector<const CGObjectInstan
|
||||
}
|
||||
}
|
||||
|
||||
//Heroes can produce gold as well - skill, speciality or arts
|
||||
//Heroes can produce gold as well - skill, specialty or arts
|
||||
std::vector<const CGHeroInstance*> heroes = LOCPLINT->cb->getHeroesInfo(true);
|
||||
for(size_t i=0; i<heroes.size(); i++)
|
||||
{
|
||||
|
@ -2872,7 +2872,7 @@ void OptionsTab::CPregameTooltipBox::genHeroWindow()
|
||||
pos = Rect(0, 0, 292, 226);
|
||||
genHeader();
|
||||
|
||||
// speciality
|
||||
// specialty
|
||||
new CAnimImage("UN44", CGI->heroh->heroes[settings.hero]->imageIndex, 0, pos.w / 2 - 22, 134);
|
||||
|
||||
new CLabel(pos.w / 2 + 4, 117, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[78]);
|
||||
|
@ -5117,10 +5117,10 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2):
|
||||
|
||||
portrait[b] = new CHeroArea(257 + 228*b, 13, heroInst[b]);
|
||||
|
||||
speciality[b] = new LRClickableAreaWText();
|
||||
speciality[b]->pos = genRect(32, 32, pos.x + 69 + 490*b, pos.y + 45);
|
||||
speciality[b]->hoverText = CGI->generaltexth->heroscrn[27];
|
||||
speciality[b]->text = heroInst[b]->type->specDescr;
|
||||
specialty[b] = new LRClickableAreaWText();
|
||||
specialty[b]->pos = genRect(32, 32, pos.x + 69 + 490*b, pos.y + 45);
|
||||
specialty[b]->hoverText = CGI->generaltexth->heroscrn[27];
|
||||
specialty[b]->text = heroInst[b]->type->specDescr;
|
||||
|
||||
experience[b] = new LRClickableAreaWText();
|
||||
experience[b]->pos = genRect(32, 32, pos.x + 105 + 490*b, pos.y + 45);
|
||||
|
@ -1019,7 +1019,7 @@ class CExchangeWindow : public CWindowObject, public CWindowWithGarrison, public
|
||||
|
||||
MoraleLuckBox *morale[2], *luck[2];
|
||||
|
||||
LRClickableAreaWText *speciality[2];
|
||||
LRClickableAreaWText *specialty[2];
|
||||
LRClickableAreaWText *experience[2];
|
||||
LRClickableAreaWText *spellPoints[2];
|
||||
CHeroArea *portrait[2];
|
||||
|
@ -1764,8 +1764,8 @@ UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
|
||||
if(stack.armyObj->ID == Obj::TOWN)
|
||||
t = static_cast<const CGTownInstance *>(stack.armyObj);
|
||||
else if(h)
|
||||
{ //hero speciality
|
||||
TBonusListPtr lista = h->speciality.getBonuses(Selector::typeSubtype(Bonus::SPECIAL_UPGRADE, base->idNumber));
|
||||
{ //hero specialty
|
||||
TBonusListPtr lista = h->getBonuses(Selector::typeSubtype(Bonus::SPECIAL_UPGRADE, base->idNumber));
|
||||
BOOST_FOREACH(const Bonus *it, *lista)
|
||||
{
|
||||
ui16 nid = it->additionalInfo;
|
||||
|
@ -248,7 +248,7 @@ void CModHandler::initialize(std::vector<std::string> availableMods)
|
||||
detectedMods.push_back(name);
|
||||
}
|
||||
else
|
||||
tlog1 << "\t\t Directory " << name << " does not contains VCMI mod\n";
|
||||
tlog3 << "\t\t Directory " << name << " does not contains VCMI mod\n";
|
||||
}
|
||||
|
||||
if (!checkDependencies(detectedMods))
|
||||
|
@ -716,8 +716,6 @@ CGHeroInstance::CGHeroInstance()
|
||||
commander = NULL;
|
||||
sex = 0xff;
|
||||
secSkills.push_back(std::make_pair(-1, -1));
|
||||
speciality.setNodeType(CBonusSystemNode::SPECIALITY);
|
||||
attachTo(&speciality); //do we ever need to detach it?
|
||||
}
|
||||
|
||||
void CGHeroInstance::initHero(int SUBID)
|
||||
@ -926,23 +924,23 @@ const std::string & CGHeroInstance::getBiography() const
|
||||
void CGHeroInstance::initObj() //TODO: use bonus system
|
||||
{
|
||||
blockVisit = true;
|
||||
speciality.growthsWithLevel = false;
|
||||
HeroSpecial * hs = new HeroSpecial();
|
||||
|
||||
if(!type)
|
||||
return; //TODO: support prison
|
||||
|
||||
BOOST_FOREACH(const auto &spec, type->spec)
|
||||
BOOST_FOREACH(const auto &spec, type->spec) //TODO: unfity with bonus system
|
||||
{
|
||||
Bonus *bonus = new Bonus();
|
||||
bonus->val = spec.val;
|
||||
bonus->sid = id; //from the hero, speciality has no unique id
|
||||
bonus->sid = id; //from the hero, specialty has no unique id
|
||||
bonus->duration = Bonus::PERMANENT;
|
||||
bonus->source = Bonus::HERO_SPECIAL;
|
||||
switch (spec.type)
|
||||
{
|
||||
case 1:// creature speciality
|
||||
case 1:// creature specialty
|
||||
{
|
||||
speciality.growthsWithLevel = true;
|
||||
hs->growsWithLevel = true;
|
||||
|
||||
const CCreature &specCreature = *VLC->creh->creatures[spec.additionalinfo]; //creature in which we have specialty
|
||||
|
||||
@ -960,30 +958,29 @@ void CGHeroInstance::initObj() //TODO: use bonus system
|
||||
|
||||
bonus->limiter.reset(new CCreatureTypeLimiter (specCreature, true)); //with upgrades
|
||||
bonus->type = Bonus::PRIMARY_SKILL;
|
||||
bonus->additionalInfo = spec.additionalinfo;
|
||||
bonus->valType = Bonus::ADDITIVE_VALUE;
|
||||
|
||||
bonus->subtype = PrimarySkill::ATTACK;
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
|
||||
bonus = new Bonus(*bonus);
|
||||
bonus->subtype = PrimarySkill::DEFENSE;
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
//values will be calculated later
|
||||
|
||||
bonus = new Bonus(*bonus);
|
||||
bonus->type = Bonus::STACKS_SPEED;
|
||||
bonus->val = 1; //+1 speed
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
}
|
||||
break;
|
||||
case 2://secondary skill
|
||||
speciality.growthsWithLevel = true;
|
||||
hs->growsWithLevel = true;
|
||||
bonus->type = Bonus::SPECIAL_SECONDARY_SKILL; //needs to be recalculated with level, based on this value
|
||||
bonus->valType = Bonus::BASE_NUMBER; // to receive nonzero value
|
||||
bonus->subtype = spec.subtype; //skill id
|
||||
bonus->val = spec.val; //value per level, in percent
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
bonus = new Bonus(*bonus);
|
||||
|
||||
switch (spec.additionalinfo)
|
||||
@ -996,12 +993,12 @@ void CGHeroInstance::initObj() //TODO: use bonus system
|
||||
break;
|
||||
}
|
||||
bonus->type = Bonus::SECONDARY_SKILL_PREMY; //value will be calculated later
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
break;
|
||||
case 3://spell damage bonus, level dependent but calculated elsewhere
|
||||
bonus->type = Bonus::SPECIAL_SPELL_LEV;
|
||||
bonus->subtype = spec.subtype;
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
break;
|
||||
case 4://creature stat boost
|
||||
switch (spec.subtype)
|
||||
@ -1029,30 +1026,30 @@ void CGHeroInstance::initObj() //TODO: use bonus system
|
||||
}
|
||||
bonus->valType = Bonus::ADDITIVE_VALUE;
|
||||
bonus->limiter.reset(new CCreatureTypeLimiter (*VLC->creh->creatures[spec.additionalinfo], true));
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
break;
|
||||
case 5://spell damage bonus in percent
|
||||
bonus->type = Bonus::SPECIFIC_SPELL_DAMAGE;
|
||||
bonus->valType = Bonus::BASE_NUMBER; // current spell system is screwed
|
||||
bonus->subtype = spec.subtype; //spell id
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
break;
|
||||
case 6://damage bonus for bless (Adela)
|
||||
bonus->type = Bonus::SPECIAL_BLESS_DAMAGE;
|
||||
bonus->subtype = spec.subtype; //spell id if you ever wanted to use it otherwise
|
||||
bonus->additionalInfo = spec.additionalinfo; //damage factor
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
break;
|
||||
case 7://maxed mastery for spell
|
||||
bonus->type = Bonus::MAXED_SPELL;
|
||||
bonus->subtype = spec.subtype; //spell i
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
break;
|
||||
case 8://peculiar spells - enchantments
|
||||
bonus->type = Bonus::SPECIAL_PECULIAR_ENCHANT;
|
||||
bonus->subtype = spec.subtype; //spell id
|
||||
bonus->additionalInfo = spec.additionalinfo;//0, 1 for Coronius
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
break;
|
||||
case 9://upgrade creatures
|
||||
{
|
||||
@ -1060,13 +1057,13 @@ void CGHeroInstance::initObj() //TODO: use bonus system
|
||||
bonus->type = Bonus::SPECIAL_UPGRADE;
|
||||
bonus->subtype = spec.subtype; //base id
|
||||
bonus->additionalInfo = spec.additionalinfo; //target id
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
bonus = new Bonus(*bonus);
|
||||
|
||||
BOOST_FOREACH(auto cre_id, creatures[spec.subtype]->upgrades)
|
||||
{
|
||||
bonus->subtype = cre_id; //propagate for regular upgrades of base creature
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
bonus = new Bonus(*bonus);
|
||||
}
|
||||
vstd::clear_pointer(bonus);
|
||||
@ -1075,14 +1072,14 @@ void CGHeroInstance::initObj() //TODO: use bonus system
|
||||
case 10://resource generation
|
||||
bonus->type = Bonus::GENERATE_RESOURCE;
|
||||
bonus->subtype = spec.subtype;
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
break;
|
||||
case 11://starting skill with mastery (Adrienne)
|
||||
cb->changeSecSkill(id, spec.val, spec.additionalinfo); //simply give it and forget
|
||||
break;
|
||||
case 12://army speed
|
||||
bonus->type = Bonus::STACKS_SPEED;
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
break;
|
||||
case 13://Dragon bonuses (Mutare)
|
||||
bonus->type = Bonus::PRIMARY_SKILL;
|
||||
@ -1097,62 +1094,86 @@ void CGHeroInstance::initObj() //TODO: use bonus system
|
||||
break;
|
||||
}
|
||||
bonus->limiter.reset(new HasAnotherBonusLimiter(Bonus::DRAGON_NATURE));
|
||||
speciality.addNewBonus(bonus);
|
||||
hs->addNewBonus(bonus);
|
||||
break;
|
||||
default:
|
||||
tlog2 << "Unexpected hero speciality " << type <<'\n';
|
||||
tlog2 << "Unexpected hero specialty " << type <<'\n';
|
||||
}
|
||||
}
|
||||
hs->setNodeType(CBonusSystemNode::specialty);
|
||||
attachTo(hs); //do we ever need to detach it?
|
||||
specialty.push_back(hs); //will it work?
|
||||
|
||||
//initialize bonuses
|
||||
BOOST_FOREACH(auto skill_info, secSkills)
|
||||
updateSkill(skill_info.first, skill_info.second);
|
||||
UpdateSpeciality();
|
||||
Updatespecialty();
|
||||
|
||||
mana = manaLimit(); //after all bonuses are taken into account, make sure this line is the last one
|
||||
type->name = name;
|
||||
}
|
||||
void CGHeroInstance::UpdateSpeciality() //TODO: calculate special value of bonuses on-the-fly?
|
||||
void CGHeroInstance::Updatespecialty() //TODO: calculate special value of bonuses on-the-fly?
|
||||
{
|
||||
if (speciality.growthsWithLevel)
|
||||
BOOST_FOREACH (auto hs, specialty)
|
||||
{
|
||||
const auto &creatures = VLC->creh->creatures;
|
||||
|
||||
BOOST_FOREACH(Bonus *it, speciality.getBonusList())
|
||||
if (hs->growsWithLevel)
|
||||
{
|
||||
switch (it->type)
|
||||
{
|
||||
case Bonus::SECONDARY_SKILL_PREMY:
|
||||
it->val = (speciality.valOfBonuses(Bonus::SPECIAL_SECONDARY_SKILL, it->subtype) * level);
|
||||
break; //use only hero skills as bonuses to avoid feedback loop
|
||||
case Bonus::PRIMARY_SKILL: //for crearures, that is
|
||||
int creLevel = creatures[it->additionalInfo]->level;
|
||||
if(!creLevel)
|
||||
{
|
||||
if(it->additionalInfo == 146)
|
||||
creLevel = 5; //treat ballista as 5-level
|
||||
else
|
||||
{
|
||||
tlog2 << "Warning: unknown level of " << creatures[it->additionalInfo]->namePl << std::endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const auto &creatures = VLC->creh->creatures;
|
||||
|
||||
double primSkillModifier = (int)(level / creLevel) / 20.0;
|
||||
int param;
|
||||
switch (it->subtype)
|
||||
BOOST_FOREACH(Bonus * b, hs->getBonusList())
|
||||
{
|
||||
switch (b->type)
|
||||
{
|
||||
case Bonus::SECONDARY_SKILL_PREMY:
|
||||
b->val = (hs->valOfBonuses(Bonus::SPECIAL_SECONDARY_SKILL, b->subtype) * level);
|
||||
break; //use only hero skills as bonuses to avoid feedback loop
|
||||
case Bonus::PRIMARY_SKILL: //for creatures, that is
|
||||
{
|
||||
case PrimarySkill::ATTACK:
|
||||
param = creatures[it->additionalInfo]->Attack();
|
||||
CCreatureTypeLimiter * foundLimiter = NULL;
|
||||
CCreature * cre = NULL;
|
||||
int creLevel = 0;
|
||||
TLimiterPtr limiterNode (b);
|
||||
while (limiterNode->next)
|
||||
{
|
||||
limiterNode = limiterNode->next; //search list
|
||||
if (foundLimiter = dynamic_cast<CCreatureTypeLimiter*>(limiterNode.get())) //TODO: more general eveluation of bonuses?
|
||||
{
|
||||
cre = const_cast<CCreature*>(foundLimiter->creature);
|
||||
creLevel = cre->level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundLimiter)
|
||||
{
|
||||
tlog2 << "Primary skill specialty growth supported only with creature type limiters\n";
|
||||
break;
|
||||
case PrimarySkill::DEFENSE:
|
||||
param = creatures[it->additionalInfo]->Defense();
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
param = 0;
|
||||
}
|
||||
if (cre)
|
||||
{
|
||||
creLevel = cre->level;
|
||||
}
|
||||
if(!creLevel)
|
||||
{
|
||||
creLevel = 5; //treat ballista as tier 5
|
||||
}
|
||||
double primSkillModifier = (int)(level / creLevel) / 20.0;
|
||||
int param;
|
||||
switch (b->subtype)
|
||||
{
|
||||
case PrimarySkill::ATTACK:
|
||||
param = creatures[b->additionalInfo]->Attack();
|
||||
break;
|
||||
case PrimarySkill::DEFENSE:
|
||||
param = creatures[b->additionalInfo]->Defense();
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
param = 0;
|
||||
}
|
||||
b->val = ceil(param * (1 + primSkillModifier)) - param; //yep, overcomplicated but matches original
|
||||
break;
|
||||
}
|
||||
it->val = ceil(param * (1 + primSkillModifier)) - param; //yep, overcomplicated but matches original
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1288,7 +1309,7 @@ ui8 CGHeroInstance::getSpellSchoolLevel(const CSpell * spell, int *outSelectedSc
|
||||
|
||||
vstd::amax(skill, valOfBonuses(Bonus::MAGIC_SCHOOL_SKILL, 0)); //any school bonus
|
||||
vstd::amax(skill, valOfBonuses(Bonus::SPELL, spell->id)); //given by artifact or other effect
|
||||
if (hasBonusOfType(Bonus::MAXED_SPELL, spell->id))//hero speciality (Daremyth, Melodia)
|
||||
if (hasBonusOfType(Bonus::MAXED_SPELL, spell->id))//hero specialty (Daremyth, Melodia)
|
||||
skill = 3;
|
||||
assert(skill >= 0 && skill <= 3);
|
||||
return skill;
|
||||
|
@ -42,7 +42,7 @@ struct TerrainTile;
|
||||
struct InfoWindow;
|
||||
struct Component;
|
||||
struct BankConfig;
|
||||
struct UpdateHeroSpeciality;
|
||||
struct UpdateHerospecialty;
|
||||
struct NewArtifact;
|
||||
class CGBoat;
|
||||
class CArtifactSet;
|
||||
@ -328,13 +328,18 @@ public:
|
||||
|
||||
struct DLL_LINKAGE HeroSpecial : CBonusSystemNode
|
||||
{
|
||||
bool growthsWithLevel;
|
||||
bool growsWithLevel;
|
||||
|
||||
HeroSpecial(){growsWithLevel = false;};
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
h & growthsWithLevel;
|
||||
h & growsWithLevel;
|
||||
}
|
||||
} speciality;
|
||||
};
|
||||
|
||||
std::vector<HeroSpecial*> specialty;
|
||||
|
||||
//BonusList bonuses;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -347,7 +352,7 @@ public:
|
||||
h & exp & level & name & biography & portrait & mana & secSkills & movement
|
||||
& sex & inTownGarrison & /*artifacts & artifWorn & */spells & patrol & moveDir;
|
||||
|
||||
h & type & speciality & commander;
|
||||
h & type & specialty & commander;
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
//visitied town pointer will be restored by map serialization method
|
||||
}
|
||||
@ -411,7 +416,7 @@ public:
|
||||
//void giveArtifact (ui32 aid);
|
||||
void initHeroDefInfo();
|
||||
void pushPrimSkill(int which, int val);
|
||||
void UpdateSpeciality();
|
||||
void Updatespecialty();
|
||||
void updateSkill(int which, int val);
|
||||
|
||||
CGHeroInstance();
|
||||
|
@ -25,7 +25,7 @@ struct BonusLimitationContext;
|
||||
struct BonusCalculationContext;
|
||||
|
||||
typedef shared_ptr<BonusList> TBonusListPtr;
|
||||
typedef shared_ptr<ILimiter> TLimiterPtr;
|
||||
typedef shared_ptr<LimiterDecorator> TLimiterPtr;
|
||||
typedef shared_ptr<IPropagator> TPropagatorPtr;
|
||||
typedef shared_ptr<ICalculator> TCalculatorPtr;
|
||||
typedef std::vector<std::pair<int,std::string> > TModDescr; //modifiers values and their descriptions
|
||||
@ -44,6 +44,11 @@ public:
|
||||
|
||||
virtual ~LimiterDecorator()
|
||||
{}
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & next;
|
||||
}
|
||||
};
|
||||
|
||||
#define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving && h.smartPointerSerialization) deserializationFix();
|
||||
@ -303,6 +308,7 @@ struct DLL_LINKAGE Bonus : public LimiterDecorator
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<LimiterDecorator&>(*this);
|
||||
h & duration & type & subtype & source & val & sid & description & additionalInfo & turnsRemain & valType & effectRange & limiter & propagator;
|
||||
}
|
||||
|
||||
@ -520,7 +526,9 @@ public:
|
||||
virtual ~ILimiter();
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{}
|
||||
{
|
||||
h & static_cast<LimiterDecorator&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE IBonusBearer
|
||||
@ -663,7 +671,7 @@ public:
|
||||
}
|
||||
enum ENodeTypes
|
||||
{
|
||||
UNKNOWN, STACK_INSTANCE, STACK_BATTLE, SPECIALITY, ARTIFACT, CREATURE, ARTIFACT_INSTANCE, HERO, PLAYER, TEAM,
|
||||
UNKNOWN, STACK_INSTANCE, STACK_BATTLE, specialty, ARTIFACT, CREATURE, ARTIFACT_INSTANCE, HERO, PLAYER, TEAM,
|
||||
TOWN_AND_VISITOR, BATTLE
|
||||
};
|
||||
};
|
||||
|
@ -950,8 +950,8 @@ DLL_LINKAGE void HeroLevelUp::applyGs( CGameState *gs )
|
||||
{
|
||||
CGHeroInstance* h = gs->getHero(heroid);
|
||||
h->level = level;
|
||||
//speciality
|
||||
h->UpdateSpeciality();
|
||||
//specialty
|
||||
h->Updatespecialty();
|
||||
}
|
||||
|
||||
DLL_LINKAGE void CommanderLevelUp::applyGs (CGameState *gs)
|
||||
|
@ -76,6 +76,7 @@ void registerTypes1(Serializer &s)
|
||||
s.template registerType<IPropagator>();
|
||||
s.template registerType<CPropagatorNodeType>();
|
||||
|
||||
s.template registerType<LimiterDecorator>();
|
||||
s.template registerType<ILimiter>();
|
||||
s.template registerType<CCreatureTypeLimiter>();
|
||||
s.template registerType<HasAnotherBonusLimiter>();
|
||||
|
@ -4063,7 +4063,7 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, BattleHex dest
|
||||
const Bonus * bonus = NULL;
|
||||
if (caster)
|
||||
bonus = caster->getBonusLocalFirst(Selector::typeSubtype(Bonus::SPECIAL_PECULIAR_ENCHANT, spellID));
|
||||
//TODO does hero speciality should affects his stack casting spells?
|
||||
//TODO does hero specialty should affects his stack casting spells?
|
||||
|
||||
si32 power = 0;
|
||||
BOOST_FOREACH(const CStack *affected, attackedCres)
|
||||
@ -4073,7 +4073,7 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, BattleHex dest
|
||||
sse.stacks.push_back(affected->ID);
|
||||
|
||||
//Apply hero specials - peculiar enchants
|
||||
const ui8 tier = affected->getCreature()->level;
|
||||
const ui8 tier = std::max((ui8)1, affected->getCreature()->level); //don't divide by 0 for certain creatures (commanders, war machines)
|
||||
if (bonus)
|
||||
{
|
||||
switch(bonus->additionalInfo)
|
||||
|
Loading…
Reference in New Issue
Block a user