Jelajahi Sumber

Fixed PR_REDEMPTIO and LG_INSPIRATION requirement
* Only charge the Base EXP.
* Lost EXP will be displayed.

Signed-off-by: Cydh Ramdh <cydh@pservero.com>

Cydh Ramdh 9 tahun lalu
induk
melakukan
9944c1dd46
7 mengubah file dengan 45 tambahan dan 15 penghapusan
  1. 11 0
      conf/battle/exp.conf
  2. 3 0
      src/map/battle.c
  3. 3 0
      src/map/battle.h
  4. 1 1
      src/map/clif.c
  5. 1 1
      src/map/pc.c
  6. 1 0
      src/map/pc.h
  7. 25 13
      src/map/skill.c

+ 11 - 0
conf/battle/exp.conf

@@ -95,3 +95,14 @@ disp_zeny: no
 // If no, an equation will be used which preserves statpoints earned/lost 
 // through external means (ie: stat point buyers/sellers)
 use_statpoint_table: yes
+
+// EXP cost for cast PR_REDEMPTIO (Note 2)
+exp_cost_redemptio: 1
+
+// How many player needed to makes PR_REDEMPTIO's EXP penalty become 0?
+// If by default, the 'exp_cost_redemptio' is 1 (1%) and every single player revived the penalty is reduced to 0.2%,
+// it means 'exp_cost_redemptio_limit' is 5.
+exp_cost_redemptio_limit: 5
+
+// EXP cost for cast LG_INSPIRATION (Note 2)
+exp_cost_inspiration: 1

+ 3 - 0
src/map/battle.c

@@ -8200,6 +8200,9 @@ static const struct _battle_data {
 	{ "monster_stuck_warning",              &battle_config.mob_stuck_warning,               0,      0,      1,              },
 	{ "skill_eightpath_algorithm",          &battle_config.skill_eightpath_algorithm,       1,      0,      1,              },
 	{ "death_penalty_maxlv",                &battle_config.death_penalty_maxlv,             0,      0,      3,              },
+	{ "exp_cost_redemptio",                 &battle_config.exp_cost_redemptio,              1,      0,      100,            },
+	{ "exp_cost_redemptio_limit",           &battle_config.exp_cost_redemptio_limit,        5,      0,      MAX_PARTY,      },
+	{ "exp_cost_inspiration",               &battle_config.exp_cost_inspiration,            1,      0,      100,            },
 };
 
 #ifndef STATS_OPT_OUT

+ 3 - 0
src/map/battle.h

@@ -602,6 +602,9 @@ extern struct Battle_Config
 	int mob_stuck_warning; //Show warning if a monster is stuck too long
 	int skill_eightpath_algorithm; //Official path algorithm
 	int death_penalty_maxlv;
+	int exp_cost_redemptio;
+	int exp_cost_redemptio_limit;
+	int exp_cost_inspiration;
 } battle_config;
 
 void do_init_battle(void);

+ 1 - 1
src/map/clif.c

@@ -16674,7 +16674,7 @@ void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, b
 	WFIFOHEAD(fd, packet_len(0x7f6));
 	WFIFOW(fd,0) = 0x7f6;
 	WFIFOL(fd,2) = sd->bl.id;
-	WFIFOL(fd,6) = (int)min(exp, INT_MAX) * (lost ? -1 : 1);
+	WFIFOL(fd,6) = (int)umin(exp, INT_MAX) * (lost ? -1 : 1);
 	WFIFOW(fd,10) = type;
 	WFIFOW(fd,12) = quest?1:0;// Normal exp is shown in yellow, quest exp is shown in purple.
 	WFIFOSET(fd,packet_len(0x7f6));

+ 1 - 1
src/map/pc.c

@@ -6390,7 +6390,7 @@ static void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsi
  * @param next_job_exp Job EXP needed for next job level
  * @param lost True:EXP penalty, lose EXP
  **/
-static void pc_gainexp_disp(struct map_session_data *sd, unsigned int base_exp, unsigned int next_base_exp, unsigned int job_exp, unsigned int next_job_exp, bool lost) {
+void pc_gainexp_disp(struct map_session_data *sd, unsigned int base_exp, unsigned int next_base_exp, unsigned int job_exp, unsigned int next_job_exp, bool lost) {
 	char output[CHAT_SIZE_MAX];
 
 	nullpo_retv(sd);

+ 1 - 0
src/map/pc.h

@@ -1009,6 +1009,7 @@ bool pc_is_maxjoblv(struct map_session_data *sd);
 int pc_checkbaselevelup(struct map_session_data *sd);
 int pc_checkjoblevelup(struct map_session_data *sd);
 int pc_gainexp(struct map_session_data*,struct block_list*,unsigned int,unsigned int, bool);
+void pc_gainexp_disp(struct map_session_data *sd, unsigned int base_exp, unsigned int next_base_exp, unsigned int job_exp, unsigned int next_job_exp, bool lost);
 unsigned int pc_nextbaseexp(struct map_session_data *sd);
 unsigned int pc_nextjobexp(struct map_session_data *sd);
 int pc_gets_status_point(int);

+ 25 - 13
src/map/skill.c

@@ -5925,12 +5925,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 				clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
 				break;
 			}
-			skill_area_temp[0] = 5 - skill_area_temp[0]; // The actual penalty...
-			if (skill_area_temp[0] > 0 && !map[src->m].flag.noexppenalty) { //Apply penalty
-				sd->status.base_exp -= min(sd->status.base_exp, pc_nextbaseexp(sd) * skill_area_temp[0] * 2/1000); //0.2% penalty per each.
-				sd->status.job_exp -= min(sd->status.job_exp, pc_nextjobexp(sd) * skill_area_temp[0] * 2/1000);
+			skill_area_temp[0] = battle_config.exp_cost_redemptio_limit - skill_area_temp[0]; // The actual penalty...
+			if (skill_area_temp[0] > 0 && !map[src->m].flag.noexppenalty && battle_config.exp_cost_redemptio) { //Apply penalty
+				//If total penalty is 1% => reduced 0.2% penalty per each revived player
+				unsigned int base_penalty = u32min(sd->status.base_exp, (pc_nextbaseexp(sd) * skill_area_temp[0] * battle_config.exp_cost_redemptio / battle_config.exp_cost_redemptio_limit) / 100);
+				sd->status.base_exp -= base_penalty;
+				clif_displayexp(sd, base_penalty, SP_BASEEXP, false, true);
 				clif_updatestatus(sd,SP_BASEEXP);
-				clif_updatestatus(sd,SP_JOBEXP);
+				if (sd->state.showexp)
+					pc_gainexp_disp(sd, base_penalty, pc_nextbaseexp(sd), 0, pc_nextjobexp(sd), true);
 			}
 			status_set_hp(src, 1, 0);
 			status_set_sp(src, 0, 0);
@@ -9634,11 +9637,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		break;
 
 	case LG_INSPIRATION:
-		if( sd && !map[sd->bl.m].flag.noexppenalty ) {
-			sd->status.base_exp -= min(sd->status.base_exp, pc_nextbaseexp(sd) * 1 / 100); // 1% penalty.
-			sd->status.job_exp -= min(sd->status.job_exp, pc_nextjobexp(sd) * 1 / 100);
+		if( sd && !map[sd->bl.m].flag.noexppenalty && battle_config.exp_cost_inspiration ) {
+			unsigned int base_penalty = u32min(sd->status.base_exp, pc_nextbaseexp(sd) * battle_config.exp_cost_inspiration / 100); // 1% penalty.
+			sd->status.base_exp -= base_penalty;
+			clif_displayexp(sd, base_penalty, SP_BASEEXP, false, true);
 			clif_updatestatus(sd,SP_BASEEXP);
-			clif_updatestatus(sd,SP_JOBEXP);
+			if (sd->state.showexp)
+				pc_gainexp_disp(sd, base_penalty, pc_nextbaseexp(sd), 0, pc_nextjobexp(sd), true);
 		}
 		clif_skill_nodamage(bl,src,skill_id,skill_lv, sc_start(src,bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv)));
 		break;
@@ -14756,12 +14761,19 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
 				}
 			}
 			break;
-		case LG_INSPIRATION:
 		case PR_REDEMPTIO:
+		case LG_INSPIRATION:
 			{
-				int exp;
-				if( ((exp = pc_nextbaseexp(sd)) > 0 && get_percentage(sd->status.base_exp, exp) < 1) ||
-					((exp = pc_nextjobexp(sd)) > 0 && get_percentage(sd->status.job_exp, exp) < 1)) {
+				unsigned int exp, exp_needp = 0;
+				switch (skill_id) {
+					case PR_REDEMPTIO:
+						exp_needp = battle_config.exp_cost_redemptio;
+						break;
+					case LG_INSPIRATION:
+						exp_needp = battle_config.exp_cost_inspiration;
+						break;
+				}
+				if (exp_needp && ((exp = pc_nextbaseexp(sd)) > 0 && get_percentage(sd->status.base_exp, exp) < exp_needp)) {
 					clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); //Not enough exp.
 					return false;
 				}