* 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://svn.code.sf.net/p/rathena/svn/trunk@13485 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
9a8c2a60c9
commit
743de085b2
@ -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.
|
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||||
|
|
||||||
2009/01/24
|
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 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]
|
* Changed all uses of struct skill_unit_group* to group_id in status_change_entry's. [FlavioJS]
|
||||||
2009/01/23
|
2009/01/23
|
||||||
|
48
src/map/pc.c
48
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)
|
static int pc_spiritball_timer(int tid, unsigned int tick, int id, intptr data)
|
||||||
{
|
{
|
||||||
struct map_session_data *sd;
|
struct map_session_data *sd;
|
||||||
|
int i;
|
||||||
|
|
||||||
if( (sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC )
|
if( (sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if(sd->spirit_timer[0] != tid){
|
if( sd->spiritball <= 0 )
|
||||||
ShowError("spirit_timer %d != %d\n",sd->spirit_timer[0],tid);
|
{
|
||||||
return 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);
|
||||||
}
|
|
||||||
|
|
||||||
if(sd->spiritball <= 0) {
|
|
||||||
ShowError("Spiritballs are already 0 when pc_spiritball_timer gets called");
|
|
||||||
sd->spiritball = 0;
|
sd->spiritball = 0;
|
||||||
return 0;
|
return 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--;
|
sd->spiritball--;
|
||||||
// I leave this here as bad example [Shinomori]
|
if( i != sd->spiritball )
|
||||||
//memcpy( &sd->spirit_timer[0], &sd->spirit_timer[1], sizeof(sd->spirit_timer[0]) * sd->spiritball );
|
memmove(sd->spirit_timer+i, sd->spirit_timer+i+1, (sd->spiritball-i)*sizeof(int));
|
||||||
memmove( sd->spirit_timer+0, sd->spirit_timer+1, (sd->spiritball)*sizeof(int) );
|
sd->spirit_timer[sd->spiritball] = INVALID_TIMER;
|
||||||
sd->spirit_timer[sd->spiritball]=-1;
|
|
||||||
|
|
||||||
clif_spiritball(sd);
|
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 pc_addspiritball(struct map_session_data *sd,int interval,int max)
|
||||||
{
|
{
|
||||||
|
int tid, i;
|
||||||
|
|
||||||
nullpo_retr(0, sd);
|
nullpo_retr(0, sd);
|
||||||
|
|
||||||
if(max > MAX_SKILL_LEVEL)
|
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)
|
if(sd->spiritball < 0)
|
||||||
sd->spiritball = 0;
|
sd->spiritball = 0;
|
||||||
|
|
||||||
if(sd->spiritball >= max) {
|
if( sd->spiritball && sd->spiritball >= max )
|
||||||
|
{
|
||||||
if(sd->spirit_timer[0] != -1)
|
if(sd->spirit_timer[0] != -1)
|
||||||
delete_timer(sd->spirit_timer[0],pc_spiritball_timer);
|
delete_timer(sd->spirit_timer[0],pc_spiritball_timer);
|
||||||
// I leave this here as bad example [Shinomori]
|
sd->spiritball--;
|
||||||
//memcpy( &sd->spirit_timer[0], &sd->spirit_timer[1], sizeof(sd->spirit_timer[0]) * (sd->spiritball - 1));
|
if( sd->spiritball != 0 )
|
||||||
memmove( sd->spirit_timer+0, sd->spirit_timer+1, (sd->spiritball - 1)*sizeof(int) );
|
memmove(sd->spirit_timer+0, sd->spirit_timer+1, (sd->spiritball)*sizeof(int));
|
||||||
//sd->spirit_timer[sd->spiritball-1] = -1; // intentionally, but will be overwritten
|
sd->spirit_timer[sd->spiritball] = INVALID_TIMER;
|
||||||
} else
|
}
|
||||||
sd->spiritball++;
|
|
||||||
|
|
||||||
sd->spirit_timer[sd->spiritball-1] = add_timer(gettick()+interval,pc_spiritball_timer,sd->bl.id,0);
|
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);
|
clif_spiritball(sd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user