From 101dd12ba7fa9cb34363361ef9bbbe5c74f8b375 Mon Sep 17 00:00:00 2001 From: FlavioJS Date: Sat, 24 Jan 2009 23:43:27 +0000 Subject: * Changed pc_spiritball_timer and pc_addspiritball: (bugreport:2705) - don't make assumptions about the calling order of timers - ensure that sd->spirit_timer is is ordered by expiration time git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13485 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 5 +++++ src/map/pc.c | 46 ++++++++++++++++++++++++++++------------------ 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 3fd448b07..4acb8a01a 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,11 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. 2009/01/24 + * Changed pc_spiritball_timer and pc_addspiritball: (bugreport:2705) [FlavioJS] + - don't make assumptions about the calling order of timers + - ensure that sd->spirit_timer is is ordered by expiration time + * Changed pc_spiritball_timer to not assume that timers are called in the same order they are created. (bugreport:2705) + - the timer heap makes no garantees about the order order when timers have the same tick * Changed the variables of the mapcache structs to fixed size equivalents. * Changed all uses of struct skill_unit_group* to group_id in status_change_entry's. [FlavioJS] 2009/01/23 diff --git a/src/map/pc.c b/src/map/pc.c index 268a461c0..08b511fc7 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -127,26 +127,29 @@ void pc_delinvincibletimer(struct map_session_data* sd) static int pc_spiritball_timer(int tid, unsigned int tick, int id, intptr data) { struct map_session_data *sd; + int i; if( (sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC ) return 1; - if(sd->spirit_timer[0] != tid){ - ShowError("spirit_timer %d != %d\n",sd->spirit_timer[0],tid); + if( sd->spiritball <= 0 ) + { + ShowError("pc_spiritball_timer: %d spiritball's available. (aid=%d cid=%d tid=%d)\n", sd->spiritball, sd->status.account_id, sd->status.char_id, tid); + sd->spiritball = 0; return 0; } - if(sd->spiritball <= 0) { - ShowError("Spiritballs are already 0 when pc_spiritball_timer gets called"); - sd->spiritball = 0; + ARR_FIND(0, sd->spiritball, i, sd->spirit_timer[i] == tid); + if( i == sd->spiritball ) + { + ShowError("pc_spiritball_timer: timer not found (aid=%d cid=%d tid=%d)\n", sd->status.account_id, sd->status.char_id, tid); return 0; } sd->spiritball--; - // I leave this here as bad example [Shinomori] - //memcpy( &sd->spirit_timer[0], &sd->spirit_timer[1], sizeof(sd->spirit_timer[0]) * sd->spiritball ); - memmove( sd->spirit_timer+0, sd->spirit_timer+1, (sd->spiritball)*sizeof(int) ); - sd->spirit_timer[sd->spiritball]=-1; + if( i != sd->spiritball ) + memmove(sd->spirit_timer+i, sd->spirit_timer+i+1, (sd->spiritball-i)*sizeof(int)); + sd->spirit_timer[sd->spiritball] = INVALID_TIMER; clif_spiritball(sd); @@ -155,6 +158,8 @@ static int pc_spiritball_timer(int tid, unsigned int tick, int id, intptr data) int pc_addspiritball(struct map_session_data *sd,int interval,int max) { + int tid, i; + nullpo_retr(0, sd); if(max > MAX_SKILL_LEVEL) @@ -162,17 +167,22 @@ int pc_addspiritball(struct map_session_data *sd,int interval,int max) if(sd->spiritball < 0) sd->spiritball = 0; - if(sd->spiritball >= max) { + if( sd->spiritball && sd->spiritball >= max ) + { if(sd->spirit_timer[0] != -1) delete_timer(sd->spirit_timer[0],pc_spiritball_timer); - // I leave this here as bad example [Shinomori] - //memcpy( &sd->spirit_timer[0], &sd->spirit_timer[1], sizeof(sd->spirit_timer[0]) * (sd->spiritball - 1)); - memmove( sd->spirit_timer+0, sd->spirit_timer+1, (sd->spiritball - 1)*sizeof(int) ); - //sd->spirit_timer[sd->spiritball-1] = -1; // intentionally, but will be overwritten - } else - sd->spiritball++; - - sd->spirit_timer[sd->spiritball-1] = add_timer(gettick()+interval,pc_spiritball_timer,sd->bl.id,0); + sd->spiritball--; + if( sd->spiritball != 0 ) + memmove(sd->spirit_timer+0, sd->spirit_timer+1, (sd->spiritball)*sizeof(int)); + sd->spirit_timer[sd->spiritball] = INVALID_TIMER; + } + + tid = add_timer(gettick()+interval, pc_spiritball_timer, sd->bl.id, 0); + ARR_FIND(0, sd->spiritball, i, DIFF_TICK(get_timer(tid)->tick, get_timer(sd->spirit_timer[i])->tick) < 0); + if( i != sd->spiritball ) + memmove(sd->spirit_timer+i+1, sd->spirit_timer+i, (sd->spiritball-i)*sizeof(int)); + sd->spirit_timer[i] = tid; + sd->spiritball++; clif_spiritball(sd); return 0; -- cgit v1.2.3-70-g09d2