diff options
-rw-r--r-- | Changelog.txt | 1 | ||||
-rw-r--r-- | conf-tmpl/atcommand_athena.conf | 3 | ||||
-rw-r--r-- | src/map/atcommand.c | 86 | ||||
-rw-r--r-- | src/map/atcommand.h | 1 | ||||
-rw-r--r-- | src/map/pc.c | 97 | ||||
-rw-r--r-- | src/map/pc.h | 4 | ||||
-rw-r--r-- | src/map/skill.c | 2 | ||||
-rw-r--r-- | src/map/skill.h | 2 |
8 files changed, 147 insertions, 49 deletions
diff --git a/Changelog.txt b/Changelog.txt index e930d9f2a..b89769f76 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,5 +1,6 @@ Date Added 11/25 + * Added @skilltree to help GM's answer skill tree questions [MouseJstr] * Update Spider Web; I believe you cannot use it on yourself now. [Codemaster] * Added Ore Discovery, and base code for Slim Pitcher and Preservation [celest] diff --git a/conf-tmpl/atcommand_athena.conf b/conf-tmpl/atcommand_athena.conf index ae6f0204b..f215d2db2 100644 --- a/conf-tmpl/atcommand_athena.conf +++ b/conf-tmpl/atcommand_athena.conf @@ -284,6 +284,9 @@ skillid: 40 // use a skill by id useskill: 40 +// What skills are required to get this skill +skilltree: 40 + // make another player killable charkillable: 40 diff --git a/src/map/atcommand.c b/src/map/atcommand.c index b2830d41c..4020b82e3 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -230,6 +230,8 @@ ATCOMMAND_FUNC(sound); // [Valaris] ATCOMMAND_FUNC(refreshonline); // [Valaris] #endif /* TXT_ONLY */ +ATCOMMAND_FUNC(skilltree); // by MouseJstr + /*========================================== *AtCommandInfo atcommand_info[]構造体の定義 *------------------------------------------ @@ -480,6 +482,7 @@ static AtCommandInfo atcommand_info[] = { { AtCommand_RefreshOnline, "@refreshonline", 99, atcommand_refreshonline }, // [Valaris] #endif /* TXT_ONLY */ + { AtCommand_SkillTree, "@skilltree", 40, atcommand_skilltree }, // [MouseJstr] // add new commands before this line { AtCommand_Unknown, NULL, 1, NULL } @@ -7142,6 +7145,7 @@ atcommand_skillid(const int fd, struct map_session_data* sd, } return 0; } + /*========================================== * @useskill by [MouseJstr] * @@ -7177,6 +7181,88 @@ atcommand_useskill(const int fd, struct map_session_data* sd, return 0; } + +/*========================================== + * @skilltree by [MouseJstr] + * + * prints the skill tree for a player required to get to a skill + *------------------------------------------ + */ +int +atcommand_skilltree(const int fd, struct map_session_data* sd, + const char* command, const char* message) +{ + struct map_session_data *pl_sd = NULL; + int skillnum, skillidx = -1; + int meets = 1, j, c=0, s=0; + struct pc_base_job s_class; + char target[255], *tbl; + char output[255]; + + if (!message || !*message) + return -1; + + if(sscanf(message, "%d %[^\r\n]", &skillnum, target) != 2) { + clif_displaymessage(fd, "Usage: @skilltree <skillnum> <target>"); + return -1; + } + if((pl_sd=map_nick2sd(target)) == NULL) + return -1; + + s_class = pc_calc_base_job(pl_sd->status.class); + c = s_class.job; + s = s_class.upper; + + c = pc_calc_skilltree_normalize_job(c, pl_sd); + + tbl = job_name(c); + + sprintf(output, "Player is using %s %s skill tree (%d basic points)", + s_class.upper ? "upper" : "lower", + tbl, pc_checkskill(pl_sd, 1)); + clif_displaymessage(fd, output); + + for (j = 0; j < MAX_SKILL; j++) { + if (skill_tree[s][c][j].id == skillnum) { + skillidx = j; + break; + } + } + + if (skillidx == -1) { + sprintf(output, "I do not believe the player can use that skill"); + clif_displaymessage(fd, output); + return 0; + } + + struct skill_tree_entry *ent = &skill_tree[s][c][skillidx]; + + for(j=0;j<5;j++) + if( ent->need[j].id && + pc_checkskill(sd,ent->need[j].id) < ent->need[j].lv) + { + int idx = 0; + char *desc; + while (skill_names[idx].id != 0 && skill_names[idx].id != ent->need[j].id) + idx++; + if (skill_names[idx].id == 0) + desc = "Unknown skill"; + else + desc = skill_names[idx].desc; + sprintf(output, "player requires level %d of skill %s", + ent->need[j].lv, desc); + clif_displaymessage(fd, output); + meets = 0; + } + + if (meets == 1) { + sprintf(output, "I believe the player meets all the requirements for that skill"); + clif_displaymessage(fd, output); + } + + return 0; +} + /*========================================== * It is made to rain. *------------------------------------------ diff --git a/src/map/atcommand.h b/src/map/atcommand.h index ee715bc4d..caaad51cc 100644 --- a/src/map/atcommand.h +++ b/src/map/atcommand.h @@ -214,6 +214,7 @@ enum AtCommandType { AtCommand_RefreshOnline, // [Valaris] // SQL-only commands end #endif + AtCommand_SkillTree, // by MouseJstr // end AtCommand_Unknown, diff --git a/src/map/pc.c b/src/map/pc.c index 2d0f14385..a4503b2c1 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -913,6 +913,56 @@ int pc_calc_skilltree(struct map_session_data *sd) //s = (s_class.upper==1) ? 1 : 0 ; //?生以外は通常のスキル? s = s_class.upper; + c = pc_calc_skilltree_normalize_job(c, sd); + + for(i=0;i<MAX_SKILL;i++){ + if (sd->status.skill[i].flag != 13) sd->status.skill[i].id=0; + if (sd->status.skill[i].flag && sd->status.skill[i].flag != 13){ // cardスキルなら、 + sd->status.skill[i].lv=(sd->status.skill[i].flag==1)?0:sd->status.skill[i].flag-2; // 本?のlvに + sd->status.skill[i].flag=0; // flagは0にしておく + } + } + + if (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill){ + // 全てのスキル + for(i=1;i<158;i++) + sd->status.skill[i].id=i; + for(i=210;i<291;i++) + sd->status.skill[i].id=i; + for(i=304;i<337;i++){ + if(i==331) continue; + sd->status.skill[i].id=i; + } + if(battle_config.enable_upper_class){ //confで無?でなければ?み?む + for(i=355;i<MAX_SKILL;i++) + sd->status.skill[i].id=i; + } + }else{ + // 通常の計算 + do{ + flag=0; + for(i=0;(id=skill_tree[s][c][i].id)>0;i++){ + int j,f=1; + if(!battle_config.skillfree) { + for(j=0;j<5;j++) { + if( skill_tree[s][c][i].need[j].id && + pc_checkskill(sd,skill_tree[s][c][i].need[j].id) < skill_tree[s][c][i].need[j].lv) + f=0; + } + } + if(f && sd->status.skill[id].id==0 ){ + sd->status.skill[id].id=id; + flag=1; + } + } + }while(flag); + } +// if(battle_config.etc_log) +// printf("calc skill_tree\n"); + return 0; +} + +int pc_calc_skilltree_normalize_job(int c, struct map_session_data *sd) { //if((battle_config.skillup_limit) && ((c >= 0 && c < 23) || (c >= 4001 && c < 4023) || (c >= 4023 && c < 4045))) { if (battle_config.skillup_limit && c >= 0 && c < 23) { int skill_point = pc_calc_skillpoint(sd); @@ -1000,52 +1050,7 @@ int pc_calc_skilltree(struct map_session_data *sd) } } } - - for(i=0;i<MAX_SKILL;i++){ - if (sd->status.skill[i].flag != 13) sd->status.skill[i].id=0; - if (sd->status.skill[i].flag && sd->status.skill[i].flag != 13){ // cardスキルなら、 - sd->status.skill[i].lv=(sd->status.skill[i].flag==1)?0:sd->status.skill[i].flag-2; // 本?のlvに - sd->status.skill[i].flag=0; // flagは0にしておく - } - } - - if (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill){ - // 全てのスキル - for(i=1;i<158;i++) - sd->status.skill[i].id=i; - for(i=210;i<291;i++) - sd->status.skill[i].id=i; - for(i=304;i<337;i++){ - if(i==331) continue; - sd->status.skill[i].id=i; - } - if(battle_config.enable_upper_class){ //confで無?でなければ?み?む - for(i=355;i<MAX_SKILL;i++) - sd->status.skill[i].id=i; - } - }else{ - // 通常の計算 - do{ - flag=0; - for(i=0;(id=skill_tree[s][c][i].id)>0;i++){ - int j,f=1; - if(!battle_config.skillfree) { - for(j=0;j<5;j++) { - if( skill_tree[s][c][i].need[j].id && - pc_checkskill(sd,skill_tree[s][c][i].need[j].id) < skill_tree[s][c][i].need[j].lv) - f=0; - } - } - if(f && sd->status.skill[id].id==0 ){ - sd->status.skill[id].id=id; - flag=1; - } - } - }while(flag); - } -// if(battle_config.etc_log) -// printf("calc skill_tree\n"); - return 0; + return c; } /*========================================== diff --git a/src/map/pc.h b/src/map/pc.h index 0a7026815..7861fb43c 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -44,6 +44,8 @@ int pc_checkskill(struct map_session_data *sd,int skill_id); int pc_checkallowskill(struct map_session_data *sd); int pc_checkequip(struct map_session_data *sd,int pos); +int pc_calc_skilltree_normalize_job(int c, struct map_session_data *sd); + int pc_checkoverhp(struct map_session_data*); int pc_checkoversp(struct map_session_data*); @@ -170,7 +172,7 @@ struct pc_base_job pc_calc_base_job(int b_class);//転生や養子職の元の職業を返す int pc_calc_base_job2(int b_class); // Celest int pc_calc_upper(int b_class); -struct { +struct skill_tree_entry { int id; int max; struct { diff --git a/src/map/skill.c b/src/map/skill.c index 932542365..7f000f4b4 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -264,7 +264,7 @@ int SkillStatusChangeTable[]={ /* skill.hのenumのSC_***とあわせること */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; -struct skill_name_db skill_names[] = { +const struct skill_name_db skill_names[] = { { AC_CHARGEARROW, "CHARGEARROW", "Charge_Arrow" } , { AC_CONCENTRATION, "CONCENTRATION", "Improve_Concentration" } , { AC_DOUBLE, "DOUBLE", "Double_Strafe" } , diff --git a/src/map/skill.h b/src/map/skill.h index 9e5db0f59..2a7c17652 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -31,7 +31,7 @@ struct skill_name_db { char *name; // search strings char *desc; // description that shows up for search's }; -extern struct skill_name_db skill_names[]; +extern const struct skill_name_db skill_names[]; // アイテム作成デ?タベ?ス struct skill_produce_db { |