Monster AI Improvements, Clashing Spiral, Skid Trap, Throw Stone (#8269)

- Added config setting mob_unlock_time that defines how long a monster can be trapped (immobile) before it unlocks its target 
  * Default is 2000ms, which makes Clashing Spiral no longer cause monsters to drop their target, but Ankle Snare still will even at minimum duration 
- Monsters will now promptly use idle skills while trapped (there was a delay before)
- Increased the time the AI is still active when there are no players left on the map from 0ms to 5000ms
  * This fixes an issue that monsters never unlocked their target if it was the last player to leave the map
- Clashing Spiral now has a range of 4 instead of 5
- Skid Trap no longer has a stop effect in pre-re, but it will make monsters unlock their target and become idle
- Skid Trap still stops targets for 3 seconds in renewal, but will no longer activate on bosses
- Throw Stone now deals 30 damage when used by monsters
- Fixes #7846
This commit is contained in:
Playtester 2024-04-22 08:39:11 +02:00 committed by GitHub
parent 75f518859f
commit f15cb72f94
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 49 additions and 22 deletions

View File

@ -79,10 +79,10 @@ monster_chase_refresh: 30
// 8: Enable mob-warping when standing on Dimensional Door
mob_warp: 0
// If these are set above 0, they define the time (in ms) during which monsters
// will have their 'AI' active after all players have left their vicinity.
mob_active_time: 0
boss_active_time: 0
// Defines the time (in ms) during which monsters will have their AI active
// after all players have left their vicinity.
mob_active_time: 5000
boss_active_time: 5000
// Mobs and Pets view-range adjustment (range2 column in the mob_db) (Note 2)
view_range_rate: 100
@ -302,3 +302,8 @@ slave_stick_with_master: no
// Also used in delaying the spawning of guardians when a guild is not loaded.
// Default (Official): 1000
mob_respawn_time: 1000
// Defines the time (in ms) after which a monster unlocks its target when trapped.
// During this time monsters will still be in idle mode and use idle skills on random
// targets, but they continue chasing their original target when no longer trapped.
mob_unlock_time: 2000

View File

@ -4153,7 +4153,6 @@ Body:
Time: 120000
- Level: 5
Time: 60000
Duration2: 3000
Requires:
SpCost: 10
ItemCost:
@ -10805,7 +10804,7 @@ Body:
IgnoreDefense: true
Flags:
TargetTrap: true
Range: 5
Range: 4
Hit: Multi_Hit
HitCount: 5
Element: Weapon
@ -32756,7 +32755,7 @@ Body:
IgnoreDefense: true
Flags:
TargetTrap: true
Range: 5
Range: 4
Hit: Multi_Hit
HitCount: 5
Element: Weapon

View File

@ -11048,7 +11048,7 @@ Body:
TargetType: Attack
Flags:
TargetTrap: true
Range: 5
Range: 4
Hit: Multi_Hit
HitCount: 5
Element: Weapon
@ -46222,7 +46222,7 @@ Body:
TargetType: Attack
Flags:
TargetTrap: true
Range: 5
Range: 4
Hit: Multi_Hit
HitCount: 5
Element: Weapon

View File

@ -8940,7 +8940,10 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
switch (skill_id) {
case TF_THROWSTONE:
md.damage = 50;
if (sd)
md.damage = 50;
else
md.damage = 30;
md.flag |= BF_WEAPON;
break;
case NPC_KILLING_AURA:
@ -11126,8 +11129,8 @@ static const struct _battle_data {
{ "day_duration", &battle_config.day_duration, 0, 0, INT_MAX, },
{ "night_duration", &battle_config.night_duration, 0, 0, INT_MAX, },
{ "mob_remove_delay", &battle_config.mob_remove_delay, 60000, 1000, INT_MAX, },
{ "mob_active_time", &battle_config.mob_active_time, 0, 0, INT_MAX, },
{ "boss_active_time", &battle_config.boss_active_time, 0, 0, INT_MAX, },
{ "mob_active_time", &battle_config.mob_active_time, 5000, 0, INT_MAX, },
{ "boss_active_time", &battle_config.boss_active_time, 5000, 0, INT_MAX, },
{ "sg_miracle_skill_duration", &battle_config.sg_miracle_skill_duration, 3600000, 0, INT_MAX, },
{ "hvan_explosion_intimate", &battle_config.hvan_explosion_intimate, 45000, 0, 100000, },
{ "quest_exp_rate", &battle_config.quest_exp_rate, 100, 0, INT_MAX, },
@ -11377,6 +11380,7 @@ static const struct _battle_data {
{ "feature.dynamicnpc_direction", &battle_config.feature_dynamicnpc_direction, 0, 0, 1, },
{ "mob_respawn_time", &battle_config.mob_respawn_time, 1000, 1000, INT_MAX, },
{ "mob_unlock_time", &battle_config.mob_unlock_time, 2000, 0, INT_MAX, },
{ "feature.stylist", &battle_config.feature_stylist, 1, 0, 1, },
{ "feature.banking_state_enforce", &battle_config.feature_banking_state_enforce, 0, 0, 1, },

View File

@ -746,6 +746,7 @@ struct Battle_Config
int feature_dynamicnpc_direction;
int mob_respawn_time;
int mob_unlock_time;
int feature_stylist;
int feature_banking_state_enforce;

View File

@ -1164,6 +1164,7 @@ int mob_spawn (struct mob_data *md)
md->last_linktime = tick;
md->dmgtick = tick - 5000;
md->last_pcneartime = 0;
md->last_canmove = tick;
t_tick c = tick - MOB_MAX_DELAY;
@ -1720,6 +1721,8 @@ static bool mob_ai_sub_hard(struct mob_data *md, t_tick tick)
mode = status_get_mode(&md->bl);
can_move = (mode&MD_CANMOVE) && unit_can_move(&md->bl);
if (can_move)
md->last_canmove = tick;
if (md->target_id)
{ //Check validity of current target. [Skotlex]
@ -1956,13 +1959,21 @@ static bool mob_ai_sub_hard(struct mob_data *md, t_tick tick)
&& mob_is_chasing(md->state.skillstate))
return true;
//Out of range...
if (!(mode&MD_CANMOVE) || (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0))
{ //Can't chase. Immobile and trapped mobs should unlock target and use an idle skill.
// Out of range
if (!(mode&MD_CANMOVE) || (!can_move && (md->sc.cant.move || DIFF_TICK(tick, md->ud.canmove_tick) > 0)))
{ // Can't chase. Immobile and trapped mobs will use idle skills and unlock their target after a while
if (md->ud.attacktimer == INVALID_TIMER)
{ //Only unlock target if no more attack delay left
//This handles triggering idle/walk skill.
mob_unlocktarget(md,tick);
{ // Only switch mode if no more attack delay left
if (DIFF_TICK(tick, md->last_canmove) > battle_config.mob_unlock_time) {
// Unlock target or use idle/walk skill
mob_unlocktarget(md, tick);
}
else {
// Use idle skill but keep target for now
md->state.skillstate = MSS_IDLE;
if (!(++md->ud.walk_count%IDLE_SKILL_INTERVAL))
mobskill_use(md, tick, -1);
}
}
return true;
}

View File

@ -359,7 +359,7 @@ struct mob_data {
int areanpc_id; //Required in OnTouchNPC (to avoid multiple area touchs)
int bg_id; // BattleGround System
t_tick next_walktime,last_thinktime,last_linktime,last_pcneartime,dmgtick;
t_tick next_walktime,last_thinktime,last_linktime,last_pcneartime,dmgtick,last_canmove;
short move_fail_count;
short lootitem_count;
short min_chase;

View File

@ -16192,8 +16192,15 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, t_t
sg->unit_id = UNT_USED_TRAPS;
clif_changetraplook(&unit->bl, UNT_USED_TRAPS);
sg->limit=DIFF_TICK(tick,sg->tick)+1500;
//Target will be stopped for 3 seconds
#ifdef RENEWAL
// In renewal, target will be stopped for 3 seconds
sc_start(ss,bl,SC_STOP,100,0,skill_get_time2(sg->skill_id,sg->skill_lv));
#else
// In pre-renewal, if target was a monster, it will unlock target and become idle
struct mob_data* md = BL_CAST(BL_MOB, bl);
if (md)
mob_unlocktarget(md, tick);
#endif
}
break;
@ -21256,8 +21263,8 @@ int skill_unit_timer_sub_onplace(struct block_list* bl, va_list ap)
return 0; //AoE skills are ineffective. [Skotlex]
#ifdef RENEWAL
// Ankle Snare can no longer trap bosses in renewal
if (group->unit_id == UNT_ANKLESNARE && status_bl_has_mode(bl, MD_STATUSIMMUNE))
// Ankle Snare and Skid Trap can no longer trap bosses in renewal
if ((group->unit_id == UNT_ANKLESNARE || group->unit_id == UNT_SKIDTRAP) && status_bl_has_mode(bl, MD_STATUSIMMUNE))
return 0;
#endif