diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/map/battle.c | 3 | ||||
-rw-r--r-- | src/map/battle.h | 3 | ||||
-rw-r--r-- | src/map/mob.c | 31 | ||||
-rw-r--r-- | src/map/unit.c | 32 |
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; } |