diff --git a/changelog b/changelog index d31e146..95010e4 100644 --- a/changelog +++ b/changelog @@ -63,7 +63,7 @@ Changes in v1.3.0-alpha: * Migration away from OLC with new command "mset" and for builders to update NPC's * Migration away from OLC with new commands "qcreate" and "qset" for builders to create quests * Updated mset, oset, and rset commands with missing parameters - * NPC extra descriptions are supported via mset and [[mob.extra_desc]] in TOML + * Added NPC extra descriptions for future support Features that will be implemented in the next few releases: diff --git a/src/interpreter.c b/src/interpreter.c index 5906129..b506278 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -254,8 +254,10 @@ cpp_extern const struct command_info cmd_info[] = { { "prefedit" , "pre" , POS_DEAD , do_oasis_prefedit , 0, 0 }, { "purge" , "purge" , POS_DEAD , do_purge , LVL_BUILDER, 0 }, + { "qcreate" , "qcreate" , POS_DEAD , do_qcreate , LVL_BUILDER, 0 }, { "qedit" , "qedit" , POS_DEAD , do_oasis_qedit, LVL_BUILDER, 0 }, { "qlist" , "qlist" , POS_DEAD , do_oasis_list, LVL_BUILDER, SCMD_OASIS_QLIST }, + { "qsave" , "qsav" , POS_DEAD , do_qsave , LVL_BUILDER, 0 }, { "quaff" , "qua" , POS_RESTING , do_use , 0, SCMD_QUAFF }, { "qecho" , "qec" , POS_DEAD , do_qcomm , LVL_GOD, SCMD_QECHO }, { "quest" , "que" , POS_DEAD , do_quest , 0, 0 }, diff --git a/src/set.c b/src/set.c index bfd47c7..921b109 100644 --- a/src/set.c +++ b/src/set.c @@ -38,6 +38,7 @@ #include "dg_scripts.h" #include "fight.h" #include "toml.h" +#include "quest.h" #include "set.h" @@ -4931,6 +4932,118 @@ ACMD(do_ocreate) } } +ACMD(do_qcreate) +{ + char arg[MAX_INPUT_LENGTH]; + char buf[MAX_STRING_LENGTH]; + char namebuf[MAX_NAME_LENGTH]; + char timestr[64]; + struct aq_data *quest; + qst_vnum vnum; + zone_rnum znum; + time_t ct; + + if (IS_NPC(ch) || ch->desc == NULL) { + send_to_char(ch, "qcreate is only usable by connected players.\r\n"); + return; + } + + one_argument(argument, arg); + + if (!*arg) { + send_to_char(ch, + "Creates a new unfinished quest which can be configured.\r\n" + "\r\n" + "Usage:\r\n" + " qcreate \r\n" + "\r\n" + "Examples:\r\n" + " qcreate 1001\r\n"); + return; + } + + if (!is_number(arg)) { + send_to_char(ch, + "Creates a new unfinished quest which can be configured.\r\n" + "\r\n" + "Usage:\r\n" + " qcreate \r\n" + "\r\n" + "Examples:\r\n" + " qcreate 1001\r\n"); + return; + } + + vnum = atoi(arg); + if (vnum < IDXTYPE_MIN || vnum > IDXTYPE_MAX) { + send_to_char(ch, "That quest VNUM can't exist.\r\n"); + return; + } + + if (real_quest(vnum) != NOTHING) { + send_to_char(ch, "Quest %d already exists.\r\n", vnum); + return; + } + + znum = real_zone_by_thing(vnum); + if (znum == NOWHERE) { + send_to_char(ch, "Sorry, there is no zone for that number!\r\n"); + return; + } + + if (!can_edit_zone(ch, znum)) { + send_cannot_edit(ch, zone_table[znum].number); + return; + } + + CREATE(quest, struct aq_data, 1); + quest->vnum = vnum; + quest->qm = NOBODY; + quest->flags = 0; + quest->type = AQ_UNDEFINED; + quest->target = NOTHING; + quest->prereq = NOTHING; + quest->value[0] = 0; + quest->value[1] = 0; + quest->value[2] = 0; + quest->value[3] = LVL_IMPL; + quest->value[4] = -1; + quest->value[5] = NOBODY; + quest->value[6] = 1; + quest->prev_quest = NOTHING; + quest->next_quest = NOTHING; + quest->coins_reward = 0; + quest->exp_reward = 0; + quest->obj_reward = NOTHING; + quest->func = NULL; + + strlcpy(namebuf, GET_NAME(ch), sizeof(namebuf)); + snprintf(buf, sizeof(buf), "unfinished quest made by %.*s", + (int)sizeof(namebuf) - 1, namebuf); + quest->name = strdup(buf); + + ct = time(0); + strftime(timestr, sizeof(timestr), "%c", localtime(&ct)); + snprintf(buf, sizeof(buf), + "This is an unfinished quest created by %.*s on %.*s", + (int)sizeof(namebuf) - 1, namebuf, + (int)sizeof(timestr) - 1, timestr); + quest->desc = strdup(buf); + + quest->info = strdup("There is no information on this quest.\r\n"); + quest->done = strdup("You have completed the quest.\r\n"); + quest->quit = strdup("You have abandoned the quest.\r\n"); + + add_quest(quest); + + if (in_save_list(zone_table[znum].number, SL_QST)) + remove_from_save_list(zone_table[znum].number, SL_QST); + + free_quest(quest); + + send_to_char(ch, "Quest %d created.\r\n", vnum); +} + ACMD(do_osave) { char arg[MAX_INPUT_LENGTH]; @@ -5035,6 +5148,73 @@ ACMD(do_osave) send_to_char(ch, "osave: object %d saved to disk.\r\n", vnum); } +ACMD(do_qsave) +{ + char arg[MAX_INPUT_LENGTH]; + qst_vnum vnum; + zone_rnum znum; + + if (IS_NPC(ch) || ch->desc == NULL) { + send_to_char(ch, "qsave is only usable by connected players.\r\n"); + return; + } + + one_argument(argument, arg); + + if (!*arg) { + send_to_char(ch, + "Saves a quest and its current properties to disk, which will load upon next boot.\r\n" + "\r\n" + "Usage:\r\n" + " qsave \r\n" + "\r\n" + "Examples:\r\n" + " qsave 1001\r\n"); + return; + } + + if (!is_number(arg)) { + send_to_char(ch, + "Saves a quest and its current properties to disk, which will load upon next boot.\r\n" + "\r\n" + "Usage:\r\n" + " qsave \r\n" + "\r\n" + "Examples:\r\n" + " qsave 1001\r\n"); + return; + } + + vnum = atoi(arg); + if (vnum < IDXTYPE_MIN || vnum > IDXTYPE_MAX) { + send_to_char(ch, "That quest VNUM can't exist.\r\n"); + return; + } + + if (real_quest(vnum) == NOTHING) { + send_to_char(ch, "Quest %d does not exist.\r\n", vnum); + return; + } + + znum = real_zone_by_thing(vnum); + if (znum == NOWHERE) { + send_to_char(ch, "Sorry, there is no zone for that number!\r\n"); + return; + } + + if (!can_edit_zone(ch, znum)) { + send_cannot_edit(ch, zone_table[znum].number); + return; + } + + if (!save_quests(znum)) { + send_to_char(ch, "qsave: failed.\r\n"); + return; + } + + send_to_char(ch, "qsave: quest %d saved to disk.\r\n", vnum); +} + /* ====== Builder snapshot: save a staged mob's gear as its prototype loadout ====== */ static void msave_loadout_append(struct mob_loadout **head, struct mob_loadout **tail, diff --git a/src/set.h b/src/set.h index d11d2e2..bb941bd 100644 --- a/src/set.h +++ b/src/set.h @@ -13,10 +13,12 @@ ACMD(do_rset); ACMD(do_rcreate); ACMD(do_ocreate); +ACMD(do_qcreate); ACMD(do_mcreate); ACMD(do_mset); ACMD(do_oset); ACMD(do_osave); +ACMD(do_qsave); ACMD(do_msave); ACMD(do_rsave);