ソースを参照

A little clean for Skill Damage Adjustment
* re-Disabled the ADJUST_SKILL_DAMAGE by default (core.h) that enabled by accident since 794c1a8. :P
* Removed MAX_MAP_SKILL_MODIFIER variable.
* Removed fixed array for skill damage adjustment in each map.

Signed-off-by: Cydh Ramdh <house.bad@gmail.com>

Cydh Ramdh 10 年 前
コミット
72cb55470b
8 ファイル変更146 行追加69 行削除
  1. 1 1
      src/config/core.h
  2. 12 15
      src/map/atcommand.c
  3. 32 25
      src/map/battle.c
  4. 75 1
      src/map/map.c
  5. 17 9
      src/map/map.h
  6. 5 16
      src/map/npc.c
  7. 2 1
      src/map/script.c
  8. 2 1
      src/map/skill.c

+ 1 - 1
src/config/core.h

@@ -59,7 +59,7 @@
 /// Uncomment to enable skills damage adjustments
 /// By enabling this, db/skill_damage.txt and the skill_damage mapflag will adjust the
 /// damage rate of specified skills.
-#define ADJUST_SKILL_DAMAGE
+//#define ADJUST_SKILL_DAMAGE
 
 /// Uncomment to enable the job base HP/SP table (job_basehpsp_db.txt)
 //#define HP_SP_TABLES

+ 12 - 15
src/map/atcommand.c

@@ -3952,22 +3952,19 @@ ACMD_FUNC(mapinfo) {
 			,map[m_id].adjust.damage.other
 			,map[m_id].adjust.damage.caster);
 		clif_displaymessage(fd, atcmd_output);
-		if (map[m_id].skill_damage[0].skill_id) {
-			int j;
-
+		if (map[m_id].skill_damage.count) {
+			uint8 j;
 			clif_displaymessage(fd," > [Map Skill] Name : Player, Monster, Boss Monster, Other | Caster");
-			for (j = 0; j < MAX_MAP_SKILL_MODIFIER; j++) {
-				if (map[m_id].skill_damage[j].skill_id) {
-					sprintf(atcmd_output,"     %d. %s : %d%%, %d%%, %d%%, %d%% | %d"
-						,j+1
-						,skill_get_name(map[m_id].skill_damage[j].skill_id)
-						,map[m_id].skill_damage[j].pc
-						,map[m_id].skill_damage[j].mob
-						,map[m_id].skill_damage[j].boss
-						,map[m_id].skill_damage[j].other
-						,map[m_id].skill_damage[j].caster);
-					clif_displaymessage(fd,atcmd_output);
-				}
+			for (j = 0; j < map[m_id].skill_damage.count; j++) {
+				sprintf(atcmd_output,"     %d. %s : %d%%, %d%%, %d%%, %d%% | %d"
+					,j+1
+					,skill_get_name(map[m_id].skill_damage.entries[j]->skill_id)
+					,map[m_id].skill_damage.entries[j]->pc
+					,map[m_id].skill_damage.entries[j]->mob
+					,map[m_id].skill_damage.entries[j]->boss
+					,map[m_id].skill_damage.entries[j]->other
+					,map[m_id].skill_damage.entries[j]->caster);
+				clif_displaymessage(fd,atcmd_output);
 			}
 		}
 	}

+ 32 - 25
src/map/battle.c

@@ -1850,13 +1850,12 @@ static int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id)
 	return 0;
 }
 
+#ifdef ADJUST_SKILL_DAMAGE
 /**
  * Damage calculation for adjusting skill damage
  * @param caster Applied caster type for damage skill
  * @param type BL_Type of attacker
- * @author [Lilith] for the first release of this, [Cydh]
  */
-#ifdef ADJUST_SKILL_DAMAGE
 static bool battle_skill_damage_iscaster(uint8 caster, enum bl_type src_type) {
 	if (caster == 0)
 		return false;
@@ -1882,6 +1881,7 @@ static bool battle_skill_damage_iscaster(uint8 caster, enum bl_type src_type) {
 static int battle_skill_damage_skill(struct block_list *src, struct block_list *target, uint16 skill_id) {
 	uint16 idx = skill_get_index(skill_id), m = src->m;
 	struct s_skill_damage *damage = NULL;
+	struct map_data *mapd = &map[m];
 
 	if (!idx || !skill_db[idx].damage.map)
 		return 0;
@@ -1892,12 +1892,12 @@ static int battle_skill_damage_skill(struct block_list *src, struct block_list *
 	if (!battle_skill_damage_iscaster(damage->caster, src->type))
 		return 0;
 
-	if ((damage->map&1 && (!map[m].flag.pvp && !map_flag_gvg(m) && !map[m].flag.battleground && !map[m].flag.skill_damage && !map[m].flag.restricted)) ||
-		(damage->map&2 && map[m].flag.pvp) ||
+	if ((damage->map&1 && (!mapd->flag.pvp && !map_flag_gvg(m) && !mapd->flag.battleground && !mapd->flag.skill_damage && !mapd->flag.restricted)) ||
+		(damage->map&2 && mapd->flag.pvp) ||
 		(damage->map&4 && map_flag_gvg(m)) ||
-		(damage->map&8 && map[m].flag.battleground) ||
-		(damage->map&16 && map[m].flag.skill_damage) ||
-		(map[m].flag.restricted && skill_db[idx].damage.map&(8*map[m].zone)))
+		(damage->map&8 && mapd->flag.battleground) ||
+		(damage->map&16 && mapd->flag.skill_damage) ||
+		(mapd->flag.restricted && damage->map&(8*mapd->zone)))
 	{
 		switch (target->type) {
 			case BL_PC:
@@ -1924,46 +1924,52 @@ static int battle_skill_damage_skill(struct block_list *src, struct block_list *
  */
 static int battle_skill_damage_map(struct block_list *src, struct block_list *target, uint16 skill_id) {
 	int rate = 0;
-	uint16 m = src->m;
-	uint8 i;
+	uint8 i = 0;
+	struct map_data *mapd = NULL;
+
+	mapd = &map[src->m];
 
-	if (!map[m].flag.skill_damage)
+	if (!mapd || !mapd->flag.skill_damage)
 		return 0;
 
 	// Damage rate for all skills at this map
-	if (battle_skill_damage_iscaster(map[m].adjust.damage.caster, src->type)) {
+	if (battle_skill_damage_iscaster(mapd->adjust.damage.caster, src->type)) {
 		switch (target->type) {
 			case BL_PC:
-				rate = map[m].adjust.damage.pc;
+				rate = mapd->adjust.damage.pc;
 				break;
 			case BL_MOB:
 				if (is_boss(target))
-					rate = map[m].adjust.damage.boss;
+					rate = mapd->adjust.damage.boss;
 				else
-					rate = map[m].adjust.damage.mob;
+					rate = mapd->adjust.damage.mob;
 				break;
 			default:
-				rate = map[m].adjust.damage.other;
+				rate = mapd->adjust.damage.other;
 				break;
 		}
 	}
 
+	if (!mapd->skill_damage.count)
+		return rate;
+
 	// Damage rate for specified skill at this map
-	ARR_FIND(0, ARRAYLENGTH(map[m].skill_damage), i, map[m].skill_damage[i].skill_id == skill_id);
-	if (i < ARRAYLENGTH(map[m].skill_damage)) {
-		if (battle_skill_damage_iscaster(map[m].skill_damage[i].caster, src->type)) {
+	for (i = 0; i < mapd->skill_damage.count; i++) {
+		if (mapd->skill_damage.entries[i]->skill_id == skill_id &&
+			battle_skill_damage_iscaster(mapd->skill_damage.entries[i]->caster, src->type))
+		{
 			switch (target->type) {
 				case BL_PC:
-					rate += map[m].skill_damage[i].pc;
+					rate += mapd->skill_damage.entries[i]->pc;
 					break;
 				case BL_MOB:
 					if (is_boss(target))
-						rate += map[m].skill_damage[i].boss;
+						rate += mapd->skill_damage.entries[i]->boss;
 					else
-						rate += map[m].skill_damage[i].mob;
+						rate += mapd->skill_damage.entries[i]->mob;
 					break;
 				default:
-					rate += map[m].skill_damage[i].other;
+					rate += mapd->skill_damage.entries[i]->other;
 					break;
 			}
 		}
@@ -1979,6 +1985,7 @@ static int battle_skill_damage_map(struct block_list *src, struct block_list *ta
  * @return Total damage rate
  */
 static int battle_skill_damage(struct block_list *src, struct block_list *target, uint16 skill_id) {
+	nullpo_ret(src);
 	if (!target)
 		return 0;
 	return battle_skill_damage_skill(src, target, skill_id) + battle_skill_damage_map(src, target, skill_id);
@@ -4687,7 +4694,7 @@ struct Damage battle_calc_weapon_final_atk_modifiers(struct Damage wd, struct bl
 	struct status_data *sstatus = status_get_status_data(src);
 	struct status_data *tstatus = status_get_status_data(target);
 #ifdef ADJUST_SKILL_DAMAGE
-	int skill_damage;
+	int skill_damage = 0;
 #endif
 
 	//Reject Sword bugreport:4493 by Daegaladh
@@ -5260,7 +5267,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 {
 	int i, nk;
 #ifdef ADJUST_SKILL_DAMAGE
-	int skill_damage;
+	int skill_damage = 0;
 #endif
 	short s_ele = 0;
 
@@ -6018,7 +6025,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag)
 {
 #ifdef ADJUST_SKILL_DAMAGE
-	int skill_damage;
+	int skill_damage = 0;
 #endif
 	short i, nk;
 	short s_ele;

+ 75 - 1
src/map/map.c

@@ -112,6 +112,8 @@ int agit_flag = 0;
 int agit2_flag = 0;
 int night_flag = 0; // 0=day, 1=night [Yor]
 
+struct eri *map_skill_damage_ers = NULL;
+
 struct charid_request {
 	struct charid_request* next;
 	int charid;// who want to be notified of the nick
@@ -3227,8 +3229,9 @@ void map_flags_init(void)
 
 		// skill damage
 #ifdef ADJUST_SKILL_DAMAGE
-		memset(map[i].skill_damage, 0, sizeof(map[i].skill_damage));
 		memset(&map[i].adjust.damage, 0, sizeof(map[i].adjust.damage));
+		if (map[i].skill_damage.count)
+			map_skill_damage_free(&map[i]);
 #endif
 
 		// adjustments
@@ -3916,6 +3919,65 @@ int cleanup_sub(struct block_list *bl, va_list ap)
 	return 1;
 }
 
+#ifdef ADJUST_SKILL_DAMAGE
+/**
+ * Free all skill damage entries for a map
+ * @param m Map data
+ **/
+void map_skill_damage_free(struct map_data *m) {
+	uint8 i;
+
+	for (i = 0; i < m->skill_damage.count; i++) {
+		ers_free(map_skill_damage_ers, m->skill_damage.entries[i]);
+		m->skill_damage.entries[i] = NULL;
+	}
+
+	aFree(m->skill_damage.entries);
+	m->skill_damage.entries = NULL;
+	m->skill_damage.count = 0;
+}
+
+/**
+ * Add new skill damage adjustment entry for a map
+ * @param m Map data
+ * @param skill_id Skill
+ * @param pc Rate to PC
+ * @param mobs Rate to Monster
+ * @param boss Rate to Boss-monster
+ * @param other Rate to Other target
+ * @param caster Caster type
+ **/
+void map_skill_damage_add(struct map_data *m, uint16 skill_id, int pc, int mob, int boss, int other, uint8 caster) {
+	struct s_skill_damage *entry;
+	int i = 0;
+
+	if (m->skill_damage.count >= UINT8_MAX)
+		return;
+
+	for (i = 0; i < m->skill_damage.count; i++) {
+		if (m->skill_damage.entries[i]->skill_id == skill_id) {
+			m->skill_damage.entries[i]->pc = pc;
+			m->skill_damage.entries[i]->mob = mob;
+			m->skill_damage.entries[i]->boss = boss;
+			m->skill_damage.entries[i]->other = other;
+			m->skill_damage.entries[i]->caster = caster;
+			return;
+		}
+	}
+
+	entry = ers_alloc(map_skill_damage_ers, struct s_skill_damage);
+	entry->skill_id = skill_id;
+	entry->pc = pc;
+	entry->mob = mob;
+	entry->boss = boss;
+	entry->other = other;
+	entry->caster = caster;
+
+	RECREATE(m->skill_damage.entries, struct s_skill_damage *, m->skill_damage.count+1);
+	m->skill_damage.entries[m->skill_damage.count++] = entry;
+}
+#endif
+
 /**
  * @see DBApply
  */
@@ -4001,6 +4063,10 @@ void do_final(void)
 			for (j=0; j<MAX_MOB_LIST_PER_MAP; j++)
 				if (map[i].moblist[j]) aFree(map[i].moblist[j]);
 		}
+#ifdef ADJUST_SKILL_DAMAGE
+		if (map[i].skill_damage.count)
+			map_skill_damage_free(&map[i]);
+#endif
 	}
 
 	mapindex_final();
@@ -4016,6 +4082,10 @@ void do_final(void)
 	iwall_db->destroy(iwall_db, NULL);
 	regen_db->destroy(regen_db, NULL);
 
+#ifdef ADJUST_SKILL_DAMAGE
+	ers_destroy(map_skill_damage_ers);
+#endif
+
 	map_sql_close();
 
 	ShowStatus("Finished.\n");
@@ -4255,6 +4325,10 @@ int do_init(int argc, char *argv[])
 	regen_db = idb_alloc(DB_OPT_BASE); // efficient status_natural_heal processing
 	iwall_db = strdb_alloc(DB_OPT_RELEASE_DATA,2*NAME_LENGTH+2+1); // [Zephyrus] Invisible Walls
 
+#ifdef ADJUST_SKILL_DAMAGE
+	map_skill_damage_ers = ers_new(sizeof(struct s_skill_damage), "map.c:map_skill_damage_ers", ERS_OPT_NONE);
+#endif
+
 	map_sql_init();
 	if (log_config.sql_logs)
 		log_sql_init();

+ 17 - 9
src/map/map.h

@@ -589,16 +589,18 @@ struct iwall_data {
 };
 
 #ifdef ADJUST_SKILL_DAMAGE
+/// Struct of skill damage adjustment
 struct s_skill_damage {
-	uint16 map, skill_id;
-	/* additional rates */
-	int pc,
-		mob,
-		boss,
-		other;
-	uint8 caster;	/* caster type */
+	unsigned int map; ///< Maps (used for skill_damage_db.txt)
+	uint16 skill_id; ///< Skill ID (used for mapflag)
+	// Additional rates
+	int pc, ///< Rate to Player
+		mob, ///< Rate to Monster
+		boss, ///< Rate to Boss-Monster
+		other; ///< Rate to Other target
+	uint8 caster; ///< Caster type
 };
-#define MAX_MAP_SKILL_MODIFIER 5
+struct eri *map_skill_damage_ers;
 #endif
 
 struct questinfo {
@@ -703,7 +705,10 @@ struct map_data {
 #endif
 	} adjust;
 #ifdef ADJUST_SKILL_DAMAGE
-	struct s_skill_damage skill_damage[MAX_MAP_SKILL_MODIFIER];
+	struct {
+		struct s_skill_damage **entries;
+		uint8 count;
+	} skill_damage;
 #endif
 	// Instance Variables
 	int instance_id;
@@ -893,6 +898,9 @@ void do_reconnect_map(void); //Invoked on map-char reconnection [Skotlex]
 void map_addmap2db(struct map_data *m);
 void map_removemapdb(struct map_data *m);
 
+void map_skill_damage_free(struct map_data *m);
+void map_skill_damage_add(struct map_data *m, uint16 skill_id, int pc, int mob, int boss, int other, uint8 caster);
+
 #define CHK_ELEMENT(ele) ((ele) > ELE_NONE && (ele) < ELE_MAX) /// Check valid Element
 #define CHK_ELEMENT_LEVEL(lv) ((lv) >= 1 && (lv) <= MAX_ELE_LEVEL) /// Check valid element level
 #define CHK_RACE(race) ((race) > RC_NONE_ && (race) < RC_MAX) /// Check valid Race

+ 5 - 16
src/map/npc.c

@@ -3740,8 +3740,9 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
 		map[m].flag.skill_damage = state;	// Set the mapflag
 
 		if (!state) {
-			memset(map[m].skill_damage, 0, sizeof(map[m].skill_damage));
 			memset(&map[m].adjust.damage, 0, sizeof(map[m].adjust.damage));
+			if (map[m].skill_damage.count)
+				map_skill_damage_free(&map[m]);
 		}
 		else {
 			if (sscanf(w4, "%30[^,],%d,%d,%d,%d,%d[^\n]", skill, &caster, &pc, &mob, &boss, &other) >= 3) {
@@ -3751,7 +3752,7 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
 				boss = cap_value(boss, -100, INT_MAX);
 				other = cap_value(other, -100, INT_MAX);
 
-				if (strcmp(skill,"all") == 0) {	// Adjust damages for all skills
+				if (strcmp(skill,"all") == 0) { // Adjust damages for all skills
 					map[m].adjust.damage.caster = caster;
 					map[m].adjust.damage.pc = pc;
 					map[m].adjust.damage.mob = mob;
@@ -3760,20 +3761,8 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
 				}
 				else if (skill_name2id(skill) <= 0)
 					ShowWarning("npc_parse_mapflag: skill_damage: Invalid skill name '%s'. Skipping (file '%s', line '%d')\n", skill, filepath, strline(buffer,start-buffer));
-				else {	//damages for specified skill
-					uint8 i;
-					ARR_FIND(0, ARRAYLENGTH(map[m].skill_damage), i, map[m].skill_damage[i].skill_id <= 0);
-					if (i >= ARRAYLENGTH(map[m].skill_damage))
-						ShowWarning("npc_parse_mapflag: skill_damage: Skill damage for map '%s' is overflow.\n", map[m].name);
-					else {
-						map[m].skill_damage[i].skill_id = skill_name2id(skill);
-						map[m].skill_damage[i].caster = caster;
-						map[m].skill_damage[i].pc = pc;
-						map[m].skill_damage[i].mob = mob;
-						map[m].skill_damage[i].boss = boss;
-						map[m].skill_damage[i].other = other;
-					}
-				}
+				else //Damages for specified skill
+					map_skill_damage_add(&map[m], skill_name2id(skill), pc, mob, boss, other, caster);
 			}
 		}
 #else

+ 2 - 1
src/map/script.c

@@ -11631,8 +11631,9 @@ BUILDIN_FUNC(removemapflag)
 			case MF_SKILL_DAMAGE:
 				{
 					map[m].flag.skill_damage = 0;
-					memset(map[m].skill_damage, 0, sizeof(map[m].skill_damage));
 					memset(&map[m].adjust.damage, 0, sizeof(map[m].adjust.damage));
+					if (map[m].skill_damage.count)
+						map_skill_damage_free(&map[m]);
 				} break;
 #endif
 		}

+ 2 - 1
src/map/skill.c

@@ -20451,7 +20451,8 @@ static bool skill_parse_row_changematerialdb(char* split[], int columns, int cur
 }
 
 /**
- * Manage Skill Damage database [Lilith]
+ * Reads skill damage adjustment
+ * @author [Lilith]
  */
 #ifdef ADJUST_SKILL_DAMAGE
 static bool skill_parse_row_skilldamage(char* split[], int columns, int current)