From 5a80f29b65f3989f488acfa96f5d13525ec354ce Mon Sep 17 00:00:00 2001 From: Jeybla Date: Wed, 20 Dec 2017 01:00:10 +0100 Subject: [PATCH] Fixes potential map server crashes. (#2695) * status_change_timer refactorization * Changes some pointers to const pointers to prevent unwanted behavoir. * Changes sc_timer_next to a lambda function with only the tick as a paramter. * sce is not reassigned in sc_timer_next anymore, therefore it should be crash safe (see #2414 and #2539) * Fixes #2539 * Thanks to @whupdo, @MuzTank and @admkakaroto! --- src/map/status.cpp | 177 ++++++++++++++++++++++----------------------- 1 file changed, 88 insertions(+), 89 deletions(-) diff --git a/src/map/status.cpp b/src/map/status.cpp index 03efd2041f..a6c2308efd 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "../common/cbasetypes.h" @@ -12626,9 +12627,6 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) enum sc_type type = (sc_type)data; struct block_list *bl; struct map_session_data *sd; - struct status_data *status; - struct status_change *sc; - struct status_change_entry *sce; int interval = status_get_sc_interval(type); bool dounlock = false; @@ -12637,14 +12635,19 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) ShowDebug("status_change_timer: Null pointer id: %d data: %d\n", id, data); return 0; } - sc = status_get_sc(bl); - status = status_get_status_data(bl); - if(!(sc && (sce = sc->data[type]))) { + struct status_change * const sc = status_get_sc(bl); + struct status_data * const status = status_get_status_data(bl); + if(!sc) { + ShowDebug("status_change_timer: Null pointer id: %d data: %d bl-type: %d\n", id, data, bl->type); + return 0; + } + + struct status_change_entry * const sce = sc->data[type]; + if(!sce) { ShowDebug("status_change_timer: Null pointer id: %d data: %d bl-type: %d\n", id, data, bl->type); return 0; } - if( sce->timer != tid ) { ShowError("status_change_timer: Mismatch for type %d: %d != %d (bl id %d)\n",type,tid,sce->timer, bl->id); return 0; @@ -12652,19 +12655,16 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) sd = BL_CAST(BL_PC, bl); -// Set the next timer of the sce (don't assume the status still exists) -#define sc_timer_next(t,f,i,d) \ - if( (sce=sc->data[type]) ) \ - sce->timer = add_timer(t,f,i,d); \ - else \ - ShowError("status_change_timer: Unexpected NULL status change id: %d data: %d\n", id, data) - + std::function sc_timer_next = [&sce, &bl, &data](unsigned int t) { + sce->timer = add_timer(t, status_change_timer, bl->id, data); + }; + switch(type) { case SC_MAXIMIZEPOWER: case SC_CLOAKING: if(!status_charge(bl, 0, 1)) break; // Not enough SP to continue. - sc_timer_next(sce->val2+tick, status_change_timer, bl->id, data); + sc_timer_next(sce->val2+tick); return 0; case SC_CHASEWALK: @@ -12676,7 +12676,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE?10:1) // SL bonus -> x10 duration *skill_get_time2(status_sc2skill(type),sce->val1)); } - sc_timer_next(sce->val2+tick, status_change_timer, bl->id, data); + sc_timer_next(sce->val2+tick); return 0; break; @@ -12686,7 +12686,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if(sce->val2 % sce->val4 == 0 && !status_charge(bl, 0, 1)) break; // Fail if it's time to substract SP and there isn't. - sc_timer_next(1000+tick, status_change_timer,bl->id, data); + sc_timer_next(1000+tick); return 0; } break; @@ -12706,14 +12706,14 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if( --(sce->val2)>0 ) { sce->val4 += 20; // Use for Shadow Form 2 seconds checking. - sc_timer_next(20+tick, status_change_timer, bl->id, data); + sc_timer_next(20+tick); return 0; } break; case SC_PROVOKE: if(sce->val2) { // Auto-provoke (it is ended in status_heal) - sc_timer_next(1000*60+tick,status_change_timer, bl->id, data ); + sc_timer_next(1000*60+tick); return 0; } break; @@ -12729,7 +12729,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) status_change_end(bl, SC_AETERNA, INVALID_TIMER); sc->opt1 = OPT1_STONE; clif_changeoption(bl); - sc_timer_next(min(sce->val4, interval) + tick, status_change_timer, bl->id, data); + sc_timer_next(min(sce->val4, interval) + tick); sce->val4 -= interval; //Remaining time status_calc_bl(bl, StatusChangeFlagTable[type]); return 0; @@ -12844,7 +12844,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC_TENSIONRELAX: if(status->max_hp > status->hp && --(sce->val3) >= 0) { - sc_timer_next(10000 + tick, status_change_timer, bl->id, data); + sc_timer_next(10000 + tick); return 0; } break; @@ -12868,7 +12868,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if( status->hp < status->max_hp ) hp = (sce->val1 < 0) ? (int)(sd->status.max_hp * -1 * sce->val1 / 100.) : sce->val1 ; status_heal(bl, hp, 0, 2); - sc_timer_next((sce->val2 * 1000) + tick, status_change_timer, bl->id, data); + sc_timer_next((sce->val2 * 1000) + tick); return 0; } break; @@ -12888,7 +12888,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) clif_bossmapinfo(sd, boss_md, BOSS_INFO_DEAD); } } - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; } break; @@ -12944,14 +12944,14 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if (!status_charge(bl, 0, sp)) break; } - sc_timer_next(1000+tick, status_change_timer, bl->id, data); + sc_timer_next(1000+tick); return 0; } break; case SC_BERSERK: // 5% every 10 seconds [DracoRPG] if( --( sce->val3 ) > 0 && status_charge(bl, sce->val2, 0) && status->hp > 100 ) { - sc_timer_next(sce->val4+tick, status_change_timer, bl->id, data); + sc_timer_next(sce->val4+tick); return 0; } break; @@ -12962,7 +12962,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) clif_changestatus(sd,SP_MANNER,sd->status.manner); clif_updatestatus(sd,SP_MANNER); if (sd->status.manner < 0) { // Every 60 seconds your manner goes up by 1 until it gets back to 0. - sc_timer_next(60000+tick, status_change_timer, bl->id, data); + sc_timer_next(60000+tick); return 0; } } @@ -12976,7 +12976,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) // clif_message(bl, timer); // } if((sce->val4 -= 500) > 0) { - sc_timer_next(500 + tick, status_change_timer, bl->id, data); + sc_timer_next(500 + tick); return 0; } break; @@ -12986,7 +12986,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) { struct block_list *pbl = map_id2bl(sce->val1); if( pbl && check_distance_bl(bl, pbl, 7) ) { - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; } } @@ -12999,35 +12999,35 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) sp = (sce->val1 > 5) ? 35 : 20; if(!status_charge(bl, hp, sp)) break; - sc_timer_next(10000+tick, status_change_timer, bl->id, data); + sc_timer_next(10000+tick); return 0; } break; case SC_JAILED: if(sce->val1 == INT_MAX || --(sce->val1) > 0) { - sc_timer_next(60000+tick, status_change_timer, bl->id,data); + sc_timer_next(60000+tick); return 0; } break; case SC_BLIND: if(sc->data[SC_FOGWALL]) { // Blind lasts forever while you are standing on the fog. - sc_timer_next(5000+tick, status_change_timer, bl->id, data); + sc_timer_next(5000+tick); return 0; } break; case SC_ABUNDANCE: if(--(sce->val4) > 0) { status_heal(bl,0,60,0); - sc_timer_next(10000+tick, status_change_timer, bl->id, data); + sc_timer_next(10000+tick); } break; case SC_OBLIVIONCURSE: if( --(sce->val4) >= 0 ) { clif_emotion(bl,ET_QUESTION); - sc_timer_next(3000 + tick, status_change_timer, bl->id, data ); + sc_timer_next(3000 + tick); return 0; } break; @@ -13036,7 +13036,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if( --(sce->val4) >= 0 ) { if( !status_charge(bl,0,3) ) break; - sc_timer_next(5000+tick,status_change_timer,bl->id,data); + sc_timer_next(5000+tick); return 0; } break; @@ -13044,7 +13044,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC_CLOAKINGEXCEED: if(!status_charge(bl,0,10-sce->val1)) break; - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; case SC_RENOVATIO: @@ -13053,7 +13053,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if( sc && sc->data[SC_AKAITSUKI] && heal ) heal = ~heal + 1; status_heal(bl, heal, 0, 3); - sc_timer_next(5000 + tick, status_change_timer, bl->id, data); + sc_timer_next(5000 + tick); return 0; } break; @@ -13066,7 +13066,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if( --(sce->val4) >= 0 ) { if( !status_charge(bl, 0, 1) ) break; - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; } break; @@ -13078,13 +13078,13 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) status_change_end(bl, (sc_type)i, INVALID_TIMER); break; } - sc_timer_next(10000 + tick, status_change_timer, bl->id, data); + sc_timer_next(10000 + tick); return 0; case SC_ELECTRICSHOCKER: if( --(sce->val4) >= 0 ) { status_charge(bl, 0, 5 * sce->val1 * status->max_sp / 100); - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; } break; @@ -13094,20 +13094,20 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) break; if (--sce->val4 >= 0) sce->val3++; - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; case SC__REPRODUCE: if(!status_charge(bl, 0, 1)) break; - sc_timer_next(1000+tick, status_change_timer, bl->id, data); + sc_timer_next(1000+tick); return 0; case SC__SHADOWFORM: if( --(sce->val4) >= 0 ) { if( !status_charge(bl, 0, 11 - sce->val1) ) break; - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; } break; @@ -13115,14 +13115,14 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC__INVISIBILITY: if( !status_charge(bl, 0, (12 - 2 * sce->val1) * status->max_sp / 100) ) // 6% - skill_lv. break; - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; case SC_STRIKING: if( --(sce->val4) >= 0 ) { if( !status_charge(bl,0, sce->val3 ) ) break; - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; } break; @@ -13135,7 +13135,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) dounlock = true; skill_attack(skill_get_type(status_sc2skill(type)), src, unit_bl, bl, SO_CLOUD_KILL, sce->val1, tick, 0); if (!status_isdead(bl)) { - sc_timer_next(500 + tick, status_change_timer, bl->id, data); + sc_timer_next(500 + tick); } } } @@ -13153,7 +13153,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) hp = ~hp + 1; if (status->hp != status->max_hp) status_heal(bl, hp, 0, 0); - sc_timer_next(3000 + tick, status_change_timer, bl->id, data); + sc_timer_next(3000 + tick); return 0; } @@ -13171,7 +13171,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) status_damage(src, bl, damage, 0, clif_damage(bl,bl,tick,status->amotion,status->dmotion+200,damage,1,DMG_NORMAL,0,false), 0); unit_skillcastcancel(bl,1); if ( sc->data[type] ) { - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); } map_freeblock_unlock(); status_heal(src, damage*(5 + 5 * sce->val1)/100, 0, 0); // 5 + 5% per level @@ -13182,7 +13182,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC_VOICEOFSIREN: if( --(sce->val4) >= 0 ) { clif_emotion(bl,ET_THROB); - sc_timer_next(2000 + tick, status_change_timer, bl->id, data); + sc_timer_next(2000 + tick); return 0; } break; @@ -13190,7 +13190,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC_DEEPSLEEP: if( --(sce->val4) >= 0 ) { // Recovers 3% HP/SP every 2 seconds. status_heal(bl, status->max_hp * 3 / 100, status->max_sp * 3 / 100, 2); - sc_timer_next(2000 + tick, status_change_timer, bl->id, data); + sc_timer_next(2000 + tick); return 0; } break; @@ -13200,7 +13200,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if( !status_charge(bl,0,sce->val3) ) break; status_heal(bl, sce->val2, 0, 1); - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; } break; @@ -13208,7 +13208,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC_SONGOFMANA: if( --(sce->val4) >= 0 ) { status_heal(bl,0,sce->val3,3); - sc_timer_next(5000 + tick, status_change_timer, bl->id, data); + sc_timer_next(5000 + tick); return 0; } break; @@ -13219,7 +13219,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if( --(sce->val3) >= 0 ) { if( !status_charge(bl, status->hp / 100, status->sp / 100) ) break; - sc_timer_next(sce->val4+tick, status_change_timer, bl->id, data); + sc_timer_next(sce->val4+tick); return 0; } break; @@ -13227,7 +13227,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC_MELODYOFSINK: if( --(sce->val4) >= 0 ) { status_charge(bl, 0, status->max_sp * ( 2 * sce->val1 + 2 * sce->val2 ) / 100); - sc_timer_next(1000+tick, status_change_timer, bl->id, data); + sc_timer_next(1000+tick); return 0; } break; @@ -13236,7 +13236,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if( --(sce->val4) >= 0 ) { // Drains 2% of HP and 1% of SP every seconds. if (!status_charge(bl, status->max_hp * 2 / 100, status->max_sp / 100)) break; - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; } break; @@ -13244,13 +13244,13 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC_FORCEOFVANGUARD: if( !status_charge(bl,0,24 - 4 * sce->val1) ) break; - sc_timer_next(10000 + tick, status_change_timer, bl->id, data); + sc_timer_next(10000 + tick); return 0; case SC_BANDING: if( status_charge(bl, 0, 7 - sce->val1) ) { if( sd ) pc_banding(sd, sce->val1); - sc_timer_next(5000 + tick, status_change_timer, bl->id, data); + sc_timer_next(5000 + tick); return 0; } break; @@ -13259,14 +13259,14 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if( --(sce->val4) > 0 ) { if( !status_charge(bl,0,10) ) break; - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; } break; case SC_OVERHEAT_LIMITPOINT: if( --(sce->val1) > 0 ) { // Cooling - sc_timer_next(30000 + tick, status_change_timer, bl->id, data); + sc_timer_next(30000 + tick); } break; @@ -13277,7 +13277,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) map_freeblock_lock(); status_fix_damage(NULL,bl,damage,clif_damage(bl,bl,tick,0,0,damage,0,DMG_NORMAL,0,false)); if( sc->data[type] ) { - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); } map_freeblock_unlock(); } @@ -13291,7 +13291,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) break; if (!status_charge(bl, 0, 50)) status_zap(bl, 0, status->sp); - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; } break; @@ -13303,7 +13303,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if( !status_charge(bl,hp,sp) ) break; - sc_timer_next(5000+tick,status_change_timer,bl->id, data); + sc_timer_next(5000+tick); return 0; } break; @@ -13312,7 +13312,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) // 1% every 5 seconds [Jobbie] if( --(sce->val3)>0 && status_charge(bl, sce->val2, 0) ) { if( !sc->data[type] ) return 0; - sc_timer_next(5000 + tick, status_change_timer, bl->id, data); + sc_timer_next(5000 + tick); return 0; } break; @@ -13346,12 +13346,12 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) status_change_end(bl,type,INVALID_TIMER); break; } - sc_timer_next(sce->val3 + tick, status_change_timer, bl->id, data); + sc_timer_next(sce->val3 + tick); return 0; case SC_WATER_SCREEN_OPTION: status_heal(bl,1000,0,2); - sc_timer_next(10000 + tick,status_change_timer,bl->id,data); + sc_timer_next(10000 + tick); return 0; case SC_TEARGAS: @@ -13363,7 +13363,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) clif_damage(bl, bl, tick, 0, 0, damage, 1, DMG_MULTI_HIT_ENDURE, 0, false); status_damage(src, bl, damage,0, 0, 1); if( sc->data[type] ) { - sc_timer_next(2000 + tick, status_change_timer, bl->id, data); + sc_timer_next(2000 + tick); } map_freeblock_unlock(); return 0; @@ -13372,7 +13372,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC_TEARGAS_SOB: if( --(sce->val4) >= 0 ) { clif_emotion(bl, ET_CRY); - sc_timer_next(3000 + tick, status_change_timer, bl->id, data); + sc_timer_next(3000 + tick); return 0; } break; @@ -13384,7 +13384,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) skill_sit(sd, 1); clif_sitting(bl); } - sc_timer_next(10000 + tick, status_change_timer, bl->id, data); + sc_timer_next(10000 + tick); return 0; } break; @@ -13393,26 +13393,26 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC_SOULCOLD: case SC_HAWKEYES: // They only end by status_change_end - sc_timer_next(600000 + tick, status_change_timer, bl->id, data); + sc_timer_next(600000 + tick); return 0; case SC_MEIKYOUSISUI: if( --(sce->val4) >= 0 ) { status_heal(bl, status->max_hp * sce->val2 / 100, status->max_sp * sce->val3 / 100, 0); - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; } break; case SC_KAGEMUSYA: if( --(sce->val2) >= 0 ) { if(!status_charge(bl, 0, 1)) break; - sc_timer_next(1000+tick, status_change_timer, bl->id, data); + sc_timer_next(1000+tick); return 0; } break; case SC_ANGRIFFS_MODUS: if(--(sce->val4) >= 0) { // Drain hp/sp if( !status_charge(bl,100,20) ) break; - sc_timer_next(1000+tick,status_change_timer,bl->id, data); + sc_timer_next(1000+tick); return 0; } break; @@ -13422,35 +13422,35 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) int sp = (status->max_sp * sce->val3) / 100; if(bl->type == BL_MOB) hp = sp*10; if( !status_charge(bl,hp,sp) )break; - sc_timer_next(1000+tick,status_change_timer,bl->id, data); + sc_timer_next(1000+tick); return 0; } break; case SC_FULL_THROTTLE: if( --(sce->val4) >= 0 ) { status_percent_damage(bl, bl, 0, sce->val2, false); - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; } break; case SC_REBOUND: if( --(sce->val4) >= 0 ) { clif_emotion(bl, ET_SWEAT); - sc_timer_next(2000 + tick, status_change_timer, bl->id, data); + sc_timer_next(2000 + tick); return 0; } break; case SC_KINGS_GRACE: if( --(sce->val4) >= 0 ) { status_percent_heal(bl, sce->val2, 0); - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; } break; case SC_FRIGG_SONG: if( --(sce->val4) >= 0 ) { status_heal(bl, sce->val3, 0, 0); - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; } break; @@ -13459,7 +13459,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) TBL_PC *caster = map_id2sd(sce->val2); if (!caster || caster->bl.m != bl->m) //End the SC if caster isn't in same map break; - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); clif_crimson_marker(caster, bl, false); return 0; } @@ -13468,7 +13468,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if (--(sce->val4) >= 0) { if (!status_charge(bl, 0, status->max_sp * 3 / 100)) break; - sc_timer_next(sce->val3 + tick, status_change_timer, bl->id, data); + sc_timer_next(sce->val3 + tick); return 0; } break; @@ -13478,7 +13478,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) clif_slide(bl, sce->val3>>16, sce->val3&0xFFFF); clif_fixpos(bl); } - sc_timer_next(tick+sce->val4, status_change_timer, bl->id, data); + sc_timer_next(tick+sce->val4); sce->val4 = 0; } break; @@ -13488,7 +13488,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) status_heal(bl, status->max_hp / 100, 0, 1); else if (status->def_ele == ELE_EARTH) status_zap(bl, status->max_hp / 100, 0); - sc_timer_next(5000 + tick, status_change_timer, bl->id, data); + sc_timer_next(5000 + tick); return 0; } break; @@ -13499,7 +13499,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) status_heal(bl, status->max_hp / 100, 0, 1); else if (status->def_ele == ELE_FIRE) status_zap(bl, status->max_hp / 100, 0); - sc_timer_next(5000 + tick, status_change_timer, bl->id, data); + sc_timer_next(5000 + tick); return 0; } break; @@ -13510,7 +13510,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) status_heal(bl, status->max_hp / 100, 0, 1); else if (status->def_ele == ELE_WATER) status_zap(bl, status->max_hp / 100, 0); - sc_timer_next(5000 + tick, status_change_timer, bl->id, data); + sc_timer_next(5000 + tick); return 0; } break; @@ -13521,21 +13521,21 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) status_heal(bl, status->max_hp / 100, 0, 1); else if (status->def_ele == ELE_WIND) status_zap(bl, status->max_hp / 100, 0); - sc_timer_next(5000 + tick, status_change_timer, bl->id, data); + sc_timer_next(5000 + tick); return 0; } break; case SC_BITESCAR: if (--(sce->val4) >= 0) { status_percent_damage(bl, bl, -(sce->val2), 0, 0); - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + sc_timer_next(1000 + tick); return 0; } break; case SC_FRESHSHRIMP: if (--(sce->val4) >= 0) { status_heal(bl, sce->val2, 0, 3); - sc_timer_next((10000 - ((sce->val1 - 1) * 1000)) + tick, status_change_timer, bl->id, data); + sc_timer_next((10000 - ((sce->val1 - 1) * 1000)) + tick); return 0; } break; @@ -13543,7 +13543,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if( sd && --(sce->val4) >= 0 ) { if( status->hp < status->max_hp ) status_heal(bl, 10, 0, 2); - sc_timer_next(10000 + tick, status_change_timer, bl->id, data); + sc_timer_next(10000 + tick); return 0; } break; @@ -13551,7 +13551,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if( sd && --(sce->val4) >= 0 ) { if( status->sp < status->max_sp ) status_heal(bl, 0, 5, 2); - sc_timer_next(10000 + tick, status_change_timer, bl->id, data); + sc_timer_next(10000 + tick); return 0; } break; @@ -13559,7 +13559,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) // If status has an interval and there is at least 100ms remaining time, wait for next interval if(interval > 0 && sc->data[type] && sce->val4 >= 100) { - sc_timer_next(min(sce->val4,interval)+tick, status_change_timer, bl->id, data); + sc_timer_next(min(sce->val4,interval)+tick); sce->val4 -= interval; if (dounlock) map_freeblock_unlock(); @@ -13571,7 +13571,6 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) // Default for all non-handled control paths is to end the status return status_change_end( bl,type,tid ); -#undef sc_timer_next } /**