summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2009-06-15 14:00:27 +0000
committerultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2009-06-15 14:00:27 +0000
commit00be89f64050ff5373a63cc599f533f57ffaead1 (patch)
treed6ffded38d53e36cf5075a62242c8a03b21e13b0
parent2503f4ca66cfd8c7014d099883ca696082c27a39 (diff)
downloadhercules-00be89f64050ff5373a63cc599f533f57ffaead1.tar.gz
hercules-00be89f64050ff5373a63cc599f533f57ffaead1.tar.bz2
hercules-00be89f64050ff5373a63cc599f533f57ffaead1.tar.xz
hercules-00be89f64050ff5373a63cc599f533f57ffaead1.zip
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
-rw-r--r--src/map/pc.c2
-rw-r--r--src/map/skill.c43
-rw-r--r--src/map/skill.h1
-rw-r--r--src/map/status.c42
-rw-r--r--src/map/unit.c2
5 files changed, 24 insertions, 66 deletions
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:
@@ -9901,45 +9901,6 @@ bool skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce
/*==========================================
*
- *
- *------------------------------------------*/
-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);
-}
-
-/*==========================================
- *
*------------------------------------------*/
struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int x, int y, int val1, int val2)
{
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);