From 6a6e3bb8e69890ee69981467f1e5e3591c0f9356 Mon Sep 17 00:00:00 2001 From: Michieru Date: Sat, 18 Oct 2014 17:52:17 +0200 Subject: Fix bug:7454 * Official Icewall implementation and other fixes - Reverted all the icewall-related changes done in SVN r15777 and following as testing shows they aren't official and are actually pretty exploitable (bugreport:7412) - Instead implemented the official icewall characteristic that monsters can only leave an icewall cell to the west or south, the changes include: * The "sight" path check no longer checks for the current cell so standing on an icewall allows you to see/attack into any direction * The path finding will still ignore the current cell as before but the walk routine will not allow to walk east or north while standing on an icewall cell * This leads monsters in the situation where they go through an AI loop not allowing them to escape the icewall (if their target is north or east of them) * Monster in this situation will use idle skills and if they get attacked will use their rudeattacked skills if available, similar to traps like Spiderweb * Added a configuration icewall_walk_block that allows to configure how long a monster should go through the AI loop before the server allows it any movement, this "safety" system is official and seems to equal about 75 AI loops; if you want to disable the whole icewall system so that monsters don't get stuck in icewall at all, just set this to 0 * Here are videos from jRO showing how this system works: http://ragdo.blog56.fc2.com/blog-entry-763.html - Implemented the official calculation for "direction"; now you will be considered horizontal/vertical/diagonally aligned with a target cell in the exact same way as on official servers, this is for example used to determine whether an icewall or a firewall should be horizontal, vertical or diagonal; the only thing that is still unofficial is the default direction (officially always "west"); effectively now there are more situations considered diagonal than before - Further cleanups on the idle skill use code for immobile monsters and monsters near a player but without a target (now skill using will always go via mob_unlocktarget) * This also fixes that monsters switched to idle mode and start to use idle skills one second too late Mega thanks to Playtester (rathena 5540d89cb0e) --- src/map/unit.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src/map/unit.c') diff --git a/src/map/unit.c b/src/map/unit.c index f823a3fed..2d8fd530d 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -250,6 +250,19 @@ int unit_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) { if(map->getcell(bl->m,x+dx,y+dy,CELL_CHKNOPASS)) 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)) { + //Needs to be done here so that rudeattack skills are invoked + md->walktoxy_fail_count++; + clif->fixpos(bl); + 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; + } + //Refresh view for all those we lose sight map->foreachinmovearea(clif->outsight, bl, AREA_SIZE, dx, dy, sd?BL_ALL:BL_PC, bl); @@ -300,6 +313,8 @@ int unit_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) { sd->hd->masterteleport_timer = 0; } } else if (md) { + //Movement was successful, reset walktoxy_fail_count + md->walktoxy_fail_count = 0; if( map->getcell(bl->m,x,y,CELL_CHKNPC) ) { if( npc->touch_areanpc2(md) ) return 0; // Warped } else @@ -2010,8 +2025,9 @@ int unit_attack_timer_sub(struct block_list* src, int tid, int64 tick) { sstatus = status->get_status_data(src); range = sstatus->rhw.range; - if( unit->is_walking(target) ) - range++; //Extra range when chasing + if( unit->is_walking(target) && (target->type == BL_PC || !map->getcell(target->m,target->x,target->y,CELL_CHKICEWALL)) ) + range++; // Extra range when chasing (does not apply to mobs locked in an icewall) + if(sd && !check_distance_client_bl(src,target,range)) { // Player tries to attack but target is too far, notify client clif->movetoattack(sd,target); -- cgit v1.2.3-60-g2f50