diff --git a/db/re/item_combo_db.txt b/db/re/item_combo_db.txt index f9e6c87b0b..5398119dc1 100644 --- a/db/re/item_combo_db.txt +++ b/db/re/item_combo_db.txt @@ -23,7 +23,9 @@ 1421:2133,{ bonus2 bAddClass,Class_All,4; bonus bDef,2; } 1422:2133,{ bonus2 bAddClass,Class_All,4; bonus bDef,2; } 1428:2115,{ bonus3 bAutoSpellWhenHit,"HP_ASSUMPTIO",2,5; } -1433:2153,{ bonus2 bSkillAtk,"CR_GRANDCROSS",10; bonus2 bSkillAtk,"LG_RAYOFGENESIS",10; } +1433:2153,{ bonus2 bSkillAtk,"LG_RAYOFGENESIS",10; bonus2 bSkillAtk,"CR_GRANDCROSS",10; } +1433:2153:18823,{ bonus2 bSkillAtk,"LG_BANISHINGPOINT",20; bonus2 bSkillAtk,"LG_CANNONSPEAR",20; bonus2 bSkillAtk,"LG_SHIELDPRESS",20; } +1433:2153:18823:28372,{ bonus2 bSkillUseSP,"LG_BANISHINGPOINT",-15; bonus2 bSkillUseSP,"LG_CANNONSPEAR",-10; bonus2 bSkillUseSP,"CR_GRANDCROSS",-30; bonus2 bSkillUseSP,"LG_SHIELDPRESS",-5; } 1433:28372,{ .@r = getequiprefinerycnt(EQI_HAND_R)/2*7; bonus2 bSkillAtk,"LG_CANNONSPEAR",.@r; bonus2 bSkillAtk,"LG_BANISHINGPOINT",.@r; } 1472:2677,{ bonus bMatkRate,6; bonus bDex,2; bonus bVariableCastrate,-getequiprefinerycnt(EQI_HEAD_TOP); } 1472:2711,{ bonus bMatkRate,6; bonus bDex,2; bonus bVariableCastrate,-getequiprefinerycnt(EQI_HAND_R); } @@ -119,7 +121,7 @@ 2125:5782,{ bonus bDef,2; bonus2 bSubEle,Ele_Neutral,5; bonus2 bSubEle,Ele_Fire,5; bonus2 bSubEle,Ele_Water,5; bonus2 bSubEle,Ele_Wind,5; bonus2 bSubEle,Ele_Earth,5; bonus2 bSubEle,Ele_Dark,5; bonus2 bSubEle,Ele_Holy,5; bonus2 bSubEle,Ele_Ghost,5; } 2135:2426,{ bonus2 bAddEff,Eff_Blind,500; autobonus "{ bonus bFlee,20; }",200,10000,BF_WEAPON,"{ specialeffect2 EF_INCAGILITY; }"; } 2137:2353:5124,{ bonus bDef,2-getequiprefinerycnt(EQI_HAND_L)-getequiprefinerycnt(EQI_HEAD_TOP); bonus bMdef,5+getequiprefinerycnt(EQI_HAND_L)+getequiprefinerycnt(EQI_HEAD_TOP); } -2153:28372,{ .@r = getequiprefinerycnt(EQI_HAND_R)/6*8; bonus2 bSkillAtk,"LG_SHIELDPRESS",.@r; } +2153:28372,{ .@r = getequiprefinerycnt(EQI_HAND_R); bonus2 bSkillAtk,"LG_SHIELDPRESS",.@r > 5 ? (.@r - 5) * 8 : 0; } 2160:19021,{ bonus2 bSubSize,Size_Large,5+(getequiprefinerycnt(EQI_HAND_L)*2); } 2169:2491:2590:15051,{ bonus2 bAddDefMonster,2311,30; bonus2 bAddDefMonster,2312,30; bonus2 bAddDefMonster,2320,30; bonus2 bAddDefMonster,2321,30; bonus2 bAddDefMonster,2322,30; bonus2 bAddDefMonster,2317,30; bonus2 bAddDefMonster,2318,30; bonus2 bAddDefMonster,2327,30; bonus2 bAddDefMonster,2319,30; bonus2 bAddDefMonster,2330,30; bonus2 bAddDefMonster,2329,30; bonus2 bAddDefMonster,2333,30; bonus2 bAddDefMonster,2332,30; bonus2 bAddDefMonster,2309,30; bonus2 bAddDefMonster,2310,30; bonus2 bAddDefMonster,2315,30; bonus2 bAddDefMonster,2316,30; bonus2 bAddDefMonster,2314,30; bonus2 bAddDefMonster,2313,30; bonus bMaxHPrate,20; bonus bMaxSPrate,10; } 2171:15053,{ bonus bAgi,2; } @@ -507,7 +509,9 @@ 18563:18564,{ bonus bFixedCastrate,-10; } 18776:20710,{ bonus bBaseAtk,10; } 18776:22015,{ bonus bMatk,20; } -18823:28372,{ bonus2 bSkillAtk,"CR_GRANDCROSS",BaseLevel; bonus2 bVariableCastrate,"CR_GRANDCROSS",-BaseLevel*2; bonus2 bSkillAtk,"CR_GRANDCROSS",BaseLevel/30; bonus2 bSkillUseSP,"CR_GRANDCROSS",-(BaseLevel/30)*10; } +18823:19246,{ .@atk = 40; .@aspd = 3; .@dmg = 2; .@agi = readparam(bAgi); if (.@agi > 107) { .@atk += 60; .@aspd += 5; .@dmg += 2; } if (.@agi > 119) { .@atk += 80; .@aspd += 7; .@dmg += 4; } bonus bBaseAtk,.@atk; bonus bAspdRate,.@aspd; bonus2 bSubRace,RC_Player,.@dmg; bonus2 bResEff,Eff_Blind,100; bonus2 bResEff,Eff_Silence,100; } +18823:28372,{ bonus2 bSkillVariableCast,"CR_GRANDCROSS",-1500; bonus2 bSkillAtk,"LG_RAYOFGENESIS",BaseLevel/30 + BaseLevel; bonus2 bSkillUseSP,"LG_RAYOFGENESIS",-10; } +18823:28551,{ bonus2 bSkillDelay,"LG_OVERBRAND",-2000; bonus bLongAtkRate,getskilllv("LG_CANNONSPEAR") * 2; bonus bLongAtkRate,getskilllv("LG_OVERBRAND") * 2; bonus2 bSkillAtk,"LG_CANNONSPEAR",30; bonus2 bSkillAtk,"LG_OVERBRAND",20; } 18867:1720,{ bonus bLongAtkRate,3+(getequiprefinerycnt(EQI_HAND_R) > 6 ? 5:0); } 18937:28302,{ bonus bInt,8; bonus bMaxSPrate,5;} 18937:28303,{ bonus bInt,8; bonus bBaseAtk,20;} diff --git a/db/re/item_db.txt b/db/re/item_db.txt index 15af4f8c5b..16db77fcc9 100644 --- a/db/re/item_db.txt +++ b/db/re/item_db.txt @@ -9994,6 +9994,7 @@ 19180,Anubis_Helm_,Anubis Helm,4,20,,0,,8,,1,0xFFFFFFFF,63,2,768,,65,0,485,{ bonus bMdef,5; bonus2 bSubClass,Class_Boss,10; bonus bHealpower2,10; bonus bAddItemHealRate,10; },{},{} 19181,New_Wave_Sunglasses_,New Wave Sunglasses,4,20,,100,,1,,1,0xFFFFFFFF,63,2,512,,30,0,856,{ bonus bDelayRate,-5; },{},{} // +19246,Royal_Guard_Necklace,Royal Guard Necklace,4,20,,300,,0,,0,0xFFFFFFFF,63,2,1,,80,0,1629,{ bonus bAspd,1; },{},{} 19306,Gambler_Card,Heart Card in Mouth,4,20,,300,,0,,0,0xFFFFFFFF,63,2,1,,80,0,1679,{ bonus bCritAtkRate,5; },{},{} //=================================================================== // Costume System @@ -11684,6 +11685,7 @@ 28472,Para_Team_Agi_Necklace160,Awakened Eden Group Necklace of Agility V,4,0,,0,,0,,0,0xFFFFFFFF,63,2,136,,160,,,{ bonus bDex,4; skill "AL_TELEPORT",1; },{},{} 28483,Royal_Guardian_Ring,Royal Guardian Ring,4,0,,10,,1,,1,0xFFFFFFFF,63,2,136,,99,,,{ .@b = min(BaseLevel/25,7); bonus bMaxHPrate,.@b; bonus bMaxSPrate,.@b; },{},{} 28499,Proof_of_Glory,Proof of Glory,4,0,,100,,0,,0,0xFFFFFFFF,63,2,136,,100,,,{ bonus bAllStats,1; bonus2 bAddRace,RC_All,2; bonus2 bMagicAddRace,RC_All,2; if(BaseLevel>=150) { bonus bAllStats,1; bonus2 bAddRace,RC_All,2; bonus2 bMagicAddRace,RC_All,2; } },{},{} +28551,Imperial_Glove,Imperial Glove,4,20,,400,,0,,1,0xFFFFFFFF,63,2,136,,100,0,0,{ bonus2 bAddClass,Class_All,5; bonus bVariableCastrate,-10; bonus bNoCastCancel; },{},{} //=================================================================== // More books //=================================================================== diff --git a/doc/item_bonus.txt b/doc/item_bonus.txt index 09301ef151..7ffe172b5f 100644 --- a/doc/item_bonus.txt +++ b/doc/item_bonus.txt @@ -210,6 +210,7 @@ bonus bNoCastCancel; Prevents casting from being interrupted when hit (does n bonus bNoCastCancel2; Prevents casting from being interrupted when hit (works even in GvG) bonus bDelayrate,n; Increases skill delay by n% +bonus2 bSkillDelay,sk,t; Increases delay of skill sk by t milliseconds bonus2 bSkillCooldown,sk,t; Increases cooldown of skill sk by t milliseconds ============================= diff --git a/src/map/map.hpp b/src/map/map.hpp index c649721b81..9eb74f868e 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -495,7 +495,7 @@ enum _sp { SP_HP_VANISH_RACE_RATE, SP_SP_VANISH_RACE_RATE, SP_ABSORB_DMG_MAXHP, SP_SUB_SKILL, SP_SUBDEF_ELE, // 2074-2078 SP_STATE_NORECOVER_RACE, SP_CRITICAL_RANGEATK, SP_MAGIC_ADDRACE2, SP_IGNORE_MDEF_RACE2_RATE, // 2079-2082 SP_WEAPON_ATK_RATE, SP_WEAPON_MATK_RATE, SP_DROP_ADDRACE, SP_DROP_ADDCLASS, SP_NO_MADO_FUEL, // 2083-2087 - SP_IGNORE_DEF_CLASS_RATE, SP_REGEN_PERCENT_HP, SP_REGEN_PERCENT_SP, //2088-2091 + SP_IGNORE_DEF_CLASS_RATE, SP_REGEN_PERCENT_HP, SP_REGEN_PERCENT_SP, SP_SKILL_DELAY //2088-2092 }; enum _look { diff --git a/src/map/pc.cpp b/src/map/pc.cpp index f06641b91c..20f476d3b7 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -3663,6 +3663,21 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val) sd->skillusesprate[i].val = val; } break; + case SP_SKILL_DELAY: + if(sd->state.lr_flag == 2) + break; + ARR_FIND(0, ARRAYLENGTH(sd->skilldelay), i, sd->skilldelay[i].id == 0 || sd->skilldelay[i].id == type2); + if (i == ARRAYLENGTH(sd->skilldelay)) { + ShowError("pc_bonus2: SP_SKILL_DELAY: Reached max (%d) number of skills per character, bonus skill %d (%d) lost.\n", ARRAYLENGTH(sd->skilldelay), type2, val); + break; + } + if (sd->skilldelay[i].id == type2) + sd->skilldelay[i].val += val; + else { + sd->skilldelay[i].id = type2; + sd->skilldelay[i].val = val; + } + break; case SP_SKILL_COOLDOWN: // bonus2 bSkillCooldown,sk,t; if(sd->state.lr_flag == 2) break; diff --git a/src/map/pc.hpp b/src/map/pc.hpp index 0b7ec7f081..74f6626403 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -412,7 +412,7 @@ struct map_session_data { struct s_skill_bonus_i32 { uint16 id; int32 val; - } skillcooldown[MAX_PC_BONUS], skillfixcast[MAX_PC_BONUS], skillvarcast[MAX_PC_BONUS]; + } skillcooldown[MAX_PC_BONUS], skillfixcast[MAX_PC_BONUS], skillvarcast[MAX_PC_BONUS], skilldelay[MAX_PC_BONUS]; struct s_regen { short value; int rate; diff --git a/src/map/script.cpp b/src/map/script.cpp index 6c03af0e2f..3453208803 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -9232,6 +9232,7 @@ BUILDIN_FUNC(bonus) case SP_SKILL_VARIABLECAST: case SP_VARCASTRATE: case SP_FIXCASTRATE: + case SP_SKILL_DELAY: case SP_SKILL_USE_SP: case SP_SUB_SKILL: // these bonuses support skill names diff --git a/src/map/script_constants.hpp b/src/map/script_constants.hpp index a41c2abb21..f2be5ff4a4 100644 --- a/src/map/script_constants.hpp +++ b/src/map/script_constants.hpp @@ -709,6 +709,7 @@ export_constant2("bIgnoreDefClassRate", SP_IGNORE_DEF_CLASS_RATE); export_constant2("bRegenPercentHP", SP_REGEN_PERCENT_HP); export_constant2("bRegenPercentSP", SP_REGEN_PERCENT_SP); + export_constant2("bSkillDelay",SP_SKILL_DELAY); /* equip indices */ export_constant(EQI_COMPOUND_ON); diff --git a/src/map/skill.cpp b/src/map/skill.cpp index fcbd162117..7edc05c8a3 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -16690,8 +16690,18 @@ int skill_delayfix(struct block_list *bl, uint16 skill_id, uint16 skill_lv) } } - if (!(delaynodex&4) && sd && sd->delayrate != 100) - time = time * sd->delayrate / 100; + if (!(delaynodex&4) && sd) { + uint8 i, len = ARRAYLENGTH(sd->skilldelay); + + if (sd->delayrate != 100) + time = time * sd->delayrate / 100; + + if (len) { + ARR_FIND(0, len, i, sd->skilldelay[i].id == skill_id); + if (i < len) + time += sd->skilldelay[i].val; + } + } if (battle_config.delay_rate != 100) time = time * battle_config.delay_rate / 100; diff --git a/src/map/status.cpp b/src/map/status.cpp index 215f8c3714..cba0e679bc 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -3465,6 +3465,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) + sizeof(sd->norecover_state_race) + sizeof(sd->hp_vanish_race) + sizeof(sd->sp_vanish_race) + + sizeof(sd->skilldelay) ); memset (&sd->bonus, 0, sizeof(sd->bonus));