summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2019-10-18 16:53:38 +0200
committerGitHub <noreply@github.com>2019-10-18 16:53:38 +0200
commit9fb69836caaa3bc46ad1109c3aa9df8ee60cc6fe (patch)
tree26c58b5cbadfe5731ef1902b50e1c095b8321a66 /src/map
parent29b587ae936fc76828cb3982de8c43caaea5fe86 (diff)
parent9e5994866305ef23628020d1605fac43305c2105 (diff)
downloadhercules-9fb69836caaa3bc46ad1109c3aa9df8ee60cc6fe.tar.gz
hercules-9fb69836caaa3bc46ad1109c3aa9df8ee60cc6fe.tar.bz2
hercules-9fb69836caaa3bc46ad1109c3aa9df8ee60cc6fe.tar.xz
hercules-9fb69836caaa3bc46ad1109c3aa9df8ee60cc6fe.zip
Merge pull request #2551 from guilherme-gm/201910-fix-sc-times
Fixes status changes effect timer when relogging
Diffstat (limited to 'src/map')
-rw-r--r--src/map/chrif.c5
-rw-r--r--src/map/clif.c18
-rw-r--r--src/map/clif.h3
-rw-r--r--src/map/status.c269
-rw-r--r--src/map/status.h4
5 files changed, 169 insertions, 130 deletions
diff --git a/src/map/chrif.c b/src/map/chrif.c
index a3277d4c2..ddc106d0c 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -1226,6 +1226,7 @@ static bool chrif_save_scdata(struct map_session_data *sd)
} else {
data.tick = INFINITE_DURATION;
}
+ data.total_tick = sc->data[i]->total_tick;
data.type = i;
data.val1 = sc->data[i]->val1;
data.val2 = sc->data[i]->val2;
@@ -1273,8 +1274,8 @@ static bool chrif_load_scdata(int fd)
for (i = 0; i < count; i++) {
const struct status_change_data *data = RFIFOP(fd,14 + i*sizeof(struct status_change_data));
- status->change_start(NULL, &sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4,
- data->tick, SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_LOADED|SCFLAG_FIXEDRATE);
+ status->change_start_sub(NULL, &sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4,
+ data->tick, data->total_tick, SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_LOADED|SCFLAG_FIXEDRATE);
}
pc->scdata_received(sd);
diff --git a/src/map/clif.c b/src/map/clif.c
index cd4281b6f..d45929190 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -6041,7 +6041,7 @@ static void clif_cooking_list(struct map_session_data *sd, int trigger, uint16 s
}
}
-static void clif_status_change_notick(struct block_list *bl, int type, int flag, int tick, int val1, int val2, int val3)
+static void clif_status_change_notick(struct block_list *bl, int type, int flag, int tick, int total_tick, int val1, int val2, int val3)
{
struct packet_sc_notick p;
struct map_session_data *sd;
@@ -6070,7 +6070,7 @@ static void clif_status_change_notick(struct block_list *bl, int type, int flag,
/// 08ff <id>.L <index>.W <remain msec>.L { <val>.L }*3 (PACKETVER >= 20111108)
/// 0983 <index>.W <id>.L <state>.B <total msec>.L <remain msec>.L { <val>.L }*3 (PACKETVER >= 20120618)
/// 0984 <id>.L <index>.W <total msec>.L <remain msec>.L { <val>.L }*3 (PACKETVER >= 20120618)
-static void clif_status_change(struct block_list *bl, int type, int flag, int tick, int val1, int val2, int val3)
+static void clif_status_change_sub(struct block_list *bl, int type, int flag, int tick, int total_tick, int val1, int val2, int val3)
{
struct packet_status_change p;
struct map_session_data *sd;
@@ -6094,7 +6094,7 @@ static void clif_status_change(struct block_list *bl, int type, int flag, int ti
p.state = (unsigned char)flag;
#if PACKETVER >= 20120618
- p.Total = tick; /* at this stage remain and total are the same value I believe */
+ p.Total = total_tick;
#endif
#if PACKETVER >= 20090121
p.Left = tick;
@@ -6105,6 +6105,13 @@ static void clif_status_change(struct block_list *bl, int type, int flag, int ti
clif->send(&p,sizeof(p), bl, (sd && sd->status.option&OPTION_INVISIBLE) ? SELF : AREA);
}
+/// Notifies clients of a status change.
+/// @see clif_status_change_sub
+static void clif_status_change(struct block_list *bl, int type, int flag, int total_tick, int val1, int val2, int val3)
+{
+ clif->status_change_sub(bl, type, flag, total_tick, total_tick, val1, val2, val3);
+}
+
/// Send message (modified by [Yor]) (ZC_NOTIFY_PLAYERCHAT).
/// 008e <packet len>.W <message>.?B
static void clif_displaymessage(const int fd, const char *mes)
@@ -23679,9 +23686,9 @@ static void packetdb_loaddb(void)
static void clif_bc_ready(void)
{
if( battle_config.display_status_timers )
- clif->status_change = clif_status_change;
+ clif->status_change_sub = clif_status_change_sub;
else
- clif->status_change = clif_status_change_notick;
+ clif->status_change_sub = clif_status_change_notick;
switch( battle_config.packet_obfuscation ) {
case 0:
@@ -23899,6 +23906,7 @@ void clif_defaults(void)
clif->autospell = clif_autospell;
clif->combo_delay = clif_combo_delay;
clif->status_change = clif_status_change;
+ clif->status_change_sub = clif_status_change_sub;
clif->insert_card = clif_insert_card;
clif->inventoryList = clif_inventoryList;
clif->inventoryItems = clif_inventoryItems;
diff --git a/src/map/clif.h b/src/map/clif.h
index 4bc3abdeb..0dfc00c01 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -902,7 +902,8 @@ struct clif_interface {
void (*cooking_list) (struct map_session_data *sd, int trigger, uint16 skill_id, int qty, int list_type);
void (*autospell) (struct map_session_data *sd,uint16 skill_lv);
void (*combo_delay) (struct block_list *bl,int wait);
- void (*status_change) (struct block_list *bl,int type,int flag,int tick,int val1, int val2, int val3);
+ void (*status_change) (struct block_list *bl, int type, int flag, int total_tick, int val1, int val2, int val3);
+ void (*status_change_sub) (struct block_list *bl, int type, int flag, int tick, int total_tick, int val1, int val2, int val3);
void (*insert_card) (struct map_session_data *sd,int idx_equip,int idx_card,int flag);
void (*inventoryList) (struct map_session_data *sd);
void (*inventoryItems) (struct map_session_data *sd, enum inventory_type type);
diff --git a/src/map/status.c b/src/map/status.c
index 6d37032c0..96a02c023 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -7515,7 +7515,7 @@ static void status_display_remove(struct map_session_data *sd, enum sc_type type
}
/**
- * Starts a status change.
+ * Starts a status change with a set remaining time.
*
* @param src Status change source bl.
* @param bl Status change target bl.
@@ -7525,13 +7525,14 @@ static void status_display_remove(struct map_session_data *sd, enum sc_type type
* @param val2 Additional value (meaning depends on type).
* @param val3 Additional value (meaning depends on type).
* @param val4 Additional value (meaning depends on type).
- * @param tick Base duration (milliseconds).
+ * @param tick Remaining duration (miliseconds). (if flag doesn't contain SCFLAG_LOADED, it will become the final total_tick)
+ * @param total_tick Base duration (milliseconds).
* @param flag Special flags (@see enum scstart_flag).
*
* @retval 0 if no status change happened.
* @retval 1 if the status change was successfully applied.
*/
-static int status_change_start(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag)
+static int status_change_start_sub(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int total_tick, int flag)
{
struct map_session_data *sd = NULL;
struct status_change* sc;
@@ -7545,7 +7546,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
st = status->get_status_data(bl);
if (type <= SC_NONE || type >= SC_MAX) {
- ShowError("status_change_start: invalid status change (%d)!\n", type);
+ ShowError("status_change_start_sub: invalid status change (%d)!\n", type);
return 0;
}
@@ -7570,10 +7571,10 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
sd = BL_CAST(BL_PC, bl);
- //Adjust tick according to status resistances
+ //Adjust total_tick according to status resistances
if( !(flag&(SCFLAG_NOAVOID|SCFLAG_LOADED)) ) {
- tick = status->get_sc_def(src, bl, type, rate, tick, flag);
- if( !tick ) return 0;
+ total_tick = status->get_sc_def(src, bl, type, rate, total_tick, flag);
+ if( !total_tick ) return 0;
}
undead_flag = battle->check_undead(st->race, st->def_ele);
@@ -7724,7 +7725,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
}
if (!opt_flag) return 0;
}
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_NOEQUIPSHIELD:
if (val2 == 1) {
@@ -7740,7 +7741,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
}
- if (tick == 1)
+ if (total_tick == 1)
return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_NOEQUIPARMOR:
@@ -7753,7 +7754,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
return 0;
pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_NOEQUIPHELM:
if (sd && !(flag&SCFLAG_LOADED)) {
@@ -7765,7 +7766,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
return 0;
pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_MER_FLEE:
case SC_MER_ATK:
@@ -7819,7 +7820,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
if( i < 0 )
return 0;
}
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_TOXIN:
case SC_PARALYSE:
@@ -7989,33 +7990,33 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
int i;
for( i = 0; i < MAX_PC_DEVOTION; i++ ) {
if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL)
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
} else if (bl->type == BL_MER) {
struct mercenary_data *mc = BL_UCAST(BL_MER, bl);
if (mc->devotion_flag && (tsd = mc->master) != NULL) {
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
}
}
//val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk)
if (val4)
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_AUTOBERSERK:
if (st->hp < st->max_hp>>2 &&
(!sc->data[SC_PROVOKE] || sc->data[SC_PROVOKE]->val2==0))
sc_start4(src,bl,SC_PROVOKE,100,10,1,0,0,60000);
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_CRUCIS:
val2 = 10 + 4*val1; //Def reduction
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
clif->emotion(bl,E_SWT);
break;
case SC_MAXIMIZEPOWER:
- tick_time = val2 = tick>0?tick:60000;
- tick = INFINITE_DURATION; // duration sent to the client should be infinite
+ tick_time = val2 = total_tick>0?total_tick:60000;
+ total_tick = INFINITE_DURATION; // duration sent to the client should be infinite
break;
case SC_EDP: // [Celest]
//Chance to Poison enemies.
@@ -8026,7 +8027,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
#endif
val3 = 50 * (val1 + 1); //Damage increase (+50 +50*lv%)
if( sd )//[Ind] - iROwiki says each level increases its duration by 3 seconds
- tick += pc->checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
+ total_tick += pc->checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
break;
case SC_POISONREACT:
val2=(val1+1)/2 + val1/10; // Number of counters [Skotlex]
@@ -8056,7 +8057,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_SACRIFICE:
val2 = 5; //Lasts 5 hits
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_ENCHANTPOISON:
val2= 250+50*val1; //Poisoning Chance (2.5+0.5%) in 1/10000 rate
@@ -8093,12 +8094,12 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
int i;
for( i = 0; i < MAX_PC_DEVOTION; i++ ) {
if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL)
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
} else if (bl->type == BL_MER) {
struct mercenary_data *mc = BL_UCAST(BL_MER, bl);
if (mc->devotion_flag && (tsd = mc->master) != NULL) {
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
}
}
@@ -8177,9 +8178,9 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
//val3 : Brings the skill_lv (merged into val1 here)
//val4 : Partner
if (val1 == CG_MOONLIT)
- clif->status_change(bl,SI_MOON,1,tick,0, 0, 0);
+ clif->status_change(bl,SI_MOON,1,total_tick,0, 0, 0);
val1|= (val3<<16);
- val3 = tick/1000; //Tick duration
+ val3 = total_tick/1000; //Tick duration
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_LONGING:
@@ -8216,7 +8217,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
// mmocharstatus.manner, each negative point results in 1 minute with this status activated
// This is done this way because the message that the client displays is hardcoded, and only
// shows how many minutes are remaining. [Panikon]
- tick = 60000;
+ total_tick = 60000;
val1 = battle_config.manner_system; //Mute filters.
if (sd)
{
@@ -8226,11 +8227,11 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_STONE:
- val3 = tick/1000; //Petrified HP-damage iterations.
+ val3 = total_tick/1000; //Petrified HP-damage iterations.
if(val3 < 1) val3 = 1;
- tick = val4; //Petrifying time.
+ total_tick = val4; //Petrifying time.
if(val4 > 500) // not with WL_SIENNAEXECRATE
- tick = max(tick, 1000); //Min time
+ total_tick = max(total_tick, 1000); //Min time
calc_flag = 0; //Actual status changes take effect on petrified state.
break;
@@ -8249,7 +8250,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
}
// fall through
case SC_POISON:
- val3 = tick/1000; //Damage iterations
+ val3 = total_tick/1000; //Damage iterations
if(val3 < 1) val3 = 1;
tick_time = 1000; // [GodLesZ] tick time
//val4: HP damage
@@ -8263,7 +8264,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
clif->emotion(bl,E_WHAT);
break;
case SC_BLOODING:
- val4 = tick/10000;
+ val4 = total_tick/10000;
if (!val4) val4 = 1;
tick_time = 10000; // [GodLesZ] tick time
break;
@@ -8276,7 +8277,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
// val2 = seconds between heals
// val4 = total of heals
if (val2 < 1) val2 = 1;
- if ((val4 = tick / (val2 * 1000)) < 1)
+ if ((val4 = total_tick / (val2 * 1000)) < 1)
val4 = 1;
tick_time = val2 * 1000; // [GodLesZ] tick time
break;
@@ -8289,19 +8290,19 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
return 0; // No need to start SC
}
val1 = boss_md->bl.id;
- if( (val4 = tick/1000) < 1 )
+ if( (val4 = total_tick/1000) < 1 )
val4 = 1;
tick_time = 1000; // [GodLesZ] tick time
}
break;
case SC_HIDING:
- val2 = tick/1000;
+ val2 = total_tick/1000;
tick_time = 1000; // [GodLesZ] tick time
val3 = 0; // unused, previously speed adjustment
val4 = val1+3; //Seconds before SP substraction happen.
break;
case SC_CHASEWALK:
- val2 = tick>0?tick:10000; //Interval at which SP is drained.
+ val2 = total_tick>0?total_tick:10000; //Interval at which SP is drained.
val3 = 35 - 5 * val1; //Speed adjustment.
if (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_ROGUE)
val3 -= 40;
@@ -8311,8 +8312,8 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_CLOAKING:
if (!sd) //Monsters should be able to walk with no penalties. [Skotlex]
val1 = 10;
- tick_time = val2 = tick>0?tick:60000; //SP consumption rate.
- tick = INFINITE_DURATION; // duration sent to the client should be infinite
+ tick_time = val2 = total_tick>0?total_tick:60000; //SP consumption rate.
+ total_tick = INFINITE_DURATION; // duration sent to the client should be infinite
val3 = 0; // unused, previously walk speed adjustment
//val4&1 signals the presence of a wall.
//val4&2 makes cloak not end on normal attacks [Skotlex]
@@ -8326,7 +8327,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_RUWACH:
case SC_WZ_SIGHTBLASTER:
val3 = skill->get_splash(val2, val1); //Val2 should bring the skill-id.
- val2 = tick/20;
+ val2 = total_tick/20;
tick_time = 20; // [GodLesZ] tick time
break;
@@ -8344,7 +8345,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_DODGE_READY:
case SC_PUSH_CART:
case SC_DAILYSENDMAILCNT:
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_AUTOGUARD:
@@ -8360,12 +8361,12 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
if( sd ) {
for( i = 0; i < MAX_PC_DEVOTION; i++ ) {
if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL)
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
} else if (bl->type == BL_MER) {
struct mercenary_data *mc = BL_UCAST(BL_MER, bl);
if (mc->devotion_flag && (tsd = mc->master) != NULL) {
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
}
}
@@ -8384,7 +8385,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
for (i = 0; i < MAX_PC_DEVOTION; i++) {
//See if there are devoted characters, and pass the status to them. [Skotlex]
if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL)
- status->change_start(bl, &tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,SCFLAG_NOAVOID);
+ status->change_start(bl, &tsd->bl,type,10000,val1,5+val1*5,val3,val4,total_tick,SCFLAG_NOAVOID);
}
}
}
@@ -8397,8 +8398,8 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
}
val2 = 12; //SP cost
val4 = 10000; //Decrease at 10secs intervals.
- val3 = tick/val4;
- tick = INFINITE_DURATION; // duration sent to the client should be infinite
+ val3 = total_tick/val4;
+ total_tick = INFINITE_DURATION; // duration sent to the client should be infinite
tick_time = val4; // [GodLesZ] tick time
break;
case SC_PARRYING:
@@ -8416,21 +8417,21 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_BERSERK:
if( val3 == SC__BLOODYLUST )
- sc_start(src,bl,(sc_type)val3,100,val1,tick);
+ sc_start(src,bl,(sc_type)val3,100,val1,total_tick);
if (!val3 && (!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4))
- sc_start4(src, bl, SC_ENDURE, 100,10,0,0,2, tick);
+ sc_start4(src, bl, SC_ENDURE, 100,10,0,0,2, total_tick);
//HP healing is performing after the calc_status call.
//Val2 holds HP penalty
if (!val4) val4 = skill->get_time2(status->sc2skill(type),val1);
if (!val4) val4 = 10000; //Val4 holds damage interval
- val3 = tick/val4; //val3 holds skill duration
+ val3 = total_tick/val4; //val3 holds skill duration
tick_time = val4; // [GodLesZ] tick time
break;
case SC_GOSPEL:
if(val4 == BCT_SELF) {
// self effect
- val2 = tick/10000;
+ val2 = total_tick/10000;
tick_time = 10000; // [GodLesZ] tick time
status->change_clear_buffs(bl,3); //Remove buffs/debuffs
}
@@ -8494,12 +8495,12 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_SWORDREJECT:
val2 = 15*val1; //Reflect chance
val3 = 3; //Reflections
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_MEMORIZE:
val2 = 5; //Memorized casts.
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_GRAVITATION:
@@ -8553,11 +8554,11 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
struct status_change_entry *sce2 = sc2 ? sc2->data[SC_RG_CCONFINE_M] : NULL;
if (src2 && sc2) {
if (!sce2) //Start lock on caster.
- sc_start4(src,src2,SC_RG_CCONFINE_M,100,val1,1,0,0,tick+1000);
+ sc_start4(src,src2,SC_RG_CCONFINE_M,100,val1,1,0,0,total_tick+1000);
else { //Increase count of locked enemies and refresh time.
(sce2->val2)++;
timer->delete(sce2->timer, status->change_timer);
- sce2->timer = timer->add(timer->gettick()+tick+1000, status->change_timer, src2->id, SC_RG_CCONFINE_M);
+ sce2->timer = timer->add(timer->gettick()+total_tick+1000, status->change_timer, src2->id, SC_RG_CCONFINE_M);
}
} else //Status failed.
return 0;
@@ -8593,13 +8594,13 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
//val4: TK: Combo time
struct unit_data *ud = unit->bl2ud(bl);
if( ud && (!val3 || val3 == 2) ) {
- tick += 300 * battle_config.combo_delay_rate/100;
- ud->attackabletime = timer->gettick()+tick;
+ total_tick += 300 * battle_config.combo_delay_rate/100;
+ ud->attackabletime = timer->gettick()+total_tick;
if( !val3 )
- unit->set_walkdelay(bl, timer->gettick(), tick, 1);
+ unit->set_walkdelay(bl, timer->gettick(), total_tick, 1);
}
val3 = 0;
- val4 = tick;
+ val4 = total_tick;
break;
}
case SC_EARTHSCROLL:
@@ -8613,7 +8614,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val3 = (int)(currenttick&0x00000000ffffffffLL);
val4 = (int)((currenttick&0xffffffff00000000LL)>>32);
}
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_KAAHI:
val2 = 200*val1; //HP heal
@@ -8628,7 +8629,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_TRICKDEAD:
if (vd) vd->dead_sit = 1;
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_CONCENTRATION:
val2 = 2 + val1;
@@ -8646,7 +8647,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
//val2 holds if it was casted on self, or is bonus received from others
val3 = 5*val1; //Power increase
if(sd && pc->checkskill(sd,BS_HILTBINDING)>0)
- tick += tick / 10;
+ total_tick += total_tick / 10;
break;
case SC_ADRENALINE2:
case SC_ADRENALINE:
@@ -8654,13 +8655,13 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
FALLTHROUGH
case SC_WEAPONPERFECT:
if(sd && pc->checkskill(sd,BS_HILTBINDING)>0)
- tick += tick / 10;
+ total_tick += total_tick / 10;
break;
case SC_LKCONCENTRATION:
val2 = 5*val1; //Batk/Watk Increase
val3 = 10*val1; //Hit Increase
val4 = 5*val1; //Def reduction
- sc_start(src, bl, SC_ENDURE, 100, 1, tick); //Endure effect
+ sc_start(src, bl, SC_ENDURE, 100, 1, total_tick); //Endure effect
break;
case SC_ANGELUS:
val2 = 5*val1; //def increase
@@ -8730,7 +8731,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val3 = 12*val1; //mdef2 reduction.
break;
case SC_SKA:
- val2 = tick/1000;
+ val2 = total_tick/1000;
val3 = rnd()%100; //Def changes randomly every second...
tick_time = 1000; // [GodLesZ] tick time
break;
@@ -8743,7 +8744,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
// When renewing status' information
// val3 Return map_index
// val4 return coordinates
- tick = val1>0?1000:250;
+ total_tick = val1>0?1000:250;
if (sd)
{
if (sd->mapindex != val2)
@@ -8778,11 +8779,11 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_SWOO:
if(st->mode&MD_BOSS)
- tick /= 5; //TODO: Reduce skill's duration. But for how long?
+ total_tick /= 5; //TODO: Reduce skill's duration. But for how long?
break;
case SC_SPIDERWEB:
if( bl->type == BL_PC )
- tick /= 2;
+ total_tick /= 2;
break;
case SC_ARMOR:
//NPC_DEFENDER:
@@ -8848,7 +8849,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val2 = 10*val1; //% of life to be revived with
break;
case SC_ARMORPROPERTY:
- clif->status_change(bl, (val1 > 0 ? SI_RESIST_PROPERTY_WATER : (val2 > 0 ? SI_RESIST_PROPERTY_GROUND : (val3 > 0 ? SI_RESIST_PROPERTY_FIRE : (val4 > 0 ? SI_RESIST_PROPERTY_WIND : SI_BLANK)))), 1, tick, 0, 0, 0);
+ clif->status_change(bl, (val1 > 0 ? SI_RESIST_PROPERTY_WATER : (val2 > 0 ? SI_RESIST_PROPERTY_GROUND : (val3 > 0 ? SI_RESIST_PROPERTY_FIRE : (val4 > 0 ? SI_RESIST_PROPERTY_WIND : SI_BLANK)))), 1, total_tick, 0, 0, 0);
break;
// case SC_ARMOR_RESIST:
// Mod your resistance against elements:
@@ -8890,11 +8891,11 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
**/
case SC_FEAR:
val2 = 2;
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_BURNING:
- val4 = tick / 3000; // Total Ticks to Burn!!
+ val4 = total_tick / 3000; // Total Ticks to Burn!!
tick_time = 3000; // [GodLesZ] tick time
break;
/**
@@ -8908,14 +8909,14 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val1 = sd->status.job_level * pc->checkskill(sd, RK_RUNEMASTERY) / 4; //DEF/MDEF Increase
break;
case SC_ABUNDANCE:
- val4 = tick / 10000;
+ val4 = total_tick / 10000;
tick_time = 10000; // [GodLesZ] tick time
break;
/**
* Arch Bishop
**/
case SC_RENOVATIO:
- val4 = tick / 5000;
+ val4 = total_tick / 5000;
tick_time = 5000;
break;
case SC_SECRAMENT:
@@ -8926,28 +8927,28 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_WEAPONBLOCKING:
val2 = 10 + 2 * val1; // Chance
- val4 = tick / 5000;
+ val4 = total_tick / 5000;
tick_time = 5000; // [GodLesZ] tick time
break;
case SC_TOXIN:
- val4 = tick / 10000;
+ val4 = total_tick / 10000;
tick_time = 10000; // [GodLesZ] tick time
break;
case SC_MAGICMUSHROOM:
- val4 = tick / 4000;
+ val4 = total_tick / 4000;
tick_time = 4000; // [GodLesZ] tick time
break;
case SC_PYREXIA:
status->change_start(src, bl,SC_BLIND,10000,val1,0,0,0,30000,SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE); // Blind status that last for 30 seconds
- val4 = tick / 3000;
+ val4 = total_tick / 3000;
tick_time = 3000; // [GodLesZ] tick time
break;
case SC_LEECHESEND:
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_OBLIVIONCURSE:
- val4 = tick / 3000;
+ val4 = total_tick / 3000;
tick_time = 3000; // [GodLesZ] tick time
break;
case SC_CLOAKINGEXCEED:
@@ -8986,7 +8987,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_SUMMON3:
case SC_SUMMON4:
case SC_SUMMON5:
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
if( val4 < 1 )
val4 = 1;
tick_time = 1000; // [GodLesZ] tick time
@@ -9001,19 +9002,19 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
}
break;
case SC_STEALTHFIELD_MASTER:
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 2000 + (1000 * val1);
break;
case SC_ELECTRICSHOCKER:
case SC_COLD:
case SC_MEIKYOUSISUI:
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
if( val4 < 1 )
val4 = 1;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_CAMOUFLAGE:
- val4 = tick/1000;
+ val4 = total_tick/1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_WUGDASH:
@@ -9024,17 +9025,17 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val3 = (int)(currenttick&0x00000000ffffffffLL);
val4 = (int)((currenttick&0xffffffff00000000LL)>>32);
}
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC__REPRODUCE:
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000;
break;
case SC__SHADOWFORM: {
struct map_session_data * s_sd = map->id2sd(val2);
if( s_sd )
s_sd->shadowform_id = bl->id;
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
}
break;
@@ -9045,7 +9046,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC__INVISIBILITY:
val2 = 50 - 10 * val1; // ASPD
val3 = 200 * val1; // CRITICAL
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC__ENERVATION:
@@ -9087,8 +9088,8 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC__WEAKNESS:
val2 = 10 * val1;
// bypasses coating protection and MADO
- sc_start(src, bl,SC_NOEQUIPWEAPON,100,val1,tick);
- sc_start(src, bl,SC_NOEQUIPSHIELD,100,val1,tick);
+ sc_start(src, bl,SC_NOEQUIPWEAPON,100,val1,total_tick);
+ sc_start(src, bl,SC_NOEQUIPSHIELD,100,val1,total_tick);
break;
case SC_GN_CARTBOOST:
if( val1 < 3 )
@@ -9108,7 +9109,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_STRIKING:
val1 = 6 - val1;//spcost = 6 - level (lvl1:5 ... lvl 5: 1)
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_BLOOD_SUCKER:
@@ -9117,7 +9118,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val3 = 1;
if(src2)
val3 = 200 + 100 * val1 + status_get_int(src2);
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
}
break;
@@ -9138,22 +9139,22 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val2 = 5 + 5 * val1;
break;
case SC_SIREN:
- val4 = tick / 2000;
+ val4 = total_tick / 2000;
tick_time = 2000; // [GodLesZ] tick time
break;
case SC_DEEP_SLEEP:
- val4 = tick / 2000;
+ val4 = total_tick / 2000;
tick_time = 2000; // [GodLesZ] tick time
break;
case SC_SIRCLEOFNATURE:
val2 = 40 * val1;//HP recovery
val3 = 4 * val1;//SP drain
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_SONG_OF_MANA:
val3 = 10 + 5 * val2;
- val4 = tick/5000;
+ val4 = total_tick/5000;
tick_time = 5000; // [GodLesZ] tick time
break;
case SC_SATURDAY_NIGHT_FEVER:
@@ -9161,7 +9162,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
if ( val2 < 1000 )
val2 = 1000;//Added to prevent val3 from dividing by 0 when using level 6 or higher through commands. [Rytech]
val3 = tick/val2;*/
- val3 = tick / 3000;
+ val3 = total_tick / 3000;
tick_time = 3000;// [GodLesZ] tick time
break;
case SC_GLOOMYDAY:
@@ -9197,7 +9198,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_MELODYOFSINK:
val3 = val1 * (2 + val2);//INT Reduction. Formula Includes Caster And 2nd Performer.
- val4 = tick/1000;
+ val4 = total_tick/1000;
tick_time = 1000;
break;
case SC_BEYOND_OF_WARCRY:
@@ -9215,13 +9216,13 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_LG_REFLECTDAMAGE:
val2 = 15 + 5 * val1;
val3 = 25 + 5 * val1; //Number of Reflects
- val4 = tick/1000;
+ val4 = total_tick/1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_FORCEOFVANGUARD:
val2 = 8 + 12 * val1; // Chance
val3 = 5 + 2 * val1; // Max rage counters
- tick = INFINITE_DURATION; //endless duration in the client
+ total_tick = INFINITE_DURATION; //endless duration in the client
break;
case SC_EXEEDBREAK:
if( sd ){
@@ -9244,7 +9245,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
tick_time = 5000; // [GodLesZ] tick time
break;
case SC_MAGNETICFIELD:
- val3 = tick / 1000;
+ val3 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_INSPIRATION:
@@ -9252,7 +9253,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val2 = 40 * val1 + 3 * sd->status.job_level;// ATK bonus
val3 = sd->status.base_level / 10 + sd->status.job_level / 5;// All stat bonus
}
- val4 = tick / 5000;
+ val4 = total_tick / 5000;
tick_time = 5000; // [GodLesZ] tick time
status->change_clear_buffs(bl,3); //Remove buffs/debuffs
break;
@@ -9263,7 +9264,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val1 = (sd?sd->status.job_level:2)/2 + 40 + 5 * val1;
break;
case SC_RAISINGDRAGON:
- val3 = tick / 5000;
+ val3 = total_tick / 5000;
tick_time = 5000; // [GodLesZ] tick time
break;
case SC_GENTLETOUCH_CHANGE:
@@ -9373,7 +9374,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_STONE_SHIELD:
val2 += 5;
val3 += 1000;
- val4 = tick;
+ val4 = total_tick;
tick_time = val3;
break;
case SC_WATER_BARRIER:
@@ -9396,18 +9397,18 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_STOMACHACHE:
val3 = 8; // SP consume.
- val4 = tick / 10000;
+ val4 = total_tick / 10000;
tick_time = 10000; // [GodLesZ] tick time
break;
case SC_STEAMPACK: // [Frost]
val3 = 100; // HP Consume.
- val4 = tick / 10000;
+ val4 = total_tick / 10000;
tick_time = 10000;
- sc_start(src, bl, SC_ENDURE, 100, 10, tick); // Endure effect
+ sc_start(src, bl, SC_ENDURE, 100, 10, total_tick); // Endure effect
break;
case SC_MAGIC_CANDY: // [Frost]
val3 = 90; // SP Consume.
- val4 = tick / 10000;
+ val4 = total_tick / 10000;
tick_time = 10000;
break;
case SC_PROMOTE_HEALTH_RESERCH:
@@ -9446,7 +9447,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val3 = val1 * 2;
FALLTHROUGH
case SC_IZAYOI:
- val2 = tick/1000;
+ val2 = total_tick/1000;
tick_time = 1000;
break;
case SC_ZANGETSU:
@@ -9486,12 +9487,12 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_ANGRIFFS_MODUS:
val2 = 50 + 20 * val1; //atk bonus
val3 = 40 + 20 * val1; // Flee reduction.
- val4 = tick/1000; // hp/sp reduction timer
+ val4 = total_tick/1000; // hp/sp reduction timer
tick_time = 1000;
break;
case SC_NEUTRALBARRIER:
- tick_time = tick;
- tick = INFINITE_DURATION;
+ tick_time = total_tick;
+ total_tick = INFINITE_DURATION;
break;
case SC_GOLDENE_FERSE:
val2 = 10 + 10*val1; //max hp bonus
@@ -9520,10 +9521,10 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val2 = 2*val1; //aspd reduction %
val3 = 2*val1; //dmg reduction %
if(sc->data[SC_NEEDLE_OF_PARALYZE])
- sc_start(src, bl, SC_ENDURE, 100, val1, tick); //start endure for same duration
+ sc_start(src, bl, SC_ENDURE, 100, val1, total_tick); //start endure for same duration
break;
case SC_STYLE_CHANGE: //[Lighta] need real info
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
if(val2 == MH_MD_FIGHTING) val2 = MH_MD_GRAPPLING;
else val2 = MH_MD_FIGHTING;
break;
@@ -9531,12 +9532,12 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
status_percent_heal(bl,100,0);
val2 = 7 - val1;
tick_time = 1000;
- val4 = tick / tick_time;
+ val4 = total_tick / tick_time;
break;
case SC_KINGS_GRACE:
val2 = 3 + val1;
tick_time = 1000;
- val4 = tick / tick_time;
+ val4 = total_tick / tick_time;
break;
case SC_TELEKINESIS_INTENSE:
val2 = 10 * val1;
@@ -9549,7 +9550,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val2 = 5 * val1;
val3 = (20 * val1) + 80;
tick_time = 1000;
- val4 = tick / tick_time;
+ val4 = total_tick / tick_time;
break;
case SC_DARKCROW:
val2 = 30 * val1;
@@ -9560,7 +9561,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_SPRITEMABLE:
case SC_ALL_RIDING:
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_FLASHCOMBO:
/**
@@ -9573,7 +9574,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
* Summoner
*/
case SC_FRESHSHRIMP:
- val4 = tick / (10000 - ((val1 - 1) * 1000));
+ val4 = total_tick / (10000 - ((val1 - 1) * 1000));
tick_time = 10000 - ((val1 - 1) * 1000);
if (val4 <= 0) // Prevents a negeative value from happening
val4 = 0;
@@ -9589,7 +9590,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_BITESCAR:
val2 = 2 * val1; // MHP% damage
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000;
break;
case SC_SHRIMP:
@@ -9600,7 +9601,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val3 = 25 * val1; // Move speed reduction
break;
default:
- if (status->change_start_unknown_sc(src, bl, type, calc_flag, rate, val1, val2, val3, val4, tick, flag)) {
+ if (status->change_start_unknown_sc(src, bl, type, calc_flag, rate, val1, val2, val3, val4, total_tick, flag)) {
return 0;
}
}
@@ -9670,13 +9671,15 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
}
#endif
- if(!(flag&SCFLAG_NOICON) && !(flag&SCFLAG_LOADED && status->dbs->DisplayType[type]))
- clif->status_change(bl,status->dbs->IconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
+ if (!(flag & SCFLAG_LOADED))
+ tick = total_tick; // When starting a new SC (not loading), its remaining duration is the same as the total
+ if(!(flag & SCFLAG_NOICON) && !(flag & SCFLAG_LOADED && status->dbs->DisplayType[type]))
+ clif->status_change_sub(bl, status->dbs->IconChangeTable[type], 1, tick, total_tick, (val_flag & 1) ? val1 : 1, (val_flag & 2) ? val2 : 0, (val_flag & 4) ? val3 : 0);
/**
* used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first.
**/
- if( tick_time )
+ if(tick_time)
tick = tick_time;
//Don't trust the previous sce assignment, in case the SC ended somewhere between there and here.
@@ -9692,6 +9695,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
sce->val2 = val2;
sce->val3 = val3;
sce->val4 = val4;
+ sce->total_tick = total_tick;
if (tick >= 0) {
sce->timer = timer->add(timer->gettick() + tick, status->change_timer, bl->id, type);
@@ -9800,7 +9804,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
return 1;
}
-static bool status_change_start_unknown_sc(struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int tick, int flag)
+static bool status_change_start_unknown_sc(struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag)
{
Assert_retr(false, type >= SC_NONE && type < SC_MAX);
if (calc_flag == SCB_NONE && status->dbs->SkillChangeTable[type] == 0 && status->dbs->IconChangeTable[type] == 0) {
@@ -9811,6 +9815,28 @@ static bool status_change_start_unknown_sc(struct block_list *src, struct block_
return false;
}
+/**
+ * Starts a status change in its full duration.
+ *
+ * @param src Status change source bl.
+ * @param bl Status change target bl.
+ * @param type Status change type.
+ * @param rate Base success rate. 1 means 0.01%, 10000 means 100%.
+ * @param val1 Additional value (meaning depends on type).
+ * @param val2 Additional value (meaning depends on type).
+ * @param val3 Additional value (meaning depends on type).
+ * @param val4 Additional value (meaning depends on type).
+ * @param tick Base duration (milliseconds).
+ * @param flag Special flags (@see enum scstart_flag).
+ *
+ * @retval 0 if no status change happened.
+ * @retval 1 if the status change was successfully applied.
+ */
+static int status_change_start(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag)
+{
+ return status->change_start_sub(src, bl, type, rate, val1, val2, val3, val4, 0, tick, flag);
+}
+
static void status_change_start_display(struct map_session_data *sd, enum sc_type type, int val1, int val2, int val3, int val4)
{
Assert_retv(type >= SC_NONE && type < SC_MAX);
@@ -13635,6 +13661,7 @@ void status_defaults(void)
status->get_sc_def = status_get_sc_def;
status->change_start = status_change_start;
+ status->change_start_sub = status_change_start_sub;
status->change_end_ = status_change_end_;
status->kaahi_heal_timer = kaahi_heal_timer;
status->change_timer = status_change_timer;
diff --git a/src/map/status.h b/src/map/status.h
index 536003d04..e2280e409 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -2138,6 +2138,7 @@ struct sc_display_entry {
struct status_change_entry {
int timer;
+ int total_tick;
int val1,val2,val3,val4;
bool infinite_duration;
};
@@ -2306,6 +2307,7 @@ struct status_interface {
int (*isimmune) (struct block_list *bl);
int (*get_sc_def) (struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, int flag);
int (*change_start) (struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag);
+ int (*change_start_sub) (struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int total_tick, int flag);
int (*change_end_) (struct block_list* bl, enum sc_type type, int tid, const char* file, int line);
bool (*is_immune_to_status) (struct status_change* sc, enum sc_type type);
bool (*is_boss_resist_sc) (enum sc_type type);
@@ -2314,7 +2316,7 @@ struct status_interface {
int (*change_start_set_option) (struct block_list *bl, struct status_change* sc, enum sc_type type, int val1, int val2, int val3, int val4);
int (*get_val_flag) (enum sc_type type);
void (*change_start_display) (struct map_session_data *sd, enum sc_type type, int val1, int val2, int val3, int val4);
- bool (*change_start_unknown_sc) (struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int tick, int flag);
+ bool (*change_start_unknown_sc) (struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag);
int (*kaahi_heal_timer) (int tid, int64 tick, int id, intptr_t data);
int (*change_timer) (int tid, int64 tick, int id, intptr_t data);
int (*change_timer_sub) (struct block_list* bl, va_list ap);