summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2017-07-11 12:53:09 +0200
committerHaru <haru@dotalux.com>2017-07-11 12:53:09 +0200
commitaaa2b237b4b24d0565afd375046dd7f4480d91f1 (patch)
tree26e9f4ebe5396fe040a31739af9d4d17bdbb162e
parenteef92522dcf835f42a922a580be8f855cfea1aa6 (diff)
parent79b69495bbc5d758529a485eb1144bd64b8ea50f (diff)
downloadhercules-aaa2b237b4b24d0565afd375046dd7f4480d91f1.tar.gz
hercules-aaa2b237b4b24d0565afd375046dd7f4480d91f1.tar.bz2
hercules-aaa2b237b4b24d0565afd375046dd7f4480d91f1.tar.xz
hercules-aaa2b237b4b24d0565afd375046dd7f4480d91f1.zip
Merge pull request #1593 from guilherme-gm/script-setquest
Closes #1593 as merged
-rw-r--r--doc/script_commands.txt28
-rw-r--r--src/map/date.c7
-rw-r--r--src/map/date.h1
-rw-r--r--src/map/quest.c21
-rw-r--r--src/map/quest.h2
-rw-r--r--src/map/script.c106
6 files changed, 150 insertions, 15 deletions
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index d72d1d4b7..9148e023c 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -3408,6 +3408,30 @@ Example :
---------------------------------------
+*getcalendartime(<hour>, <minute>{, <day of month>{, <day of week>}})
+
+This function returns the timestamp of the next ocurrence of given time.
+
+Day of Month specifies a day between 1 and 31 in the future, by default its value is -1 (don't use).
+Day of Week specifies a day in the week and its valid values are:
+ 0 - SUNDAY
+ 1 - MONDAY
+ 2 - TUESDAY
+ 3 - WEDNESDAY
+ 4 - THURSDAY
+ 5 - FRIDAY
+ 6 - SATURDAY
+
+In order to use Day of Week, you must use Day of Month as -1.
+If for some reason the command fails, it'll return -1.
+
+Examples :
+ getcalendartime(19, 00); // Next 7 pm
+ getcalendartime(19, 00, 6); // Next day 6 of the month, at 7pm
+ getcalendartime(19, 10, -1, 1); // Next Monday, at 7:10pm
+
+---------------------------------------
+
*gettimestr(<format string>, <max length>)
This function will return a string containing time data as specified by
@@ -9152,9 +9176,11 @@ Example
---------------------------------------
-*setquest(<ID>)
+*setquest(<ID>{, <Time Limit>})
Place quest of <ID> in the users quest log, the state of which is "active".
+If Time Limit is given, this quest will have its expire time set to <Time Limit>, an UNIX epoch time,
+ignoring quest_db setting.
If questinfo() is set, and the same ID is specified here, the icon will be cleared when the quest is set.
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/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 d85438903..bef3dc13a 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"
@@ -20336,19 +20337,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
@@ -23209,6 +23212,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(_)
{
@@ -23918,7 +24015,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?"),
@@ -23970,6 +24067,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"),
};