summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db/const.txt1
-rw-r--r--src/map/map.h2
-rw-r--r--src/map/pc.c25
-rw-r--r--src/map/pc.h16
-rw-r--r--src/map/script.c103
-rw-r--r--src/map/skill.c4
-rw-r--r--src/map/status.c1
7 files changed, 88 insertions, 64 deletions
diff --git a/db/const.txt b/db/const.txt
index 9fbbac640..a189e5bb5 100644
--- a/db/const.txt
+++ b/db/const.txt
@@ -580,6 +580,7 @@ bWeaponMatk 2046
bMatk 2047
bSPGainRaceAttack 2048
bHPGainRaceAttack 2049
+bUseSPrateSkill 2050
EQI_HEAD_TOP 1
EQI_ARMOR 2
diff --git a/src/map/map.h b/src/map/map.h
index 4fe3bdf15..c51353b26 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -392,7 +392,7 @@ enum _sp {
SP_UNSTRIPABLE_WEAPON,SP_UNSTRIPABLE_ARMOR,SP_UNSTRIPABLE_HELM,SP_UNSTRIPABLE_SHIELD, // 2034-2037
SP_INTRAVISION, SP_ADD_MONSTER_DROP_ITEMGROUP, SP_SP_LOSS_RATE, // 2038-2040
SP_ADD_SKILL_BLOW, SP_SP_VANISH_RATE, SP_MAGIC_SP_GAIN_VALUE, SP_MAGIC_HP_GAIN_VALUE, SP_ADD_CLASS_DROP_ITEM, //2041-2045
- SP_WEAPON_MATK, SP_BASE_MATK, SP_SP_GAIN_RACE_ATTACK, SP_HP_GAIN_RACE_ATTACK //2046-2049
+ SP_WEAPON_MATK, SP_BASE_MATK, SP_SP_GAIN_RACE_ATTACK, SP_HP_GAIN_RACE_ATTACK, SP_SP_RATE_SKILL //2046-2050
};
enum _look {
diff --git a/src/map/pc.c b/src/map/pc.c
index 1d7e2c9d5..b7f4a965e 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -3046,6 +3046,21 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
if(sd->state.lr_flag != 2)
sd->hp_gain_race_attack[type2] = cap_value(sd->hp_gain_race_attack[type2] + val, 0, INT16_MAX);
break;
+ case SP_SP_RATE_SKILL: //bonus2 bUseSPrateSkill,n,x;
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->sprateskill), i, sd->sprateskill[i].id == 0 || sd->sprateskill[i].id == type2);
+ if (i == ARRAYLENGTH(sd->sprateskill)) {
+ ShowDebug("run_script: bonus2 bUseSPrateSkill reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->sprateskill), type2, val);
+ break;
+ }
+ if (sd->sprateskill[i].id == type2)
+ sd->sprateskill[i].val += val;
+ else {
+ sd->sprateskill[i].id = type2;
+ sd->sprateskill[i].val = val;
+ }
+ break;
default:
ShowWarning("pc_bonus2: unknown type %d %d %d!\n",type,type2,val);
break;
@@ -6083,6 +6098,16 @@ int pc_skillatk_bonus(struct map_session_data *sd, int skill_num)
return bonus;
}
+inline int pc_sp_rate_skill(struct map_session_data *sd, int skill_num) {
+ int i, bonus = 100;
+
+ ARR_FIND(0, ARRAYLENGTH(sd->sprateskill), i, sd->sprateskill[i].id == skill_num);
+ if( i < ARRAYLENGTH(sd->sprateskill) )
+ bonus += sd->sprateskill[i].val;
+
+ return bonus;
+}
+
int pc_skillheal_bonus(struct map_session_data *sd, int skill_num) {
int i, bonus = sd->bonus.add_heal_rate;
diff --git a/src/map/pc.h b/src/map/pc.h
index 0eb90344f..418f59b9e 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -261,7 +261,7 @@ struct map_session_data {
struct { //skillatk raises bonus dmg% of skills, skillheal increases heal%, skillblown increases bonus blewcount for some skills.
unsigned short id;
short val;
- } skillatk[MAX_PC_BONUS], skillheal[5], skillheal2[5], skillblown[MAX_PC_BONUS], skillcast[MAX_PC_BONUS];
+ } skillatk[MAX_PC_BONUS], sprateskill[MAX_PC_BONUS], skillheal[5], skillheal2[5], skillblown[MAX_PC_BONUS], skillcast[MAX_PC_BONUS];
struct {
short value;
int rate;
@@ -901,16 +901,12 @@ void pc_inventory_rental_add(struct map_session_data *sd, int seconds);
int pc_read_motd(void); // [Valaris]
int pc_disguise(struct map_session_data *sd, int class_);
bool pc_isautolooting(struct map_session_data *sd, int nameid);
-/**
- * Mechanic (Mado Gear)
- **/
+
void pc_overheat(struct map_session_data *sd, int val);
-/**
- * Royal Guard
- **/
+
int pc_banding(struct map_session_data *sd, short skill_lv);
-/**
- * Item Cooldown persistency
- **/
+
void pc_itemcd_do(struct map_session_data *sd, bool load);
+
+inline int pc_sp_rate_skill(struct map_session_data *sd, int skill_num);
#endif /* _PC_H_ */
diff --git a/src/map/script.c b/src/map/script.c
index 5bd55e106..d1ff921c5 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -7320,63 +7320,62 @@ BUILDIN_FUNC(bonus)
return 0; // no player attached
type = script_getnum(st,2);
- switch( type )
- {
- case SP_AUTOSPELL:
- case SP_AUTOSPELL_WHENHIT:
- case SP_AUTOSPELL_ONSKILL:
- case SP_SKILL_ATK:
- case SP_SKILL_HEAL:
- case SP_SKILL_HEAL2:
- case SP_ADD_SKILL_BLOW:
- case SP_CASTRATE:
- case SP_ADDEFF_ONSKILL:
- // these bonuses support skill names
- val1 = ( script_isstring(st,3) ? skill_name2id(script_getstr(st,3)) : script_getnum(st,3) );
- break;
- default:
- val1 = script_getnum(st,3);
- break;
+ switch( type ) {
+ case SP_AUTOSPELL:
+ case SP_AUTOSPELL_WHENHIT:
+ case SP_AUTOSPELL_ONSKILL:
+ case SP_SKILL_ATK:
+ case SP_SKILL_HEAL:
+ case SP_SKILL_HEAL2:
+ case SP_ADD_SKILL_BLOW:
+ case SP_CASTRATE:
+ case SP_ADDEFF_ONSKILL:
+ case SP_SP_RATE_SKILL:
+ // these bonuses support skill names
+ val1 = ( script_isstring(st,3) ? skill_name2id(script_getstr(st,3)) : script_getnum(st,3) );
+ break;
+ default:
+ val1 = script_getnum(st,3);
+ break;
}
- switch( script_lastdata(st)-2 )
- {
- case 1:
- pc_bonus(sd, type, val1);
- break;
- case 2:
- val2 = script_getnum(st,4);
- pc_bonus2(sd, type, val1, val2);
- break;
- case 3:
- val2 = script_getnum(st,4);
- val3 = script_getnum(st,5);
- pc_bonus3(sd, type, val1, val2, val3);
- break;
- case 4:
- if( type == SP_AUTOSPELL_ONSKILL && script_isstring(st,4) )
- val2 = skill_name2id(script_getstr(st,4)); // 2nd value can be skill name
- else
+ switch( script_lastdata(st)-2 ) {
+ case 1:
+ pc_bonus(sd, type, val1);
+ break;
+ case 2:
val2 = script_getnum(st,4);
-
- val3 = script_getnum(st,5);
- val4 = script_getnum(st,6);
- pc_bonus4(sd, type, val1, val2, val3, val4);
- break;
- case 5:
- if( type == SP_AUTOSPELL_ONSKILL && script_isstring(st,4) )
- val2 = skill_name2id(script_getstr(st,4)); // 2nd value can be skill name
- else
+ pc_bonus2(sd, type, val1, val2);
+ break;
+ case 3:
val2 = script_getnum(st,4);
+ val3 = script_getnum(st,5);
+ pc_bonus3(sd, type, val1, val2, val3);
+ break;
+ case 4:
+ if( type == SP_AUTOSPELL_ONSKILL && script_isstring(st,4) )
+ val2 = skill_name2id(script_getstr(st,4)); // 2nd value can be skill name
+ else
+ val2 = script_getnum(st,4);
- val3 = script_getnum(st,5);
- val4 = script_getnum(st,6);
- val5 = script_getnum(st,7);
- pc_bonus5(sd, type, val1, val2, val3, val4, val5);
- break;
- default:
- ShowDebug("buildin_bonus: unexpected number of arguments (%d)\n", (script_lastdata(st) - 1));
- break;
+ val3 = script_getnum(st,5);
+ val4 = script_getnum(st,6);
+ pc_bonus4(sd, type, val1, val2, val3, val4);
+ break;
+ case 5:
+ if( type == SP_AUTOSPELL_ONSKILL && script_isstring(st,4) )
+ val2 = skill_name2id(script_getstr(st,4)); // 2nd value can be skill name
+ else
+ val2 = script_getnum(st,4);
+
+ val3 = script_getnum(st,5);
+ val4 = script_getnum(st,6);
+ val5 = script_getnum(st,7);
+ pc_bonus5(sd, type, val1, val2, val3, val4, val5);
+ break;
+ default:
+ ShowDebug("buildin_bonus: unexpected number of arguments (%d)\n", (script_lastdata(st) - 1));
+ break;
}
return 0;
diff --git a/src/map/skill.c b/src/map/skill.c
index 43bda4b60..a273a245b 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -12747,9 +12747,11 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, short
req.sp += (status->sp * sp_rate)/100;
else
req.sp += (status->max_sp * (-sp_rate))/100;
- if( sd->dsprate!=100 )
+ if( sd->dsprate != 100 )
req.sp = req.sp * sd->dsprate / 100;
+ req.sp = cap_value(req.sp * pc_sp_rate_skill(sd,skill) / 100, 0, SHRT_MAX);
+
if( sc ) {
if( sc->data[SC__LAZINESS] )
req.sp += req.sp + sc->data[SC__LAZINESS]->val1 * 10;
diff --git a/src/map/status.c b/src/map/status.c
index 17cf26d3d..aa8825b58 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -2337,6 +2337,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
+ sizeof(sd->addeff2)
+ sizeof(sd->addeff3)
+ sizeof(sd->skillatk)
+ + sizeof(sd->sprateskill)
+ sizeof(sd->skillheal)
+ sizeof(sd->skillheal2)
+ sizeof(sd->hp_loss)