From 6fccf18b6112475d00c3abc63804043df8cb4df6 Mon Sep 17 00:00:00 2001 From: Dastgir Date: Mon, 11 Jan 2016 19:37:02 +0530 Subject: Added NoKnockback Mode for monsters Signed-off-by: Haru --- db/mob_db2.conf | 1 + db/pre-re/mob_db.conf | 1 + db/re/mob_db.conf | 1 + doc/mob_db_mode_list.txt | 35 +++++++++++++++++++---------------- src/map/mob.c | 3 +++ src/map/skill.c | 2 +- src/map/status.h | 1 + 7 files changed, 27 insertions(+), 17 deletions(-) diff --git a/db/mob_db2.conf b/db/mob_db2.conf index e1084cff2..f7b8bd9af 100644 --- a/db/mob_db2.conf +++ b/db/mob_db2.conf @@ -76,6 +76,7 @@ mob_db: ( ChangeTargetMelee: true/false (bool, defaults to false) ChangeTargetChase: true/false (bool, defaults to false) TargetWeak: true/false (bool, defaults to false) + NoKnockback: true/false (bool, defaults to false) } MoveSpeed: move speed (int, defaults to 0) AttackDelay: attack delay (int, defaults to 4000) diff --git a/db/pre-re/mob_db.conf b/db/pre-re/mob_db.conf index baf88d52c..7d3da3f6d 100644 --- a/db/pre-re/mob_db.conf +++ b/db/pre-re/mob_db.conf @@ -76,6 +76,7 @@ mob_db: ( ChangeTargetMelee: true/false (bool, defaults to false) ChangeTargetChase: true/false (bool, defaults to false) TargetWeak: true/false (bool, defaults to false) + NoKnockback: true/false (bool, defaults to false) } MoveSpeed: move speed (int, defaults to 0) AttackDelay: attack delay (int, defaults to 4000) diff --git a/db/re/mob_db.conf b/db/re/mob_db.conf index d4e4f4357..41dd8a35b 100644 --- a/db/re/mob_db.conf +++ b/db/re/mob_db.conf @@ -76,6 +76,7 @@ mob_db: ( ChangeTargetMelee: true/false (bool, defaults to false) ChangeTargetChase: true/false (bool, defaults to false) TargetWeak: true/false (bool, defaults to false) + NoKnockback: true/false (bool, defaults to false) } MoveSpeed: move speed (int, defaults to 0) AttackDelay: attack delay (int, defaults to 4000) diff --git a/doc/mob_db_mode_list.txt b/doc/mob_db_mode_list.txt index 08abf800d..32e7a0e8d 100644 --- a/doc/mob_db_mode_list.txt +++ b/doc/mob_db_mode_list.txt @@ -11,22 +11,23 @@ Bit Legend: ------------------------------------------------------------------------------- -MD_CANMOVE | 0x0001 | 1 -MD_LOOTER | 0x0002 | 2 -MD_AGGRESSIVE | 0x0004 | 4 -MD_ASSIST | 0x0008 | 8 -MD_CASTSENSOR_IDLE | 0x0010 | 16 -MD_BOSS | 0x0020 | 32 -MD_PLANT | 0x0040 | 64 -MD_CANATTACK | 0x0080 | 128 -MD_DETECTOR | 0x0100 | 256 -MD_CASTSENSOR_CHASE | 0x0200 | 512 -MD_CHANGECHASE | 0x0400 | 1024 -MD_ANGRY | 0x0800 | 2048 -MD_CHANGETARGET_MELEE | 0x1000 | 4096 -MD_CHANGETARGET_CHASE | 0x2000 | 8192 -MD_TARGETWEAK | 0x4000 | 16384 -MD_RANDOMTARGET | 0x8000 | 32768 (not implemented) +MD_CANMOVE | 0x00001 | 1 +MD_LOOTER | 0x00002 | 2 +MD_AGGRESSIVE | 0x00004 | 4 +MD_ASSIST | 0x00008 | 8 +MD_CASTSENSOR_IDLE | 0x00010 | 16 +MD_BOSS | 0x00020 | 32 +MD_PLANT | 0x00040 | 64 +MD_CANATTACK | 0x00080 | 128 +MD_DETECTOR | 0x00100 | 256 +MD_CASTSENSOR_CHASE | 0x00200 | 512 +MD_CHANGECHASE | 0x00400 | 1024 +MD_ANGRY | 0x00800 | 2048 +MD_CHANGETARGET_MELEE | 0x01000 | 4096 +MD_CHANGETARGET_CHASE | 0x02000 | 8192 +MD_TARGETWEAK | 0x04000 | 16384 +MD_NOKNOCKBACK | 0x08000 | 32768 +MD_RANDOMTARGET | 0x10000 | 65536 (not implemented) Explanation for modes: ------------------------------------------------------------------------------- @@ -74,6 +75,8 @@ Target Weak: Allows aggressive monsters to only be aggressive against characters that are five levels below it's own level. For example, a monster of level 104 will not pick fights with a level 99. +NoKnockback: Monsters will be immune to Knockback's. + Random Target: Picks a new random target in range on each attack / skill. (not implemented) diff --git a/src/map/mob.c b/src/map/mob.c index 063a1ff6e..e26006599 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -3760,6 +3760,8 @@ int mob_read_db_mode_sub(struct mob_db *entry, struct config_setting_t *t) mode |= libconfig->setting_get_bool(t2) ? MD_CHANGETARGET_CHASE : 0; if ((t2 = libconfig->setting_get_member(t, "TargetWeak"))) mode |= libconfig->setting_get_bool(t2) ? MD_TARGETWEAK : 0; + if ((t2 = libconfig->setting_get_member(t, "NoKnockback"))) + mode |= libconfig->setting_get_bool(t2) ? MD_NOKNOCKBACK : 0; return mode; } @@ -4109,6 +4111,7 @@ int mob_read_db_sub(struct config_setting_t *mobt, int n, const char *source) * ChangeTargetMelee: true/false * ChangeTargetChase: true/false * TargetWeak: true/false + * NoKnockback: true/false * } * MoveSpeed: move speed * AttackDelay: attack delay diff --git a/src/map/skill.c b/src/map/skill.c index 366d66234..fb08103e7 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -2089,7 +2089,7 @@ int skill_blown(struct block_list* src, struct block_list* target, int count, in case BL_MOB: { const struct mob_data *md = BL_UCCAST(BL_MOB, target); - if (md->class_ == MOBID_EMPELIUM) + if (md->status.mode&MD_NOKNOCKBACK) return 0; if (src != target && is_boss(target)) // Bosses can't be knocked-back return 0; diff --git a/src/map/status.h b/src/map/status.h index 85219b280..14cda8545 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -1823,6 +1823,7 @@ enum e_mode MD_CHANGETARGET_MELEE = 0x1000, MD_CHANGETARGET_CHASE = 0x2000, MD_TARGETWEAK = 0x4000, + MD_NOKNOCKBACK = 0x8000, MD_MASK = 0xFFFF, }; -- cgit v1.2.3-70-g09d2 From 38df89621f9e5b4196a91f8361b4493247f41bd3 Mon Sep 17 00:00:00 2001 From: Dastgir Date: Mon, 11 Jan 2016 19:41:47 +0530 Subject: Added monsters with NoKnockback --- db/pre-re/mob_db.conf | 1 + db/re/mob_db.conf | 1 + 2 files changed, 2 insertions(+) diff --git a/db/pre-re/mob_db.conf b/db/pre-re/mob_db.conf index 7d3da3f6d..8e5e93465 100644 --- a/db/pre-re/mob_db.conf +++ b/db/pre-re/mob_db.conf @@ -14109,6 +14109,7 @@ mob_db: ( Mode: { Boss: true Detector: true + NoKnockback: true } MoveSpeed: 300 AttackDelay: 1288 diff --git a/db/re/mob_db.conf b/db/re/mob_db.conf index 41dd8a35b..190f590bb 100644 --- a/db/re/mob_db.conf +++ b/db/re/mob_db.conf @@ -14064,6 +14064,7 @@ mob_db: ( Boss: true Plant: true Detector: true + NoKnockback: true } MoveSpeed: 300 AttackDelay: 1288 -- cgit v1.2.3-70-g09d2 From 905b59d85b790ea57198c47e249690094b296bda Mon Sep 17 00:00:00 2001 From: Haru Date: Sun, 28 Feb 2016 22:18:29 +0100 Subject: Changed mob mode field to 32 bit, for future expansion Signed-off-by: Haru --- src/char/int_elemental.c | 4 +-- src/common/mmo.h | 2 +- src/map/atcommand.c | 2 +- src/map/elemental.c | 35 ++++++++++++++------- src/map/elemental.h | 2 +- src/map/mob.c | 82 ++++++++++++++++++++++++++---------------------- src/map/mob.h | 6 ++-- src/map/pc.c | 17 +++++++--- src/map/pc.h | 2 +- src/map/script.c | 7 +++-- src/map/skill.c | 4 +-- src/map/status.c | 58 ++++++++++++++++++++-------------- src/map/status.h | 49 ++++++++++++++++------------- src/plugins/db2sql.c | 2 +- 14 files changed, 158 insertions(+), 114 deletions(-) diff --git a/src/char/int_elemental.c b/src/char/int_elemental.c index d4b8dfea6..c25cfa5c8 100644 --- a/src/char/int_elemental.c +++ b/src/char/int_elemental.c @@ -57,7 +57,7 @@ bool mapif_elemental_create(struct s_elemental *ele) if (SQL_ERROR == SQL->Query(inter->sql_handle, "INSERT INTO `%s` (`char_id`,`class`,`mode`,`hp`,`sp`,`max_hp`,`max_sp`,`atk1`,`atk2`,`matk`,`aspd`,`def`,`mdef`,`flee`,`hit`,`life_time`)" - "VALUES ('%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d')", + "VALUES ('%d','%d','%u','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d')", elemental_db, ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->atk, ele->atk2, ele->matk, ele->amotion, ele->def, ele->mdef, ele->flee, ele->hit, ele->life_time)) { Sql_ShowDebug(inter->sql_handle); @@ -79,7 +79,7 @@ bool mapif_elemental_save(const struct s_elemental *ele) Assert_retr(false, ele->elemental_id > 0); if (SQL_ERROR == SQL->Query(inter->sql_handle, - "UPDATE `%s` SET `char_id` = '%d', `class` = '%d', `mode` = '%d', `hp` = '%d', `sp` = '%d'," + "UPDATE `%s` SET `char_id` = '%d', `class` = '%d', `mode` = '%u', `hp` = '%d', `sp` = '%d'," "`max_hp` = '%d', `max_sp` = '%d', `atk1` = '%d', `atk2` = '%d', `matk` = '%d', `aspd` = '%d', `def` = '%d'," "`mdef` = '%d', `flee` = '%d', `hit` = '%d', `life_time` = '%d' WHERE `ele_id` = '%d'", elemental_db, ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->atk, ele->atk2, diff --git a/src/common/mmo.h b/src/common/mmo.h index 91eccb8cd..77b9abab6 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -475,7 +475,7 @@ struct s_elemental { int elemental_id; int char_id; short class_; - int mode; + uint32 mode; int hp, sp, max_hp, max_sp, matk, atk, atk2; short hit, flee, amotion, def, mdef; int life_time; diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 839fb6ce0..14eab56e0 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -7919,7 +7919,7 @@ ACMD(clone) { y = sd->bl.y; } - if ((x = mob->clone_spawn(pl_sd, sd->bl.m, x, y, "", master, 0, flag?1:0, 0)) > 0) { + if ((x = mob->clone_spawn(pl_sd, sd->bl.m, x, y, "", master, MD_NONE, flag?1:0, 0)) > 0) { clif->message(fd, msg_fd(fd,128+flag*2)); // Evil Clone spawned. Clone spawned. Slave clone spawned. return true; } diff --git a/src/map/elemental.c b/src/map/elemental.c index 0eed4e799..b6297c2cf 100644 --- a/src/map/elemental.c +++ b/src/map/elemental.c @@ -545,28 +545,38 @@ int elemental_change_mode_ack(struct elemental_data *ed, int mode) { return 1; } -/*=============================================================== - * Change elemental mode. - *-------------------------------------------------------------*/ -int elemental_change_mode(struct elemental_data *ed, int mode) { +/** + * Changes elemental mode. + * + * @param ed The elemental data. + * @param mode The new mode. + * @retval 1 in case of success. + */ +int elemental_change_mode(struct elemental_data *ed, uint32 mode) +{ + int skillmode = EL_SKILLMODE_PASIVE; nullpo_ret(ed); // Remove target elemental->unlocktarget(ed); // Removes the effects of the previous mode. - if(ed->elemental.mode != mode ) elemental->clean_effect(ed); + if (ed->elemental.mode != mode) + elemental->clean_effect(ed); ed->battle_status.mode = ed->elemental.mode = mode; // Normalize elemental mode to elemental skill mode. - if( mode == EL_MODE_AGGRESSIVE ) mode = EL_SKILLMODE_AGGRESSIVE; // Aggressive spirit mode -> Aggressive spirit skill. - else if( mode == EL_MODE_ASSIST ) mode = EL_SKILLMODE_ASSIST; // Assist spirit mode -> Assist spirit skill. - else mode = EL_SKILLMODE_PASIVE; // Passive spirit mode -> Passive spirit skill. + if (mode == EL_MODE_AGGRESSIVE) + skillmode = EL_SKILLMODE_AGGRESSIVE; // Aggressive spirit mode -> Aggressive spirit skill. + else if (mode == EL_MODE_ASSIST) + skillmode = EL_SKILLMODE_ASSIST; // Assist spirit mode -> Assist spirit skill. + else + skillmode = EL_SKILLMODE_PASIVE; // Passive spirit mode -> Passive spirit skill. // Use a skill immediately after every change mode. - if( mode != EL_SKILLMODE_AGGRESSIVE ) - elemental->change_mode_ack(ed,mode); + if (skillmode != EL_SKILLMODE_AGGRESSIVE) + elemental->change_mode_ack(ed, skillmode); return 1; } @@ -681,7 +691,8 @@ int elemental_ai_sub_timer_activesearch(struct block_list *bl, va_list ap) { int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *sd, int64 tick) { struct block_list *target = NULL; - int master_dist, view_range, mode; + int master_dist, view_range; + uint32 mode; nullpo_ret(ed); nullpo_ret(sd); @@ -760,7 +771,7 @@ int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *s return 0; } - if( mode == EL_MODE_AGGRESSIVE ) { + if (mode == EL_MODE_AGGRESSIVE) { target = map->id2bl(ed->ud.target); if( !target ) diff --git a/src/map/elemental.h b/src/map/elemental.h index 8a9bf9414..cdd83fd21 100644 --- a/src/map/elemental.h +++ b/src/map/elemental.h @@ -126,7 +126,7 @@ struct elemental_interface { int (*save) (struct elemental_data *ed); int (*change_mode_ack) (struct elemental_data *ed, int mode); - int (*change_mode) (struct elemental_data *ed, int mode); + int (*change_mode) (struct elemental_data *ed, uint32 mode); void (*heal) (struct elemental_data *ed, int hp, int sp); int (*dead) (struct elemental_data *ed); diff --git a/src/map/mob.c b/src/map/mob.c index e26006599..8d38fead7 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -842,7 +842,8 @@ int mob_delayspawn(int tid, int64 tick, int id, intptr_t data) { *------------------------------------------*/ int mob_setdelayspawn(struct mob_data *md) { - unsigned int spawntime, mode; + unsigned int spawntime; + uint32 mode; struct mob_db *db; if (!md->spawn) //Doesn't has respawn data! @@ -989,7 +990,7 @@ int mob_spawn (struct mob_data *md) /*========================================== * Determines if the mob can change target. [Skotlex] *------------------------------------------*/ -int mob_can_changetarget(struct mob_data* md, struct block_list* target, int mode) +int mob_can_changetarget(const struct mob_data *md, const struct block_list *target, uint32 mode) { // if the monster was provoked ignore the above rule [celest] if(md->state.provoke_flag) @@ -1006,7 +1007,7 @@ int mob_can_changetarget(struct mob_data* md, struct block_list* target, int mod return 0; return (battle_config.mob_ai&0x4 || check_distance_bl(&md->bl, target, 3)); case MSS_RUSH: - return (mode&MD_CHANGETARGET_CHASE); + return (mode&MD_CHANGETARGET_CHASE) ? 1 : 0; case MSS_FOLLOW: case MSS_ANGRY: case MSS_IDLE: @@ -1045,17 +1046,17 @@ int mob_target(struct mob_data *md,struct block_list *bl,int dist) /*========================================== * The ?? routine of an active monster *------------------------------------------*/ -int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap) +int mob_ai_sub_hard_activesearch(struct block_list *bl, va_list ap) { struct mob_data *md; struct block_list **target; - int mode; + uint32 mode; int dist; nullpo_ret(bl); md=va_arg(ap,struct mob_data *); target= va_arg(ap,struct block_list**); - mode= va_arg(ap,int); + mode = va_arg(ap, uint32); //If can't seek yet, not an enemy, or you can't attack it, skip. if (md->bl.id == bl->id || (*target) == bl || !status->check_skilluse(&md->bl, bl, 0, 0)) @@ -1401,7 +1402,7 @@ int mob_warpchase(struct mob_data *md, struct block_list *target) *------------------------------------------*/ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) { struct block_list *tbl = NULL, *abl = NULL; - int mode; + uint32 mode; int view_range, can_move; if(md->bl.prev == NULL || md->status.hp <= 0) @@ -1542,7 +1543,7 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) { } if ((!tbl && mode&MD_AGGRESSIVE) || md->state.skillstate == MSS_FOLLOW) { - map->foreachinrange (mob->ai_sub_hard_activesearch, &md->bl, view_range, DEFAULT_ENEMY_TYPE(md), md, &tbl, mode); + map->foreachinrange(mob->ai_sub_hard_activesearch, &md->bl, view_range, DEFAULT_ENEMY_TYPE(md), md, &tbl, mode); } else if ((mode&MD_CHANGECHASE && (md->state.skillstate == MSS_RUSH || md->state.skillstate == MSS_FOLLOW)) || (md->sc.count && md->sc.data[SC__CHAOS])) { int search_size; search_size = view_rangestatus.rhw.range ? view_range:md->status.rhw.range; @@ -3369,7 +3370,8 @@ int mob_is_clone(int class_) //If mode is not passed, a default aggressive mode is used. //If master_id is passed, clone is attached to him. //Returns: ID of newly crafted copy. -int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, const char *event, int master_id, int mode, int flag, unsigned int duration) { +int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, const char *event, int master_id, uint32 mode, int flag, unsigned int duration) +{ int class_; int i,j,h,inf, fd; struct mob_data *md; @@ -3399,7 +3401,7 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons mstatus->lhw.atk2= mstatus->dex + mstatus->lhw.atk + mstatus->lhw.atk2; //Max ATK mstatus->lhw.atk = mstatus->dex; //Min ATK } - if (mode) //User provided mode. + if (mode != MD_NONE) //User provided mode. mstatus->mode = mode; else if (flag&1) //Friendly Character, remove looting. mstatus->mode &= ~MD_LOOTER; @@ -3725,45 +3727,45 @@ void mob_read_db_stats_sub(struct mob_db *entry, struct config_setting_t *t) * * @return The parsed mode. */ -int mob_read_db_mode_sub(struct mob_db *entry, struct config_setting_t *t) +uint32 mob_read_db_mode_sub(struct mob_db *entry, struct config_setting_t *t) { - int mode = 0; + uint32 mode = 0; struct config_setting_t *t2; if ((t2 = libconfig->setting_get_member(t, "CanMove"))) - mode |= libconfig->setting_get_bool(t2) ? MD_CANMOVE : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_CANMOVE : MD_NONE; if ((t2 = libconfig->setting_get_member(t, "Looter"))) - mode |= libconfig->setting_get_bool(t2) ? MD_LOOTER : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_LOOTER : MD_NONE; if ((t2 = libconfig->setting_get_member(t, "Aggressive"))) - mode |= libconfig->setting_get_bool(t2) ? MD_AGGRESSIVE : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_AGGRESSIVE : MD_NONE; if ((t2 = libconfig->setting_get_member(t, "Assist"))) - mode |= libconfig->setting_get_bool(t2) ? MD_ASSIST : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_ASSIST : MD_NONE; if ((t2 = libconfig->setting_get_member(t, "CastSensorIdle"))) - mode |= libconfig->setting_get_bool(t2) ? MD_CASTSENSOR_IDLE : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_CASTSENSOR_IDLE : MD_NONE; if ((t2 = libconfig->setting_get_member(t, "Boss"))) - mode |= libconfig->setting_get_bool(t2) ? MD_BOSS : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_BOSS : MD_NONE; if ((t2 = libconfig->setting_get_member(t, "Plant"))) - mode |= libconfig->setting_get_bool(t2) ? MD_PLANT : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_PLANT : MD_NONE; if ((t2 = libconfig->setting_get_member(t, "CanAttack"))) - mode |= libconfig->setting_get_bool(t2) ? MD_CANATTACK : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_CANATTACK : MD_NONE; if ((t2 = libconfig->setting_get_member(t, "Detector"))) - mode |= libconfig->setting_get_bool(t2) ? MD_DETECTOR : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_DETECTOR : MD_NONE; if ((t2 = libconfig->setting_get_member(t, "CastSensorChase"))) - mode |= libconfig->setting_get_bool(t2) ? MD_CASTSENSOR_CHASE : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_CASTSENSOR_CHASE : MD_NONE; if ((t2 = libconfig->setting_get_member(t, "ChangeChase"))) - mode |= libconfig->setting_get_bool(t2) ? MD_CHANGECHASE : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_CHANGECHASE : MD_NONE; if ((t2 = libconfig->setting_get_member(t, "Angry"))) - mode |= libconfig->setting_get_bool(t2) ? MD_ANGRY : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_ANGRY : MD_NONE; if ((t2 = libconfig->setting_get_member(t, "ChangeTargetMelee"))) - mode |= libconfig->setting_get_bool(t2) ? MD_CHANGETARGET_MELEE : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_CHANGETARGET_MELEE : MD_NONE; if ((t2 = libconfig->setting_get_member(t, "ChangeTargetChase"))) - mode |= libconfig->setting_get_bool(t2) ? MD_CHANGETARGET_CHASE : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_CHANGETARGET_CHASE : MD_NONE; if ((t2 = libconfig->setting_get_member(t, "TargetWeak"))) - mode |= libconfig->setting_get_bool(t2) ? MD_TARGETWEAK : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_TARGETWEAK : MD_NONE; if ((t2 = libconfig->setting_get_member(t, "NoKnockback"))) - mode |= libconfig->setting_get_bool(t2) ? MD_NOKNOCKBACK : 0; + mode |= libconfig->setting_get_bool(t2) ? MD_NOKNOCKBACK : MD_NONE; - return mode; + return mode & MD_MASK; } /** @@ -4288,7 +4290,7 @@ int mob_read_db_sub(struct config_setting_t *mobt, int n, const char *source) if (config_setting_is_group(t)) { md.status.mode = mob->read_db_mode_sub(&md, t); } else if (mob->lookup_const(mobt, "Mode", &i32) && i32 >= 0) { - md.status.mode = i32; + md.status.mode = (uint32)i32 & MD_MASK; } } if (!battle_config.monster_active_enable) @@ -4906,19 +4908,23 @@ bool mob_parse_row_mobskilldb(char** str, int columns, int current) ms->val[3]=(int)strtol(str[15],NULL,0); ms->val[4]=(int)strtol(str[16],NULL,0); - if(ms->skill_id == NPC_EMOTION && mob_id>0 && - ms->val[1] == mob->db(mob_id)->status.mode) - { - ms->val[1] = 0; + if (ms->skill_id == NPC_EMOTION) { + ms->val[1] &= MD_MASK; + ms->val[2] &= MD_MASK; + ms->val[3] &= MD_MASK; + } + if (ms->skill_id == NPC_EMOTION && mob_id > 0 + && (uint32)ms->val[1] == mob->db(mob_id)->status.mode) { + ms->val[1] = MD_NONE; ms->val[4] = 1; //request to return mode to normal. } - if (ms->skill_id == NPC_EMOTION_ON && mob_id>0 && ms->val[1]) { + if (ms->skill_id == NPC_EMOTION_ON && mob_id>0 && ms->val[1] != MD_NONE) { //Adds a mode to the mob. //Remove aggressive mode when the new mob type is passive. if (!(ms->val[1]&MD_AGGRESSIVE)) - ms->val[3]|=MD_AGGRESSIVE; - ms->val[2]|= ms->val[1]; //Add the new mode. - ms->val[1] = 0; //Do not "set" it. + ms->val[3] |= MD_AGGRESSIVE; + ms->val[2] |= (uint32)ms->val[1]; //Add the new mode. + ms->val[1] = MD_NONE; //Do not "set" it. } if(*str[17]) diff --git a/src/map/mob.h b/src/map/mob.h index 00e2b0723..60bc4b869 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -459,7 +459,7 @@ struct mob_interface { int (*setdelayspawn) (struct mob_data *md); int (*count_sub) (struct block_list *bl, va_list ap); int (*spawn) (struct mob_data *md); - int (*can_changetarget) (struct mob_data *md, struct block_list *target, int mode); + int (*can_changetarget) (const struct mob_data *md, const struct block_list *target, uint32 mode); int (*target) (struct mob_data *md, struct block_list *bl, int dist); int (*ai_sub_hard_activesearch) (struct block_list *bl, va_list ap); int (*ai_sub_hard_changechase) (struct block_list *bl, va_list ap); @@ -505,7 +505,7 @@ struct mob_interface { int (*skill_use) (struct mob_data *md, int64 tick, int event); int (*skill_event) (struct mob_data *md, struct block_list *src, int64 tick, int flag); int (*is_clone) (int class_); - int (*clone_spawn) (struct map_session_data *sd, int16 m, int16 x, int16 y, const char *event, int master_id, int mode, int flag, unsigned int duration); + int (*clone_spawn) (struct map_session_data *sd, int16 m, int16 x, int16 y, const char *event, int master_id, uint32 mode, int flag, unsigned int duration); int (*clone_delete) (struct mob_data *md); unsigned int (*drop_adjust) (int baserate, int rate_adjust, unsigned short rate_min, unsigned short rate_max); void (*item_dropratio_adjust) (int nameid, int mob_id, int *rate_adjust); @@ -518,7 +518,7 @@ struct mob_interface { int (*read_db_sub) (struct config_setting_t *mobt, int id, const char *source); void (*read_db_drops_sub) (struct mob_db *entry, struct config_setting_t *t); void (*read_db_mvpdrops_sub) (struct mob_db *entry, struct config_setting_t *t); - int (*read_db_mode_sub) (struct mob_db *entry, struct config_setting_t *t); + uint32 (*read_db_mode_sub) (struct mob_db *entry, struct config_setting_t *t); void (*read_db_stats_sub) (struct mob_db *entry, struct config_setting_t *t); void (*name_constants) (void); bool (*readdb_mobavail) (char *str[], int columns, int current); diff --git a/src/map/pc.c b/src/map/pc.c index a79247134..93f23c584 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -10539,11 +10539,18 @@ void pc_del_charm(struct map_session_data *sd, int count, int type) clif->spiritcharm(sd); } -/*========================================== - * Renewal EXP/Itemdrop rate modifier base on level penalty - * 1=exp 2=itemdrop - *------------------------------------------*/ -int pc_level_penalty_mod(int diff, unsigned char race, unsigned short mode, int type) { + +/** + * Renewal EXP/Itemdrop rate modifier base on level penalty. + * + * @param diff Level difference. + * @param race Monster race. + * @param mode Monster mode. + * @param type Modifier type (1=exp 2=itemdrop) + * @return The percent rate modifier (100 = 100%) + */ +int pc_level_penalty_mod(int diff, unsigned char race, uint32 mode, int type) +{ #if defined(RENEWAL_DROP) || defined(RENEWAL_EXP) int rate = 100, i; diff --git a/src/map/pc.h b/src/map/pc.h index 246209f87..db1d7a9da 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -1028,7 +1028,7 @@ END_ZEROED_BLOCK; /* End */ void (*del_charm) (struct map_session_data *sd, int count, int type); void (*baselevelchanged) (struct map_session_data *sd); - int (*level_penalty_mod) (int diff, unsigned char race, unsigned short mode, int type); + int (*level_penalty_mod) (int diff, unsigned char race, uint32 mode, int type); int (*calc_skillpoint) (struct map_session_data* sd); int (*invincible_timer) (int tid, int64 tick, int id, intptr_t data); diff --git a/src/map/script.c b/src/map/script.c index f72176e50..7d5ce7d43 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -10051,7 +10051,8 @@ BUILDIN(killmonsterall) { *------------------------------------------*/ BUILDIN(clone) { struct map_session_data *sd, *msd = NULL; - int char_id,master_id=0,x,y, mode = 0, flag = 0, m; + int char_id, master_id = 0, x, y, flag = 0, m; + uint32 mode = 0; unsigned int duration = 0; const char *mapname, *event; @@ -10064,8 +10065,8 @@ BUILDIN(clone) { if( script_hasdata(st,7) ) master_id=script_getnum(st,7); - if( script_hasdata(st,8) ) - mode=script_getnum(st,8); + if (script_hasdata(st,8)) + mode = script_getnum(st,8); if( script_hasdata(st,9) ) flag=script_getnum(st,9); diff --git a/src/map/skill.c b/src/map/skill.c index fb08103e7..55bf30338 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -9431,7 +9431,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case SO_EL_CONTROL: if( sd ) { - int mode = EL_MODE_PASSIVE; // Standard mode. + uint32 mode = EL_MODE_PASSIVE; // Standard mode. if( !sd->ed ) break; @@ -9443,7 +9443,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case 2: mode = EL_MODE_ASSIST; break; case 3: mode = EL_MODE_AGGRESSIVE; break; } - if( !elemental->change_mode(sd->ed,mode) ) { + if (!elemental->change_mode(sd->ed, mode)) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); break; } diff --git a/src/map/status.c b/src/map/status.c index d0b84f1b8..d04e88e3c 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2095,7 +2095,7 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) { mstatus->max_hp = 3000 + 3000 * ud->skill_lv + status_get_max_sp(battle->get_master(mbl)); } else { //AM_CANNIBALIZE mstatus->max_hp = 1500 + 200*ud->skill_lv + 10*status->get_lv(mbl); - mstatus->mode|= MD_CANATTACK|MD_AGGRESSIVE; + mstatus->mode |= MD_CANATTACK|MD_AGGRESSIVE; } mstatus->hp = mstatus->max_hp; if( ud->skill_id == NC_SILVERSNIPER ) @@ -2200,9 +2200,9 @@ int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt) pd->status.mode = MD_CANMOVE; // pets discard all modes, except walking pd->status.speed = pd->petDB->speed; - if(battle_config.pet_attack_support || battle_config.pet_damage_support) - {// attack support requires the pet to be able to attack - pd->status.mode|= MD_CANATTACK; + if(battle_config.pet_attack_support || battle_config.pet_damage_support) { + // attack support requires the pet to be able to attack + pd->status.mode |= MD_CANATTACK; } } @@ -3212,7 +3212,7 @@ int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt if ( opt&SCO_FIRST ) { memcpy(estatus, &ed->db->status, sizeof(struct status_data)); - if ( !ele->mode ) + if (ele->mode == MD_NONE) estatus->mode = EL_MODE_PASSIVE; else estatus->mode = ele->mode; @@ -6218,19 +6218,27 @@ unsigned char status_calc_attack_element(struct block_list *bl, struct status_ch return (unsigned char)cap_value(element,0,UCHAR_MAX); } -unsigned short status_calc_mode(struct block_list *bl, struct status_change *sc, int mode) +/** + * Calculates the new mode, based on status changes. + * + * @param bl The current unit. + * @param sc The current status change list. + * @param mode The starting mode. + * @return The calculated mode. + */ +uint32 status_calc_mode(const struct block_list *bl, const struct status_change *sc, uint32 mode) { - if(!sc || !sc->count) - return mode; - if(sc->data[SC_MODECHANGE]) { - if (sc->data[SC_MODECHANGE]->val2) + if (sc == NULL || sc->count == 0) + return mode & MD_MASK; + if (sc->data[SC_MODECHANGE] != NULL) { + if (sc->data[SC_MODECHANGE]->val2 != 0) mode = sc->data[SC_MODECHANGE]->val2; //Set mode if (sc->data[SC_MODECHANGE]->val3) - mode|= sc->data[SC_MODECHANGE]->val3; //Add mode + mode |= sc->data[SC_MODECHANGE]->val3; //Add mode if (sc->data[SC_MODECHANGE]->val4) - mode&=~sc->data[SC_MODECHANGE]->val4; //Del mode + mode &= ~sc->data[SC_MODECHANGE]->val4; //Del mode } - return cap_value(mode,0,USHRT_MAX); + return mode & MD_MASK; } const char *status_get_name(struct block_list *bl) @@ -7428,20 +7436,24 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t break; case SC_MODECHANGE: { - int mode; - struct status_data *bst = status->get_base_status(bl); - if (!bst) return 0; - if (sc->data[type]) { - //Pile up with previous values. - if(!val2) val2 = sc->data[type]->val2; + uint32 mode = MD_NONE; + const struct status_data *bst = status->get_base_status(bl); + if (bst == NULL) + return 0; + if (sc->data[type] != NULL) { + // Pile up with previous values. + if (val2 == 0) + val2 = sc->data[type]->val2; val3 |= sc->data[type]->val3; val4 |= sc->data[type]->val4; } - mode = val2 ? val2 : bst->mode; //Base mode - if (val4) mode&=~val4; //Del mode - if (val3) mode|= val3; //Add mode + mode = val2 != 0 ? val2 : bst->mode; // Base mode + if (val4 != 0) + mode &= ~val4; //Del mode + if (val3 != 0) + mode |= val3; //Add mode if (mode == bst->mode) { //No change. - if (sc->data[type]) //Abort previous status + if (sc->data[type] != NULL) //Abort previous status return status_change_end(bl, type, INVALID_TIMER); return 0; } diff --git a/src/map/status.h b/src/map/status.h index 14cda8545..296b5baae 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -1805,26 +1805,33 @@ enum e_joint_break }; -//Mode definitions to clear up code reading. [Skotlex] +/** + * Mob mode definitions. [Skotlex] + * + * @see doc/mob_db_mode_list.txt for a description of each mode. + */ enum e_mode { - MD_CANMOVE = 0x0001, - MD_LOOTER = 0x0002, - MD_AGGRESSIVE = 0x0004, - MD_ASSIST = 0x0008, - MD_CASTSENSOR_IDLE = 0x0010, - MD_BOSS = 0x0020, - MD_PLANT = 0x0040, - MD_CANATTACK = 0x0080, - MD_DETECTOR = 0x0100, - MD_CASTSENSOR_CHASE = 0x0200, - MD_CHANGECHASE = 0x0400, - MD_ANGRY = 0x0800, - MD_CHANGETARGET_MELEE = 0x1000, - MD_CHANGETARGET_CHASE = 0x2000, - MD_TARGETWEAK = 0x4000, - MD_NOKNOCKBACK = 0x8000, - MD_MASK = 0xFFFF, + MD_NONE = 0x00000000, + MD_CANMOVE = 0x00000001, + MD_LOOTER = 0x00000002, + MD_AGGRESSIVE = 0x00000004, + MD_ASSIST = 0x00000008, + MD_CASTSENSOR_IDLE = 0x00000010, + MD_BOSS = 0x00000020, + MD_PLANT = 0x00000040, + MD_CANATTACK = 0x00000080, + MD_DETECTOR = 0x00000100, + MD_CASTSENSOR_CHASE = 0x00000200, + MD_CHANGECHASE = 0x00000400, + MD_ANGRY = 0x00000800, + MD_CHANGETARGET_MELEE = 0x00001000, + MD_CHANGETARGET_CHASE = 0x00002000, + MD_TARGETWEAK = 0x00004000, + MD_NOKNOCKBACK = 0x00008000, + //MD_RANDOMTARGET = 0x00010000, // Not implemented + // Note: This should be kept within INT_MAX, since it's often cast to int. + MD_MASK = 0x7FFFFFFF, }; //Status change option definitions (options are what makes status changes visible to chars @@ -1976,8 +1983,8 @@ struct status_data { batk, matk_min, matk_max, speed, - amotion, adelay, dmotion, - mode; + amotion, adelay, dmotion; + uint32 mode; short hit, flee, cri, flee2, def2, mdef2, @@ -2289,7 +2296,7 @@ struct status_interface { unsigned int (*calc_maxsp) (struct block_list *bl, struct status_change *sc, unsigned int maxsp); unsigned char (*calc_element) (struct block_list *bl, struct status_change *sc, int element); unsigned char (*calc_element_lv) (struct block_list *bl, struct status_change *sc, int lv); - unsigned short (*calc_mode) (struct block_list *bl, struct status_change *sc, int mode); + uint32 (*calc_mode) (const struct block_list *bl, const struct status_change *sc, uint32 mode); unsigned short (*calc_ematk) (struct block_list *bl, struct status_change *sc, int matk); void (*calc_bl_main) (struct block_list *bl, int flag); void (*display_add) (struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3); diff --git a/src/plugins/db2sql.c b/src/plugins/db2sql.c index 7f2d184e3..34e1c2053 100644 --- a/src/plugins/db2sql.c +++ b/src/plugins/db2sql.c @@ -607,7 +607,7 @@ void mobdb2sql_tableheader(void) " `Scale` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',\n" " `Race` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',\n" " `Element` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',\n" - " `Mode` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n" + " `Mode` INT(11) UNSIGNED NOT NULL DEFAULT '0',\n" " `Speed` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n" " `aDelay` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n" " `aMotion` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n" -- cgit v1.2.3-70-g09d2