diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/chrif.c | 5 | ||||
-rw-r--r-- | src/map/clif.c | 18 | ||||
-rw-r--r-- | src/map/clif.h | 3 | ||||
-rw-r--r-- | src/map/status.c | 47 | ||||
-rw-r--r-- | src/map/status.h | 4 |
5 files changed, 58 insertions, 19 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 f6caa502e..7d98fcb82 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) @@ -23676,9 +23683,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: @@ -23896,6 +23903,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 d24da4180..a2c11de14 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 total_tick Total 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 total_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; } @@ -9670,14 +9671,16 @@ 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,total_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 ) - total_tick = 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. if((sce=sc->data[type])) {// reuse old sc @@ -9692,9 +9695,10 @@ 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 (total_tick >= 0) { - sce->timer = timer->add(timer->gettick() + total_tick, status->change_timer, bl->id, type); + if (tick >= 0) { + sce->timer = timer->add(timer->gettick() + tick, status->change_timer, bl->id, type); sce->infinite_duration = false; } else { sce->timer = INVALID_TIMER; //Infinite duration @@ -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); @@ -13633,6 +13659,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 67cc3b3b4..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; }; @@ -2305,7 +2306,8 @@ struct status_interface { int (*isdead) (struct block_list *bl); 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 total_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); |