/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* _TwyliteMud_ by Rv. Based on CircleMud3.0bpl9 *
* *
* OasisOLC - qedit.c *
* *
* Copyright 1997 Mike Steinmann *
* Used at Morgaelin (mud.dwango.com 3000) *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*. Original author: Levork .*/
#include "conf.h"
#include "sysdep.h"
#include "structs.h"
#include "comm.h"
#include "utils.h"
#include "handler.h"
#include "interpreter.h"
#include "db.h"
#include "boards.h"
#include "olc.h"
#include "quest.h"
/*------------------------------------------------------------------------*/
/*. External data .*/
extern int top_of_aquestt;
extern struct aq_data *aquest_table;
extern struct zone_data *zone_table;
extern char *quest_types[];
extern char *aq_flags[];
extern void strip_string(char *buffer);
/*------------------------------------------------------------------------*/
/* function protos */
void qedit_setup_new(struct descriptor_data *d);
void qedit_setup_existing(struct descriptor_data *d, int real_num);
void qedit_save_internally(struct descriptor_data *d);
void qedit_save_to_disk(int znum);
void free_quest(struct aq_data *quest);
void qedit_disp_type_menu(struct descriptor_data *d);
void qedit_disp_menu(struct descriptor_data * d);
void qedit_parse(struct descriptor_data * d, char *arg);
void qedit_disp_flags_menu(struct descriptor_data *d);
void oedit_disp_val0_menu(struct descriptor_data *d);
void oedit_disp_val1_menu(struct descriptor_data *d);
void oedit_disp_val2_menu(struct descriptor_data *d);
void oedit_disp_val3_menu(struct descriptor_data *d);
/*------------------------------------------------------------------------*\
Utils and exported functions.
\*------------------------------------------------------------------------*/
void smash_tilde(char *str)
{
for (; *str != '\0'; str++) {
if (*str == '~')
*str = '-';
if (*str == 'M')
*str = ' ';
}
return;
}
void qedit_setup_new(struct descriptor_data *d)
{
CREATE(OLC_QUEST(d), struct aq_data, 1);
OLC_QUEST(d)->short_desc = str_dup("an unfinished quest");
OLC_QUEST(d)->desc = str_dup("This is an unfinished quest.");
OLC_QUEST(d)->info = str_dup("Information for unfinished quest.\r\n");
OLC_QUEST(d)->ending = str_dup("Ending for unfinished quest.\r\n");
OLC_QUEST(d)->next_quest = -1;
qedit_disp_menu(d);
OLC_VAL(d) = 0;
}
/*------------------------------------------------------------------------*/
void qedit_setup_existing(struct descriptor_data *d, int real_num)
{
struct aq_data *quest;
int i;
/*. Build a copy of the quest .*/
CREATE (quest, struct aq_data, 1);
*quest = aquest_table[real_num];
/* allocate space for all strings */
if (aquest_table[real_num].short_desc)
quest->short_desc = str_dup (aquest_table[real_num].short_desc);
if (aquest_table[real_num].desc)
quest->desc = str_dup (aquest_table[real_num].desc);
if (aquest_table[real_num].info)
quest->info = str_dup (aquest_table[real_num].info);
if (aquest_table[real_num].ending)
quest->ending = str_dup (aquest_table[real_num].ending);
quest->type = aquest_table[real_num].type;
quest->mob_vnum = aquest_table[real_num].mob_vnum;
quest->flags = aquest_table[real_num].flags;
quest->target = aquest_table[real_num].target;
quest->exp = aquest_table[real_num].exp;
quest->next_quest = aquest_table[real_num].next_quest;
for (i=0; i < 4; i++)
quest->value[i] = aquest_table[real_num].value[i];
/*. Attach room copy to players descriptor .*/
OLC_QUEST(d) = quest;
OLC_VAL(d) = 0;
qedit_disp_menu(d);
}
/*------------------------------------------------------------------------*/
void qedit_save_internally(struct descriptor_data *d)
{
int i, quest_num, found = 0;
struct aq_data *new_quest;
quest_num = real_quest(OLC_NUM(d));
if (quest_num >= 0)
{
free_quest(aquest_table + quest_num);
aquest_table[quest_num] = *OLC_QUEST(d);
} else {
/*. Quest doesn't exist, hafta add it .*/
CREATE(new_quest, struct aq_data, top_of_aquestt + 2);
/* count thru quest tables */
for (i = 0; i <= top_of_aquestt; i++)
{
if (!found) {
/*. Is this the place? .*/
if (aquest_table[i].virtual > OLC_NUM(d))
{
found = 1;
new_quest[i] = *(OLC_QUEST(d));
new_quest[i].virtual = OLC_NUM(d);
quest_num = i;
new_quest[i + 1] = aquest_table[i];
} else {
new_quest[i] = aquest_table[i];
}
} else
{ /*. Already been found .*/
new_quest[i + 1] = aquest_table[i];
}
}
if (!found)
{ /*. Still not found, insert at top of table .*/
new_quest[i] = *(OLC_QUEST(d));
new_quest[i].virtual = OLC_NUM(d);
quest_num = i;
}
/* copy quest table over */
free(aquest_table);
aquest_table = new_quest;
top_of_aquestt++;
}
olc_add_to_save_list(zone_table[OLC_ZNUM(d)].number, OLC_SAVE_QUEST);
}
/*------------------------------------------------------------------------*/
void qedit_save_to_disk(int znum)
{
int counter, realcounter;
FILE *fp;
struct aq_data *quest;
char buf3[MAX_STRING_LENGTH];
char buf4[MAX_STRING_LENGTH];
sprintf(buf, "%s/%d.qst", QST_PREFIX, zone_table[znum].number);
if (!(fp = fopen(buf, "w+")))
{ mudlog("SYSERR: OLC: Cannot open quest file!", BRF, LVL_BUILDER, TRUE);
return;
}
for (counter = zone_table[znum].number * 100;
counter <= zone_table[znum].top;
counter++)
{ realcounter = real_quest(counter);
if (realcounter >= 0)
{
quest = (aquest_table + realcounter);
strcpy(buf1, quest->short_desc ? quest->short_desc : "an unfinished quest");
smash_tilde(buf1);
strcpy(buf2, quest->desc ? quest->desc : "This is an unfinished quest.");
smash_tilde(buf2);
strcpy(buf3, quest->info ? quest->info : "Information for an unfinished quest.\r\n");
strip_string(buf3);
smash_tilde(buf3);
strcpy(buf4, quest->ending ? quest->ending : "There is no ending!\r\n");
strip_string(buf4);
smash_tilde(buf4);
/*. Build a buffer ready to save .*/
sprintf(buf, "#%d\n%s~\n%s~\n%s~\n%s~\n%d %d %ld %d %d %d\n",
counter, buf1, buf2, buf3, buf4,
quest->type, quest->mob_vnum,
quest->flags, quest->target, quest->exp, quest->next_quest
);
/*. Save this section .*/
fputs(buf, fp);
sprintf(buf, "%d %d %d %d\n", quest->value[0], quest->value[1],
quest->value[2], quest->value[3]);
fputs(buf, fp);
fprintf(fp, "S\n");
}
}
/* write final line and close */
fprintf(fp, "$~\n");
fclose(fp);
olc_remove_from_save_list(zone_table[znum].number, OLC_SAVE_QUEST);
}
/*------------------------------------------------------------------------*/
void free_quest(struct aq_data *quest)
{
if (quest->desc)
free(quest->desc);
if (quest->short_desc)
free(quest->short_desc);
if (quest->info)
free(quest->info);
if (quest->ending)
free(quest->ending);
}
/**************************************************************************
Menu functions
**************************************************************************/
void qedit_disp_flags_menu(struct descriptor_data * d)
{ int counter, columns = 0;
get_char_cols(d->character);
send_to_char("[H[J", d->character);
for (counter = 0; counter < NUM_AQ_FLAGS; counter++)
{ sprintf(buf, "%s%2d%s) %-20.20s ",
grn, counter + 1, nrm, aq_flags[counter]);
if(!(++columns % 2))
strcat(buf, "\r\n");
send_to_char(buf, d->character);
}
sprintbit(OLC_QUEST(d)->flags, aq_flags, buf1);
sprintf(buf,
"\r\nQuest flags: %s%s%s\r\n"
"Enter quest flags, 0 to quit : ",
cyn, buf1, nrm
);
send_to_char(buf, d->character);
OLC_MODE(d) = QEDIT_FLAGS;
}
void qedit_disp_type_menu(struct descriptor_data *d)
{
int counter, columns = 0;
send_to_char("[H[J", d->character);
for (counter = 0; counter < NUM_AQ_TYPES; counter++) {
sprintf(buf, "%s%2d%s) %-20.20s ",
cyn, counter, nrm, quest_types[counter]);
if(!(++columns % 2))
strcat(buf, "\r\n");
send_to_char(buf, d->character);
}
send_to_char("\r\nEnter quest type : ", d->character);
OLC_MODE(d) = QEDIT_TYPE;
}
void qedit_disp_val0_menu(struct descriptor_data *d)
{
OLC_MODE(d) = QEDIT_VALUE_0;
switch(OLC_QUEST(d)->type) {
case AQ_RETURN_OBJ:
send_to_char("Enter vnum of mob to receive object: ", d->character);
break;
default:
qedit_disp_menu(d);
}
}
void qedit_disp_val1_menu(struct descriptor_data *d)
{
OLC_MODE(d) = QEDIT_VALUE_1;
switch(OLC_QUEST(d)->type) {
default:
qedit_disp_menu(d);
}
}
void qedit_disp_val2_menu(struct descriptor_data *d)
{
OLC_MODE(d) = QEDIT_VALUE_2;
switch(OLC_QUEST(d)->type) {
default:
qedit_disp_menu(d);
}
}
void qedit_disp_val3_menu(struct descriptor_data *d)
{
OLC_MODE(d) = QEDIT_VALUE_3;
switch(OLC_QUEST(d)->type) {
default:
qedit_disp_menu(d);
}
}
/* the main menu */
void qedit_disp_menu(struct descriptor_data * d)
{
struct aq_data *quest;
extern struct char_data *mob_proto;
get_char_cols(d->character);
quest = OLC_QUEST(d);
sprintbit(quest->flags, aq_flags, buf1);
sprintf(buf2, "%d %d %d %d", quest->value[0], quest->value[1], quest->value[2],
quest->value[3]);
sprintf(buf,
"[H[J"
"-- Quest number : [%s%d%s] Quest zone: [%s%d%s]\r\n"
"%s1%s) Name : %s%s%s\r\n"
"%s2%s) Description :\r\n%s%s%s\r\n"
"%s3%s) Information :\r\n%s%s%s"
"%s4%s) Ending :\r\n%s%s%s"
"%s5%s) Questmaster : %s%d%s -- %s%s%s\r\n"
"%s6%s) Type : %s%s%s\r\n"
"%s7%s) Flags : %s%s%s\r\n"
"%s8%s) Target vnum : %s%d%s\r\n"
"%s9%s) Experience : %s%d%s\r\n"
"%sA%s) Next quest : %s%d%s\r\n"
"%sB%s) Values : %s%s%s\r\n"
"%sQ%s) Quit\r\n"
"Enter choice : ",
cyn, OLC_NUM(d), nrm,
cyn, zone_table[OLC_ZNUM(d)].number, nrm,
cyn, nrm, grn, quest->short_desc, nrm,
cyn, nrm, grn, quest->desc, nrm,
cyn, nrm, grn, quest->info, nrm,
cyn, nrm, grn, quest->ending, nrm,
cyn, nrm, grn, quest->mob_vnum, nrm, grn,
real_mobile(quest->mob_vnum) > -1 ? mob_proto[real_mobile(quest->mob_vnum)].player.short_descr : "None", nrm,
cyn, nrm, grn, quest_types[quest->type], nrm,
cyn, nrm, grn, buf1, nrm,
cyn, nrm, grn, quest->target, nrm,
cyn, nrm, grn, quest->exp, nrm,
cyn, nrm, grn, quest->next_quest, nrm,
cyn, nrm, grn, buf2, nrm,
cyn, nrm
);
send_to_char(buf, d->character);
OLC_MODE(d) = QEDIT_MAIN_MENU;
}
/**************************************************************************
The main loop
**************************************************************************/
void qedit_parse(struct descriptor_data * d, char *arg)
{
extern struct aq_data *aquest_table;
int number=0;
switch (OLC_MODE(d)) {
case QEDIT_CONFIRM_SAVESTRING:
switch (*arg) {
case 'y':
case 'Y':
qedit_save_internally(d);
sprintf(buf, "OLC: %s edits quest %d", GET_NAME(d->character), OLC_NUM(d));
mudlog(buf, CMP, LVL_BUILDER, TRUE);
/*. Do NOT free strings! just the room structure .*/
cleanup_olc(d, CLEANUP_STRUCTS);
send_to_char("Quest saved to memory.\r\n", d->character);
break;
case 'n':
case 'N':
/* free everything up, including strings etc */
cleanup_olc(d, CLEANUP_ALL);
break;
default:
send_to_char("Invalid choice!\r\n", d->character);
send_to_char("Do you wish to save this quest internally? : ", d->character);
break;
}
return;
case QEDIT_MAIN_MENU:
switch (*arg) {
case 'q':
case 'Q':
if (OLC_VAL(d))
{ /*. Something has been modified .*/
send_to_char("Do you wish to save this quest internally? : ", d->character);
OLC_MODE(d) = QEDIT_CONFIRM_SAVESTRING;
} else
cleanup_olc(d, CLEANUP_ALL);
return;
case '1':
send_to_char("Enter quest name:-\r\n| ", d->character);
OLC_MODE(d) = QEDIT_NAME;
break;
case '2':
send_to_char("Enter quest description:-\r\n| ", d->character);
OLC_MODE(d) = QEDIT_DESC;
break;
case '3':
OLC_MODE(d) = QEDIT_INFO;
#if defined(CLEAR_SCREEN)
SEND_TO_Q("\x1B[H\x1B[J", d);
#endif
SEND_TO_Q("Enter quest information: (/s saves /h for help)\r\n\r\n", d);
d->backstr = NULL;
if (OLC_QUEST(d)->info) {
SEND_TO_Q(OLC_QUEST(d)->info, d);
d->backstr = str_dup(OLC_QUEST(d)->info);
}
d->str = &OLC_QUEST(d)->info;
d->max_str = MAX_QUEST_INFO;
d->mail_to = 0;
OLC_VAL(d) = 1;
break;
case '4':
OLC_MODE(d) = QEDIT_ENDING;
#if defined(CLEAR_SCREEN)
SEND_TO_Q("\x1B[H\x1B[J", d);
#endif
SEND_TO_Q("Enter quest ending: (/s saves /h for help)\r\n\r\n", d);
d->backstr = NULL;
if (OLC_QUEST(d)->ending) {
SEND_TO_Q(OLC_QUEST(d)->ending, d);
d->backstr = str_dup(OLC_QUEST(d)->ending);
}
d->str = &OLC_QUEST(d)->ending;
d->max_str = MAX_QUEST_ENDING;
d->mail_to = 0;
OLC_VAL(d) = 1;
break;
case '5':
send_to_char("Enter questmaster vnum: ", d->character);
OLC_MODE(d) = QEDIT_QUESTMASTER;
break;
case '6':
qedit_disp_type_menu(d);
break;
case '7':
qedit_disp_flags_menu(d);
break;
case '8':
send_to_char("Enter target vnum: ", d->character);
OLC_MODE(d) = QEDIT_TARGET;
break;
case '9':
send_to_char("Enter experience: ", d->character);
OLC_MODE(d) = QEDIT_EXP;
break;
case 'a':
case 'A':
send_to_char("Next quest (-1 to end): ", d->character);
OLC_MODE(d) = QEDIT_NEXT;
break;
case 'b':
case 'B':
OLC_QUEST(d)->value[0] = 0;
OLC_QUEST(d)->value[1] = 0;
OLC_QUEST(d)->value[2] = 0;
OLC_QUEST(d)->value[3] = 0;
qedit_disp_val0_menu(d);
break;
default:
send_to_char("Invalid choice!", d->character);
qedit_disp_menu(d);
break;
}
return;
case QEDIT_NAME:
if (OLC_QUEST(d)->short_desc)
free(OLC_QUEST(d)->short_desc);
if (strlen(arg) > MAX_QUEST_NAME)
arg[MAX_QUEST_NAME -1] = 0;
OLC_QUEST(d)->short_desc = str_dup(arg);
break;
case QEDIT_DESC:
if (OLC_QUEST(d)->desc)
free(OLC_QUEST(d)->desc);
if (strlen(arg) > 80)
arg[79] = 0;
OLC_QUEST(d)->desc = str_dup(arg);
break;
case QEDIT_INFO:
/*
* We will NEVER get here, we hope.
*/
mudlog("SYSERR: Reached QEDIT_INFO case in parse_qedit", BRF, LVL_BUILDER, TRUE);
break;
case QEDIT_ENDING:
/*
* We will NEVER get here, we hope.
*/
mudlog("SYSERR: Reached QEDIT_ENDING case in parse_qedit", BRF, LVL_BUILDER, TRUE);
break;
case QEDIT_QUESTMASTER:
number = atoi(arg);
if (real_mobile(number) >= 0)
OLC_QUEST(d)->mob_vnum = number;
else
OLC_QUEST(d)->mob_vnum = -1;
break;
case QEDIT_TYPE:
number = atoi(arg);
if (number < 0 || number >= NUM_AQ_TYPES) {
send_to_char("Invalid choice!", d->character);
qedit_disp_type_menu(d);
return;
} else
OLC_QUEST(d)->type = number;
break;
case QEDIT_FLAGS:
number = atoi(arg);
if ((number < 0) || (number > NUM_AQ_FLAGS)) {
send_to_char("That's not a valid choice!\r\n", d->character);
qedit_disp_flags_menu(d);
} else {
if (number == 0)
break;
else {
/* toggle bits */
if (IS_SET(OLC_QUEST(d)->flags, 1 << (number - 1)))
REMOVE_BIT(OLC_QUEST(d)->flags, 1 << (number - 1));
else
SET_BIT(OLC_QUEST(d)->flags, 1 << (number - 1));
qedit_disp_flags_menu(d);
}
}
return;
case QEDIT_TARGET:
number = atoi(arg);
OLC_QUEST(d)->target = MAX(0, number);
break;
case QEDIT_EXP:
number = atoi(arg);
OLC_QUEST(d)->exp = MAX(0, MIN(number, 100000));
break;
case QEDIT_NEXT:
number = atoi(arg);
if (real_quest(number) >= 0)
OLC_QUEST(d)->next_quest = number;
else
OLC_QUEST(d)->next_quest = -1;
break;
case QEDIT_VALUE_0:
number = atoi(arg);
switch (OLC_QUEST(d)->type) {
case AQ_RETURN_OBJ:
if (real_mobile(number) < 0)
number = 0;
break;
}
OLC_QUEST(d)->value[0] = number;
qedit_disp_val1_menu(d);
return;
case QEDIT_VALUE_1:
OLC_QUEST(d)->value[1] = atoi(arg);
qedit_disp_val2_menu(d);
return;
case QEDIT_VALUE_2:
OLC_QUEST(d)->value[2] = atoi(arg);
qedit_disp_val3_menu(d);
return;
case QEDIT_VALUE_3:
OLC_QUEST(d)->value[3] = atoi(arg);
break;
default:
/* we should never get here */
mudlog("SYSERR: Reached default case in parse_qedit",BRF,LVL_BUILDER,TRUE);
break;
}
/*. If we get this far, something has be changed .*/
OLC_VAL(d) = 1;
qedit_disp_menu(d);
}