Fixes statuses with tick intervals

* Adds a new storage location for these tick types.
* Reverts some of the tick_total variable assignments.
* Adjusts sc_start to account for 64 bit tick values.
Thanks to @eppc0330!
This commit is contained in:
aleos 2022-12-23 16:22:35 -05:00
parent 5676a45908
commit 50bd9cdfbe
10 changed files with 284 additions and 178 deletions

View File

@ -939,8 +939,9 @@ CREATE TABLE IF NOT EXISTS `sc_data` (
`account_id` int(11) unsigned NOT NULL,
`char_id` int(11) unsigned NOT NULL,
`type` smallint(11) unsigned NOT NULL,
`tick_total` bigint(20) NOT NULL,
`tick` bigint(20) NOT NULL,
`tick_total` bigint(20) NOT NULL,
`tick_time` bigint(20) NOT NULL,
`val1` int(11) NOT NULL default '0',
`val2` int(11) NOT NULL default '0',
`val3` int(11) NOT NULL default '0',

View File

@ -1,2 +1,5 @@
ALTER TABLE `sc_data` ADD COLUMN `tick_total` BIGINT(20) NOT NULL AFTER `tick`;
UPDATE `sc_data` SET `tick_total` = `tick`;
ALTER TABLE `sc_data` ADD COLUMN `tick_time` BIGINT(20) NOT NULL AFTER `tick_total`;
UPDATE `sc_data` SET `tick_time` = `tick`;

View File

@ -2380,7 +2380,7 @@ bool char_checkdb(void){
return false;
}
//checking scdata_db
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`char_id`,`type`,`tick`,`tick_total`,`val1`,`val2`,`val3`,`val4`"
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`char_id`,`type`,`tick`,`tick_total`,`tick_time`,`val1`,`val2`,`val3`,`val4`"
" FROM `%s` LIMIT 1;", schema_config.scdata_db) ){
Sql_ShowDebug(sql_handle);
return false;

View File

@ -279,7 +279,7 @@ int chmapif_parse_askscdata(int fd){
int aid, cid;
aid = RFIFOL(fd,2);
cid = RFIFOL(fd,6);
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT type, tick, val1, val2, val3, val4, tick_total from `%s` WHERE `account_id` = '%d' AND `char_id`='%d'",
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT type, tick, val1, val2, val3, val4, tick_total, tick_time from `%s` WHERE `account_id` = '%d' AND `char_id`='%d'",
schema_config.scdata_db, aid, cid) )
{
Sql_ShowDebug(sql_handle);
@ -304,6 +304,7 @@ int chmapif_parse_askscdata(int fd){
Sql_GetData(sql_handle, 4, &data, NULL); scdata.val3 = atoi(data);
Sql_GetData(sql_handle, 5, &data, NULL); scdata.val4 = atoi(data);
Sql_GetData(sql_handle, 6, &data, NULL); scdata.tick_total = strtoll(data, nullptr, 10);
Sql_GetData(sql_handle, 7, &data, NULL); scdata.tick_time = strtoll(data, nullptr, 10);
memcpy(WFIFOP(fd, 14+count*sizeof(struct status_change_data)), &scdata, sizeof(struct status_change_data));
}
if (count >= 50)
@ -943,14 +944,14 @@ int chmapif_parse_save_scdata(int fd){
int i;
StringBuf_Init(&buf);
StringBuf_Printf(&buf, "INSERT INTO `%s` (`account_id`, `char_id`, `type`, `tick`, `tick_total`, `val1`, `val2`, `val3`, `val4`) VALUES ", schema_config.scdata_db);
StringBuf_Printf(&buf, "INSERT INTO `%s` (`account_id`, `char_id`, `type`, `tick`, `tick_total`, `tick_time`, `val1`, `val2`, `val3`, `val4`) VALUES ", schema_config.scdata_db);
for( i = 0; i < count; ++i )
{
memcpy (&data, RFIFOP(fd, 14+i*sizeof(struct status_change_data)), sizeof(struct status_change_data));
if( i > 0 )
StringBuf_AppendStr(&buf, ", ");
StringBuf_Printf(&buf, "('%d','%d','%hu','%" PRtf "','%" PRtf "','%ld','%ld','%ld','%ld')", aid, cid,
data.type, data.tick, data.tick_total, data.val1, data.val2, data.val3, data.val4);
StringBuf_Printf(&buf, "('%d','%d','%hu','%" PRtf "','%" PRtf "','%" PRtf "','%ld','%ld','%ld','%ld')", aid, cid,
data.type, data.tick, data.tick_total, data.tick_time, data.val1, data.val2, data.val3, data.val4);
}
if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
Sql_ShowDebug(sql_handle);

View File

@ -403,6 +403,7 @@ struct status_change_data {
long val1, val2, val3, val4;
t_tick tick; //Remaining duration.
t_tick tick_total; // Total duration
t_tick tick_time; // Interval duration
};
#define MAX_BONUS_SCRIPT_LENGTH 512

View File

@ -1339,7 +1339,15 @@ int chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the
data.tick = 0; //Negative tick does not necessarily mean that sc has expired
} else
data.tick = INFINITE_TICK; //Infinite duration
data.tick_total = sc->getSCE(i)->tick_total;
if (sce->tick_timer != INVALID_TIMER) {
timer = get_timer(sce->tick_timer);
if (timer == nullptr || timer->func != status_change_tick_timer)
continue;
if (DIFF_TICK(timer->tick, tick) >= 0)
data.tick_time = DIFF_TICK(timer->tick, tick);
} else
data.tick_time = 0;
data.tick_total = sce->tick_total;
data.type = i;
data.val1 = sce->val1;
data.val2 = sce->val2;
@ -1423,7 +1431,7 @@ int chrif_load_scdata(int fd) {
for (i = 0; i < count; i++) {
struct status_change_data *data = (struct status_change_data*)RFIFOP(fd,14 + i*sizeof(struct status_change_data));
status_change_start_sub(NULL,&sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, data->tick_total, SCSTART_NOAVOID|SCSTART_NOTICKDEF|SCSTART_LOADED|SCSTART_NORATEDEF);
status_change_start_sub(NULL,&sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, data->tick_total, data->tick_time, SCSTART_NOAVOID|SCSTART_NOTICKDEF|SCSTART_LOADED|SCSTART_NORATEDEF);
}
pc_scdata_received(sd);

View File

@ -6382,9 +6382,9 @@ void clif_status_change_sub(struct block_list *bl, int id, int type, int flag, t
#if PACKETVER >= 20090121
if (battle_config.display_status_timers > 0) {
#if PACKETVER >= 20120618
p.Total = client_tick(tick_total);
p.Total = client_tick(tick);
#endif
p.Left = client_tick(tick);
p.Left = client_tick(tick_total);
p.val1 = val1;
p.val2 = val2;
p.val3 = val3;
@ -6445,8 +6445,7 @@ void clif_efst_status_change_sub(struct block_list *tbl, struct block_list *bl,
enum sc_type type = sc_display[i]->type;
struct status_change *sc = status_get_sc(bl);
const TimerData *td = (sc && sc->getSCE(type) ? get_timer(sc->getSCE(type)->timer) : nullptr);
t_tick tick_total = 0, tick = 0, cur_tick = gettick();
tick_total = DIFF_TICK(sc->getSCE(type)->tick_total, cur_tick);
t_tick tick = 0, cur_tick = gettick();
if (td != nullptr)
tick = DIFF_TICK(td->tick, cur_tick);
@ -6470,7 +6469,7 @@ void clif_efst_status_change_sub(struct block_list *tbl, struct block_list *bl,
}
#if PACKETVER > 20120418
clif_efst_status_change(tbl, bl->id, target, status_db.getIcon(type), tick_total, tick, sc_display[i]->val1, sc_display[i]->val2, sc_display[i]->val3);
clif_efst_status_change(tbl, bl->id, target, status_db.getIcon(type), sc->getSCE(type)->tick_total, tick, sc_display[i]->val1, sc_display[i]->val2, sc_display[i]->val3);
#else
clif_status_change_sub(tbl, bl->id, status_db.getIcon(type), 1, tick, tick sc_display[i]->val1, sc_display[i]->val2, sc_display[i]->val3, target);
#endif

View File

@ -12233,7 +12233,8 @@ BUILDIN_FUNC(sc_start)
TBL_NPC * nd = map_id2nd(st->oid);
struct block_list* bl;
enum sc_type type;
int tick, val1, val2, val3, val4=0, rate, flag;
int val1, val2, val3, val4=0, rate, flag;
t_tick tick;
char start_type;
const char* command = script_getfuncname(st);
@ -12245,7 +12246,7 @@ BUILDIN_FUNC(sc_start)
start_type = 1;
type = (sc_type)script_getnum(st,2);
tick = script_getnum(st,3);
tick = script_getnum64(st,3);
val1 = script_getnum(st,4);
//If from NPC we make default flag 1 to be unavoidable

File diff suppressed because it is too large Load Diff

View File

@ -3130,7 +3130,8 @@ struct sc_display_entry {
struct status_change_entry {
int timer;
int val1,val2,val3,val4;
t_tick tick_total;
int tick_timer; // Timer for the next interval based timer execution
t_tick tick_total; // Total amount of time the status is active for
};
///Status change
@ -3314,7 +3315,7 @@ int status_isimmune(struct block_list *bl);
t_tick status_get_sc_def(struct block_list *src,struct block_list *bl, enum sc_type type, int rate, t_tick tick, unsigned char flag);
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,t_tick duration,unsigned char flag, int32 delay = 0);
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, t_tick duration, t_tick duration_total, unsigned char flag, int32 delay = 0);
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, t_tick duration, t_tick duration_total, t_tick duration_tick, unsigned char flag, int32 delay = 0);
//Short version, receives rate in 1->100 range, and does not uses a flag setting.
static int sc_start(block_list *src, block_list *bl, sc_type type, int32 rate, int32 val1, t_tick duration, int32 delay = 0) {
return status_change_start(src, bl, type, 100 * rate, val1, 0, 0, 0, duration, SCSTART_NONE, delay);
@ -3327,6 +3328,7 @@ static int sc_start4(block_list *src, block_list *bl, sc_type type, int32 rate,
}
int status_change_end(struct block_list* bl, enum sc_type type, int tid = INVALID_TIMER);
TIMER_FUNC(status_change_timer);
TIMER_FUNC(status_change_tick_timer);
int status_change_timer_sub(struct block_list* bl, va_list ap);
int status_change_clear(struct block_list* bl, int type);
void status_change_clear_buffs(struct block_list* bl, uint8 type);