This fix uses timer functions and still causes the client to render the initial direction for a milisecond when you use shadow jump on a cell that is too close to you, still it's good to go.
At unit.c define the following function:
int unit_settimeddir(int tid, int64 tick, int id, intptr_t data){ struct block_list *src; src = map->id2bl(id); if (src == NULL){ ShowDebug("unit_settimeddir: src == NULL (tid=%d, id=%d)\n", tid, id); return 0;// not found } unit->setdir(src,data);//data will be the direction return 1; }
This is a function of the defined type TimerFunc which means it can be used by the timer functions after we define a name for it. But first we need to define in unit_defaults:
unit->settimeddir = unit_settimeddir;
and at do_init_unit:
timer->add_func_list(unit->settimeddir,"unit_settimeddir");
Then we go to unit.h and define inside the struct unit_interface:
int (*settimeddir)(int tid, int64 tick, int id, intptr_t data);
Now or function is ready to be used. At skill.c in skill_castend_pos2 go to the case NJ_SHADOWJUMP and make it look like this:
case NJ_SHADOWJUMP: { uint8 d = map->calc_dir(src,x,y); if( !map_flag_gvg2(src->m) && !map->list[src->m].flag.battleground ) { //You don't move on GVG grounds. unit->movepos(src, x, y, 1, 0); clif->slide(src,x,y); } timer->add(tick+10,unit->settimeddir,src->id,(intptr_t)d); status_change_end(src, SC_HIDING, INVALID_TIMER); clif->skill_poseffect(src,skill_id,skill_lv,x,y,tick); } break;
So at 10 ticks later (used 10 because I feel it's safer) the function will be executed, chaging the direction the src is facing.