From b372b02e9cc21ceeb42a428177d992998aed2eec Mon Sep 17 00:00:00 2001 From: Emistry Haoyan Date: Tue, 23 Jul 2019 22:24:57 +0800 Subject: Update mob_db - DamageTakenRate field - adjust the damage taken by monster. (default = `100 = 1x`) - ref: https://github.com/idathena/trunk/commit/e267d2e2dada6196b479a6f2f35e9d25291ef22b --- db/constants.conf | 47 ++++----- db/mob_db2.conf | 1 + db/pre-re/mob_db.conf | 1 + db/re/mob_db.conf | 1 + doc/script_commands.txt | 263 ++++++++++++++++++++++++------------------------ src/map/battle.c | 12 +++ src/map/mob.c | 7 ++ src/map/mob.h | 2 + src/map/script.c | 9 ++ src/map/script.h | 1 + src/map/skill.c | 12 +++ 11 files changed, 203 insertions(+), 153 deletions(-) diff --git a/db/constants.conf b/db/constants.conf index f1283b26e..1d6d295c0 100644 --- a/db/constants.conf +++ b/db/constants.conf @@ -1508,29 +1508,30 @@ constants_db: { } comment__: "getmonsterinfo" - MOB_NAME: 0 - MOB_LV: 1 - MOB_MAXHP: 2 - MOB_BASEEXP: 3 - MOB_JOBEXP: 4 - MOB_ATK1: 5 - MOB_ATK2: 6 - MOB_DEF: 7 - MOB_MDEF: 8 - MOB_STR: 9 - MOB_AGI: 10 - MOB_VIT: 11 - MOB_INT: 12 - MOB_DEX: 13 - MOB_LUK: 14 - MOB_RANGE: 15 - MOB_RANGE2: 16 - MOB_RANGE3: 17 - MOB_SIZE: 18 - MOB_RACE: 19 - MOB_ELEMENT: 20 - MOB_MODE: 21 - MOB_MVPEXP: 22 + MOB_NAME: 0 + MOB_LV: 1 + MOB_MAXHP: 2 + MOB_BASEEXP: 3 + MOB_JOBEXP: 4 + MOB_ATK1: 5 + MOB_ATK2: 6 + MOB_DEF: 7 + MOB_MDEF: 8 + MOB_STR: 9 + MOB_AGI: 10 + MOB_VIT: 11 + MOB_INT: 12 + MOB_DEX: 13 + MOB_LUK: 14 + MOB_RANGE: 15 + MOB_RANGE2: 16 + MOB_RANGE3: 17 + MOB_SIZE: 18 + MOB_RACE: 19 + MOB_ELEMENT: 20 + MOB_MODE: 21 + MOB_MVPEXP: 22 + MOB_DMG_TAKEN_RATE: 23 comment__: "mercenary guilds" ARCH_MERC_GUILD: 0 diff --git a/db/mob_db2.conf b/db/mob_db2.conf index e2894a719..bd8379030 100644 --- a/db/mob_db2.conf +++ b/db/mob_db2.conf @@ -93,6 +93,7 @@ mob_db: ( AegisName: (chance, "Option Drop Group") // ... } + DamageTakenRate: damage taken rate (int, defaults to 100) }, **************************************************************************/ diff --git a/db/pre-re/mob_db.conf b/db/pre-re/mob_db.conf index 553593cea..565167e95 100644 --- a/db/pre-re/mob_db.conf +++ b/db/pre-re/mob_db.conf @@ -93,6 +93,7 @@ mob_db: ( AegisName: (chance, "Option Drop Group") // ... } + DamageTakenRate: damage taken rate (int, defaults to 100) }, **************************************************************************/ diff --git a/db/re/mob_db.conf b/db/re/mob_db.conf index f787d5478..7ac31655c 100644 --- a/db/re/mob_db.conf +++ b/db/re/mob_db.conf @@ -93,6 +93,7 @@ mob_db: ( AegisName: (chance, "Option Drop Group") // ... } + DamageTakenRate: damage taken rate (int, defaults to 100) }, **************************************************************************/ diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 567d0ad56..bab4287c1 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -3969,29 +3969,30 @@ It will return -1 if there is no such monster (or the type value is invalid), or "null" if you requested the monster's name. Valid types are listed in doc/constants.md: - MOB_NAME 0 - MOB_LV 1 - MOB_MAXHP 2 - MOB_BASEEXP 3 - MOB_JOBEXP 4 - MOB_ATK1 5 - MOB_ATK2 6 - MOB_DEF 7 - MOB_MDEF 8 - MOB_STR 9 - MOB_AGI 10 - MOB_VIT 11 - MOB_INT 12 - MOB_DEX 13 - MOB_LUK 14 - MOB_RANGE 15 - MOB_RANGE2 16 - MOB_RANGE3 17 - MOB_SIZE 18 - MOB_RACE 19 - MOB_ELEMENT 20 - MOB_MODE 21 - MOB_MVPEXP 22 + MOB_NAME 0 + MOB_LV 1 + MOB_MAXHP 2 + MOB_BASEEXP 3 + MOB_JOBEXP 4 + MOB_ATK1 5 + MOB_ATK2 6 + MOB_DEF 7 + MOB_MDEF 8 + MOB_STR 9 + MOB_AGI 10 + MOB_VIT 11 + MOB_INT 12 + MOB_DEX 13 + MOB_LUK 14 + MOB_RANGE 15 + MOB_RANGE2 16 + MOB_RANGE3 17 + MOB_SIZE 18 + MOB_RACE 19 + MOB_ELEMENT 20 + MOB_MODE 21 + MOB_MVPEXP 22 + MOB_DMG_TAKEN_RATE 23 Check sample in doc/sample/getmonsterinfo.txt @@ -10240,60 +10241,61 @@ Sets or alters the data in real-time for game objects of the following types - NPCs, Pets, Monsters, Homunuculus', Mercenaries, Elementals. Applicable Data Types (available as constants) - - Data Types Description (parameter type) - UDT_SIZE: Unit Size - UDT_LEVEL: Level - UDT_HP: Current HP - UDT_MAXHP: Max HP - UDT_SP: SP - UDT_MAXSP: MAX SP - UDT_MASTERAID: Master Account ID (for Summons) - UDT_MASTERCID: Master Char ID (for Summons) - UDT_SPEED: Unit Speed. - UDT_MODE: Mode (Mobs only) - UDT_AI: Unit AI Type (see doc/constants.md for Unit AI Types) - UDT_SCOPTION: Status Options. (see doc/constants.md for Unit Option Types) - UDT_SEX: Gender of the unit. (see doc/constants.md for Genders) - UDT_CLASS: Class of the unit. (Monster ID) - UDT_HAIRSTYLE: Hair Style ID. - UDT_HAIRCOLOR: Hair Color ID. - UDT_HEADBOTTOM: Headgear Bottom Sprite ID. - UDT_HEADMIDDLE: Headgear Middle Sprite ID. - UDT_HEADTOP: Headgear Top Sprite ID. - UDT_CLOTHCOLOR: Cloth Color ID. - UDT_SHIELD: Shield Sprite ID. - UDT_WEAPON: Weapon Sprite ID. - UDT_LOOKDIR: Face direction. - UDT_CANMOVETICK: Stop a unit from move for n seconds. - UDT_STR: Unit STR. - UDT_AGI: Unit AGI. - UDT_VIT: Unit VIT. - UDT_INT: Unit INT. - UDT_DEX: Unit DEX. - UDT_LUK: Unit LUK. - UDT_ATKRANGE: Attack range of a unit. - UDT_ATKMIN: Min Atk of a unit. - UDT_ATKMAX: Max Atk of a unit. - UDT_MATKMIN: Min MATK of a unit. - UDT_MATKMAX: Max MATK of a unit. - UDT_DEF: DEF. - UDT_MDEF: MDEF. - UDT_HIT: HIT. - UDT_FLEE: FLEE. - UDT_PDODGE: Perfect Dodge. - UDT_CRIT: Critical Rate. - UDT_RACE: Race. (Eg. constants RC_DemiHuman or Integer 7). - UDT_ELETYPE: Element. (Eg. constants Ele_Neutral or Integer 0). - UDT_ELELEVEL: Element Level. - UDT_AMOTION: AMotion Rate. - UDT_ADELAY: ADelay Rate. - UDT_DMOTION: DMotion Rate. - UDT_HUNGER: Hunger Rate - for summons. - UDT_INTIMACY: Intimacy Rate - for summons. - UDT_LIFETIME: LifeTime - for summons. - UDT_MERC_KILLCOUNT: Kill count for mercenaries - UDT_STATADD: Status Points - for NPCs. - UDT_GROUP: group id + Data Types Description (parameter type) + UDT_SIZE: Unit Size + UDT_LEVEL: Level + UDT_HP: Current HP + UDT_MAXHP: Max HP + UDT_SP: SP + UDT_MAXSP: MAX SP + UDT_MASTERAID: Master Account ID (for Summons) + UDT_MASTERCID: Master Char ID (for Summons) + UDT_SPEED: Unit Speed. + UDT_MODE: Mode (Mobs only) + UDT_AI: Unit AI Type (see doc/constants.md for Unit AI Types) + UDT_SCOPTION: Status Options. (see doc/constants.md for Unit Option Types) + UDT_SEX: Gender of the unit. (see doc/constants.md for Genders) + UDT_CLASS: Class of the unit. (Monster ID) + UDT_HAIRSTYLE: Hair Style ID. + UDT_HAIRCOLOR: Hair Color ID. + UDT_HEADBOTTOM: Headgear Bottom Sprite ID. + UDT_HEADMIDDLE: Headgear Middle Sprite ID. + UDT_HEADTOP: Headgear Top Sprite ID. + UDT_CLOTHCOLOR: Cloth Color ID. + UDT_SHIELD: Shield Sprite ID. + UDT_WEAPON: Weapon Sprite ID. + UDT_LOOKDIR: Face direction. + UDT_CANMOVETICK: Stop a unit from move for n seconds. + UDT_STR: Unit STR. + UDT_AGI: Unit AGI. + UDT_VIT: Unit VIT. + UDT_INT: Unit INT. + UDT_DEX: Unit DEX. + UDT_LUK: Unit LUK. + UDT_ATKRANGE: Attack range of a unit. + UDT_ATKMIN: Min Atk of a unit. + UDT_ATKMAX: Max Atk of a unit. + UDT_MATKMIN: Min MATK of a unit. + UDT_MATKMAX: Max MATK of a unit. + UDT_DEF: DEF. + UDT_MDEF: MDEF. + UDT_HIT: HIT. + UDT_FLEE: FLEE. + UDT_PDODGE: Perfect Dodge. + UDT_CRIT: Critical Rate. + UDT_RACE: Race. (Eg. constants RC_DemiHuman or Integer 7). + UDT_ELETYPE: Element. (Eg. constants Ele_Neutral or Integer 0). + UDT_ELELEVEL: Element Level. + UDT_AMOTION: AMotion Rate. + UDT_ADELAY: ADelay Rate. + UDT_DMOTION: DMotion Rate. + UDT_HUNGER: Hunger Rate - for summons. + UDT_INTIMACY: Intimacy Rate - for summons. + UDT_LIFETIME: LifeTime - for summons. + UDT_MERC_KILLCOUNT: Kill count for mercenaries + UDT_STATADD: Status Points - for NPCs. + UDT_GROUP: group id + UDT_DAMAGE_TAKEN_RATE: damage taken rate of a unit. returns 0 if value could not be set, 1 if successful. @@ -10304,59 +10306,60 @@ returns 0 if value could not be set, 1 if successful. Retrieves real-time data of a game object. Applicable Data types (available as constants) - - Data Types Description (return type) - UDT_SIZE: Unit Size - UDT_LEVEL: Level - UDT_HP: Current HP - UDT_MAXHP: Max HP - UDT_SP: SP - UDT_MAXSP: MAX SP - UDT_MASTERAID: Master Account ID (for Summons) - UDT_MASTERCID: Master Char ID (for Summons) - UDT_SPEED: Unit Speed. - UDT_MODE: Mode (Mobs only) - UDT_AI: Unit AI Type (see doc/constants.md for Unit AI Types) - UDT_SCOPTION: Status Options. (see doc/constants.md for Unit Option Types) - UDT_SEX: Gender of the unit. (see doc/constants.md for Genders) - UDT_CLASS: Class of the unit. (Monster ID) - UDT_HAIRSTYLE: Hair Style ID. - UDT_HAIRCOLOR: Hair Color ID. - UDT_HEADBOTTOM: Headgear Bottom Sprite ID. - UDT_HEADMIDDLE: Headgear Middle Sprite ID. - UDT_HEADTOP: Headgear Top Sprite ID. - UDT_CLOTHCOLOR: Cloth Color ID. - UDT_SHIELD: Shield Sprite ID. - UDT_WEAPON: Weapon Sprite ID. - UDT_LOOKDIR: Face direction. - UDT_CANMOVETICK: Stop a unit from move for n seconds. - UDT_STR: Unit STR. - UDT_AGI: Unit AGI. - UDT_VIT: Unit VIT. - UDT_INT: Unit INT. - UDT_DEX: Unit DEX. - UDT_LUK: Unit LUK. - UDT_ATKRANGE: Attack range of a unit. - UDT_ATKMIN: Min Atk of a unit. - UDT_ATKMAX: Max Atk of a unit. - UDT_MATKMIN: Min MATK of a unit. - UDT_MATKMAX: Max MATK of a unit. - UDT_DEF: DEF. - UDT_MDEF: MDEF. - UDT_HIT: HIT. - UDT_FLEE: FLEE. - UDT_PDODGE: Perfect Dodge. - UDT_CRIT: Critical Rate. - UDT_RACE: Race. (Eg. constants RC_DemiHuman or Integer 7). - UDT_ELETYPE: Element. (Eg. constants Ele_Neutral or Integer 0). - UDT_ELELEVEL: Element Level. - UDT_AMOTION: AMotion Rate. - UDT_ADELAY: ADelay Rate. - UDT_DMOTION: DMotion Rate. - UDT_HUNGER: Hunger Rate - for summons. - UDT_INTIMACY: Intimacy Rate - for summons. - UDT_LIFETIME: LifeTime - for summons. - UDT_MERC_KILLCOUNT: Kill count for mercenaries. - UDT_GROUP: group id + Data Types Description (return type) + UDT_SIZE: Unit Size + UDT_LEVEL: Level + UDT_HP: Current HP + UDT_MAXHP: Max HP + UDT_SP: SP + UDT_MAXSP: MAX SP + UDT_MASTERAID: Master Account ID (for Summons) + UDT_MASTERCID: Master Char ID (for Summons) + UDT_SPEED: Unit Speed. + UDT_MODE: Mode (Mobs only) + UDT_AI: Unit AI Type (see doc/constants.md for Unit AI Types) + UDT_SCOPTION: Status Options. (see doc/constants.md for Unit Option Types) + UDT_SEX: Gender of the unit. (see doc/constants.md for Genders) + UDT_CLASS: Class of the unit. (Monster ID) + UDT_HAIRSTYLE: Hair Style ID. + UDT_HAIRCOLOR: Hair Color ID. + UDT_HEADBOTTOM: Headgear Bottom Sprite ID. + UDT_HEADMIDDLE: Headgear Middle Sprite ID. + UDT_HEADTOP: Headgear Top Sprite ID. + UDT_CLOTHCOLOR: Cloth Color ID. + UDT_SHIELD: Shield Sprite ID. + UDT_WEAPON: Weapon Sprite ID. + UDT_LOOKDIR: Face direction. + UDT_CANMOVETICK: Stop a unit from move for n seconds. + UDT_STR: Unit STR. + UDT_AGI: Unit AGI. + UDT_VIT: Unit VIT. + UDT_INT: Unit INT. + UDT_DEX: Unit DEX. + UDT_LUK: Unit LUK. + UDT_ATKRANGE: Attack range of a unit. + UDT_ATKMIN: Min Atk of a unit. + UDT_ATKMAX: Max Atk of a unit. + UDT_MATKMIN: Min MATK of a unit. + UDT_MATKMAX: Max MATK of a unit. + UDT_DEF: DEF. + UDT_MDEF: MDEF. + UDT_HIT: HIT. + UDT_FLEE: FLEE. + UDT_PDODGE: Perfect Dodge. + UDT_CRIT: Critical Rate. + UDT_RACE: Race. (Eg. constants RC_DemiHuman or Integer 7). + UDT_ELETYPE: Element. (Eg. constants Ele_Neutral or Integer 0). + UDT_ELELEVEL: Element Level. + UDT_AMOTION: AMotion Rate. + UDT_ADELAY: ADelay Rate. + UDT_DMOTION: DMotion Rate. + UDT_HUNGER: Hunger Rate - for summons. + UDT_INTIMACY: Intimacy Rate - for summons. + UDT_LIFETIME: LifeTime - for summons. + UDT_MERC_KILLCOUNT: Kill count for mercenaries. + UDT_GROUP: group id + UDT_DAMAGE_TAKEN_RATE: damage taken rate of a unit. returns -1 if value could not be retrieved. diff --git a/src/map/battle.c b/src/map/battle.c index c40c3afac..75ce2b894 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -6321,6 +6321,18 @@ static enum damage_lv battle_weapon_attack(struct block_list *src, struct block_ if (sd && sd->state.arrow_atk) //Consume arrow. battle->consume_ammo(sd, 0, 0); + if (target->type == BL_MOB) { + struct mob_data *md = BL_CAST(BL_MOB, target); + if (md != NULL) { + if (md->db->dmg_taken_rate != 100) { + if (wd.damage > 0) + wd.damage = apply_percentrate64(wd.damage, md->db->dmg_taken_rate, 100); + if (wd.damage2 > 0) + wd.damage2 = apply_percentrate64(wd.damage2, md->db->dmg_taken_rate, 100); + } + } + } + damage = wd.damage + wd.damage2; if( damage > 0 && src != target ) { if( sc && sc->data[SC_DUPLELIGHT] && (wd.flag&BF_SHORT) && rnd()%100 <= 10+2*sc->data[SC_DUPLELIGHT]->val1 ){ diff --git a/src/map/mob.c b/src/map/mob.c index 8511f8523..73f739264 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -4604,6 +4604,7 @@ static int mob_read_db_sub(struct config_setting_t *mobt, int n, const char *sou * AttackMotion: attack motion * DamageMotion: damage motion * MvpExp: mvp experience + * DamageTakenRate: damage taken rate * MvpDrops: { * AegisName: chance * ... @@ -4837,6 +4838,12 @@ static int mob_read_db_sub(struct config_setting_t *mobt, int n, const char *sou } } + if (mob->lookup_const(mobt, "DamageTakenRate", &i32) && i32 >= 0) { + md.dmg_taken_rate = cap_value(i32, 1, INT_MAX); + } else if (!inherit) { + md.dmg_taken_rate = 100; + } + mob->read_db_additional_fields(&md, mobt, n, source); return mob->db_validate_entry(&md, n, source); diff --git a/src/map/mob.h b/src/map/mob.h index b63efd272..a86215470 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -206,6 +206,7 @@ struct mob_db { unsigned int option; int summonper[MAX_RANDOMMONSTER]; int maxskill; + int dmg_taken_rate; struct mob_skill skill[MAX_MOBSKILL]; struct spawn_info spawn[10]; struct hplugin_data_store *hdata; ///< HPM Plugin Data Store @@ -244,6 +245,7 @@ struct mob_data { unsigned int dmg; unsigned int flag : 2; //0: Normal. 1: Homunc exp. 2: Pet exp } dmglog[DAMAGELOG_SIZE]; + int dmg_taken_rate; struct spawn_data *spawn; //Spawn data. int spawn_timer; //Required for Convex Mirror struct item *lootitem; diff --git a/src/map/script.c b/src/map/script.c index c1e210d27..8c1d69794 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -18580,6 +18580,7 @@ static BUILDIN(getmonsterinfo) case 20: script_pushint(st,monster->status.def_ele); break; case 21: script_pushint(st,monster->status.mode); break; case 22: script_pushint(st,monster->mexp); break; + case 23: script_pushint(st, monster->dmg_taken_rate); break; default: script_pushint(st,-1); //wrong Index } return true; @@ -19137,6 +19138,9 @@ static BUILDIN(setunitdata) script_pushint(st, 1); return true; } + case UDT_DAMAGE_TAKEN_RATE: + setunitdata_check_bounds(4, 1, INT_MAX); + break; default: break; } @@ -19311,6 +19315,9 @@ static BUILDIN(setunitdata) case UDT_DMOTION: md->status.dmotion = (unsigned short) val; break; + case UDT_DAMAGE_TAKEN_RATE: + md->dmg_taken_rate = (int) val; + break; default: ShowWarning("buildin_setunitdata: Invalid data type '%s' for mob unit.\n", udtype); script_pushint(st, 0); @@ -20158,6 +20165,7 @@ static BUILDIN(getunitdata) case UDT_AMOTION: script_pushint(st, md->status.amotion); break; case UDT_ADELAY: script_pushint(st, md->status.adelay); break; case UDT_DMOTION: script_pushint(st, md->status.dmotion); break; + case UDT_DAMAGE_TAKEN_RATE: script_pushint(st, md->dmg_taken_rate); break; default: ShowWarning("buildin_getunitdata: Invalid data type '%s' for Mob unit.\n", udtype); script_pushint(st, -1); @@ -26890,6 +26898,7 @@ static void script_hardcoded_constants(void) script->set_constant("UDT_ROBE", UDT_ROBE, false, false); script->set_constant("UDT_BODY2", UDT_BODY2, false, false); script->set_constant("UDT_GROUP", UDT_GROUP, false, false); + script->set_constant("UDT_DAMAGE_TAKEN_RATE", UDT_DAMAGE_TAKEN_RATE, false, false); script->constdb_comment("getguildonline types"); script->set_constant("GUILD_ONLINE_ALL", GUILD_ONLINE_ALL, false, false); diff --git a/src/map/script.h b/src/map/script.h index 62950ba8d..84a8e3b6e 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -434,6 +434,7 @@ enum script_unit_data_types { UDT_ROBE, UDT_BODY2, UDT_GROUP, + UDT_DAMAGE_TAKEN_RATE, UDT_MAX }; diff --git a/src/map/skill.c b/src/map/skill.c index a259829ef..af61c887c 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -2906,6 +2906,18 @@ static int skill_attack(int attack_type, struct block_list *src, struct block_li } } + if (bl->type == BL_MOB) { + struct mob_data *md = BL_CAST(BL_MOB, bl); + if (md != NULL) { + if (md->db->dmg_taken_rate != 100) { + if (dmg.damage > 0) + dmg.damage = apply_percentrate64(dmg.damage, md->db->dmg_taken_rate, 100); + if (dmg.damage2 > 0) + dmg.damage2 = apply_percentrate64(dmg.damage2, md->db->dmg_taken_rate, 100); + } + } + } + damage = dmg.damage + dmg.damage2; if( (skill_id == AL_INCAGI || skill_id == AL_BLESSING || -- cgit v1.2.3-70-g09d2