diff --git a/db/re/skill_db.txt b/db/re/skill_db.txt index 7ffd6c85fd..12ab65ca94 100644 --- a/db/re/skill_db.txt +++ b/db/re/skill_db.txt @@ -59,7 +59,7 @@ // 0x0200- spell range affected by NJ_SHADOWJUMP // 0x0400- spell range affected by WL_RADIUS // 0x0800- spell range affected by RA_RESEARCHTRAP -// 0x1000- spell that can't be copied +// 0x1000- free // 0x2000- spell that can be using while riding warg // 0x4000- spell that can't be used while in mado // 17 Name @@ -101,12 +101,12 @@ 26,0,6,4,0,0x1,0,2,1,yes,0,0,0,magic,0,0x60, AL_TELEPORT,Teleport 27,9,6,2,0,0x1,0,4,1,yes,0,0,3,magic,0,0x20, AL_WARP,Warp Portal 28,9,6,16,6,0x21,0,10,1,yes,0,0,0,magic,0,0x20, AL_HEAL,Heal -29,9,6,16,0,0x1,0,10,1,yes,0,0,0,magic,0,0x1020, AL_INCAGI,Increase AGI +29,9,6,16,0,0x1,0,10,1,yes,0,0,0,magic,0,0x20, AL_INCAGI,Increase AGI 30,9,6,1,0,0x1,0,10,1,yes,0,0,0,magic,0,0x0, AL_DECAGI,Decrease AGI 31,0,6,4,0,0x1,0,1,1,yes,0,0,0,magic,0,0x20, AL_HOLYWATER,Aqua Benedicta 32,0,6,4,0,0x3,15,10,1,yes,0,0,0,magic,0,0x0, AL_CRUCIS,Signum Crucis 33,0,6,4,0,0x3,-1,10,1,yes,0,0,0,magic,0,0x0, AL_ANGELUS,Angelus -34,9,6,16,0,0x1,0,10,1,yes,0,0,0,magic,0,0x1020, AL_BLESSING,Blessing +34,9,6,16,0,0x1,0,10,1,yes,0,0,0,magic,0,0x20, AL_BLESSING,Blessing 35,9,6,16,0,0x1,0,1,1,yes,0,0,0,magic,0,0x0, AL_CURE,Cure //**** @@ -812,8 +812,8 @@ //**** // Additional Skill (??) 688,9,6,16,0,0x1,0,10,0,no,0,0x200,0,none,0,0x0, GM_SANDMAN,GM Sandman -689,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x1000, CASH_BLESSING,Party Blessing -690,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x1000, CASH_INCAGI,Party Increase AGI +689,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x0, CASH_BLESSING,Party Blessing +690,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x0, CASH_INCAGI,Party Increase AGI 691,0,6,4,0,0x3,-1,5,1,yes,0,0x2,0,magic,0,0x0, CASH_ASSUMPTIO,Party Assumptio //692,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0, ALL_CATCRY,Cat Cry 693,0,6,4,0,0x3,-1,1,1,yes,0,0x2,0,magic,0,0x0, ALL_PARTYFLEE,Party Flee @@ -1192,8 +1192,8 @@ 2480,11,6,1,0,0x1,0,5,1,yes,0,0,3,misc,0,0x0, GN_BLOOD_SUCKER,Blood Sucker //CHECK Data says its a magic attack. Hmmmm.... 2481,11,6,1,-1,0x2,1:2:3:4:5,5,1,yes,0,0,0,weapon,0,0x0, GN_SPORE_EXPLOSION,Spore Explosion //CHECK Data says its element is set to neutral. Need to confirm. 2482,11,6,16,0,0,0,5,1,yes,0,0,1,weapon,2,0x0, GN_WALLOFTHORN,Wall of Thorns -2483,11,6,2,0,0x3,4,10,1,yes,0,0x2000,0,weapon,0,0x0, GN_CRAZYWEED,Crazy Weed -2484,0,6,2,2,0x2,2,10,1,no,0,0x2000,0,weapon,0,0x0, GN_CRAZYWEED_ATK,Crazy Weed Attack +2483,11,6,2,0,0x3,4,10,1,yes,0,0x0,0,weapon,0,0x1, GN_CRAZYWEED,Crazy Weed +2484,0,6,2,2,0x2,2,10,1,no,0,0x0,0,weapon,0,0x1, GN_CRAZYWEED_ATK,Crazy Weed Attack 2485,9,6,2,3,0,0,5,1,yes,0,0,0,magic,0,0x0, GN_DEMONIC_FIRE,Demonic Fire 2486,9,6,2,0,0,0,5,1,yes,0,0,0,none,0,0x0, GN_FIRE_EXPANSION,Fire Expansion //CHECK FIX ME!!!! Level 1 is reducing the damage. Should increase it by 50% 2487,9,6,2,0,0,0,1,1,no,0,0,0,none,0,0x0, GN_FIRE_EXPANSION_SMOKE_POWDER,Fire Expansion Smoke Powder @@ -1404,8 +1404,8 @@ 8236,5,6,1,0,0x1,0,10,0,yes,0,0,0,magic,0,0x0, MER_LEXDIVINA,Lex_Divina 8237,9,6,1,0,0x1,0,1,1,yes,0,0,0,magic,0,0x0, MER_ESTIMATION,Sense 8238,9,6,16,0,0x1,0,10,1,yes,0,0,0,magic,0,0x0, MER_KYRIE,Kyrie Eleison -8239,9,6,16,0,0x1,0,10,1,yes,0,0,0,magic,0,0x1000, MER_BLESSING,Blessing -8240,9,6,16,0,0x1,0,10,1,yes,0,0,0,magic,0,0x1000, MER_INCAGI,Increase Agility +8239,9,6,16,0,0x1,0,10,1,yes,0,0,0,magic,0,0x0, MER_BLESSING,Blessing +8240,9,6,16,0,0x1,0,10,1,yes,0,0,0,magic,0,0x0, MER_INCAGI,Increase Agility //8241,2,6,2,0,0,0,1,1,no,0,0,0,none,0,0x0, MER_INVINCIBLEOFF2,Mind Blaster //**** diff --git a/db/skill_copyable_db.txt b/db/skill_copyable_db.txt index 36660b8b27..9c2d6a6239 100644 --- a/db/skill_copyable_db.txt +++ b/db/skill_copyable_db.txt @@ -146,17 +146,18 @@ TK_JUMPKICK,3 // Flying Kick // Ninja NJ_ZENYNAGE,3 // Throw Zeny -NJ_TATAMIGAESHI,3 // Flip Tatami -NJ_KASUMIKIRI,3 // Haze Slasher -NJ_SHADOWJUMP,3 // Shadow Slash -NJ_UTSUSEMI,3 // Blaze Shield -NJ_KOUENKA,3 // Flaming Petals -NJ_BAKUENRYU,3 // Exploding Dragon -NJ_HYOUSENSOU,3 // Freezing Spear -NJ_HYOUSYOURAKU,3 // Snow Flake Draft +NJ_TATAMIGAESHI,3 // Improvised Defense +NJ_KASUMIKIRI,3 // Vanishing Slash +NJ_SHADOWJUMP,3 // Shadow Leap +NJ_KIRIKAGE,3 // Shadow Slash +NJ_UTSUSEMI,3 // Cicada Skin Sheeding +NJ_KOUENKA,3 // Crimson Fire Petal +NJ_BAKUENRYU,3 // Raging Fire Dragon +NJ_HYOUSENSOU,3 // Spear of Ice +NJ_HYOUSYOURAKU,3 // Ice Meteor NJ_HUUJIN,3 // Wind Blade -NJ_RAIGEKISAI,3 // Lightning Jolt -NJ_KAMAITACHI,3 // First Wind +NJ_RAIGEKISAI,3 // Lightning Strike of Destruction +NJ_KAMAITACHI,3 // Kamaitachi // 2nd Job Quest Skills KN_CHARGEATK,3 // Charge Attack @@ -167,8 +168,8 @@ MO_KITRANSLATION,3 // Excruciating Palm // Rune Knight RK_SONICWAVE,2 // Sonic Wave -RK_WINDCUTTER,2 // Ignition Break -RK_IGNITIONBREAK,2 // Wind Cutter +RK_WINDCUTTER,2 // Wind Cutter +RK_IGNITIONBREAK,2 // Ignition Break // Guillotine Cross GC_CROSSIMPACT,2 // Cross Impact diff --git a/src/map/pc.c b/src/map/pc.c index e6638c30ec..ea137e3c8f 100755 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1243,23 +1243,23 @@ int pc_reg_received(struct map_session_data *sd) } if ((i = pc_checkskill(sd,RG_PLAGIARISM)) > 0) { - sd->cloneskill_id = pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM); - if (sd->cloneskill_id > 0) { - sd->status.skill[sd->cloneskill_id].id = sd->cloneskill_id; - sd->status.skill[sd->cloneskill_id].lv = pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM_LV); - if (sd->status.skill[sd->cloneskill_id].lv > i) - sd->status.skill[sd->cloneskill_id].lv = i; - sd->status.skill[sd->cloneskill_id].flag = SKILL_FLAG_PLAGIARIZED; + sd->cloneskill_idx = skill_get_index(pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM)); + if (sd->cloneskill_idx >= 0) { + sd->status.skill[sd->cloneskill_idx].id = pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM); + sd->status.skill[sd->cloneskill_idx].lv = pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM_LV); + if (sd->status.skill[sd->cloneskill_idx].lv > i) + sd->status.skill[sd->cloneskill_idx].lv = i; + sd->status.skill[sd->cloneskill_idx].flag = SKILL_FLAG_PLAGIARIZED; } } if ((i = pc_checkskill(sd,SC_REPRODUCE)) > 0) { - sd->reproduceskill_id = pc_readglobalreg(sd,SKILL_VAR_REPRODUCE); - if( sd->reproduceskill_id > 0) { - sd->status.skill[sd->reproduceskill_id].id = sd->reproduceskill_id; - sd->status.skill[sd->reproduceskill_id].lv = pc_readglobalreg(sd,SKILL_VAR_REPRODUCE_LV); - if( i < sd->status.skill[sd->reproduceskill_id].lv) - sd->status.skill[sd->reproduceskill_id].lv = i; - sd->status.skill[sd->reproduceskill_id].flag = SKILL_FLAG_PLAGIARIZED; + sd->reproduceskill_idx = skill_get_index(pc_readglobalreg(sd,SKILL_VAR_REPRODUCE)); + if( sd->reproduceskill_idx >= 0) { + sd->status.skill[sd->reproduceskill_idx].id = pc_readglobalreg(sd,SKILL_VAR_REPRODUCE); + sd->status.skill[sd->reproduceskill_idx].lv = pc_readglobalreg(sd,SKILL_VAR_REPRODUCE_LV); + if( i < sd->status.skill[sd->reproduceskill_idx].lv) + sd->status.skill[sd->reproduceskill_idx].lv = i; + sd->status.skill[sd->reproduceskill_idx].flag = SKILL_FLAG_PLAGIARIZED; } } //Weird... maybe registries were reloaded? @@ -7629,26 +7629,26 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper) pc_setglobalreg (sd, "jobchange_level_3rd", sd->change_level_3rd); } - if(sd->cloneskill_id) { - if( sd->status.skill[sd->cloneskill_id].flag == SKILL_FLAG_PLAGIARIZED ) { - sd->status.skill[sd->cloneskill_id].id = 0; - sd->status.skill[sd->cloneskill_id].lv = 0; - sd->status.skill[sd->cloneskill_id].flag = SKILL_FLAG_PERMANENT; - clif_deleteskill(sd,sd->cloneskill_id); + if(sd->cloneskill_idx >= 0) { + if( sd->status.skill[sd->cloneskill_idx].flag == SKILL_FLAG_PLAGIARIZED ) { + sd->status.skill[sd->cloneskill_idx].id = 0; + sd->status.skill[sd->cloneskill_idx].lv = 0; + sd->status.skill[sd->cloneskill_idx].flag = SKILL_FLAG_PERMANENT; + clif_deleteskill(sd,pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM)); } - sd->cloneskill_id = 0; + sd->cloneskill_idx = -1; pc_setglobalreg(sd,SKILL_VAR_PLAGIARISM, 0); pc_setglobalreg(sd,SKILL_VAR_PLAGIARISM_LV, 0); } - if(sd->reproduceskill_id) { - if( sd->status.skill[sd->reproduceskill_id].flag == SKILL_FLAG_PLAGIARIZED ) { - sd->status.skill[sd->reproduceskill_id].id = 0; - sd->status.skill[sd->reproduceskill_id].lv = 0; - sd->status.skill[sd->reproduceskill_id].flag = SKILL_FLAG_PERMANENT; - clif_deleteskill(sd,sd->reproduceskill_id); + if(sd->reproduceskill_idx >= 0) { + if( sd->status.skill[sd->reproduceskill_idx].flag == SKILL_FLAG_PLAGIARIZED ) { + sd->status.skill[sd->reproduceskill_idx].id = 0; + sd->status.skill[sd->reproduceskill_idx].lv = 0; + sd->status.skill[sd->reproduceskill_idx].flag = SKILL_FLAG_PERMANENT; + clif_deleteskill(sd,pc_readglobalreg(sd,SKILL_VAR_REPRODUCE)); } - sd->reproduceskill_id = 0; + sd->reproduceskill_idx = -1; pc_setglobalreg(sd,SKILL_VAR_REPRODUCE,0); pc_setglobalreg(sd,SKILL_VAR_REPRODUCE_LV,0); } @@ -9966,6 +9966,8 @@ static bool pc_readdb_job_exp(char* fields[], int columns, int current) for(i=0; istatus.skill[idx].id != 0 && sd->status.skill[idx].flag != SKILL_FLAG_PLAGIARIZED) return 0; - // Never copy NPC/Wedding Skills - if (skill_get_inf2(skill_id)&(INF2_NPC_SKILL|INF2_WEDDING_SKILL)) - return 0; - - // Added so plagarize can't copy agi/bless if you're undead since it damages you - // NOTE: Is this still needed since we use skill_copyable_db now? - if (skill_get_inf3(skill_id)&INF3_DIS_PLAGIA) - return 0; - // Check if the skill is copyable by class if (!pc_has_permission(sd,PC_PERM_ALL_SKILL)) { - uint16 job_allowed; - job_allowed = skill_db[idx].copyable.joballowed; + uint16 job_allowed = skill_db[idx].copyable.joballowed; while (1) { if (job_allowed&0x01 && sd->status.class_ == JOB_ROGUE) break; if (job_allowed&0x02 && sd->status.class_ == JOB_STALKER) break; @@ -2490,7 +2481,8 @@ static void skill_do_copy(struct block_list* src,struct block_list *bl, uint16 s else if (&tsd->sc && tsd->sc.data[SC_PRESERVE] && !tsd->sc.data[SC__REPRODUCE]) return; else { - short copy_flag; + short idx; + unsigned char lv; // Copy Referal: dummy skills should point to their source upon copying switch (skill_id) { @@ -2520,49 +2512,52 @@ static void skill_do_copy(struct block_list* src,struct block_list *bl, uint16 s break; } - copy_flag = skill_isCopyable(tsd,skill_id); - if (copy_flag != 1 && copy_flag != 2) //Skill cannot be copied + //Use skill index, avoiding out-of-bound array [Cydh] + if ((idx = skill_get_index(skill_id)) < 0) return; - else { - uint8 lv; - if (copy_flag == 2) { //Copied by Reproduce - struct status_change *tsc = status_get_sc(bl); - lv = (tsc) ? tsc->data[SC__REPRODUCE]->val1 : 1; //Already did this SC check on skill_isCopyable() - if( tsd->reproduceskill_id && tsd->status.skill[tsd->reproduceskill_id].flag == SKILL_FLAG_PLAGIARIZED ) { - tsd->status.skill[tsd->reproduceskill_id].id = 0; - tsd->status.skill[tsd->reproduceskill_id].lv = 0; - tsd->status.skill[tsd->reproduceskill_id].flag = SKILL_FLAG_PERMANENT; - clif_deleteskill(tsd,tsd->reproduceskill_id); + + switch (skill_isCopyable(tsd,skill_id)) { + case 1: //Copied by Plagiarism + { + if (tsd->cloneskill_idx >= 0 && tsd->status.skill[tsd->cloneskill_idx].flag == SKILL_FLAG_PLAGIARIZED) { + clif_deleteskill(tsd,tsd->status.skill[tsd->cloneskill_idx].id); + tsd->status.skill[tsd->cloneskill_idx].id = 0; + tsd->status.skill[tsd->cloneskill_idx].lv = 0; + tsd->status.skill[tsd->cloneskill_idx].flag = SKILL_FLAG_PERMANENT; + } + + if ((lv = pc_checkskill(tsd,RG_PLAGIARISM)) < skill_lv) + skill_lv = lv; + + tsd->cloneskill_idx = idx; + pc_setglobalreg(tsd,SKILL_VAR_PLAGIARISM,skill_id); + pc_setglobalreg(tsd,SKILL_VAR_PLAGIARISM_LV,lv); } + break; + case 2: //Copied by Reproduce + { + struct status_change *tsc = status_get_sc(bl); + //Already did SC check + //Skill level copied depends on Reproduce skill that used + lv = (tsc) ? tsc->data[SC__REPRODUCE]->val1 : 1; + if( tsd->reproduceskill_idx >= 0 && tsd->status.skill[tsd->reproduceskill_idx].flag == SKILL_FLAG_PLAGIARIZED ) { + clif_deleteskill(tsd,tsd->status.skill[tsd->reproduceskill_idx].id); + tsd->status.skill[tsd->reproduceskill_idx].id = 0; + tsd->status.skill[tsd->reproduceskill_idx].lv = 0; + tsd->status.skill[tsd->reproduceskill_idx].flag = SKILL_FLAG_PERMANENT; + } - lv = min(lv,skill_get_max(skill_id)); //Level dependent and limitation. - - tsd->reproduceskill_id = skill_id; - pc_setglobalreg(tsd,SKILL_VAR_REPRODUCE,skill_id); - pc_setglobalreg(tsd,SKILL_VAR_REPRODUCE_LV,lv); - } - else if (copy_flag == 1) { //Copied by Plagiarism - if (tsd->cloneskill_id && tsd->status.skill[tsd->cloneskill_id].flag == SKILL_FLAG_PLAGIARIZED) { - tsd->status.skill[tsd->cloneskill_id].id = 0; - tsd->status.skill[tsd->cloneskill_id].lv = 0; - tsd->status.skill[tsd->cloneskill_id].flag = SKILL_FLAG_PERMANENT; - clif_deleteskill(tsd,tsd->cloneskill_id); + tsd->reproduceskill_idx = idx; + pc_setglobalreg(tsd,SKILL_VAR_REPRODUCE,skill_id); + pc_setglobalreg(tsd,SKILL_VAR_REPRODUCE_LV,lv); } - - if ((lv = pc_checkskill(tsd,RG_PLAGIARISM)) < skill_lv) - skill_lv = lv; - - tsd->cloneskill_id = skill_id; - pc_setglobalreg(tsd,SKILL_VAR_PLAGIARISM,skill_id); - pc_setglobalreg(tsd,SKILL_VAR_PLAGIARISM_LV,lv); - } - else - return; - tsd->status.skill[skill_id].id = skill_id; - tsd->status.skill[skill_id].lv = lv; - tsd->status.skill[skill_id].flag = SKILL_FLAG_PLAGIARIZED; - clif_addskill(tsd,skill_id); + break; + default: return; } + tsd->status.skill[idx].id = skill_id; + tsd->status.skill[idx].lv = lv; + tsd->status.skill[idx].flag = SKILL_FLAG_PLAGIARIZED; + clif_addskill(tsd,skill_id); } } /* @@ -8823,7 +8818,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case SC_AUTOSHADOWSPELL: if( sd ) { - if( sd->status.skill[sd->reproduceskill_id].id || sd->status.skill[sd->cloneskill_id].id ) { + if( (sd->reproduceskill_idx >= 0 && sd->status.skill[sd->reproduceskill_idx].id) || + (sd->cloneskill_idx >= 0 && sd->status.skill[sd->cloneskill_idx].id) ) + { sc_start(src,src,SC_STOP,100,skill_lv,-1);// The skill_lv is stored in val1 used in skill_select_menu to determine the used skill lvl [Xazax] clif_autoshadowspell_list(sd); clif_skill_nodamage(src,bl,skill_id,1,1); diff --git a/src/map/skill.h b/src/map/skill.h index 819228b791..e636ecbd58 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -86,7 +86,7 @@ enum e_skill_inf3 { INF3_EFF_SHADOWJUMP = 0x0200, // spell range affected by NJ_SHADOWJUMP INF3_EFF_RADIUS = 0x0400, // spell range affected by WL_RADIUS INF3_EFF_RESEARCHTRAP = 0x0800, // spell range affected by RA_RESEARCHTRAP - INF3_DIS_PLAGIA = 0x1000, // spell that can't be copied + //INF3_ = 0x1000, // free INF3_USABLE_WARG = 0x2000, // spell that can be use while riding warg INF3_DIS_MADO = 0x4000, // spell that can't be used while in mado //... add other spell list option here