From 00be89f64050ff5373a63cc599f533f57ffaead1 Mon Sep 17 00:00:00 2001 From: ultramage Date: Mon, 15 Jun 2009 14:00:27 +0000 Subject: Improving the r13888 crashfix to cover similar crash scenarios discovered: Reordered code in status_change_end(SC_DANCING) so that an ensemble's skill unit group is deleted only after removing both performers' status changes. Modified the call to skill_delunitgroup() IN status_change_end(SC_DANCING) so that it always processes the group's true owner and not others (bugreport:3253). Replaced calls to skill_stop_dancing() with status_change_end(SC_DANCING), since it now provides identical functionality. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13891 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/pc.c | 2 +- src/map/skill.c | 43 ++----------------------------------------- src/map/skill.h | 1 - src/map/status.c | 42 ++++++++++++++++++++---------------------- src/map/unit.c | 2 +- 5 files changed, 24 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/map/pc.c b/src/map/pc.c index a53a3a7fe..21173b673 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -6916,7 +6916,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) pc_calcweapontype(sd); clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); if(sd->sc.data[SC_DANCING]) //When unequipping, stop dancing. [Skotlex] - skill_stop_dancing(&sd->bl); + status_change_end(&sd->bl, SC_DANCING, -1); } if(sd->status.inventory[n].equip & EQP_HAND_L) { sd->status.shield = sd->weapontype2 = 0; diff --git a/src/map/skill.c b/src/map/skill.c index bfe20c8c9..a2b337e6a 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -4163,7 +4163,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case BD_ADAPTATION: if(tsc && tsc->data[SC_DANCING]){ clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_stop_dancing(bl); + status_change_end(bl, SC_DANCING, -1); } break; @@ -7810,7 +7810,7 @@ static int skill_unit_onleft (int skill_id, struct block_list *bl, unsigned int //it only checks if you are doing the same ensemble. So if there's two chars doing an ensemble //which overlaps, by stepping outside of the other parther's ensemble will cause you to cancel //your own. Let's pray that scenario is pretty unlikely and noone will complain too much about it. - skill_stop_dancing(bl); + status_change_end(bl, SC_DANCING, -1); } case MG_SAFETYWALL: case AL_PNEUMA: @@ -9899,45 +9899,6 @@ bool skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce return wall; } -/*========================================== - * - * - *------------------------------------------*/ -void skill_stop_dancing (struct block_list *src) -{ - struct status_change* sc; - struct status_change_entry *sce; - struct skill_unit_group* group; - struct map_session_data* dsd = NULL; - - nullpo_retv(src); - nullpo_retv(sc = status_get_sc(src)); - - if(!sc->count || !(sce=sc->data[SC_DANCING])) - return; - - group = skill_id2group(sce->val2); - sce->val2 = 0; - - if (sce->val4) - { - if (sce->val4 != BCT_SELF) - dsd = map_id2sd(sce->val4); - sce->val4 = 0; - } - - status_change_end(src, SC_DANCING, -1); - - if (dsd && (sce=dsd->sc.data[SC_DANCING])) - { - sce->val4 = sce->val2 = 0; - status_change_end(&dsd->bl, SC_DANCING, -1); - } - - if (group) - skill_delunitgroup(NULL, group); -} - /*========================================== * *------------------------------------------*/ diff --git a/src/map/skill.h b/src/map/skill.h index b6495538e..bb1e10ef3 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -302,7 +302,6 @@ int skill_unit_move(struct block_list *bl,unsigned int tick,int flag); int skill_unit_move_unit_group( struct skill_unit_group *group, int m,int dx,int dy); struct skill_unit_group *skill_check_dancing( struct block_list *src ); -void skill_stop_dancing(struct block_list *src); // Guild skills [celest] int skill_guildaura_sub (struct block_list *bl,va_list ap); diff --git a/src/map/status.c b/src/map/status.c index 5f24e244d..62170bf27 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -710,7 +710,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s } } if(sc->data[SC_DANCING] && (unsigned int)hp > status->max_hp>>2) - skill_stop_dancing(target); + status_change_end(target, SC_DANCING, -1); } unit_skillcastcancel(target, 2); } @@ -5947,7 +5947,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val pc_setstand(sd); case SC_TRICKDEAD: unit_stop_attack(bl); - skill_stop_dancing(bl); + status_change_end(bl, SC_DANCING, -1); // Cancel cast when get status [LuzZza] if (battle_config.sc_castcancel&bl->type) unit_skillcastcancel(bl, 0); @@ -6205,9 +6205,6 @@ int status_change_clear(struct block_list* bl, int type) if (!sc || !sc->count) return 0; - if(sc->data[SC_DANCING]) - skill_stop_dancing(bl); - for(i = 0; i < SC_MAX; i++) { if(!sc->data[i]) @@ -6426,25 +6423,29 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid) struct map_session_data *dsd; struct status_change_entry *dsc; struct skill_unit_group *group; - if(sce->val2) - { - group = skill_id2group(sce->val2); - sce->val2 = 0; - skill_delunitgroup(bl, group); - } - if(sce->val4 && sce->val4 != BCT_SELF && (dsd=map_id2sd(sce->val4))){ - dsc = dsd->sc.data[type]; + + if(sce->val4 && sce->val4 != BCT_SELF && (dsd=map_id2sd(sce->val4))) + {// end status on partner as well + dsc = dsd->sc.data[SC_DANCING]; if(dsc) { //This will prevent recursive loops. dsc->val2 = dsc->val4 = 0; - status_change_end(&dsd->bl, type, -1); + status_change_end(&dsd->bl, SC_DANCING, -1); } } - } - if ((sce->val1&0xFFFF) == CG_MOONLIT) - clif_status_change(bl,SI_MOONLIT,0,0); - status_change_end(bl,SC_LONGING,-1); + if(sce->val2) + {// erase associated land skill + group = skill_id2group(sce->val2); + sce->val2 = 0; + skill_delunitgroup(NULL, group); + } + + if((sce->val1&0xFFFF) == CG_MOONLIT) + clif_status_change(bl,SI_MOONLIT,0,0); + + status_change_end(bl,SC_LONGING,-1); + } break; case SC_NOCHAT: if (sd && sd->status.manner < 0 && tid != -1) @@ -7059,10 +7060,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr data) if (sc->data[SC_LONGING]) sp*= 3; if (!status_charge(bl, 0, sp)) - { - skill_stop_dancing(bl); - return 0; - } + break; } sc_timer_next(1000+tick, status_change_timer, bl->id, data); return 0; diff --git a/src/map/unit.c b/src/map/unit.c index 9a637fd60..116b8c3d5 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1752,7 +1752,7 @@ int unit_remove_map_(struct block_list *bl, int clrtype, const char* file, int l status_change_end(bl,SC_TRICKDEAD,-1); status_change_end(bl,SC_BLADESTOP_WAIT,-1); status_change_end(bl,SC_RUN,-1); - skill_stop_dancing(bl); + status_change_end(bl,SC_DANCING,-1); status_change_end(bl,SC_WARM,-1); status_change_end(bl,SC_DEVOTION,-1); status_change_end(bl,SC_MARIONETTE,-1); -- cgit v1.2.3-60-g2f50