浏览代码

Fixed monster exp definitions (#5672)

Fixes #5656

Thanks to @Skystar18
Lemongrass3110 4 年之前
父节点
当前提交
f57b037b83

+ 1 - 1
conf/msg_conf/map_msg.conf

@@ -1327,7 +1327,7 @@
 1239: Please enter a monster name/ID (usage: @mobinfo <monster_name_or_monster_ID>).
 1240: MVP Monster: '%s'/'%s'/'%s' (%d)
 1241: Monster: '%s'/'%s'/'%s' (%d)
-1242:  Lv:%d  HP:%d  Base EXP:%u  Job EXP:%u  HIT:%d  FLEE:%d
+1242:  Lv:%d  HP:%d  Base EXP:%llu  Job EXP:%llu  HIT:%d  FLEE:%d
 1243:  DEF:%d  MDEF:%d  STR:%d  AGI:%d  VIT:%d  INT:%d  DEX:%d  LUK:%d
 1244:  ATK:%d~%d  Range:%d~%d~%d  Size:%s  Race: %s  Element: %s (Lv:%d)
 1245:  Drops:

+ 1 - 1
conf/msg_conf/map_msg_chn.conf

@@ -1134,7 +1134,7 @@
 1239: 請輸入魔物名稱或魔物ID (用法: @mobinfo <魔物名稱或魔物ID>).
 1240: MVP 魔物: '%s'/'%s'/'%s' (%d)
 1241: 魔物: '%s'/'%s'/'%s' (%d)
-1242: 等級:%d  血量:%d  基本經驗值:%u  職業經驗值:%u  命中率:%d  迴避率:%d
+1242: 等級:%d  血量:%d  基本經驗值:%llu  職業經驗值:%llu  命中率:%d  迴避率:%d
 1243: 防禦:%d  魔防:%d  STR:%d  AGI:%d  VIT:%d  INT:%d  DEX:%d  LUK:%d
 1244: 物理攻擊力:%d~%d 攻擊範圍:%d~%d~%d  體型:%s  種族: %s  屬性: %s (Lv:%d)
 1245: 掉落:

+ 1 - 1
conf/msg_conf/map_msg_frn.conf

@@ -1147,7 +1147,7 @@
 1239: Entrez un nom de monstre/ID (usage: @mobinfo <nom_du_monstre_ou_ID>).
 1240: Monstre MVP: '%s'/'%s'/'%s' (%d)
 1241: Monstre: '%s'/'%s'/'%s' (%d)
-1242:  Lv:%d  HP:%d  Base EXP:%u  Job EXP:%u  HIT:%d  FLEE:%d
+1242:  Lv:%d  HP:%d  Base EXP:%llu  Job EXP:%llu  HIT:%d  FLEE:%d
 1243:  DEF:%d  MDEF:%d  STR:%d  AGI:%d  VIT:%d  INT:%d  DEX:%d  LUK:%d
 1244:  ATK:%d~%d  Range:%d~%d~%d  Size:%s  Race: %s  Elément: %s (Lv:%d)
 1245:  Drops:

+ 1 - 1
conf/msg_conf/map_msg_por.conf

@@ -1317,7 +1317,7 @@
 1239: Digite o nome de um monstro/ID (uso: @mobinfo <nome_ou_ID_do_monstro>).
 1240: Monstro MVP: '%s'/'%s'/'%s' (%d)
 1241: Monstro: '%s'/'%s'/'%s' (%d)
-1242:  Nv:%d  HP:%d  EXP Base:%u  EXP Classe:%u  HIT:%d  ESQV:%d
+1242:  Nv:%d  HP:%d  EXP Base:%llu  EXP Classe:%llu  HIT:%d  ESQV:%d
 1243:  DEF:%d  DEFM:%d  FOR:%d  AGI:%d  VIT:%d  INT:%d  DES:%d  SOR:%d
 1244:  ATQ:%d~%d  Alcance:%d~%d~%d  Tamanho:%s  Raça: %s  Elemento: %s (Nv:%d)
 1245:  Drops:

+ 1 - 1
conf/msg_conf/map_msg_rus.conf

@@ -1147,7 +1147,7 @@
 1239: Введите ID/название монстра (Использование: @mobinfo <ID/название монстра>).
 1240: MVP монстр: '%s'/'%s'/'%s' (%d)
 1241: Монстр: '%s'/'%s'/'%s' (%d)
-1242:  Ур.:%d  HP:%d  Базовый опыт:%u   Проф. опыт:%u  HIT:%d  FLEE:%d
+1242:  Ур.:%d  HP:%d  Базовый опыт:%llu   Проф. опыт:%llu  HIT:%d  FLEE:%d
 1243:  DEF:%d  MDEF:%d  STR:%d  AGI:%d  VIT:%d  INT:%d  DEX:%d  LUK:%d
 1244:  ATK:%d~%d  Дальность:%d~%d~%d  Размер:%s  Раса: %s  Элемент: %s (Ур.:%d)
 1245:  Предметы:

+ 1 - 1
conf/msg_conf/map_msg_spn.conf

@@ -1286,7 +1286,7 @@
 1239: Introduce el nombre/ID de un monstruo (instrucciones: @mobinfo <nombre/ID del monstruo>).
 1240: Monstruo MVP: '%s'/'%s'/'%s' (%d)
 1241: Monstruo: '%s'/'%s'/'%s' (%d)
-1242: Nv:%d  HP:%d  EXP de base:%u  EXP de oficio:%u  HIT:%d  FLEE:%d
+1242: Nv:%d  HP:%d  EXP de base:%llu  EXP de oficio:%llu  HIT:%d  FLEE:%d
 1243:  DEF:%d  MDEF:%d  STR:%d  AGI:%d  VIT:%d  INT:%d  DEX:%d  LUK:%d
 1244:  ATK:%d~%d  Rango:%d~%d~%d  Tamaño:%s  Raza: %s  Elemento: %s (Nv:%d)
 1245: Objetos:

+ 1 - 1
conf/msg_conf/map_msg_tha.conf

@@ -1140,7 +1140,7 @@
 1239: â»Ã´Ãкت×èÍ/ID Monster (ÇÔ¸Õãªé: @mobinfo <ª×èÍ/ID mob>).
 1240: MVP Monster: '%s'/'%s'/'%s' (%d)
 1241: Monster: '%s'/'%s'/'%s' (%d)
-1242:  Lv:%d  HP:%d  Base EXP:%u  Job EXP:%u  HIT:%d  FLEE:%d
+1242:  Lv:%d  HP:%d  Base EXP:%llu  Job EXP:%llu  HIT:%d  FLEE:%d
 1243:  DEF:%d  MDEF:%d  STR:%d  AGI:%d  VIT:%d  INT:%d  DEX:%d  LUK:%d
 1244:  ATK:%d~%d  Range:%d~%d~%d  Size:%s  Race: %s  Element: %s (Lv:%d)
 1245:  Drops:

+ 4 - 5
src/map/atcommand.cpp

@@ -7378,10 +7378,9 @@ ACMD_FUNC(mobinfo)
 		count = MAX_SEARCH;
 	}
 	for (k = 0; k < count; k++) {
-		unsigned int j,base_exp,job_exp;
 		mob = mob_db(mob_ids[k]);
-		base_exp = mob->base_exp;
-		job_exp = mob->job_exp;
+		t_exp base_exp = mob->base_exp;
+		t_exp job_exp = mob->job_exp;
 
 		if (pc_isvip(sd)) { // Display EXP rate increase for VIP
 			base_exp += (base_exp * battle_config.vip_base_exp_increase) / 100;
@@ -7401,7 +7400,7 @@ ACMD_FUNC(mobinfo)
 		else
 			sprintf(atcmd_output, msg_txt(sd,1241), mob->name, mob->jname, mob->sprite, mob->vd.class_); // Monster: '%s'/'%s'/'%s' (%d)
 		clif_displaymessage(fd, atcmd_output);
-		sprintf(atcmd_output, msg_txt(sd,1242), mob->lv, mob->status.max_hp, base_exp, job_exp, MOB_HIT(mob), MOB_FLEE(mob)); //  Lv:%d  HP:%d  Base EXP:%u  Job EXP:%u  HIT:%d  FLEE:%d
+		sprintf(atcmd_output, msg_txt(sd,1242), mob->lv, mob->status.max_hp, base_exp, job_exp, MOB_HIT(mob), MOB_FLEE(mob)); //  Lv:%d  HP:%d  Base EXP:%llu  Job EXP:%llu  HIT:%d  FLEE:%d
 		clif_displaymessage(fd, atcmd_output);
 		sprintf(atcmd_output, msg_txt(sd,1243), //  DEF:%d  MDEF:%d  STR:%d  AGI:%d  VIT:%d  INT:%d  DEX:%d  LUK:%d
 			mob->status.def, mob->status.mdef,mob->status.str, mob->status.agi,
@@ -7416,7 +7415,7 @@ ACMD_FUNC(mobinfo)
 		// drops
 		clif_displaymessage(fd, msg_txt(sd,1245)); //  Drops:
 		strcpy(atcmd_output, " ");
-		j = 0;
+		unsigned int j = 0;
 #ifdef RENEWAL_DROP
 		int penalty = pc_level_penalty_mod( sd, PENALTY_DROP, mob );
 #endif

+ 14 - 21
src/map/mob.cpp

@@ -2511,7 +2511,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 	struct {
 		struct party_data *p;
 		int id,zeny;
-		unsigned int base_exp,job_exp;
+		t_exp base_exp;
+		t_exp job_exp;
 	} pt[DAMAGELOG_SIZE];
 	int i, temp, count, m = md->bl.m;
 	int dmgbltypes = 0;  // bitfield of all bl types, that caused damage to the mob and are elligible for exp distribution
@@ -2623,7 +2624,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 
 		for(i = 0; i < DAMAGELOG_SIZE && md->dmglog[i].id; i++) {
 			int flag=1,zeny=0;
-			unsigned int base_exp, job_exp;
+			t_exp base_exp, job_exp;
 			double per; //Your share of the mob's exp
 
 			if (!tmpsd[i]) continue;
@@ -2672,7 +2673,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 				double exp = apply_rate2(md->db->base_exp, per, 1);
 				exp = apply_rate(exp, bonus);
 				exp = apply_rate(exp, map_getmapflag(m, MF_BEXP));
-				base_exp = (unsigned int)cap_value(exp, 1, UINT_MAX);
+				base_exp = (t_exp)cap_value(exp, 1, MAX_EXP);
 			}
 
 			if (map_getmapflag(m, MF_NOJOBEXP) || !md->db->job_exp
@@ -2685,7 +2686,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 				double exp = apply_rate2(md->db->job_exp, per, 1);
 				exp = apply_rate(exp, bonus);
 				exp = apply_rate(exp, map_getmapflag(m, MF_JEXP));
-				job_exp = (unsigned int)cap_value(exp, 1, UINT_MAX);
+				job_exp = (t_exp)cap_value(exp, 1, MAX_EXP);
 			}
 
 			if ((base_exp > 0 || job_exp > 0) && md->dmglog[i].flag == MDLF_HOMUN && homkillonly && battle_config.hom_idle_no_share && pc_isidle_hom(tmpsd[i]))
@@ -2706,16 +2707,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 						flag = 0;
 					}
 				} else {	//Add to total
-					if (pt[j].base_exp > UINT_MAX - base_exp)
-						pt[j].base_exp = UINT_MAX;
-					else
-						pt[j].base_exp += base_exp;
-
-					if (pt[j].job_exp > UINT_MAX - job_exp)
-						pt[j].job_exp = UINT_MAX;
-					else
-						pt[j].job_exp += job_exp;
-
+					pt[j].base_exp = util::safe_addition_cap( pt[j].base_exp, base_exp, MAX_EXP );
+					pt[j].job_exp = util::safe_addition_cap( pt[j].job_exp, job_exp, MAX_EXP );
 					pt[j].zeny += zeny;  // zeny share [Valaris]
 					flag = 0;
 				}
@@ -2734,9 +2727,9 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 						int rate = pc_level_penalty_mod( tmpsd[i], PENALTY_EXP, nullptr, md );
 						if (rate != 100) {
 							if (base_exp)
-								base_exp = (unsigned int)cap_value(apply_rate(base_exp, rate), 1, UINT_MAX);
+								base_exp = (t_exp)cap_value(apply_rate(base_exp, rate), 1, MAX_EXP);
 							if (job_exp)
-								job_exp = (unsigned int)cap_value(apply_rate(job_exp, rate), 1, UINT_MAX);
+								job_exp = (t_exp)cap_value(apply_rate(job_exp, rate), 1, MAX_EXP);
 						}
 #endif
 						pc_gainexp(tmpsd[i], &md->bl, base_exp, job_exp, 0);
@@ -4232,11 +4225,11 @@ static bool mob_parse_dbrow(char** str)
 	status->max_hp = atoi(str[5]);
 	status->max_sp = atoi(str[6]);
 
-	exp = (double)atoi(str[7]) * (double)battle_config.base_exp_rate / 100.;
-	entry.base_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
+	exp = (double)strtoull(str[7],nullptr,10) * (double)battle_config.base_exp_rate / 100.;
+	entry.base_exp = (t_exp)cap_value(exp, 0, MAX_EXP);
 
-	exp = (double)atoi(str[8]) * (double)battle_config.job_exp_rate / 100.;
-	entry.job_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
+	exp = (double)strtoull(str[8],nullptr,10) * (double)battle_config.job_exp_rate / 100.;
+	entry.job_exp = (t_exp)cap_value(exp, 0, MAX_EXP);
 
 	status->rhw.range = atoi(str[9]);
 #ifdef RENEWAL
@@ -4324,7 +4317,7 @@ static bool mob_parse_dbrow(char** str)
 	// MVP EXP Bonus: MEXP
 	// Some new MVP's MEXP multipled by high exp-rate cause overflow. [LuzZza]
 	exp = (double)atoi(str[30]) * (double)battle_config.mvp_exp_rate / 100.;
-	entry.mexp = (unsigned int)cap_value(exp, 0, UINT_MAX);
+	entry.mexp = (t_exp)cap_value(exp, 0, MAX_EXP);
 
 	//Now that we know if it is an mvp or not, apply battle_config modifiers [Skotlex]
 	maxhp = (double)status->max_hp;

+ 3 - 2
src/map/mob.hpp

@@ -176,8 +176,9 @@ struct s_mob_drop {
 
 struct mob_db {
 	char sprite[NAME_LENGTH],name[NAME_LENGTH],jname[NAME_LENGTH];
-	unsigned int base_exp,job_exp;
-	unsigned int mexp;
+	t_exp base_exp;
+	t_exp job_exp;
+	t_exp mexp;
 	short range2,range3;
 	enum e_race2 race2;	// celest
 	unsigned short lv;

+ 6 - 6
src/map/party.cpp

@@ -1074,7 +1074,7 @@ int party_send_xy_clear(struct party_data *p)
  * @param zeny Zeny gained from killed mob
  * @author Valaris
  **/
-void party_exp_share(struct party_data* p, struct block_list* src, unsigned int base_exp, unsigned int job_exp, int zeny)
+void party_exp_share(struct party_data* p, struct block_list* src, t_exp base_exp, t_exp job_exp, int zeny)
 {
 	struct map_session_data* sd[MAX_PARTY];
 	unsigned int i, c;
@@ -1104,23 +1104,23 @@ void party_exp_share(struct party_data* p, struct block_list* src, unsigned int
 		double bonus = 100 + battle_config.party_even_share_bonus*(c-1);
 
 		if (base_exp)
-			base_exp = (unsigned int) cap_value(base_exp * bonus/100, 0, UINT_MAX);
+			base_exp = (t_exp) cap_value(base_exp * bonus/100, 0, MAX_EXP);
 		if (job_exp)
-			job_exp = (unsigned int) cap_value(job_exp * bonus/100, 0, UINT_MAX);
+			job_exp = (t_exp) cap_value(job_exp * bonus/100, 0, MAX_EXP);
 		if (zeny)
 			zeny = (unsigned int) cap_value(zeny * bonus/100, INT_MIN, INT_MAX);
 	}
 
 	for (i = 0; i < c; i++) {
 #ifdef RENEWAL_EXP
-		uint32 base_gained = base_exp, job_gained = job_exp;
+		t_exp base_gained = base_exp, job_gained = job_exp;
 		if (base_exp || job_exp) {
 			int rate = pc_level_penalty_mod( sd[i], PENALTY_EXP, nullptr, md );
 			if (rate != 100) {
 				if (base_exp)
-					base_gained = (unsigned int)cap_value(apply_rate(base_exp, rate), 1, UINT_MAX);
+					base_gained = (t_exp)cap_value(apply_rate(base_exp, rate), 1, MAX_EXP);
 				if (job_exp)
-					job_gained = (unsigned int)cap_value(apply_rate(job_exp, rate), 1, UINT_MAX);
+					job_gained = (t_exp)cap_value(apply_rate(job_exp, rate), 1, MAX_EXP);
 			}
 		}
 		pc_gainexp(sd[i], src, base_gained, job_gained, 0);

+ 1 - 1
src/map/party.hpp

@@ -84,7 +84,7 @@ int party_send_message(struct map_session_data *sd,const char *mes,int len);
 int party_recv_message(int party_id,uint32 account_id,const char *mes,int len);
 int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id, uint16 skill_lv);
 int party_send_xy_clear(struct party_data *p);
-void party_exp_share(struct party_data *p,struct block_list *src,unsigned int base_exp,unsigned int job_exp,int zeny);
+void party_exp_share(struct party_data *p,struct block_list *src,t_exp base_exp,t_exp job_exp,int zeny);
 int party_share_loot(struct party_data* p, struct map_session_data* sd, struct item* item, int first_charid);
 int party_send_dot_remove(struct map_session_data *sd);
 int party_sub_count(struct block_list *bl, va_list ap);