summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/map/battle.c3
-rw-r--r--src/map/battle.h3
-rw-r--r--src/map/mob.c31
-rw-r--r--src/map/unit.c32
4 files changed, 47 insertions, 22 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index 88d83f91b..40ef15191 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -6838,7 +6838,8 @@ static const struct battle_data {
{ "song_timer_reset", &battle_config.song_timer_reset, 0, 0, 1, },
{ "snap_dodge", &battle_config.snap_dodge, 0, 0, 1, },
{ "monster_chase_refresh", &battle_config.mob_chase_refresh, 1, 0, 30, },
- { "icewall_walk_block", &battle_config.icewall_walk_block, 75, 0, 255, }
+ { "mob_icewall_walk_block", &battle_config.mob_icewall_walk_block, 75, 0, 255, },
+ { "boss_icewall_walk_block", &battle_config.boss_icewall_walk_block, 0, 0, 255, },
};
#ifndef STATS_OPT_OUT
/**
diff --git a/src/map/battle.h b/src/map/battle.h
index 6ac2df391..1b6321cbf 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -452,7 +452,8 @@ struct Battle_Config {
int mob_size_influence; // Enable modifications on earned experience, drop rates and monster status depending on monster size. [mkbu95]
int bowling_bash_area;
int mob_chase_refresh; //How often a monster should refresh its chase [Playtester]
- int icewall_walk_block; //How long a monster should stay trapped in icewall [Playtester]
+ int mob_icewall_walk_block; //How a normal monster should be trapped in icewall [Playtester]
+ int boss_icewall_walk_block; //How a boss monster should be trapped in icewall [Playtester]
/** Hercules **/
int skill_trap_type;
diff --git a/src/map/mob.c b/src/map/mob.c
index eaf8c8468..23706d293 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -1429,7 +1429,7 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
//No valid target
if (mob->warpchase(md, tbl))
return true; //Chasing this target.
- if(md->ud.walktimer != INVALID_TIMER && md->ud.walkpath.path_pos <= battle_config.mob_chase_refresh)
+ if(md->ud.walktimer != INVALID_TIMER && (!can_move || md->ud.walkpath.path_pos <= battle_config.mob_chase_refresh))
return true; //Walk at least "mob_chase_refresh" cells before dropping the target
mob_unlocktarget(md, tick); //Unlock target
tbl = NULL;
@@ -1442,13 +1442,14 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
if( md->attacked_id == md->target_id )
{ //Rude attacked check.
if( !battle->check_range(&md->bl, tbl, md->status.rhw.range)
- && ( //Can't attack back and can't reach back.
+ && ( //Can't attack back and can't reach back.
(!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || (md->sc.data[SC_SPIDERWEB] && md->sc.data[SC_SPIDERWEB]->val1)
- || md->sc.data[SC_WUGBITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNS_TRAP]
- || md->sc.data[SC__MANHOLE])) // Not yet confirmed if boss will teleport once it can't reach target.
- || !mob->can_reach(md, tbl, md->min_chase, MSS_RUSH)
- || md->walktoxy_fail_count > 0
+ || md->sc.data[SC_WUGBITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNS_TRAP]
+ || md->sc.data[SC__MANHOLE] // Not yet confirmed if boss will teleport once it can't reach target.
+ || md->walktoxy_fail_count > 0)
)
+ || !mob->can_reach(md, tbl, md->min_chase, MSS_RUSH)
+ )
&& md->state.attacked_count++ >= RUDE_ATTACKED_COUNT
&& !mob->skill_use(md, tick, MSC_RUDEATTACKED) // If can't rude Attack
&& can_move && unit->escape(&md->bl, tbl, rnd()%10 +1)) // Attempt escape
@@ -1466,11 +1467,12 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
|| (battle_config.mob_ai&0x2 && !status->check_skilluse(&md->bl, abl, 0, 0)) // Cannot normal attack back to Attacker
|| (!battle->check_range(&md->bl, abl, md->status.rhw.range) // Not on Melee Range and ...
&& ( // Reach check
- (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || (md->sc.data[SC_SPIDERWEB] && md->sc.data[SC_SPIDERWEB]->val1)
- || md->sc.data[SC_WUGBITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNS_TRAP]
- || md->sc.data[SC__MANHOLE])) // Not yet confirmed if boss will teleport once it can't reach target.
- || !mob->can_reach(md, abl, dist+md->db->range3, MSS_RUSH)
- || md->walktoxy_fail_count > 0
+ (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || (md->sc.data[SC_SPIDERWEB] && md->sc.data[SC_SPIDERWEB]->val1)
+ || md->sc.data[SC_WUGBITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNS_TRAP]
+ || md->sc.data[SC__MANHOLE] // Not yet confirmed if boss will teleport once it can't reach target.
+ || md->walktoxy_fail_count > 0)
+ )
+ || !mob->can_reach(md, abl, dist+md->db->range3, MSS_RUSH)
)
)
) {
@@ -1636,6 +1638,9 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
if(battle->check_range(&md->bl, tbl, md->status.rhw.range))
return true;
+ //Only update target cell / drop target after having moved at least "mob_chase_refresh" cells
+ if(md->ud.walktimer != INVALID_TIMER && (!can_move || md->ud.walkpath.path_pos <= battle_config.mob_chase_refresh))
+ return true;
//Out of range...
if (!(mode&MD_CANMOVE) || (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0))
@@ -1655,10 +1660,6 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
)) //Current target tile is still within attack range.
return true;
- //Only update target cell after having moved at least "mob_chase_refresh" cells
- if(md->ud.walktimer != INVALID_TIMER && md->ud.walkpath.path_pos <= battle_config.mob_chase_refresh)
- return true;
-
//Follow up if possible.
//Hint: Chase skills are handled in the walktobl routine
if(!mob->can_reach(md, tbl, md->min_chase, MSS_RUSH) ||
diff --git a/src/map/unit.c b/src/map/unit.c
index 849e9348f..76a5853df 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -108,11 +108,11 @@ int unit_walktoxy_sub(struct block_list *bl)
uint8 dir;
//Trim the last part of the path to account for range,
//but always move at least one cell when requested to move.
- for (i = ud->chaserange*10; i > 0 && ud->walkpath.path_len>1;) {
+ for (i = (ud->chaserange*10)-10; i > 0 && ud->walkpath.path_len>1;) {
ud->walkpath.path_len--;
dir = ud->walkpath.path[ud->walkpath.path_len];
if(dir&1)
- i -= MOVE_DIAGONAL_COST;
+ i -= MOVE_COST*20; //When chasing, units will target a diamond-shaped area in range [Playtester]
else
i -= MOVE_COST;
ud->to_x -= dirx[dir];
@@ -211,6 +211,7 @@ int unit_step_timer(int tid, int64 tick, int id, intptr_t data)
int unit_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) {
int i;
int x,y,dx,dy;
+ unsigned char icewall_walk_block;
uint8 dir;
struct block_list *bl;
struct map_session_data *sd;
@@ -249,19 +250,29 @@ int unit_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) {
dx = dirx[(int)dir];
dy = diry[(int)dir];
+ //Get icewall walk block depending on boss mode (players can't be trapped)
+ if(md && md->status.mode&MD_BOSS)
+ icewall_walk_block = battle_config.boss_icewall_walk_block;
+ else if(md)
+ icewall_walk_block = battle_config.mob_icewall_walk_block;
+ else
+ icewall_walk_block = 0;
+
//Monsters will walk into an icewall from the west and south if they already started walking
if(map->getcell(bl->m,x+dx,y+dy,CELL_CHKNOPASS)
- && (battle_config.icewall_walk_block == 0 || !map->getcell(bl->m,x+dx,y+dy,CELL_CHKICEWALL) || dx < 0 || dy < 0))
+ && (icewall_walk_block == 0 || !map->getcell(bl->m,x+dx,y+dy,CELL_CHKICEWALL) || dx < 0 || dy < 0))
return unit->walktoxy_sub(bl);
//Monsters can only leave icewalls to the west and south
//But if movement fails more than icewall_walk_block times, they can ignore this rule
- if(md && md->walktoxy_fail_count < battle_config.icewall_walk_block && map->getcell(bl->m,x,y,CELL_CHKICEWALL) && (dx > 0 || dy > 0)) {
+ if(md && md->walktoxy_fail_count < icewall_walk_block && map->getcell(bl->m,x,y,CELL_CHKICEWALL) && (dx > 0 || dy > 0)) {
//Needs to be done here so that rudeattack skills are invoked
md->walktoxy_fail_count++;
clif->fixpos(bl);
+ //Monsters in this situation first use a chase skill, then unlock target and then use an idle skill
+ if (!(++ud->walk_count%WALK_SKILL_INTERVAL))
+ mob->skill_use(md, tick, -1);
mob->unlocktarget(md, tick);
- //Use idle skill at this point
if (!(++ud->walk_count%WALK_SKILL_INTERVAL))
mob->skill_use(md, tick, -1);
return 0;
@@ -1060,6 +1071,17 @@ int unit_can_move(struct block_list *bl) {
return 0;
}
+
+ // Icewall walk block special trapped monster mode
+ if(bl->type == BL_MOB) {
+ struct mob_data *md = BL_CAST(BL_MOB, bl);
+ if(md && ((md->status.mode&MD_BOSS && battle_config.boss_icewall_walk_block == 1 && map->getcell(bl->m,bl->x,bl->y,CELL_CHKICEWALL))
+ || (!(md->status.mode&MD_BOSS) && battle_config.mob_icewall_walk_block == 1 && map->getcell(bl->m,bl->x,bl->y,CELL_CHKICEWALL)))) {
+ md->walktoxy_fail_count = 1; //Make sure rudeattacked skills are invoked
+ return 0;
+ }
+ }
+
return 1;
}