mirror of
https://github.com/vcmi/vcmi.git
synced 2025-04-25 12:14:46 +02:00
Partial Stack Exp operations. Can't really test it as battle is unplayable atm.
This commit is contained in:
parent
7a49240520
commit
252cee96f5
@ -114,7 +114,7 @@ public:
|
|||||||
|
|
||||||
std::map<TBonusType, std::pair<std::string, std::string> > stackBonuses; // bonus => name, description
|
std::map<TBonusType, std::pair<std::string, std::string> > stackBonuses; // bonus => name, description
|
||||||
std::vector<std::vector<ui32>> expRanks; // stack experience needed for certain rank, index 0 for other tiers (?)
|
std::vector<std::vector<ui32>> expRanks; // stack experience needed for certain rank, index 0 for other tiers (?)
|
||||||
std::vector<ui32> maxExpPerBattle; //tiers same as above
|
std::vector<ui32> maxExpPerBattle; //%, tiers same as above
|
||||||
si8 expAfterUpgrade;//multiplier in %
|
si8 expAfterUpgrade;//multiplier in %
|
||||||
|
|
||||||
void loadCreatures();
|
void loadCreatures();
|
||||||
|
@ -218,10 +218,18 @@ void CCreatureSet::setStackCount(TSlot slot, TQuantity count)
|
|||||||
{
|
{
|
||||||
assert(hasStackAtSlot(slot));
|
assert(hasStackAtSlot(slot));
|
||||||
assert(count > 0);
|
assert(count > 0);
|
||||||
|
if (STACK_EXP)
|
||||||
|
stacks[slot]->experience *= ((stacks[slot]->count + count)/(float)stacks[slot]->count);
|
||||||
stacks[slot]->count = count;
|
stacks[slot]->count = count;
|
||||||
armyChanged();
|
armyChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CCreatureSet::giveStackExp(expType exp)
|
||||||
|
{
|
||||||
|
for(TSlots::const_iterator i = stacks.begin(); i != stacks.end(); i++)
|
||||||
|
i->second->giveStackExp(exp);
|
||||||
|
}
|
||||||
|
|
||||||
void CCreatureSet::clear()
|
void CCreatureSet::clear()
|
||||||
{
|
{
|
||||||
while(!stacks.empty())
|
while(!stacks.empty())
|
||||||
@ -453,6 +461,19 @@ int CStackInstance::getExpRank() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CStackInstance::giveStackExp(expType exp)
|
||||||
|
{
|
||||||
|
int level = type->level;
|
||||||
|
if (!iswith(level, 1, 7))
|
||||||
|
level = 0;
|
||||||
|
|
||||||
|
CCreatureHandler * creh = VLC->creh;
|
||||||
|
|
||||||
|
amin(exp, (expType)creh->expRanks[level].back()); //prevent exp overflow due to different types
|
||||||
|
amin(exp, (exp * creh->maxExpPerBattle[level])/100);
|
||||||
|
amin(experience += exp, creh->expRanks[level].back()); //can't get more exp than this limit
|
||||||
|
}
|
||||||
|
|
||||||
void CStackInstance::setType(int creID)
|
void CStackInstance::setType(int creID)
|
||||||
{
|
{
|
||||||
setType(VLC->creh->creatures[creID]);
|
setType(VLC->creh->creatures[creID]);
|
||||||
@ -461,7 +482,11 @@ void CStackInstance::setType(int creID)
|
|||||||
void CStackInstance::setType(const CCreature *c)
|
void CStackInstance::setType(const CCreature *c)
|
||||||
{
|
{
|
||||||
if(type)
|
if(type)
|
||||||
|
{
|
||||||
detachFrom(const_cast<CCreature*>(type));
|
detachFrom(const_cast<CCreature*>(type));
|
||||||
|
if (type->isMyUpgrade(c) && STACK_EXP)
|
||||||
|
experience *= VLC->creh->expAfterUpgrade / 100.0f;
|
||||||
|
}
|
||||||
|
|
||||||
type = c;
|
type = c;
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ public:
|
|||||||
void setType(int creID);
|
void setType(int creID);
|
||||||
void setType(const CCreature *c);
|
void setType(const CCreature *c);
|
||||||
void setArmyObj(const CArmedInstance *ArmyObj);
|
void setArmyObj(const CArmedInstance *ArmyObj);
|
||||||
|
void giveStackExp(expType exp);
|
||||||
bool valid(bool allowUnrandomized) const;
|
bool valid(bool allowUnrandomized) const;
|
||||||
virtual std::string nodeName() const OVERRIDE;
|
virtual std::string nodeName() const OVERRIDE;
|
||||||
void deserializationFix();
|
void deserializationFix();
|
||||||
@ -118,6 +119,7 @@ public:
|
|||||||
void setStackCount(TSlot slot, TQuantity count); //stack must exist!
|
void setStackCount(TSlot slot, TQuantity count); //stack must exist!
|
||||||
CStackInstance *detachStack(TSlot slot); //removes stack from army but doesn't destroy it (so it can be moved somewhere else or safely deleted)
|
CStackInstance *detachStack(TSlot slot); //removes stack from army but doesn't destroy it (so it can be moved somewhere else or safely deleted)
|
||||||
void setStackType(TSlot slot, const CCreature *type);
|
void setStackType(TSlot slot, const CCreature *type);
|
||||||
|
void giveStackExp(expType exp);
|
||||||
|
|
||||||
//derivative
|
//derivative
|
||||||
void eraseStack(TSlot slot); //slot must be occupied
|
void eraseStack(TSlot slot); //slot must be occupied
|
||||||
|
@ -1179,7 +1179,7 @@ void CGHeroInstance::updateSkill(int which, int val)
|
|||||||
int skillVal = 0;
|
int skillVal = 0;
|
||||||
switch (which)
|
switch (which)
|
||||||
{
|
{
|
||||||
case 1: //Archery
|
case ARCHERY:
|
||||||
switch (val)
|
switch (val)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
@ -1190,27 +1190,29 @@ void CGHeroInstance::updateSkill(int which, int val)
|
|||||||
skillVal = 50; break;
|
skillVal = 50; break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: //Logistics
|
case LOGISTICS:
|
||||||
skillVal = 10 * val; break;
|
skillVal = 10 * val; break;
|
||||||
case 5: //Navigation
|
case NAVIGATION:
|
||||||
skillVal = 50 * val; break;
|
skillVal = 50 * val; break;
|
||||||
case 8: //Mysticism
|
case MYSTICISM:
|
||||||
skillVal = val; break;
|
skillVal = val; break;
|
||||||
case 11: //eagle Eye
|
case EAGLE_EYE:
|
||||||
skillVal = 30 + 10 * val; break;
|
skillVal = 30 + 10 * val; break;
|
||||||
case 12: //Necromancy
|
case NECROMANCY:
|
||||||
skillVal = 10 * val; break;
|
skillVal = 10 * val; break;
|
||||||
case 22: //Offense
|
case LEARNING:
|
||||||
skillVal = 10 * val; break;
|
|
||||||
case 23: //Armorer
|
|
||||||
skillVal = 5 * val; break;
|
skillVal = 5 * val; break;
|
||||||
case 24: //Intelligence
|
case OFFENCE:
|
||||||
|
skillVal = 10 * val; break;
|
||||||
|
case ARMORER:
|
||||||
|
skillVal = 5 * val; break;
|
||||||
|
case INTELLIGENCE:
|
||||||
skillVal = 25 << (val-1); break;
|
skillVal = 25 << (val-1); break;
|
||||||
case 25: //Sorcery
|
case SORCERY:
|
||||||
skillVal = 5 * val; break;
|
skillVal = 5 * val; break;
|
||||||
case 26: //Resistance
|
case RESISTANCE:
|
||||||
skillVal = 5 << (val-1); break;
|
skillVal = 5 << (val-1); break;
|
||||||
case 27: //First Aid
|
case FIRST_AID:
|
||||||
skillVal = 25 + 25*val; break;
|
skillVal = 25 + 25*val; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1246,6 +1248,11 @@ int CGHeroInstance::getTotalStrength() const
|
|||||||
return (int) ret;
|
return (int) ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expType CGHeroInstance::calculateXp(expType exp) const
|
||||||
|
{
|
||||||
|
return exp * (100 + valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, CGHeroInstance::LEARNING))/100.0f;
|
||||||
|
}
|
||||||
|
|
||||||
ui8 CGHeroInstance::getSpellSchoolLevel(const CSpell * spell, int *outSelectedSchool) const
|
ui8 CGHeroInstance::getSpellSchoolLevel(const CSpell * spell, int *outSelectedSchool) const
|
||||||
{
|
{
|
||||||
si16 skill = -1; //skill level
|
si16 skill = -1; //skill level
|
||||||
@ -2492,7 +2499,7 @@ void CGVisitableOPH::onNAHeroVisit(int heroID, bool alreadyVisited) const
|
|||||||
case 100: //give exp
|
case 100: //give exp
|
||||||
{
|
{
|
||||||
const CGHeroInstance *h = cb->getHero(heroID);
|
const CGHeroInstance *h = cb->getHero(heroID);
|
||||||
val = val*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f;
|
val = h->calculateXp(val);
|
||||||
InfoWindow iw;
|
InfoWindow iw;
|
||||||
iw.soundID = sound;
|
iw.soundID = sound;
|
||||||
iw.components.push_back(Component(id,subid,val,0));
|
iw.components.push_back(Component(id,subid,val,0));
|
||||||
@ -3836,7 +3843,7 @@ void CGPickable::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
sd.player = h->tempOwner;
|
sd.player = h->tempOwner;
|
||||||
sd.text << std::pair<ui8,ui32>(11,146);
|
sd.text << std::pair<ui8,ui32>(11,146);
|
||||||
sd.components.push_back(Component(2,6,val1,0));
|
sd.components.push_back(Component(2,6,val1,0));
|
||||||
int expVal = val2*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f;
|
expType expVal = h->calculateXp(val2);
|
||||||
sd.components.push_back(Component(5,0,expVal, 0));
|
sd.components.push_back(Component(5,0,expVal, 0));
|
||||||
sd.soundID = soundBase::chest;
|
sd.soundID = soundBase::chest;
|
||||||
boost::function<void(ui32)> fun = boost::bind(&CGPickable::chosen,this,_1,h->id);
|
boost::function<void(ui32)> fun = boost::bind(&CGPickable::chosen,this,_1,h->id);
|
||||||
@ -3857,7 +3864,7 @@ void CGPickable::chosen( int which, int heroID ) const
|
|||||||
cb->giveResource(cb->getOwner(heroID),6,val1);
|
cb->giveResource(cb->getOwner(heroID),6,val1);
|
||||||
break;
|
break;
|
||||||
case 2: //player pick exp
|
case 2: //player pick exp
|
||||||
cb->changePrimSkill(heroID, 4, val2*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f);
|
cb->changePrimSkill(heroID, 4, h->calculateXp(val2));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::string("Unhandled treasure choice");
|
throw std::string("Unhandled treasure choice");
|
||||||
@ -4374,7 +4381,7 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
|
|||||||
{
|
{
|
||||||
case 1: //experience
|
case 1: //experience
|
||||||
{
|
{
|
||||||
int expVal = rVal*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f;
|
expType expVal = h->calculateXp(rVal);
|
||||||
cb->changePrimSkill(h->id, 4, expVal, false);
|
cb->changePrimSkill(h->id, 4, expVal, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -4862,7 +4869,7 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
|
|||||||
|
|
||||||
if(gainedExp || changesPrimSkill || abilities.size())
|
if(gainedExp || changesPrimSkill || abilities.size())
|
||||||
{
|
{
|
||||||
expType expVal = gainedExp*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f;
|
expType expVal = h->calculateXp(gainedExp);
|
||||||
getText(iw,afterBattle,175,h);
|
getText(iw,afterBattle,175,h);
|
||||||
|
|
||||||
if(expVal)
|
if(expVal)
|
||||||
@ -6165,8 +6172,10 @@ void CGSirens::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
|
|
||||||
if(xp)
|
if(xp)
|
||||||
{
|
{
|
||||||
|
xp = h->calculateXp(xp);
|
||||||
iw.text.addTxt(11,132);
|
iw.text.addTxt(11,132);
|
||||||
iw.text.addReplacement(xp);
|
iw.text.addReplacement(xp);
|
||||||
|
cb->changePrimSkill(h->ID, 4, xp, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -6174,8 +6183,7 @@ void CGSirens::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cb->showInfoDialog(&iw);
|
cb->showInfoDialog(&iw);
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
///TODO: WHAT WITH EXP?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//bool IShipyard::validLocation() const
|
//bool IShipyard::validLocation() const
|
||||||
|
@ -408,6 +408,7 @@ public:
|
|||||||
static int3 convertPosition(int3 src, bool toh3m); //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest
|
static int3 convertPosition(int3 src, bool toh3m); //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest
|
||||||
double getHeroStrength() const;
|
double getHeroStrength() const;
|
||||||
int getTotalStrength() const;
|
int getTotalStrength() const;
|
||||||
|
expType calculateXp(expType exp) const; //apply learning skill
|
||||||
ui8 getSpellSchoolLevel(const CSpell * spell, int *outSelectedSchool = NULL) const; //returns level on which given spell would be cast by this hero (0 - none, 1 - basic etc); optionally returns number of selected school by arg - 0 - air magic, 1 - fire magic, 2 - water magic, 3 - earth magic,
|
ui8 getSpellSchoolLevel(const CSpell * spell, int *outSelectedSchool = NULL) const; //returns level on which given spell would be cast by this hero (0 - none, 1 - basic etc); optionally returns number of selected school by arg - 0 - air magic, 1 - fire magic, 2 - water magic, 3 - earth magic,
|
||||||
bool canCastThisSpell(const CSpell * spell) const; //determines if this hero can cast given spell; takes into account existing spell in spellbook, existing spellbook and artifact bonuses
|
bool canCastThisSpell(const CSpell * spell) const; //determines if this hero can cast given spell; takes into account existing spell in spellbook, existing spellbook and artifact bonuses
|
||||||
CStackBasicDescriptor calculateNecromancy (const BattleResult &battleResult) const;
|
CStackBasicDescriptor calculateNecromancy (const BattleResult &battleResult) const;
|
||||||
|
@ -196,6 +196,8 @@ void CGameHandler::levelUpHero(int ID, int skill)
|
|||||||
void CGameHandler::levelUpHero(int ID)
|
void CGameHandler::levelUpHero(int ID)
|
||||||
{
|
{
|
||||||
CGHeroInstance *hero = static_cast<CGHeroInstance *>(gs->map->objects[ID].get());
|
CGHeroInstance *hero = static_cast<CGHeroInstance *>(gs->map->objects[ID].get());
|
||||||
|
if (hero->battle)
|
||||||
|
tlog1<<"Battle found\n";
|
||||||
if (hero->exp < VLC->heroh->reqExp(hero->level+1)) // no more level-ups
|
if (hero->exp < VLC->heroh->reqExp(hero->level+1)) // no more level-ups
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -287,7 +289,9 @@ void CGameHandler::changePrimSkill(int ID, int which, si64 val, bool abs)
|
|||||||
sendAndApply(&sps);
|
sendAndApply(&sps);
|
||||||
if(which==4) //only for exp - hero may level up
|
if(which==4) //only for exp - hero may level up
|
||||||
{
|
{
|
||||||
|
//TODO: Stack Experience only after battle
|
||||||
levelUpHero(ID);
|
levelUpHero(ID);
|
||||||
|
//TODO: Commander
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,9 +344,9 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
|||||||
//end battle, remove all info, free memory
|
//end battle, remove all info, free memory
|
||||||
giveExp(*battleResult.data);
|
giveExp(*battleResult.data);
|
||||||
if (hero1)
|
if (hero1)
|
||||||
battleResult.data->exp[0] *= (100+hero1->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f;//sholar skill
|
battleResult.data->exp[0] = hero1->calculateXp(battleResult.data->exp[0]);//scholar skill
|
||||||
if (hero2)
|
if (hero2)
|
||||||
battleResult.data->exp[1] *= (100+hero2->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f;
|
battleResult.data->exp[1] = hero2->calculateXp(battleResult.data->exp[1]);
|
||||||
|
|
||||||
ui8 sides[2];
|
ui8 sides[2];
|
||||||
for(int i=0; i<2; ++i)
|
for(int i=0; i<2; ++i)
|
||||||
@ -4687,7 +4691,7 @@ bool CGameHandler::sacrificeCreatures(const IMarket *market, const CGHeroInstanc
|
|||||||
int dump, exp;
|
int dump, exp;
|
||||||
market->getOffer(crid, 0, dump, exp, CREATURE_EXP);
|
market->getOffer(crid, 0, dump, exp, CREATURE_EXP);
|
||||||
exp *= count;
|
exp *= count;
|
||||||
changePrimSkill(hero->id, 4, exp*(100+hero->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f);
|
changePrimSkill(hero->id, 4, hero->calculateXp(exp));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user