[2014-02-05] Backslide and Shadow Jump Animations - gone?

bWolfie

I'm the man
Messages
850
Points
0
Location
Alberta, Midgard
Github
bWolfie
Emulator
Is this official behavior? I remember these skills use to have animations. Now, Shadow Jump will always result in the character facing east (with no finish animation like Asura Strike has) and backsliding just throws your character back without movement animation.

 
At skill.c :

For Back Slide change in skill_castend_nodamage_id

case TF_BACKSLIDING: //This is the correct implementation as per packet logging information. [Skotlex]
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
skill->blown(src,bl,skill->get_blewcount(skill_id,skill_lv),unit->getdir(bl),0);
clif->fixpos(bl);
break;

to 

case TF_BACKSLIDING: //This is the correct implementation as per packet logging information. [Skotlex]
//clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
skill->blown(src,bl,skill->get_blewcount(skill_id,skill_lv),unit->getdir(bl),0);
clif->fixpos(bl);
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
break;

For Shadow Jump I couldn't solve the direction, but for the animation change at skill_castend_pos2 to this:

case NJ_SHADOWJUMP:
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);
}
status_change_end(src, SC_HIDING, INVALID_TIMER);
clif->skill_poseffect(src,skill_id,skill_lv,x,y,tick);
break;

Don't forget to recompile.

 
Last edited by a moderator:
Triangulated the problem with the direction in NJ_SHADOWJUMP and found out this: At map.c, in map_moveblock the following lines are causing the problem:

if (moveblock) map->delblock(bl);
#ifdef CELL_NOSTACK
else map->update_cell_bl(bl, false);
#endif
bl->x = x1;//this one
bl->y = y1;//and this one,
if (moveblock) map->addblock(bl);
#ifdef CELL_NOSTACK
else map->update_cell_bl(bl, true);
#endif

Weird. Tried different things, nothing solved it so I have no idea what to do.

 
EDIT: THIS FIX IS DEPRECATED. I did a fix using timer functions which will be in the next post. Don't use this as it will sometimes cause a "miss" animation when using the skill.

Managed to do a temporal fix on NJ_SHADOWJUMP. I realized that it does change the direction of the caster but it is never shown to the clients, even if you try it by sending a packet on the same tick. For some reason it sets itself to the direction = 6 at the end of the tick. So what I have done is change the direction a little later. For this, I still don't know how to use timer functions, so I use clif_delay_damage and clif_delay_damage_sub whenever I need that. clif_delay_damage calls clif_delay_damage_sub at the tick it is set to with a packet of data that holds multiple variables and we can take advantage of it. The fix is the following:

In skill.c at the case NJ_SHADOWJUMP in skill_castend_pos2 make it look like this:

Code:
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); } clif->delay_damage(tick+10,src,src,d,skill_id,0,1,0); status_change_end(src, SC_HIDING, INVALID_TIMER); clif->skill_poseffect(src,skill_id,skill_lv,x,y,tick); } break;
At clif.c in clif_delay_damage_sub (the sub, not the other) add at the start of the code
Code:
struct map_session_data *sd; sd=map->id2sd(dd->p.GID);//dd->p.GID is the id of the caster sent from clif_delay_damage if (sd){ if (dd->p.attackedMT==NJ_SHADOWJUMP && dd->p.count==1){//this is the "sdelay" variable where we used the skill_id, the count=1 is a security measure in the case the sdelay of the true use of the packet is =NJ_SHADOWJUMP unit->setdir(&sd->bl,dd->p.attackMT);//this is the "ddelay" variable where we used the direction ers_free(clif->delayed_damage_ers,dd);//It does this at the end, I guess it frees some memory return 0; } }
This will solve the problem until it is fixed. Probably the best way to solve it would be using timer functions but I don't know how do they work, actually I'm not even sure what language is this.
 
Last edited by a moderator:
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.

 
Back
Top