Prechádzať zdrojové kódy

Fixed Achievement Level progression (#4156)

* Fixes #4131.
* Changed the behavior of achievement experience to roll over remaining experience rather than check from the total amount.
* Cleaned up achievement level logic.
Thanks to @daisyanne1380 and @SeravySensei!
Aleos 5 rokov pred
rodič
commit
ac46920e73
2 zmenil súbory, kde vykonal 28 pridanie a 48 odobranie
  1. 14 29
      src/map/achievement.cpp
  2. 14 19
      src/map/clif.cpp

+ 14 - 29
src/map/achievement.cpp

@@ -691,54 +691,39 @@ int achievement_check_progress(struct map_session_data *sd, int achievement_id,
  * Calculate a player's achievement level
  * @param sd: Player to check achievement level
  * @param flag: If the call should attempt to give the AG_GOAL_ACHIEVE achievement
- * @return Player's achievement level or 0 on failure
+ * @return Rollover and TNL EXP or 0 on failure
  */
 int *achievement_level(struct map_session_data *sd, bool flag)
 {
+	nullpo_retr(nullptr, sd);
+
 	static int info[2];
-	int i, old_level;
+	int old_level = sd->achievement_data.level;
 	const int score_table[MAX_ACHIEVEMENT_RANK] = { 18, 31, 49, 73, 135, 104, 140, 178, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000 }; //! TODO: Figure out the EXP required to level up from 8-20
 
-	nullpo_retr(0, sd);
-
 	sd->achievement_data.total_score = 0;
-	old_level = sd->achievement_data.level;
+	sd->achievement_data.level = 0;
 
-	for (i = 0; i < sd->achievement_data.count; i++) {
+	for (int i = 0; i < sd->achievement_data.count; i++) { // Recount total score
 		if (sd->achievement_data.achievements[i].completed > 0)
 			sd->achievement_data.total_score += sd->achievement_data.achievements[i].score;
 	}
 
-	info[0] = 0;
-	info[1] = 0;
-
-	for (i = 0; i < MAX_ACHIEVEMENT_RANK; i++) {
-		info[0] = info[1];
-			
-		if (i < ARRAYLENGTH(score_table))
-			info[1] = score_table[i];
-		else {
-			info[0] = info[1];
-			info[1] = info[1] + 500;
-		}
+	int i, temp_score = sd->achievement_data.total_score;
 
-		if (sd->achievement_data.total_score < info[1])
-			break;
+	for (i = 0; i < MAX_ACHIEVEMENT_RANK && temp_score > score_table[i]; i++) { // Determine rollover and TNL EXP
+		temp_score -= score_table[i];
+		sd->achievement_data.level++;
 	}
 
-	if (i == MAX_ACHIEVEMENT_RANK)
-		i = 0;
+	info[0] = temp_score; // Left number
+	info[1] = score_table[i]; // Right number
 
-	info[1] = info[1] - info[0]; // Right number
-	info[0] = sd->achievement_data.total_score - info[0]; // Left number
-	sd->achievement_data.level = i;
-
-	if (flag == true && old_level != sd->achievement_data.level) {
+	if (flag && old_level != sd->achievement_data.level) { // Give AG_GOAL_ACHIEVE
 		int achievement_id = 240000 + sd->achievement_data.level;
 
-		if( achievement_add(sd, achievement_id) ){
+		if (achievement_add(sd, achievement_id))
 			achievement_update_achievement(sd, achievement_id, true);
-		}
 	}
 
 	return info;

+ 14 - 19
src/map/clif.cpp

@@ -20300,14 +20300,11 @@ void clif_parse_sale_remove( int fd, struct map_session_data* sd ){
 /// Author: Luxuri, Aleos
 
 /**
- * Sends all achievement data to the client (ZC_ALL_AG_LIST).
+ * Sends all achievement data to the client (ZC_ALL_ACH_LIST).
  * 0a23 <packetType>.W <packetLength>.W <ACHCount>.L <ACHPoint>.L
  */
 void clif_achievement_list_all(struct map_session_data *sd)
 {
-	int i, j, len, fd, *info;
-	uint16 count = 0;
-
 	nullpo_retv(sd);
 
 	if (!battle_config.feature_achievement) {
@@ -20315,14 +20312,14 @@ void clif_achievement_list_all(struct map_session_data *sd)
 		return;
 	}
 
-	fd = sd->fd;
-	count = sd->achievement_data.count; // All achievements should be sent to the client
-	len = (50 * count) + 22;
+	int count = sd->achievement_data.count; // All achievements should be sent to the client
 
-	if (len <= 22)
+	if (count == 0)
 		return;
 
-	info = achievement_level(sd, true);
+	int len = (50 * count) + 22;
+	int fd = sd->fd;
+	int *info = achievement_level(sd, true);
 
 	WFIFOHEAD(fd,len);
 	WFIFOW(fd, 0) = 0xa23;
@@ -20333,10 +20330,10 @@ void clif_achievement_list_all(struct map_session_data *sd)
 	WFIFOL(fd, 14) = info[0]; // Achievement EXP (left number in bar)
 	WFIFOL(fd, 18) = info[1]; // Achievement EXP TNL (right number in bar)
 
-	for (i = 0; i < count; i++) {
+	for (int i = 0; i < count; i++) {
 		WFIFOL(fd, i * 50 + 22) = (uint32)sd->achievement_data.achievements[i].achievement_id;
 		WFIFOB(fd, i * 50 + 26) = (uint32)sd->achievement_data.achievements[i].completed > 0;
-		for (j = 0; j < MAX_ACHIEVEMENT_OBJECTIVES; j++) 
+		for (int j = 0; j < MAX_ACHIEVEMENT_OBJECTIVES; j++) 
 			WFIFOL(fd, (i * 50) + 27 + (j * 4)) = (uint32)sd->achievement_data.achievements[i].count[j];
 		WFIFOL(fd, i * 50 + 67) = (uint32)sd->achievement_data.achievements[i].completed;
 		WFIFOB(fd, i * 50 + 71) = sd->achievement_data.achievements[i].rewarded > 0;
@@ -20345,13 +20342,11 @@ void clif_achievement_list_all(struct map_session_data *sd)
 }
 
 /**
- * Sends a single achievement's data to the client (ZC_AG_UPDATE).
+ * Sends a single achievement's data to the client (ZC_ACH_UPDATE).
  * 0a24 <packetType>.W <ACHPoint>.L
  */
 void clif_achievement_update(struct map_session_data *sd, struct achievement *ach, int count)
 {
-	int fd, i, *info;
-
 	nullpo_retv(sd);
 
 	if (!battle_config.feature_achievement) {
@@ -20359,8 +20354,8 @@ void clif_achievement_update(struct map_session_data *sd, struct achievement *ac
 		return;
 	}
 
-	fd = sd->fd;
-	info = achievement_level(sd, true);
+	int fd = sd->fd;
+	int *info = achievement_level(sd, true);
 
 	WFIFOHEAD(fd, packet_len(0xa24));
 	WFIFOW(fd, 0) = 0xa24;
@@ -20371,7 +20366,7 @@ void clif_achievement_update(struct map_session_data *sd, struct achievement *ac
 	if (ach) {
 		WFIFOL(fd, 16) = ach->achievement_id; // Achievement ID
 		WFIFOB(fd, 20) = ach->completed > 0; // Is it complete?
-		for (i = 0; i < MAX_ACHIEVEMENT_OBJECTIVES; i++)
+		for (int i = 0; i < MAX_ACHIEVEMENT_OBJECTIVES; i++)
 			WFIFOL(fd, 21 + (i * 4)) = (uint32)ach->count[i]; // 1~10 pre-reqs
 		WFIFOL(fd, 61) = (uint32)ach->completed; // Epoch time
 		WFIFOB(fd, 65) = ach->rewarded > 0; // Got reward?
@@ -20381,7 +20376,7 @@ void clif_achievement_update(struct map_session_data *sd, struct achievement *ac
 }
 
 /**
- * Checks if an achievement reward can be rewarded (CZ_REQ_AG_REWARD).
+ * Checks if an achievement reward can be rewarded (CZ_REQ_ACH_REWARD).
  * 0a25 <packetType>.W <achievementID>.L
  */
 void clif_parse_AchievementCheckReward(int fd, struct map_session_data *sd)
@@ -20395,7 +20390,7 @@ void clif_parse_AchievementCheckReward(int fd, struct map_session_data *sd)
 }
 
 /**
- * Returns the result of achievement_check_reward (ZC_REQ_AG_REWARD_ACK).
+ * Returns the result of achievement_check_reward (ZC_REQ_ACH_REWARD_ACK).
  * 0a26 <packetType>.W <result>.W <achievementID>.L
  */
 void clif_achievement_reward_ack(int fd, unsigned char result, int achievement_id)