瀏覽代碼

Added new bonus as per kenpachi's request: bonus2 bUseSPrateSkill,n,x; // Reduced increases/reduced the SP consumption of skilln by x%. (supports skill names)
e.g. bonus2 bUseSPrateSkill,"AL_BLESSING",50; -> increases AL_BLESSING sp usage by 50% (e.g. if its 50 it goes to 75)

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@16273 54d463be-8e91-2dee-dedb-b68131a5f0ec

shennetsind 13 年之前
父節點
當前提交
4ca3aa34ed
共有 7 個文件被更改,包括 88 次插入64 次删除
  1. 1 0
      db/const.txt
  2. 1 1
      src/map/map.h
  3. 25 0
      src/map/pc.c
  4. 6 10
      src/map/pc.h
  5. 51 52
      src/map/script.c
  6. 3 1
      src/map/skill.c
  7. 1 0
      src/map/status.c

+ 1 - 0
db/const.txt

@@ -580,6 +580,7 @@ bWeaponMatk	2046
 bMatk	2047
 bSPGainRaceAttack	2048
 bHPGainRaceAttack	2049
+bUseSPrateSkill	2050
 
 EQI_HEAD_TOP	1
 EQI_ARMOR	2

+ 1 - 1
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 {

+ 25 - 0
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;
 

+ 6 - 10
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_ */

+ 51 - 52
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;

+ 3 - 1
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;

+ 1 - 0
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)