diff options
Diffstat (limited to 'src/map/unit.c')
-rw-r--r-- | src/map/unit.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/src/map/unit.c b/src/map/unit.c index f823a3fed..849e9348f 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -95,6 +95,8 @@ int unit_walktoxy_sub(struct block_list *bl) ud = unit->bl2ud(bl); if(ud == NULL) return 0; + memset(&wpd, 0, sizeof(wpd)); + if( !path->search(&wpd,bl->m,bl->x,bl->y,ud->to_x,ud->to_y,ud->state.walk_easy,CELL_CHKNOPASS) ) return 0; @@ -247,9 +249,24 @@ int unit_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) { dx = dirx[(int)dir]; dy = diry[(int)dir]; - if(map->getcell(bl->m,x+dx,y+dy,CELL_CHKNOPASS)) + //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)) 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 +317,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 @@ -776,6 +795,7 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag) } if( sd ) { + unit->stop_stepaction(bl); //Stop stepaction when knocked back sd->ud.to_x = nx; sd->ud.to_y = ny; } @@ -1564,6 +1584,12 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; } + /** + * "WHY IS IT HEREE": ice wall cannot be canceled past this point, the client displays the animation even, + * if we cancel it from castend_pos, so it has to be here for it to not display the animation. + **/ + if ( skill_id == WZ_ICEWALL && map->getcell(src->m, skill_x, skill_y, CELL_CHKNOICEWALL) ) + return 0; } if (!status->check_skilluse(src, NULL, skill_id, 0)) @@ -2010,8 +2036,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); @@ -2367,7 +2394,7 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i sd->debug_file, sd->debug_line, sd->debug_func, file, line, func); } else if (--map->list[bl->m].users == 0 && battle_config.dynamic_mobs) //[Skotlex] map->removemobs(bl->m); - if( !(sd->sc.option&OPTION_INVISIBLE) ) { + if (!(pc_isinvisible(sd))) { // decrement the number of active pvp players on the map --map->list[bl->m].users_pvp; } |