Quellcode durchsuchen

Monster angry mode and provoke (fixes #1011)
* When provoked, monsters will now only switch targets when they would also change targets on damage
* Added a new option to the mob_ai setting to restore the old behavior (monsters always go after the one casting provoke)
* When casting provoke on an angry mode monster before it was attacked, it will now go for the one casting provoke and not switch back to the closest target
* Angry mode will now always be reset when the monster switches to idle

Playtester vor 9 Jahren
Ursprung
Commit
ecb01c44f4
3 geänderte Dateien mit 10 neuen und 6 gelöschten Zeilen
  1. 2 0
      conf/battle/monster.conf
  2. 1 1
      src/map/battle.c
  3. 7 5
      src/map/mob.c

+ 2 - 0
conf/battle/monster.conf

@@ -50,6 +50,8 @@ monster_max_aspd: 199
 //        will receive the delay). This will make monsters harder, especially MvPs.
 // 0x400: Set this to make mobs have a range of 9 for all skills. Otherwise, they 
 //        will obey the normal skill range rules.
+// 0x800: When set, monsters that are provoked will always change target to the
+//        provoking person, even if they would usually not change target on attack.
 // Example: 0x140 -> Chase players through warps + use skills in random order.
 monster_ai: 0
 

+ 1 - 1
src/map/battle.c

@@ -8014,7 +8014,7 @@ static const struct _battle_data {
 	{ "ignore_items_gender",                &battle_config.ignore_items_gender,             1,      0,      1,              },
 	{ "berserk_cancels_buffs",              &battle_config.berserk_cancels_buffs,           0,      0,      1,              },
 	{ "debuff_on_logout",                   &battle_config.debuff_on_logout,                1|2,    0,      1|2,            },
-	{ "monster_ai",                         &battle_config.mob_ai,                          0x000,  0x000,  0x7FF,          },
+	{ "monster_ai",                         &battle_config.mob_ai,                          0x000,  0x000,  0xFFF,          },
 	{ "hom_setting",                        &battle_config.hom_setting,                     0xFFFF, 0x0000, 0xFFFF,         },
 	{ "dynamic_mobs",                       &battle_config.dynamic_mobs,                    1,      0,      1,              },
 	{ "mob_remove_damaged",                 &battle_config.mob_remove_damaged,              1,      0,      1,              },

+ 7 - 5
src/map/mob.c

@@ -1036,8 +1036,8 @@ int mob_spawn (struct mob_data *md)
  *------------------------------------------*/
 static int mob_can_changetarget(struct mob_data* md, struct block_list* target, enum e_mode mode)
 {
-	// if the monster was provoked ignore the above rule [celest]
-	if(md->state.provoke_flag)
+	// Special feature that makes monsters always attack the person that provoked them
+	if(battle_config.mob_ai&0x800 && md->state.provoke_flag)
 	{
 		if (md->state.provoke_flag == target->id)
 			return 1;
@@ -1083,6 +1083,9 @@ int mob_target(struct mob_data *md,struct block_list *bl,int dist)
 	md->target_id = bl->id;	// Since there was no disturbance, it locks on to target.
 	if (md->state.provoke_flag && bl->id != md->state.provoke_flag)
 		md->state.provoke_flag = 0;
+	// When an angry monster is provoked, it will switch to retaliate AI
+	if (md->state.provoke_flag && md->state.aggressive)
+		md->state.aggressive = 0;
 	md->min_chase=dist+md->db->range3;
 	if(md->min_chase>MAX_MINCHASE)
 		md->min_chase=MAX_MINCHASE;
@@ -1362,6 +1365,8 @@ int mob_unlocktarget(struct mob_data *md, unsigned int tick)
 	default:
 		mob_stop_attack(md);
 		mob_stop_walking(md,1); //Stop chasing.
+		if (md->status.mode&MD_ANGRY && !md->state.aggressive)
+			md->state.aggressive = 1; //Restore angry state when switching to idle
 		md->state.skillstate = MSS_IDLE;
 		if(battle_config.mob_ai&0x8) //Walk instantly after dropping target
 			md->next_walktime = tick+rnd()%1000;
@@ -1615,9 +1620,6 @@ static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
 	}
 
 	if (!tbl) { //No targets available.
-		if (mode&MD_ANGRY && !md->state.aggressive)
-			md->state.aggressive = 1; //Restore angry state when no targets are available.
-
 		/* bg guardians follow allies when no targets nearby */
 		if( md->bg_id && mode&MD_CANATTACK ) {
 			if( md->ud.walktimer != INVALID_TIMER )