diff --git a/src/config/core.h b/src/config/core.h index a000977ae9..04033cadb5 100644 --- a/src/config/core.h +++ b/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 diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 62d2368ae7..a366c00b4d 100644 --- a/src/map/atcommand.c +++ b/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); } } } diff --git a/src/map/battle.c b/src/map/battle.c index 12afb3e605..e950b57a26 100644 --- a/src/map/battle.c +++ b/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; - if (!map[m].flag.skill_damage) + mapd = &map[src->m]; + + 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; diff --git a/src/map/map.c b/src/map/map.c index ae6f1223bc..8fb8b6701d 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -112,6 +112,10 @@ int agit_flag = 0; int agit2_flag = 0; int night_flag = 0; // 0=day, 1=night [Yor] +#ifdef ADJUST_SKILL_DAMAGE +struct eri *map_skill_damage_ers = NULL; +#endif + struct charid_request { struct charid_request* next; int charid;// who want to be notified of the nick @@ -3227,8 +3231,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 +3921,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 +4065,10 @@ void do_final(void) for (j=0; jdestroy(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 +4327,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(); diff --git a/src/map/map.h b/src/map/map.h index 10906d083f..e11b31bb9c 100644 --- a/src/map/map.h +++ b/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,11 @@ 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); +#ifdef ADJUST_SKILL_DAMAGE +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); +#endif + #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 diff --git a/src/map/npc.c b/src/map/npc.c index 00ff00d211..1a3c894c2e 100644 --- a/src/map/npc.c +++ b/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 diff --git a/src/map/script.c b/src/map/script.c index 2b633015b5..c618dfa6b1 100644 --- a/src/map/script.c +++ b/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 } diff --git a/src/map/skill.c b/src/map/skill.c index af7bc27d8c..edcd8e0425 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -20450,10 +20450,11 @@ static bool skill_parse_row_changematerialdb(char* split[], int columns, int cur return true; } -/** - * Manage Skill Damage database [Lilith] - */ #ifdef ADJUST_SKILL_DAMAGE +/** + * Reads skill damage adjustment + * @author [Lilith] + */ static bool skill_parse_row_skilldamage(char* split[], int columns, int current) { uint16 skill_id = skill_name2id(split[0]), idx;