Skip to content

Commit

Permalink
Skill Tree cleanup
Browse files Browse the repository at this point in the history
* Added an optional base level requirement for skills.
* Refactored some variable types and names.
  • Loading branch information
aleos89 committed Aug 11, 2016
1 parent 8857ff6 commit e40c88e
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 45 deletions.
2 changes: 1 addition & 1 deletion db/import-tmpl/skill_tree.txt
@@ -1,2 +1,2 @@
//JobNo,Skill-ID,MaxLV{,JobLV},Prerequisite Skill-ID-1,Prerequisite Skill-ID-1-Lv,PrereqSkill-ID-2,PrereqSkill-ID-2-Lv,PrereqSkill-ID-3,PrereqSkill-ID-3-Lv,PrereqSkill-ID-4,PrereqSkill-ID-4-Lv,PrereqSkill-ID-5,PrereqSkill-ID-5-Lv//CLASS_SKILLNAME#Skill Name#
//JobNo,Skill-ID,MaxLv{,BaseLvReq,JobLvReq},Prerequisite Skill-ID-1,Prerequisite Skill-ID-1-Lv,PrereqSkill-ID-2,PrereqSkill-ID-2-Lv,PrereqSkill-ID-3,PrereqSkill-ID-3-Lv,PrereqSkill-ID-4,PrereqSkill-ID-4-Lv,PrereqSkill-ID-5,PrereqSkill-ID-5-Lv//CLASS_SKILLNAME#Skill Name#

2 changes: 1 addition & 1 deletion db/pre-re/skill_tree.txt
@@ -1,4 +1,4 @@
//JobNo,Skill-ID,MaxLV{,JobLV},Prerequisite Skill-ID-1,Prerequisite Skill-ID-1-Lv,PrereqSkill-ID-2,PrereqSkill-ID-2-Lv,PrereqSkill-ID-3,PrereqSkill-ID-3-Lv,PrereqSkill-ID-4,PrereqSkill-ID-4-Lv,PrereqSkill-ID-5,PrereqSkill-ID-5-Lv//CLASS_SKILLNAME#Skill Name#
//JobNo,Skill-ID,MaxLv{,BaseLvReq,JobLvReq},Prerequisite Skill-ID-1,Prerequisite Skill-ID-1-Lv,PrereqSkill-ID-2,PrereqSkill-ID-2-Lv,PrereqSkill-ID-3,PrereqSkill-ID-3-Lv,PrereqSkill-ID-4,PrereqSkill-ID-4-Lv,PrereqSkill-ID-5,PrereqSkill-ID-5-Lv//CLASS_SKILLNAME#Skill Name#
//Novice
0,1,9,0,0,0,0,0,0,0,0,0,0 //NV_BASIC#Basic Skill#
0,142,1,0,0,0,0,0,0,0,0,0,0 //NV_FIRSTAID#First Aid#
Expand Down
2 changes: 1 addition & 1 deletion db/re/skill_tree.txt
@@ -1,4 +1,4 @@
//JobNo,Skill-ID,MaxLV{,JobLV},Prerequisite Skill-ID-1,Prerequisite Skill-ID-1-Lv,PrereqSkill-ID-2,PrereqSkill-ID-2-Lv,PrereqSkill-ID-3,PrereqSkill-ID-3-Lv,PrereqSkill-ID-4,PrereqSkill-ID-4-Lv,PrereqSkill-ID-5,PrereqSkill-ID-5-Lv//CLASS_SKILLNAME#Skill Name#
//JobNo,Skill-ID,MaxLv{,BaseLvReq,JobLvReq},Prerequisite Skill-ID-1,Prerequisite Skill-ID-1-Lv,PrereqSkill-ID-2,PrereqSkill-ID-2-Lv,PrereqSkill-ID-3,PrereqSkill-ID-3-Lv,PrereqSkill-ID-4,PrereqSkill-ID-4-Lv,PrereqSkill-ID-5,PrereqSkill-ID-5-Lv//CLASS_SKILLNAME#Skill Name#
//Novice
0,1,9,0,0,0,0,0,0,0,0,0,0 //NV_BASIC#Basic Skill#
0,142,1,0,0,0,0,0,0,0,0,0,0 //NV_FIRSTAID#First Aid#
Expand Down
8 changes: 4 additions & 4 deletions src/map/atcommand.c
Expand Up @@ -5687,8 +5687,8 @@ ACMD_FUNC(skilltree)

c = pc_class2idx(c);

ARR_FIND( 0, MAX_SKILL_TREE, j, skill_tree[c][j].id == 0 || skill_tree[c][j].id == skill_id );
if( j == MAX_SKILL_TREE || skill_tree[c][j].id == 0 )
ARR_FIND( 0, MAX_SKILL_TREE, j, skill_tree[c][j].skill_id == 0 || skill_tree[c][j].skill_id == skill_id );
if( j == MAX_SKILL_TREE || skill_tree[c][j].skill_id == 0 )
{
clif_displaymessage(fd, msg_txt(sd,1169)); // The player cannot use that skill.
return 0;
Expand All @@ -5699,9 +5699,9 @@ ACMD_FUNC(skilltree)
meets = 1;
for(j=0;j<MAX_PC_SKILL_REQUIRE;j++)
{
if( ent->need[j].id && pc_checkskill(sd,ent->need[j].id) < ent->need[j].lv)
if( ent->need[j].skill_id && pc_checkskill(sd,ent->need[j].skill_id) < ent->need[j].skill_lv)
{
sprintf(atcmd_output, msg_txt(sd,1170), ent->need[j].lv, skill_db[skill_get_index(ent->need[j].id)]->desc); // Player requires level %d of skill %s.
sprintf(atcmd_output, msg_txt(sd,1170), ent->need[j].skill_lv, skill_db[skill_get_index(ent->need[j].skill_id)]->desc); // Player requires level %d of skill %s.
clif_displaymessage(fd, atcmd_output);
meets = 0;
}
Expand Down
2 changes: 1 addition & 1 deletion src/map/mob.c
Expand Up @@ -3646,7 +3646,7 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons

//Go Backwards to give better priority to advanced skills.
for (i=0,j = MAX_SKILL_TREE-1;j>=0 && i< MAX_MOBSKILL ;j--) {
uint16 skill_id = skill_tree[pc_class2idx(sd->status.class_)][j].id;
uint16 skill_id = skill_tree[pc_class2idx(sd->status.class_)][j].skill_id;
uint16 sk_idx = 0;
if (!skill_id || !(sk_idx = skill_get_index(skill_id)) || sd->status.skill[sk_idx].lv < 1 ||
(skill_get_inf2(skill_id)&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL)) ||
Expand Down
65 changes: 36 additions & 29 deletions src/map/pc.c
Expand Up @@ -1628,10 +1628,10 @@ void pc_calc_skilltree(struct map_session_data *sd)
uint16 c_ = pc_class2idx(JOB_TAEKWON);

for (i = 0; i < MAX_SKILL_TREE; i++) {
uint16 sk_id = skill_tree[c_][i].id;
uint16 sk_id = skill_tree[c_][i].skill_id;
uint16 sk_idx = 0;

if (!sk_id || !(sk_idx = skill_get_index(skill_tree[c_][i].id)))
if (!sk_id || !(sk_idx = skill_get_index(skill_tree[c_][i].skill_id)))
continue;

if (sd->status.skill[sk_idx].flag != SKILL_FLAG_PLAGIARIZED && sd->status.skill[sk_idx].flag != SKILL_FLAG_PERM_GRANTED) {
Expand All @@ -1649,7 +1649,7 @@ void pc_calc_skilltree(struct map_session_data *sd)
uint16 skid = 0;

flag = 0;
for (i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].id) > 0; i++) {
for (i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].skill_id) > 0; i++) {
bool fail = false;
uint16 sk_idx = skill_get_index(skid);

Expand All @@ -1661,7 +1661,7 @@ void pc_calc_skilltree(struct map_session_data *sd)

// Checking required skills
for(j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
uint16 sk_need_id = skill_tree[c][i].need[j].id;
uint16 sk_need_id = skill_tree[c][i].need[j].skill_id;
uint16 sk_need_idx = 0;

if (sk_need_id && (sk_need_idx = skill_get_index(sk_need_id))) {
Expand All @@ -1674,13 +1674,19 @@ void pc_calc_skilltree(struct map_session_data *sd)
else
sk_need = pc_checkskill(sd,sk_need_id);

if (sk_need < skill_tree[c][i].need[j].lv) {
if (sk_need < skill_tree[c][i].need[j].skill_lv) {
fail = true;
break;
}
}
}

if (sd->status.base_level < skill_tree[c][i].baselv) { //We need to get the actual class in this case
int class_ = pc_mapid2jobid(sd->class_, sd->status.sex);
class_ = pc_class2idx(class_);
if (class_ == c || (class_ != c && sd->status.base_level < skill_tree[class_][i].baselv))
fail = true; // base level requirement wasn't satisfied
}
if (sd->status.job_level < skill_tree[c][i].joblv) { //We need to get the actual class in this case
int class_ = pc_mapid2jobid(sd->class_, sd->status.sex);
class_ = pc_class2idx(class_);
Expand Down Expand Up @@ -1718,7 +1724,7 @@ void pc_calc_skilltree(struct map_session_data *sd)
- (c > 0) to avoid grant Novice Skill Tree in case of Skill Reset (need more logic)
- (sd->status.skill_point == 0) to wait until all skill points are assigned to avoid problems with Job Change quest. */

for( i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].id) > 0; i++ ) {
for( i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].skill_id) > 0; i++ ) {
uint16 sk_idx = 0;
if (!(sk_idx = skill_get_index(skid)))
continue;
Expand Down Expand Up @@ -1755,7 +1761,7 @@ static void pc_check_skilltree(struct map_session_data *sd)
uint16 skid = 0;

flag = 0;
for (i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].id) > 0; i++ ) {
for (i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].skill_id) > 0; i++ ) {
uint16 sk_idx = skill_get_index(skid);
bool fail = false;
uint8 j = 0;
Expand All @@ -1765,7 +1771,7 @@ static void pc_check_skilltree(struct map_session_data *sd)

// Checking required skills
for (j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
uint16 sk_need_id = skill_tree[c][i].need[j].id;
uint16 sk_need_id = skill_tree[c][i].need[j].skill_id;
uint16 sk_need_idx = 0;

if (sk_need_id && (sk_need_idx = skill_get_index(sk_need_id))) {
Expand All @@ -1778,7 +1784,7 @@ static void pc_check_skilltree(struct map_session_data *sd)
else
sk_need = pc_checkskill(sd,sk_need_id);

if (sk_need < skill_tree[c][i].need[j].lv) {
if (sk_need < skill_tree[c][i].need[j].skill_lv) {
fail = true;
break;
}
Expand All @@ -1787,7 +1793,7 @@ static void pc_check_skilltree(struct map_session_data *sd)

if( fail )
continue;
if( sd->status.job_level < skill_tree[c][i].joblv )
if (sd->status.base_level < skill_tree[c][i].baselv || sd->status.job_level < skill_tree[c][i].joblv)
continue;

j = skill_get_inf2(skid);
Expand Down Expand Up @@ -6976,7 +6982,7 @@ int pc_allskillup(struct map_session_data *sd)

if (!pc_grant_allskills(sd, true)) {
uint16 sk_id;
for (i = 0; i < MAX_SKILL_TREE && (sk_id = skill_tree[pc_class2idx(sd->status.class_)][i].id) > 0;i++){
for (i = 0; i < MAX_SKILL_TREE && (sk_id = skill_tree[pc_class2idx(sd->status.class_)][i].skill_id) > 0;i++){
int inf2 = 0;
uint16 sk_idx = 0;
if (!sk_id || !(sk_idx = skill_get_index(sk_id)))
Expand Down Expand Up @@ -8387,10 +8393,10 @@ bool pc_jobchange(struct map_session_data *sd,int job, char upper)

if ( (b_class&MAPID_UPPERMASK) != (sd->class_&MAPID_UPPERMASK) ) { //Things to remove when changing class tree.
const int class_ = pc_class2idx(sd->status.class_);
short id;
for(i = 0; i < MAX_SKILL_TREE && (id = skill_tree[class_][i].id) > 0; i++) {
uint16 skill_id;
for(i = 0; i < MAX_SKILL_TREE && (skill_id = skill_tree[class_][i].skill_id) > 0; i++) {
//Remove status specific to your current tree skills.
enum sc_type sc = status_skill2sc(id);
enum sc_type sc = status_skill2sc(skill_id);
if (sc > SC_COMMON_MAX && sd->sc.data[sc])
status_change_end(&sd->bl, sc, INVALID_TIMER);
}
Expand Down Expand Up @@ -10675,18 +10681,18 @@ int pc_split_atoui(char* str, unsigned int* val, char sep, int max)
*------------------------------------------*/
static bool pc_readdb_skilltree(char* fields[], int columns, int current)
{
unsigned char joblv = 0, skill_lv;
uint16 skill_id;
uint32 baselv = 0, joblv = 0;
uint16 skill_id, skill_lv;
int idx, class_;
unsigned int i, offset = 3, skill_idx;

class_ = atoi(fields[0]);
skill_id = (uint16)atoi(fields[1]);
skill_lv = (unsigned char)atoi(fields[2]);
skill_lv = (uint16)atoi(fields[2]);

if(columns==4+MAX_PC_SKILL_REQUIRE*2)
{// job level requirement extra column
joblv = (unsigned char)atoi(fields[3]);
if (columns == 5 + MAX_PC_SKILL_REQUIRE * 2) { // Base/Job level requirement extra columns
baselv = (uint32)atoi(fields[3]);
joblv = (uint32)atoi(fields[4]);
offset++;
}

Expand All @@ -10698,25 +10704,26 @@ static bool pc_readdb_skilltree(char* fields[], int columns, int current)
idx = pc_class2idx(class_);

//This is to avoid adding two lines for the same skill. [Skotlex]
ARR_FIND( 0, MAX_SKILL_TREE, skill_idx, skill_tree[idx][skill_idx].id == 0 || skill_tree[idx][skill_idx].id == skill_id );
ARR_FIND( 0, MAX_SKILL_TREE, skill_idx, skill_tree[idx][skill_idx].skill_id == 0 || skill_tree[idx][skill_idx].skill_id == skill_id );
if( skill_idx == MAX_SKILL_TREE )
{
ShowWarning("pc_readdb_skilltree: Unable to load skill %hu into job %d's tree. Maximum number of skills per class has been reached.\n", skill_id, class_);
return false;
}
else if(skill_tree[idx][skill_idx].id)
else if(skill_tree[idx][skill_idx].skill_id)
{
ShowNotice("pc_readdb_skilltree: Overwriting skill %hu for job class %d.\n", skill_id, class_);
}

skill_tree[idx][skill_idx].id = skill_id;
skill_tree[idx][skill_idx].max = skill_lv;
skill_tree[idx][skill_idx].joblv = joblv;
skill_tree[idx][skill_idx].skill_id = skill_id;
skill_tree[idx][skill_idx].skill_lv = skill_lv;
skill_tree[idx][skill_idx].baselv = baselv;
skill_tree[idx][skill_idx].joblv = joblv;

for(i = 0; i < MAX_PC_SKILL_REQUIRE; i++)
{
skill_tree[idx][skill_idx].need[i].id = atoi(fields[i*2+offset]);
skill_tree[idx][skill_idx].need[i].lv = atoi(fields[i*2+offset+1]);
skill_tree[idx][skill_idx].need[i].skill_id = atoi(fields[i*2+offset]);
skill_tree[idx][skill_idx].need[i].skill_lv = atoi(fields[i*2+offset+1]);
}
return true;
}
Expand Down Expand Up @@ -11087,8 +11094,8 @@ void pc_readdb(void) {

// Reset and read skilltree
memset(skill_tree,0,sizeof(skill_tree));
sv_readdb(db_path, DBPATH"skill_tree.txt", ',', 3+MAX_PC_SKILL_REQUIRE*2, 4+MAX_PC_SKILL_REQUIRE*2, -1, &pc_readdb_skilltree, 0);
sv_readdb(db_path, DBIMPORT"/skill_tree.txt", ',', 3+MAX_PC_SKILL_REQUIRE*2, 4+MAX_PC_SKILL_REQUIRE*2, -1, &pc_readdb_skilltree, 1);
sv_readdb(db_path, DBPATH"skill_tree.txt", ',', 3+MAX_PC_SKILL_REQUIRE*2, 5+MAX_PC_SKILL_REQUIRE*2, -1, &pc_readdb_skilltree, 0);
sv_readdb(db_path, DBIMPORT"/skill_tree.txt", ',', 3+MAX_PC_SKILL_REQUIRE*2, 5+MAX_PC_SKILL_REQUIRE*2, -1, &pc_readdb_skilltree, 1);

#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
sv_readdb(db_path, "re/level_penalty.txt", ',', 4, 4, -1, &pc_readdb_levelpenalty, 0);
Expand Down
8 changes: 3 additions & 5 deletions src/map/pc.h
Expand Up @@ -1144,12 +1144,10 @@ int pc_mapid2jobid(unsigned short class_, int sex); // Skotlex
const char * job_name(int class_);

struct skill_tree_entry {
uint16 id;
uint8 max;
uint8 joblv;
uint16 skill_id, skill_lv;
uint32 baselv, joblv;
struct {
uint16 id;
uint8 lv;
uint16 skill_id, skill_lv;
} need[MAX_PC_SKILL_REQUIRE];
}; // Celest
extern struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE];
Expand Down
6 changes: 3 additions & 3 deletions src/map/skill.c
Expand Up @@ -302,9 +302,9 @@ int skill_tree_get_max(uint16 skill_id, int b_class)
int i;
b_class = pc_class2idx(b_class);

ARR_FIND( 0, MAX_SKILL_TREE, i, skill_tree[b_class][i].id == 0 || skill_tree[b_class][i].id == skill_id );
if( i < MAX_SKILL_TREE && skill_tree[b_class][i].id == skill_id )
return skill_tree[b_class][i].max;
ARR_FIND( 0, MAX_SKILL_TREE, i, skill_tree[b_class][i].skill_id == 0 || skill_tree[b_class][i].skill_id == skill_id );
if( i < MAX_SKILL_TREE && skill_tree[b_class][i].skill_id == skill_id )
return skill_tree[b_class][i].skill_lv;
else
return skill_get_max(skill_id);
}
Expand Down

0 comments on commit e40c88e

Please sign in to comment.