Lets have a look into the source code.
It starts in weapons.cpp:
TFS-0.4-DEV/weapons.cpp at master · laerciosant/TFS-0.4-DEV · GitHub
When you use a weapon:
C++:
void Weapon::onUsedWeapon(Player* player, Item* item, Tile*) const
{
if(!player->hasFlag(PlayerFlag_NotGainSkill))
{
skills_t skillType;
uint32_t skillPoint = 0;
if(getSkillType(player, item, skillType, skillPoint))
player->addSkillAdvance(skillType, skillPoint);
}
// removed irelevant code ...
}
What I found odd is that skillPoint is set to 0...
lets check that getSkillType since its weird.
TFS-0.4-DEV/weapons.cpp at master · laerciosant/TFS-0.4-DEV · GitHub
C++:
bool WeaponMelee::getSkillType(const Player* player, const Item* item,
skills_t& skill, uint32_t& skillpoint) const
{
skillpoint = 0;
if(player->getAddAttackSkill())
{
switch(player->getLastAttackBlockType())
{
case BLOCK_ARMOR:
case BLOCK_NONE:
skillpoint = 1; // overwrites skillPoint in Weapon::onUsedWeapon
break;
case BLOCK_DEFENSE:
default:
skillpoint = 0;
break;
}
}
switch(item->getWeaponType())
{
case WEAPON_SWORD:
{
skill = SKILL_SWORD; // Overwrites skillType in Weapon::onUsedWeapon
return true;
}
// repeat for every other weapon type
// overwrites the skillType value which was passed to this function to represent skill_type instead of weapon_type.
// returns true means the condition this function was called in will succeed toward skill gaining
}
return false;
}
These params are a bit special, I guess this is the deal with C++ and pointers and references and stuff. Basically this function overwrites the value of skillPoint and skillType (which was defined but not given a value) in the previous function Weapon:: onUsedWeapon
So now that those variables are set, we head on to the addSkillAdvance function:
player.cpp:
TFS-0.4-DEV/player.cpp at master · laerciosant/TFS-0.4-DEV · GitHub
C++:
void Player::addSkillAdvance(skills_t skill, uint32_t count, bool useMultiplier/* = true*/)
{
if(!count)
return;
//player has reached max skill
uint32_t currReqTries = vocation->getReqSkillTries(skill, skills[skill][SKILL_LEVEL]),
nextReqTries = vocation->getReqSkillTries(skill, skills[skill][SKILL_LEVEL] + 1);
if(currReqTries > nextReqTries)
return;
if(useMultiplier)
count = uint32_t((double)count * rates[skill] * g_config.getDouble(ConfigManager::RATE_SKILL));
std::stringstream s;
while(skills[skill][SKILL_TRIES] + count >= nextReqTries)
{
count -= nextReqTries - skills[skill][SKILL_TRIES];
skills[skill][SKILL_TRIES] = skills[skill][SKILL_PERCENT] = 0;
skills[skill][SKILL_LEVEL]++;
s.str("");
s << "You advanced in " << getSkillName(skill);
if(g_config.getBool(ConfigManager::ADVANCING_SKILL_LEVEL))
s << " [" << skills[skill][SKILL_LEVEL] << "]";
s << ".";
sendTextMessage(MSG_EVENT_ADVANCE, s.str().c_str());
CreatureEventList advanceEvents = getCreatureEvents(CREATURE_EVENT_ADVANCE);
for(CreatureEventList::iterator it = advanceEvents.begin(); it != advanceEvents.end(); ++it)
(*it)->executeAdvance(this, skill, (skills[skill][SKILL_LEVEL] - 1), skills[skill][SKILL_LEVEL]);
currReqTries = nextReqTries;
nextReqTries = vocation->getReqSkillTries(skill, skills[skill][SKILL_LEVEL] + 1);
if(currReqTries > nextReqTries)
{
count = 0;
break;
}
}
if(count)
skills[skill][SKILL_TRIES] += count;
//update percent
uint32_t newPercent = Player::getPercentLevel(skills[skill][SKILL_TRIES], nextReqTries);
if(skills[skill][SKILL_PERCENT] != newPercent)
{
skills[skill][SKILL_PERCENT] = newPercent;
sendSkills();
}
else if(!s.str().empty())
sendSkills();
}
This is were things seems a bit confusing to me.
As far as I understand it:
Your total skilltry/progress:
skills[skill][SKILL_TRIES]
Your skill_tries incremental value progress from your recent attack, this is being manipulated from earlier defined 1, to something else based on vocations.xml skill rate * config.lua rate_skill:
count
The skill_tries total goal you need to overcome in order to advance in skill level:
nextReqTries
But why is there a while loop here?
Anyway, what we need to adjust is probably the count variable below the useMultiplier addition and before the while statement.
I'm not sure what is the best approach, perhaps fetch the weapon speed (Player::getAttackSpeed() ? ).