diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/map/date.c | 7 | ||||
-rw-r--r-- | src/map/date.h | 1 | ||||
-rw-r--r-- | src/map/pc.c | 3 | ||||
-rw-r--r-- | src/map/quest.c | 21 | ||||
-rw-r--r-- | src/map/quest.h | 2 | ||||
-rw-r--r-- | src/map/script.c | 170 | ||||
-rw-r--r-- | src/plugins/HPMHooking/HPMHooking.Defs.inc | 4 | ||||
-rw-r--r-- | src/plugins/HPMHooking/HPMHooking_map.Hooks.inc | 12 |
8 files changed, 196 insertions, 24 deletions
diff --git a/src/map/date.c b/src/map/date.c index a20578e51..20ab9fe95 100644 --- a/src/map/date.c +++ b/src/map/date.c @@ -77,6 +77,13 @@ int date_get_sec(void) return lt->tm_sec; } +int date_get_dayofweek(void) +{ + time_t t = time(NULL); + struct tm *lt = localtime(&t); + return lt->tm_wday; +} + /*========================================== * Star gladiator related checks *------------------------------------------*/ diff --git a/src/map/date.h b/src/map/date.h index 3a109d1ad..ac0a3a7fa 100644 --- a/src/map/date.h +++ b/src/map/date.h @@ -31,6 +31,7 @@ int date_get_day(void); int date_get_hour(void); int date_get_min(void); int date_get_sec(void); +int date_get_dayofweek(void); bool is_day_of_sun(void); bool is_day_of_moon(void); diff --git a/src/map/pc.c b/src/map/pc.c index aedb029b6..a925b523c 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5118,9 +5118,8 @@ int pc_useitem(struct map_session_data *sd,int n) { clif->msgtable_num(sd, MSG_SECONDS_UNTIL_USE, delay_tick + 1); // [%d] seconds left until you can use #else char delay_msg[100]; - clif->msgtable_num(sd, MSG_SECONDS_UNTIL_USE, delay_tick + 1); // [%d] seconds left until you can use sprintf(delay_msg, msg_sd(sd, 26), delay_tick + 1); - clif->messagecolor_self(sd->fd, COLOR_YELLOW, delay_msg); + clif->messagecolor_self(sd->fd, COLOR_YELLOW, delay_msg); // [%d] seconds left until you can use #endif return 0; // Delay has not expired yet } diff --git a/src/map/quest.c b/src/map/quest.c index ed8e5bd33..4e3362adb 100644 --- a/src/map/quest.c +++ b/src/map/quest.c @@ -103,22 +103,23 @@ int quest_pc_login(struct map_session_data *sd) * * New quest will be added as Q_ACTIVE. * - * @param sd Player's data - * @param quest_id ID of the quest to add. + * @param sd Player's data + * @param quest_id ID of the quest to add. + * @param time_limit Custom time, in UNIX epoch, for this quest * @return 0 in case of success, nonzero otherwise */ -int quest_add(struct map_session_data *sd, int quest_id) +int quest_add(struct map_session_data *sd, int quest_id, unsigned int time_limit) { int n; struct quest_db *qi = quest->db(quest_id); nullpo_retr(-1, sd); - if( qi == &quest->dummy ) { + if (qi == &quest->dummy) { ShowError("quest_add: quest %d not found in DB.\n", quest_id); return -1; } - if( quest->check(sd, quest_id, HAVEQUEST) >= 0 ) { + if (quest->check(sd, quest_id, HAVEQUEST) >= 0) { ShowError("quest_add: Character %d already has quest %d.\n", sd->status.char_id, quest_id); return -1; } @@ -130,7 +131,7 @@ int quest_add(struct map_session_data *sd, int quest_id) sd->avail_quests++; RECREATE(sd->quest_log, struct quest, sd->num_quests); - if( sd->avail_quests != sd->num_quests ) { + if (sd->avail_quests != sd->num_quests) { // The character has some completed quests, make room before them so that they will stay at the end of the array memmove(&sd->quest_log[n+1], &sd->quest_log[n], sizeof(struct quest)*(sd->num_quests-sd->avail_quests)); } @@ -138,7 +139,9 @@ int quest_add(struct map_session_data *sd, int quest_id) memset(&sd->quest_log[n], 0, sizeof(struct quest)); sd->quest_log[n].quest_id = qi->id; - if( qi->time ) + if (time_limit != 0) + sd->quest_log[n].time = time_limit; + else if (qi->time != 0) sd->quest_log[n].time = (unsigned int)(time(NULL) + qi->time); sd->quest_log[n].state = Q_ACTIVE; @@ -147,8 +150,8 @@ int quest_add(struct map_session_data *sd, int quest_id) clif->quest_add(sd, &sd->quest_log[n]); clif->quest_update_objective(sd, &sd->quest_log[n]); - if( map->save_settings&64 ) - chrif->save(sd,0); + if ((map->save_settings & 64) != 0) + chrif->save(sd, 0); return 0; } diff --git a/src/map/quest.h b/src/map/quest.h index 8837a1fb6..dda7c2c0a 100644 --- a/src/map/quest.h +++ b/src/map/quest.h @@ -69,7 +69,7 @@ struct quest_interface { /* */ struct quest_db *(*db) (int quest_id); int (*pc_login) (struct map_session_data *sd); - int (*add) (struct map_session_data *sd, int quest_id); + int (*add) (struct map_session_data *sd, int quest_id, unsigned int time_limit); int (*change) (struct map_session_data *sd, int qid1, int qid2); int (*delete) (struct map_session_data *sd, int quest_id); int (*update_objective_sub) (struct block_list *bl, va_list ap); diff --git a/src/map/script.c b/src/map/script.c index 69c210b28..628598584 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -30,6 +30,7 @@ #include "map/chat.h" #include "map/chrif.h" #include "map/clif.h" +#include "map/date.h" #include "map/elemental.h" #include "map/guild.h" #include "map/homunculus.h" @@ -16218,6 +16219,60 @@ BUILDIN(isstr) return true; } +enum datatype { + DATATYPE_NIL = 1 << 7, // we don't start at 1, to leave room for primitives + DATATYPE_STR = 1 << 8, + DATATYPE_INT = 1 << 9, + DATATYPE_CONST = 1 << 10, + DATATYPE_PARAM = 1 << 11, + DATATYPE_VAR = 1 << 12, + DATATYPE_LABEL = 1 << 13, +}; + +BUILDIN(getdatatype) { + int type; + + if (script_hasdata(st, 2)) { + struct script_data *data = script_getdata(st, 2); + + if (data_isstring(data)) { + type = DATATYPE_STR; + if (data->type == C_CONSTSTR) { + type |= DATATYPE_CONST; + } + } else if (data_isint(data)) { + type = DATATYPE_INT; + } else if (data_islabel(data)) { + type = DATATYPE_LABEL; + } else if (data_isreference(data)) { + if (reference_toconstant(data)) { + type = DATATYPE_CONST | DATATYPE_INT; + } else if (reference_toparam(data)) { + type = DATATYPE_PARAM | DATATYPE_INT; + } else if (reference_tovariable(data)) { + type = DATATYPE_VAR; + if (is_string_variable(reference_getname(data))) { + type |= DATATYPE_STR; + } else { + type |= DATATYPE_INT; + } + } else { + ShowError("script:getdatatype: Unknown reference type!\n"); + script->reportdata(data); + st->state = END; + return false; + } + } else { + type = data->type; // fallback to primitive type if unknown + } + } else { + type = DATATYPE_NIL; // nothing was passed + } + + script_pushint(st, type); + return true; +} + //======================================================= // chr <int> //------------------------------------------------------- @@ -20283,19 +20338,21 @@ BUILDIN(setquest) { unsigned short i; int quest_id; + unsigned int time_limit; struct map_session_data *sd = script->rid2sd(st); if (sd == NULL) return true; quest_id = script_getnum(st, 2); + time_limit = script_hasdata(st, 3) ? script_getnum(st, 3) : 0; - quest->add(sd, quest_id); + quest->add(sd, quest_id, time_limit); // If questinfo is set, remove quest bubble once quest is set. - for(i = 0; i < map->list[sd->bl.m].qi_count; i++) { + for (i = 0; i < map->list[sd->bl.m].qi_count; i++) { struct questinfo *qi = &map->list[sd->bl.m].qi_data[i]; - if( qi->quest_id == quest_id ) { + if (qi->quest_id == quest_id) { #if PACKETVER >= 20120410 clif->quest_show_event(sd, &qi->nd->bl, 9999, 0); #else @@ -23156,6 +23213,100 @@ BUILDIN(mergeitem) return true; } +// getcalendartime(<day of month>, <day of week>{, <hour>{, <minute>}}); +// Returns the UNIX Timestamp of next ocurrency of given time +BUILDIN(getcalendartime) +{ + struct tm info = { 0 }; + int day_of_month = script_hasdata(st, 4) ? script_getnum(st, 4) : -1; + int day_of_week = script_hasdata(st, 5) ? script_getnum(st, 5) : -1; + int year = date_get_year(); + int month = date_get_month(); + int day = date_get_day(); + int cur_hour = date_get_hour(); + int cur_min = date_get_min(); + int hour = script_getnum(st, 2); + int minute = script_getnum(st, 3); + + info.tm_sec = 0; + info.tm_min = minute; + info.tm_hour = hour; + info.tm_mday = day; + info.tm_mon = month - 1; + info.tm_year = year - 1900; + + if (day_of_month > -1 && day_of_week > -1) { + ShowError("script:getcalendartime: You must only specify a day_of_week or a day_of_month, not both\n"); + script_pushint(st, -1); + return false; + } + if (day_of_month > -1 && (day_of_month < 1 || day_of_month > 31)) { + ShowError("script:getcalendartime: Day of Month in invalid range. Must be between 1 and 31.\n"); + script_pushint(st, -1); + return false; + } + if (day_of_week > -1 && (day_of_week < 0 || day_of_week > 6)) { + ShowError("script:getcalendartime: Day of Week in invalid range. Must be between 0 and 6.\n"); + script_pushint(st, -1); + return false; + } + if (hour > -1 && (hour > 23)) { + ShowError("script:getcalendartime: Hour in invalid range. Must be between 0 and 23.\n"); + script_pushint(st, -1); + return false; + } + if (minute > -1 && (minute > 59)) { + ShowError("script:getcalendartime: Minute in invalid range. Must be between 0 and 59.\n"); + script_pushint(st, -1); + return false; + } + if (hour == -1 || minute == -1) { + ShowError("script:getcalendartime: Minutes and Hours are required\n"); + script_pushint(st, -1); + return false; + } + + if (day_of_month > -1) { + if (day_of_month < day) { // Next Month + info.tm_mon++; + } else if (day_of_month == day) { // Today + if (hour < cur_hour || (hour == cur_hour && minute < cur_min)) { // But past time, next month + info.tm_mon++; + } + } + + // Loops until month has finding a month that has day_of_month + do { + time_t t; + struct tm *lt; + info.tm_mday = day_of_month; + t = mktime(&info); + lt = localtime(&t); + info = *lt; + } while (info.tm_mday != day_of_month); + } else if (day_of_week > -1) { + int cur_wday = date_get_dayofweek(); + + if (day_of_week > cur_wday) { // This week + info.tm_mday += (day_of_week - cur_wday); + } else if (day_of_week == cur_wday) { // Today + if (hour < cur_hour || (hour == cur_hour && minute <= cur_min)) { + info.tm_mday += 7; // Next week + } + } else if (day_of_week < cur_wday) { // Next week + info.tm_mday += (7 - cur_wday + day_of_week); + } + } else if (day_of_week == -1 && day_of_month == -1) { // Next occurence of hour/min + if (hour < cur_hour || (hour == cur_hour && minute < cur_min)) { + info.tm_mday++; + } + } + + script_pushint(st, mktime(&info)); + + return true; +} + /** place holder for the translation macro **/ BUILDIN(_) { @@ -23662,6 +23813,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(charisalpha,"si"), //isalpha [Valaris] BUILDIN_DEF(charat,"si"), BUILDIN_DEF(isstr,"v"), + BUILDIN_DEF(getdatatype, "?"), BUILDIN_DEF(chr,"i"), BUILDIN_DEF(ord,"s"), BUILDIN_DEF(setchar,"ssi"), @@ -23864,7 +24016,7 @@ void script_parse_builtin(void) { //Quest Log System [Inkfish] BUILDIN_DEF(questinfo, "ii??"), - BUILDIN_DEF(setquest, "i"), + BUILDIN_DEF(setquest, "i?"), BUILDIN_DEF(erasequest, "i?"), BUILDIN_DEF(completequest, "i?"), BUILDIN_DEF(questprogress, "i?"), @@ -23916,6 +24068,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(removechannelhandler, "ss"), BUILDIN_DEF(showscript, "s?"), BUILDIN_DEF(mergeitem,""), + BUILDIN_DEF(getcalendartime, "ii??"), BUILDIN_DEF(_,"s"), BUILDIN_DEF2(_, "_$", "s"), }; @@ -24135,6 +24288,15 @@ void script_hardcoded_constants(void) script->set_constant("PERM_DISABLE_EXP", PC_PERM_DISABLE_EXP, false, false); script->set_constant("PERM_DISABLE_SKILL_USAGE", PC_PERM_DISABLE_SKILL_USAGE, false, false); + script->constdb_comment("Data types"); + script->set_constant("DATATYPE_NIL", DATATYPE_NIL, false, false); + script->set_constant("DATATYPE_STR", DATATYPE_STR, false, false); + script->set_constant("DATATYPE_INT", DATATYPE_INT, false, false); + script->set_constant("DATATYPE_CONST", DATATYPE_CONST, false, false); + script->set_constant("DATATYPE_PARAM", DATATYPE_PARAM, false, false); + script->set_constant("DATATYPE_VAR", DATATYPE_VAR, false, false); + script->set_constant("DATATYPE_LABEL", DATATYPE_LABEL, false, false); + script->constdb_comment("Renewal"); #ifdef RENEWAL script->set_constant("RENEWAL", 1, false, false); diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index b4be9aff4..28009ff7a 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -5738,8 +5738,8 @@ typedef struct quest_db* (*HPMHOOK_pre_quest_db) (int *quest_id); typedef struct quest_db* (*HPMHOOK_post_quest_db) (struct quest_db* retVal___, int quest_id); typedef int (*HPMHOOK_pre_quest_pc_login) (struct map_session_data **sd); typedef int (*HPMHOOK_post_quest_pc_login) (int retVal___, struct map_session_data *sd); -typedef int (*HPMHOOK_pre_quest_add) (struct map_session_data **sd, int *quest_id); -typedef int (*HPMHOOK_post_quest_add) (int retVal___, struct map_session_data *sd, int quest_id); +typedef int (*HPMHOOK_pre_quest_add) (struct map_session_data **sd, int *quest_id, unsigned int *time_limit); +typedef int (*HPMHOOK_post_quest_add) (int retVal___, struct map_session_data *sd, int quest_id, unsigned int time_limit); typedef int (*HPMHOOK_pre_quest_change) (struct map_session_data **sd, int *qid1, int *qid2); typedef int (*HPMHOOK_post_quest_change) (int retVal___, struct map_session_data *sd, int qid1, int qid2); typedef int (*HPMHOOK_pre_quest_delete) (struct map_session_data **sd, int *quest_id); diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index 4bd397240..3bde41022 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -60383,15 +60383,15 @@ int HP_quest_pc_login(struct map_session_data *sd) { } return retVal___; } -int HP_quest_add(struct map_session_data *sd, int quest_id) { +int HP_quest_add(struct map_session_data *sd, int quest_id, unsigned int time_limit) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_quest_add_pre > 0) { - int (*preHookFunc) (struct map_session_data **sd, int *quest_id); + int (*preHookFunc) (struct map_session_data **sd, int *quest_id, unsigned int *time_limit); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_quest_add_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_quest_add_pre[hIndex].func; - retVal___ = preHookFunc(&sd, &quest_id); + retVal___ = preHookFunc(&sd, &quest_id, &time_limit); } if (*HPMforce_return) { *HPMforce_return = false; @@ -60399,13 +60399,13 @@ int HP_quest_add(struct map_session_data *sd, int quest_id) { } } { - retVal___ = HPMHooks.source.quest.add(sd, quest_id); + retVal___ = HPMHooks.source.quest.add(sd, quest_id, time_limit); } if (HPMHooks.count.HP_quest_add_post > 0) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int quest_id); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, int quest_id, unsigned int time_limit); for (hIndex = 0; hIndex < HPMHooks.count.HP_quest_add_post; hIndex++) { postHookFunc = HPMHooks.list.HP_quest_add_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, quest_id); + retVal___ = postHookFunc(retVal___, sd, quest_id, time_limit); } } return retVal___; |