View Single Post
  #1  
Old 07-16-2003, 01:23 AM
Wiz
Dragon
 
Join Date: Feb 2002
Posts: 583
Default Skill Caps & Item Skill Mods (snippet + SQL)

This diff includes snippets with a GetSkill() supporting item skill mods, and functions and a SQL db to propely implement skill caps. Please note that some work is needed to make the skill cap db sync perfectly with live - it deviates a bit.

in client.h, put:

Code:
int16	GetSkillCap(int8 skillid);
int8	GetItemSkillMod(int8 skillid);
inline int16	GetSkill(int skill_id, bool item_skill_mod = true) { assert(skill_id >= 0 && skill_id < 74); if (pp.skills[skill_id + 1] > 250) pp.skills[skill_id + 1] = 0; if (item_skill_mod) return pp.skills[skill_id + 1] + GetItemSkillMod(skill_id); else return pp.skills[skill_id + 1]; }
in client.cpp, put:

Code:
int8 Client::GetItemSkillMod(int8 skillid)
{
	const Item_Struct* TempItem;
	int8 Total = 0;

	for(int x=1; x<=20; x++)
	{
		TempItem = database.GetItem(pp.inventory[x]);
		if (TempItem && TempItem->common.skillModId == skillid)
		{
			Total += TempItem->common.skillModPercent;
		}
	}
	return Total;
}
bool Client::CheckIncreaseSkill(int16 skillid, sint16 chancemod)
{
	if (GetSkill(skillid,false) < GetSkillCap(skillid))
	{
		if (rand()%100 < (5+chancemod))
		{
			SetSkill(skillid,GetSkill(skillid)+1);
			return true;
		}
	}
	else if (GetSkill(skillid,false) > GetSkillCap(skillid))
	{
		SetSkill(skillid,GetSkillCap(skillid));
	}
	return false;
}

int16 Client::GetSkillCap(int8 skillid)
{
	int8 skill_level = 0, skill_formula = 0;
	int16 base_cap = 0, skill_cap = 0, skill_cap2 = 0;
	char errbuf[MYSQL_ERRMSG_SIZE];
	char *query = 0;
	int32	affected_rows = 0;
	MYSQL_RES *result;
	MYSQL_ROW row;	
	//Fetch the data from DB.
	if (database.RunQuery(query, MakeAnyLenString(&query, "SELECT level, formula, pre50cap, post50cap from skillcaps where skill = %i && class = %i", skillid, GetClass()), errbuf, &result, &affected_rows))
	{
		if (affected_rows == 0)
		{
			delete[] query;
			mysql_free_result(result);
			return 0;
		}
		row = mysql_fetch_row(result);
		skill_level = atoi(row[0]);
		skill_formula = atoi(row[1]);
		skill_cap = atoi(row[2]);
		if (atoi(row[3]) > skill_cap)
			skill_cap2 = (atoi(row[3])-skill_cap)/10; //Split the post-50 skill cap into difference between pre-50 cap and post-50 cap / 10 to determine amount of points per level.
		delete[] query;
		mysql_free_result(result);
	}
	else
		return 0;
	//Too low level for this skill?
	if (GetLevel() < skill_level)
		return 0;
	//Determine pre-51 level-based cap
	base_cap = GetLevel()*skill_formula+skill_formula;
	if (base_cap > skill_cap)
		base_cap = skill_cap;
	//If post 50, add post 50 cap to base cap.
	if (GetLevel() > 50 && skill_cap2 > 0)
		base_cap += skill_cap2*(GetLevel()-50);
	//Base cap is now the max value at the person's level, return it!
	return base_cap;
}
Make sure to replace existing GetSkill() and CheckIncreaseSkill(). Then, source http://www.wintersroar.com/files/skillcaps.sql into your DB, and you're quite done - just put CheckIncreaseSkill(SKILLID, +/- deviation of 5% increase chance) whereever you want a potential for skill increase.

Note on the DB: level is the level you acquire the skill, formula is the formula*formula+formula that determines pre-51 skill caps per level, and pre50/post50 determines pre-51 and L60 caps, respectively, with the difference between the two being spread evently over levels 51-60 (so a skill with a pre50cap of 200 and post50cap of 250 has the cap 205 at level 51)
Reply With Quote