/******************************************************************************** ** ( .-""-. )+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+( .-""-. ) ** ** / _ _ \ ( | | | | | | |D|A|R|K| |R|E|A|L|M|S| | | | | | ) / _ _ \ ** ** |(_\/_)| )+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+( |/_)(_\| ** ** (_ /\ _) MULTIVERSE Distribution v1.0 (_ /\ _) ** ** |v==v| ( Multiverse source created by Exodus ) |mmmm| ** ** '-..-' with Aeone, Kain, Kyros, and Kast '-..-' ** **----------------------------------------------------------------------------** ** SMAUG 1.4 written by : Thoric (Derek Snider) with Altrag, Blodkai, ** ** Haus, Narn, Scryn, Swordbearer, Tricops, Gorog, ** ** Rennard, Grishnakh, Fireblade and Nivek. ** **----------------------------------------------------------------------------** ** Original MERC 2.1 by : Hatchet, Furey, and Kahn. ** ** Original Diku MUD by : Hans Staerfeldt, Katja Nyboe, Tom Madsen, ** ** Michael Seifert & Sebastian Hammer. ** **----------------------------------------------------------------------------** * Bug/Idea/Typo Tracking Module * ********************************************************************************/ #include <time.h> #include "h/files.h" #include "h/mud.h" #include "h/key.h" BUG_DATA *firstBug; BUG_DATA *lastBug; IDEA_DATA *firstIdea; IDEA_DATA *lastIdea; TYPO_DATA *firstTypo; TYPO_DATA *lastTypo; char *timeStamp args((void)); void checkBuidty args((CHAR_DATA *ch)); void nstralloc args((char **pointer)); struct bug_data { BUG_DATA *next; BUG_DATA *prev; char *bugDesc; char *foundBy; char *foundWhen; char *fixedBy; char *fixedWhen; char *fixDesc; short type; short bonus; bool reward; int room; }; struct idea_data { IDEA_DATA *next; IDEA_DATA *prev; char *ideaDesc; char *madeBy; char *madeWhen; char *usedBy; char *usedWhen; char *useDesc; short type; short bonus; bool reward; int room; }; struct typo_data { TYPO_DATA *next; TYPO_DATA *prev; char *typoDesc; char *foundBy; char *foundWhen; char *fixedBy; char *fixedWhen; short type; short bonus; bool reward; int room; }; void freeOneBug(BUG_DATA * Bug) { UNLINK(Bug, firstBug, lastBug, next, prev); STRFREE(Bug->bugDesc); STRFREE(Bug->foundBy); STRFREE(Bug->foundWhen); STRFREE(Bug->fixedBy); STRFREE(Bug->fixedWhen); STRFREE(Bug->fixDesc); DISPOSE(Bug); } void freeBugs(void) { BUG_DATA *bug, *bug_next; for(bug = firstBug; bug; bug = bug_next) { bug_next = bug->next; freeOneBug(bug); } } // Quick timestamp function. Feel free to change the format if you wish --Exo char *timeStamp(void) { static char buf[MSL]; struct tm *t = localtime(¤t_time); bool ispm = FALSE; short htime; htime = t->tm_hour; if(htime >= 12) { htime -= 12; ispm = TRUE; } snprintf(buf, MSL, "%02d-%02d-%04d %02d:%02d:%02d%s", (t->tm_mon + 1), t->tm_mday, (t->tm_year + 1900), htime, t->tm_min, t->tm_sec, ispm ? "PM" : "AM"); return buf; } void saveBugs(void) { FILE *fp = NULL; BUG_DATA *Bug = NULL; char fname[MFL]; snprintf(fname, MFL, "%s%s", SYSTEM_DIR, PBUG_FILE); if(!(fp = FileOpen(fname, "w"))) { bug("%s: Couldn't open %s for writing!", __FUNCTION__, fname); return; } for(Bug = firstBug; Bug; Bug = Bug->next) { fprintf(fp, "#BUG\n"); fprintf(fp, "FoundBy %s~\n", Bug->foundBy); fprintf(fp, "FoundWhen %s~\n", Bug->foundWhen); fprintf(fp, "BugDesc %s~\n", strip_cr(Bug->bugDesc)); fprintf(fp, "Type %d\n", Bug->type); if(Bug->fixedBy) fprintf(fp, "FixedBy %s~\n", Bug->fixedBy); if(Bug->fixedWhen) fprintf(fp, "FixedWhen %s~\n", Bug->fixedWhen); if(Bug->fixDesc) fprintf(fp, "FixDesc %s~\n", Bug->fixDesc); fprintf(fp, "Reward %d\n", Bug->reward); fprintf(fp, "RewardBonus %d\n", Bug->bonus); fprintf(fp, "Room %d\n", Bug->room); fprintf(fp, "End\n\n"); } fprintf(fp, "#END\n"); FileClose(fp); } void fReadBug(BUG_DATA * Bug, FILE * fp) { const char *word; bool fMatch; for(;;) { word = feof(fp) ? "End" : fread_word(fp); fMatch = FALSE; switch (UPPER(word[0])) { case '*': fMatch = TRUE; fread_to_eol(fp); break; case 'B': KEY("BugDesc", Bug->bugDesc, fread_string(fp)); break; case 'E': if(!str_cmp(word, "End")) { nstralloc(&Bug->bugDesc); nstralloc(&Bug->foundBy); nstralloc(&Bug->foundWhen); nstralloc(&Bug->fixedBy); nstralloc(&Bug->fixedWhen); nstralloc(&Bug->fixDesc); return; } break; case 'F': KEY("FixDesc", Bug->fixDesc, fread_string(fp)); KEY("FixedBy", Bug->fixedBy, fread_string(fp)); KEY("FixedWhen", Bug->fixedWhen, fread_string(fp)); KEY("FoundBy", Bug->foundBy, fread_string(fp)); KEY("FoundWhen", Bug->foundWhen, fread_string(fp)); break; case 'R': KEY("Reward", Bug->reward, fread_number(fp)); KEY("RewardBonus", Bug->bonus, fread_number(fp)); KEY("Room", Bug->room, fread_number(fp)); break; case 'T': KEY("Type", Bug->type, fread_number(fp)); break; } if(!fMatch) bug("%s: no match: %s", __FUNCTION__, word); } } void loadBugs(void) { char fname[MFL]; BUG_DATA *Bug; FILE *fp; firstBug = NULL; lastBug = NULL; snprintf(fname, MFL, "%s%s", SYSTEM_DIR, PBUG_FILE); if((fp = FileOpen(fname, "r")) != NULL) { for(;;) { char letter; const char *word; letter = fread_letter(fp); if(letter == '*') { fread_to_eol(fp); continue; } if(letter != '#') { bug("%s: # not found: (%c)", __FUNCTION__, letter); break; } word = fread_word(fp); if(!str_cmp(word, "BUG")) { CREATE(Bug, BUG_DATA, 1); fReadBug(Bug, fp); LINK(Bug, firstBug, lastBug, next, prev); continue; } else if(!str_cmp(word, "END")) break; else { bug("%s: bad section: %s", __FUNCTION__, word); continue; } } FileClose(fp); } return; } const char *bugSeverity(short type) { switch (type) { case 1: return "Lesser"; break; case 2: return "Minor"; break; case 3: return "Major"; break; case 4: return "Severe"; break; case 5: return "Critical"; break; default: return "Unknown??"; break; } } short severityArg(char *arg) { if(!str_cmp(arg, "lesser")) return 1; else if(!str_cmp(arg, "nothing")) return 0; else if(!str_cmp(arg, "minor")) return 2; else if(!str_cmp(arg, "major")) return 3; else if(!str_cmp(arg, "severe")) return 4; else if(!str_cmp(arg, "critical")) return 5; else return -1; } void bugReward(CHAR_DATA *ch, BUG_DATA * error) { int gold = 0; int glory = 0; char buf1[MSL], buf2[MSL]; if(error->reward || IS_NPC(ch)) return; if(!str_cmp(error->foundBy, ch->name)) { switch (error->type) { case 0: gold = 0; glory = 0; break; case 1: gold = 10; glory = 1; break; case 2: gold = 25; glory = 2; break; case 3: gold = 50; glory = 3; break; case 4: gold = 100; glory = 5; break; case 5: gold = 200; glory = 10; break; default: break; } if(error->bonus == 1) { gold = gold + (gold / 2); glory = glory + (glory / 2); } else if(error->bonus == 2) { gold = gold * 2; glory = glory * 2; } else if(error->bonus == 3) { gold = (gold * 2) + (gold / 2); glory = (glory * 2) + (glory / 2); } snprintf(buf1, MSL, "%s", num_punct(gold)); snprintf(buf2, MSL, "%s", num_punct(glory)); if(gold == 0 && glory == 0) { ch_printf(ch, "&CSomeone says, 'The STAFF did not find it fit to reward you for your reported bug!'\r\n"); ch_printf(ch, "&CSomeone says, 'The bug was probably submitted prior to your discovery. Keep looking though!'\r\n"); } else ch_printf(ch, "&CSomeone says, 'The STAFF have rewarded you %s gold and %s glory for finding a %s bug!'\r\n", buf1, buf2, bugSeverity(error->type)); error->reward = TRUE; ch->pcdata->num_bugs++; ch->pcdata->bugReward1 += gold; ch->pcdata->bugReward2 += glory; GET_MONEY(ch, CURR_GOLD) += gold; ch->quest_curr += glory; /* Volk - bug fix */ send_to_pager("&CYour bug was:\r\n&B----------------------------------------------------------------------&W\r\n", ch); send_to_pager(error->bugDesc, ch); send_to_pager("\r\n", ch); send_to_pager("&CSTAFF note:\r\n&B----------------------------------------------------------------------&W\r\n", ch); send_to_pager(error->fixDesc, ch); send_to_pager("\r\n", ch); save_char_obj(ch); freeOneBug(error); saveBugs(); return; } return; } void do_bug(CHAR_DATA *ch, char *argument) { char arg1[MIL]; char arg2[MIL]; BUG_DATA *Bug, *nBug; short cnt = 0; DESCRIPTOR_DATA *d; if(IS_NPC(ch)) { send_to_char("Huh?\r\n", ch); return; } switch (ch->substate) { default: break; case SUB_RESTRICTED: send_to_char("You cannot do this while in another command.\r\n", ch); return; case SUB_BUG_DESC: nBug = (BUG_DATA *) ch->dest_buf; if(nBug->bugDesc) STRFREE(nBug->bugDesc); nBug->bugDesc = copy_buffer(ch); stop_editing(ch); if(!VLD_STR(nBug->bugDesc)) { send_to_char("&CSomeone says, 'Nothing was in the bug report so it has been discarded.'\r\n", ch); freeOneBug(nBug); } else { send_to_char("&CSomeone says, 'Thanks, your bug report has been recorded.'\r\n", ch); send_to_char("&CSomeone says, 'You will be notified when the bug is fixed.'\r\n", ch); log_printf("%s has reported a bug.", ch->name); saveBugs(); } ch->substate = ch->tempnum; return; case SUB_BUG_FIXDESC: Bug = (BUG_DATA *) ch->dest_buf; if(Bug->fixDesc) STRFREE(Bug->fixDesc); Bug->fixDesc = copy_buffer(ch); stop_editing(ch); saveBugs(); ch->substate = ch->tempnum; send_to_char("Ok, the bug has been fixed and the player who reported it will be notified.\r\n", ch); if(Bug->foundBy) { for(d = first_descriptor; d; d = d->next) { if(!d->character) continue; if(!str_cmp(Bug->foundBy, d->character->name) && !NULLSTR(Bug->fixedBy)) { checkBuidty(d->character); break; } } } return; } argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); if(NULLSTR(arg1)) { if(IS_IMMORTAL(ch)) { send_to_char("&WThe following are the known bugs within the &CSIX DRAGONS&W realms&D\r\n", ch); send_to_char("&CNum Room Date Time Name\r\n", ch); if(!IS_BLIND(ch)) { send_to_char("&B--------------------------------------------------\r\n", ch); } for(Bug = firstBug; Bug; Bug = Bug->next) { cnt++; ch_printf(ch, "%s%3d> %-6d %-21s %-10s\r\n", NULLSTR(Bug->fixedBy) ? "&R" : "&G", cnt, Bug->room, Bug->foundWhen, Bug->foundBy); } if(cnt <= 0) { send_to_char("No bugs have been reported.\r\n", ch); return; } if(IS_BLIND(ch)) { send_to_char("&B--------------------------------------------------\r\n", ch); } send_to_char("\r\n&WSyntax: bug <field> <number> <severity> <bonus>\r\n", ch); send_to_char("\r\n&cField being : edit, delete, show, fixed, report\r\n", ch); send_to_char("&cNumber being : (what bug number)\r\n", ch); send_to_char("&cSeverity being: nothing, lesser, minor, major, severe, critical\r\n", ch); send_to_char("&cBonus being : none, bonus, bonusx2, both\r\n", ch); } else { send_to_char("&CBugs\r\nLv Degree Gold Glory\r\n", ch); send_to_char("&B--------------------------\r\n", ch); send_to_char("&W0 nothing 0 0\r\n", ch); send_to_char("&W1 lesser 10 1\r\n", ch); send_to_char("&W2 minor 25 2\r\n", ch); send_to_char("&W3 major 50 3\r\n", ch); send_to_char("&W4 severe 100 5\r\n", ch); send_to_char("&W5 critical 200 10\r\n", ch); send_to_char("&B--------------------------\r\n", ch); send_to_char("&CThe STAFF of 6 Dragons will reward you based on the above criteria for\r\nbugs reported. The reward is automatically generated by the code once the bug is fixed.\r\n", ch); send_to_char("\r\nIf you want to report a bug, type &WBUG REPORT&D\r\n", ch); } return; } if(!str_cmp(arg1, "report")) { CREATE(nBug, BUG_DATA, 1); LINK(nBug, firstBug, lastBug, next, prev); nBug->foundBy = STRALLOC(ch->name); nBug->foundWhen = STRALLOC(timeStamp()); nBug->type = -1; nBug->reward = FALSE; nBug->room = ch->in_room ? ch->in_room->vnum : -1; nBug->fixedBy = NULL; nBug->fixedWhen = NULL; nBug->fixDesc = NULL; nBug->bugDesc = NULL; if(ch->substate == SUB_REPEATCMD) ch->tempnum = SUB_REPEATCMD; else ch->tempnum = SUB_NONE; ch->substate = SUB_BUG_DESC; ch->dest_buf = nBug; start_editing(ch, nBug->bugDesc); return; } if(!IS_IMMORTAL(ch)) { send_to_char("Huh?\r\n", ch); return; } if(!str_cmp(arg1, "show")) { if(NULLSTR(arg2)) { send_to_char("Show which bug?\r\nSyntax: bug show <number>\r\n", ch); return; } cnt = 0; for(Bug = firstBug; Bug; Bug = Bug->next) { cnt++; if(cnt == atoi(arg2)) break; } if(!Bug) { send_to_char("No such bug.\r\n", ch); return; } send_to_char("&CNum Room Date Time Name\r\n", ch); send_to_char("&B----------------------------------------------------------------------\r\n", ch); ch_printf(ch, "%s%3d&C> &W%-6d %-21s %-10s\r\n", NULLSTR(Bug->fixedBy) ? "&R" : "&W", cnt, Bug->room, Bug->foundWhen, Bug->foundBy); send_to_char("&B----------------------------------------------------------------------\r\n", ch); ch_printf(ch, "&CDescription\r\n&W%s\r\n", Bug->bugDesc); send_to_char("&B----------------------------------------------------------------------\r\n", ch); if(!NULLSTR(Bug->fixedBy)) { ch_printf(ch, "&CFixed by: &W%s\r\n", Bug->fixedBy); ch_printf(ch, "&CWhen : &W%s\r\n", Bug->fixedWhen); ch_printf(ch, "&CSeverity: &W%s\r\n", bugSeverity(Bug->type)); ch_printf(ch, "&CRewarded: &W%s\r\n", Bug->reward ? "Yes" : "No"); if(Bug->bonus > 0) ch_printf(ch, "&CBonus : &W%s\r\n", Bug->bonus == 1 ? "+50%" : Bug->bonus == 1 ? "x2" : Bug->bonus > 1 ? "+50% x2" : "None"); send_to_char("&B----------------------------------------------------------------------\r\n", ch); ch_printf(ch, "&CNotes\r\n&W%s\r\n", Bug->fixDesc); send_to_char("&B----------------------------------------------------------------------\r\n", ch); } return; } else if(!str_cmp(arg1, "edit")) { cnt = 0; for(Bug = firstBug; Bug; Bug = Bug->next) { cnt++; if(cnt == atoi(arg2)) break; } if(!Bug) { send_to_char("No such bug.\r\n", ch); return; } if(ch->substate == SUB_REPEATCMD) ch->tempnum = SUB_REPEATCMD; else ch->tempnum = SUB_NONE; ch->substate = SUB_BUG_DESC; ch->dest_buf = Bug; start_editing(ch, Bug->bugDesc); return; } else if(!str_cmp(arg1, "fixed")) { char arg3[MIL]; char arg4[MIL]; argument = one_argument(argument, arg3); argument = one_argument(argument, arg4); if(NULLSTR(arg2)) { send_to_char("&WWhich bug is fixed?\r\nSyntax: bug fixed <number> <severity> <bonus>\r\n", ch); send_to_char("Severity can be:\r\n &wnothing lesser minor major severe critical\r\n", ch); send_to_char("&WBonus can be either: &wnone bonus bonusx2 &Wor &wboth\r\n", ch); send_to_char("\r\n&RDo not set a bug as fixed until you are positive the issue is resolved.\r\n", ch); return; } cnt = 0; for(Bug = firstBug; Bug; Bug = Bug->next) { cnt++; if(cnt == atoi(arg2)) break; } if(!Bug) { send_to_char("No such bug.\r\n", ch); return; } if(NULLSTR(arg3) || severityArg(arg3) <= -1) { send_to_char("How severe is the bug you are fixing?\r\nValid types are: nothing lesser minor major severe critical\r\n", ch); return; } if(NULLSTR(arg4)) { send_to_char("Are you giving a bonus for this bug?\r\nValid types are: bonus bonusx2 both\r\nIf not, use none.\r\n", ch); return; } if(!str_cmp(arg4, "bonus")) Bug->bonus = 1; else if(!str_cmp(arg4, "bonusx2")) Bug->bonus = 2; else if(!str_cmp(arg4, "both")) Bug->bonus = 3; else if(!str_cmp(arg4, "none")) Bug->bonus = -1; else { send_to_char("If you're giving a bonus to the bug reporter, use bonus or bonusx2. If not, use none.\r\n", ch); return; } if(!NULLSTR(Bug->fixedBy)) { send_to_char("That bug has already been fixed.\r\n", ch); return; } Bug->fixedBy = STRALLOC(ch->name); Bug->fixedWhen = STRALLOC(timeStamp()); Bug->type = severityArg(arg3); Bug->fixDesc = NULL; Bug->reward = FALSE; send_to_char("Please enter a description of how the issue was resolved.\r\n", ch); if(ch->substate == SUB_REPEATCMD) ch->tempnum = SUB_REPEATCMD; else ch->tempnum = SUB_NONE; ch->substate = SUB_BUG_FIXDESC; ch->dest_buf = Bug; start_editing(ch, Bug->fixDesc); return; } else if(!str_cmp(arg1, "delete")) { if(NULLSTR(arg2)) { send_to_char("Delete which bug?\r\nSyntax: bug delete <number>\r\n", ch); return; } cnt = 0; for(Bug = firstBug; Bug; Bug = Bug->next) { cnt++; if(cnt == atoi(arg2)) break; } if(!Bug) { send_to_char("No such bug.\r\n", ch); return; } ch_printf(ch, "Bug #%d deleted.\r\n", cnt); freeOneBug(Bug); saveBugs(); return; } else { send_to_char("\r\n&WSyntax: bug\r\nSyntax: bug report\r\n" "Syntax: bug show <number>\r\nSyntax: bug fixed <number> <severity> <bonus>\r\n", ch); return; } } void freeOneIdea(IDEA_DATA * idea) { UNLINK(idea, firstIdea, lastIdea, next, prev); STRFREE(idea->ideaDesc); STRFREE(idea->madeBy); STRFREE(idea->madeWhen); STRFREE(idea->usedBy); STRFREE(idea->usedWhen); STRFREE(idea->useDesc); DISPOSE(idea); } void freeIdeas(void) { IDEA_DATA *idea, *idea_next; for(idea = firstIdea; idea; idea = idea_next) { idea_next = idea->next; freeOneIdea(idea); } } void saveIdeas(void) { FILE *fp = NULL; IDEA_DATA *idea = NULL; char fname[MFL]; snprintf(fname, MFL, "%s%s", SYSTEM_DIR, IDEA_FILE); if(!(fp = FileOpen(fname, "w"))) { bug("%s: Couldn't open %s for writing", __FUNCTION__, fname); return; } for(idea = firstIdea; idea; idea = idea->next) { fprintf(fp, "#IDEA\n"); fprintf(fp, "MadeBy %s~\n", idea->madeBy); fprintf(fp, "MadeWhen %s~\n", idea->madeWhen); fprintf(fp, "IdeaDesc %s~\n", strip_cr(idea->ideaDesc)); fprintf(fp, "Type %d\n", idea->type); if(idea->usedBy) fprintf(fp, "UsedBy %s~\n", idea->usedBy); if(idea->usedWhen) fprintf(fp, "UsedWhen %s~\n", idea->usedWhen); if(idea->useDesc) fprintf(fp, "UseDesc %s~\n", idea->useDesc); fprintf(fp, "Reward %d\n", idea->reward); fprintf(fp, "RewardBonus %d\n", idea->bonus); fprintf(fp, "Room %d\n", idea->room); fprintf(fp, "End\n\n"); } fprintf(fp, "#END\n"); FileClose(fp); } void fReadIdea(IDEA_DATA * idea, FILE * fp) { const char *word; bool fMatch; for(;;) { word = feof(fp) ? "End" : fread_word(fp); fMatch = FALSE; switch (UPPER(word[0])) { case '*': fMatch = TRUE; fread_to_eol(fp); break; case 'E': if(!str_cmp(word, "End")) { nstralloc(&idea->ideaDesc); nstralloc(&idea->madeBy); nstralloc(&idea->madeWhen); nstralloc(&idea->usedBy); nstralloc(&idea->usedWhen); nstralloc(&idea->useDesc); return; } break; case 'I': KEY("IdeaDesc", idea->ideaDesc, fread_string(fp)); break; case 'M': KEY("MadeBy", idea->madeBy, fread_string(fp)); KEY("MadeWhen", idea->madeWhen, fread_string(fp)); break; case 'R': KEY("Reward", idea->reward, fread_number(fp)); KEY("RewardBonus", idea->bonus, fread_number(fp)); KEY("Room", idea->room, fread_number(fp)); break; case 'T': KEY("Type", idea->type, fread_number(fp)); break; case 'U': KEY("UsedBy", idea->usedBy, fread_string(fp)); KEY("UsedWhen", idea->usedWhen, fread_string(fp)); KEY("UseDesc", idea->useDesc, fread_string(fp)); } if(!fMatch) bug("%s: no match: %s", __FUNCTION__, word); } } void loadIdeas(void) { char fname[MFL]; IDEA_DATA *idea; FILE *fp; firstIdea = NULL; lastIdea = NULL; snprintf(fname, MFL, "%s%s", SYSTEM_DIR, IDEA_FILE); if((fp = FileOpen(fname, "r")) != NULL) { for(;;) { char letter; const char *word; letter = fread_letter(fp); if(letter == '*') { fread_to_eol(fp); continue; } if(letter != '#') { bug("%s: # not found: (%c)", __FUNCTION__, letter); break; } word = fread_word(fp); if(!str_cmp(word, "IDEA")) { CREATE(idea, IDEA_DATA, 1); fReadIdea(idea, fp); LINK(idea, firstIdea, lastIdea, next, prev); continue; } else if(!str_cmp(word, "END")) break; else { bug("%s: bad section: %s", __FUNCTION__, word); continue; } } FileClose(fp); } return; } const char *ideaLevel(short type) { switch (type) { case 0: return "nothing"; break; case 1: return "good"; break; case 2: return "great"; break; case 3: return "phenomenal"; break; default: return "unknown??"; break; } } short ideaLevelArg(char *arg) { if(!str_cmp(arg, "good")) return 1; else if(!str_cmp(arg, "nothing")) return 0; else if(!str_cmp(arg, "great")) return 2; else if(!str_cmp(arg, "phenomenal")) return 3; else return -1; } void ideaReward(CHAR_DATA *ch, IDEA_DATA * idea) { int gold = 0; int glory = 0; char buf1[MSL], buf2[MSL]; if(idea->reward) return; if(!str_cmp(idea->madeBy, ch->name)) { switch (idea->type) { case 0: gold = 0; glory = 0; break; case 1: gold = 3; glory = 1; break; case 2: gold = 5; glory = 3; break; case 3: gold = 10; glory = 5; break; default: break; } if(idea->bonus == 1) { gold = gold + (gold / 2); glory = glory + (glory / 2); } else if(idea->bonus == 2) { gold = gold * 2; glory = glory * 2; } else if(idea->bonus == 3) { gold = (gold * 2) + (gold / 2); glory = (glory * 2) + (glory / 2); } snprintf(buf1, MSL, "%s", num_punct(gold)); snprintf(buf2, MSL, "%s", num_punct(glory)); if(gold == 0 && glory == 0) { ch_printf(ch, "&CSomeone says, 'The STAFF did not find it fit to reward you for your submitted idea!'\r\n"); ch_printf(ch, "&CSomeone says, 'The idea was probably submitted prior to your discovery. Keep looking though!'\r\n"); } else ch_printf(ch, "&CSomeone says, 'The STAFF have rewarded you %s gold and %s glory for your %s idea!'\r\n", buf1, buf2, ideaLevel(idea->type)); idea->reward = TRUE; ch->pcdata->num_ideas++; ch->pcdata->ideaReward1 += gold; ch->pcdata->ideaReward2 += glory; GET_MONEY(ch, CURR_GOLD) += gold; ch->quest_curr += glory; send_to_pager("&CYour idea was:\r\n&B----------------------------------------------------------------------&W\r\n", ch); send_to_pager(idea->ideaDesc, ch); send_to_pager("\r\n", ch); send_to_pager("&CSTAFF note:\r\n&B----------------------------------------------------------------------&W\r\n", ch); send_to_pager(idea->useDesc, ch); send_to_pager("\r\n", ch); save_char_obj(ch); freeOneIdea(idea); saveIdeas(); return; } return; } void do_idea(CHAR_DATA *ch, char *argument) { char arg1[MIL]; char arg2[MIL]; IDEA_DATA *Idea = NULL, *nIdea; short cnt = 0; DESCRIPTOR_DATA *d; if(IS_NPC(ch)) { send_to_char("Huh?\r\n", ch); return; } switch (ch->substate) { default: break; case SUB_RESTRICTED: send_to_char("You cannot do this while in another command.\r\n", ch); return; case SUB_IDEA_DESC: nIdea = (IDEA_DATA *) ch->dest_buf; STRFREE(nIdea->ideaDesc); nIdea->ideaDesc = copy_buffer(ch); stop_editing(ch); if(!VLD_STR(nIdea->ideaDesc)) { send_to_char("&CSomeone says, 'Nothing was in the idea submission so it has been discarded.'\r\n", ch); freeOneIdea(nIdea); } else { saveIdeas(); send_to_char("&CSomeone says, 'Thanks, your idea submission has been recorded.'\r\n", ch); send_to_char("&CSomeone says, 'You will be notified if the idea is implemented.'\r\n", ch); log_printf("%s has submitted an idea.", ch->name); } ch->substate = ch->tempnum; return; case SUB_IDEA_USEDESC: Idea = (IDEA_DATA *) ch->dest_buf; if(Idea->useDesc) STRFREE(Idea->useDesc); Idea->useDesc = copy_buffer(ch); stop_editing(ch); saveIdeas(); ch->substate = ch->tempnum; send_to_char("Ok, the idea has been used and the player who submitted it will be notified.\r\n", ch); if(Idea->madeBy) { for(d = first_descriptor; d; d = d->next) { if(!d->character) continue; if(!str_cmp(Idea->madeBy, d->character->name) && !NULLSTR(Idea->usedBy)) { checkBuidty(d->character); break; } } } return; } argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); if(NULLSTR(arg1)) { if(IS_IMMORTAL(ch)) { send_to_char("&WThe following are the known ideas within the &CSIX DRAGONS&W realms&D\r\n", ch); send_to_char("&CNum Room Date Time Name\r\n", ch); send_to_char("&B--------------------------------------------------\r\n", ch); for(Idea = firstIdea; Idea; Idea = Idea->next) { cnt++; ch_printf(ch, "%s%3d> %-6d %-21s %-10s\r\n", NULLSTR(Idea->usedBy) ? "&R" : "&G", cnt, Idea->room, Idea->madeWhen, Idea->madeBy); } if(cnt <= 0) { send_to_char("No ideas have been submitted.\r\n", ch); return; } send_to_char("&B--------------------------------------------------\r\n", ch); send_to_char("\r\n&WSyntax: idea <field> <number> <level> <bonus>\r\n", ch); send_to_char("\r\n&cField being : edit, delete, show, use, submit\r\n", ch); send_to_char("&cNumber being : (what idea number)\r\n", ch); send_to_char("&cLevel being : nothing, good, great, phenomenal\r\n", ch); send_to_char("&cBonus being : none, bonus, bonusx2, both\r\n", ch); } else { send_to_char("&CIdeas\r\nLv Degree Gold Glory\r\n", ch); send_to_char("&B--------------------------\r\n", ch); send_to_char("&W0 Nothing 0 0\r\n", ch); send_to_char("&W1 Good 3 1\r\n", ch); send_to_char("&W2 Great 5 3\r\n", ch); send_to_char("&W3 Phenomenal 10 5\r\n", ch); send_to_char("&B--------------------------\r\n", ch); send_to_char ("&CThe STAFF of 6 Dragons will reward you based on the above criteria for\r\nideas submitted. The reward is automatically generated by the code once the idea is utilized.\r\n", ch); send_to_char("\r\nIf you want to submit a idea, type &WIDEA SUBMIT&D\r\n", ch); } return; } if(!str_cmp(arg1, "submit")) { CREATE(nIdea, IDEA_DATA, 1); LINK(nIdea, firstIdea, lastIdea, next, prev); nIdea->madeBy = STRALLOC(ch->name); nIdea->madeWhen = STRALLOC(timeStamp()); nIdea->type = -1; nIdea->reward = FALSE; nIdea->room = ch->in_room ? ch->in_room->vnum : -1; nIdea->usedBy = NULL; nIdea->usedWhen = NULL; nIdea->useDesc = NULL; nIdea->ideaDesc = NULL; if(ch->substate == SUB_REPEATCMD) ch->tempnum = SUB_REPEATCMD; else ch->tempnum = SUB_NONE; ch->substate = SUB_IDEA_DESC; ch->dest_buf = nIdea; start_editing(ch, nIdea->ideaDesc); return; } if(!IS_IMMORTAL(ch)) { send_to_char("Huh?\r\n", ch); return; } if(!str_cmp(arg1, "edit")) { cnt = 0; for(nIdea = firstIdea; nIdea; nIdea = nIdea->next) { cnt++; if(cnt == atoi(arg2)) break; } if(!nIdea) { send_to_char("No such idea.\r\n", ch); return; } if(ch->substate == SUB_REPEATCMD) ch->tempnum = SUB_REPEATCMD; else ch->tempnum = SUB_NONE; ch->substate = SUB_IDEA_DESC; ch->dest_buf = nIdea; start_editing(ch, nIdea->ideaDesc); return; } else if(!str_cmp(arg1, "show")) { if(NULLSTR(arg2)) { send_to_char("Show which idea?\r\nSyntax: idea show <number>\r\n", ch); return; } cnt = 0; for(Idea = firstIdea; Idea; Idea = Idea->next) { cnt++; if(cnt == atoi(arg2)) break; } if(!Idea) { send_to_char("No such idea.\r\n", ch); return; } send_to_char("&CNum Room Date Time Name\r\n", ch); send_to_char("&B----------------------------------------------------------------------\r\n", ch); ch_printf(ch, "%s%3d&C> &W%-6d %-21s %-10s\r\n", NULLSTR(Idea->usedBy) ? "&R" : "&W", cnt, Idea->room, Idea->madeWhen, Idea->madeBy); send_to_char("&B----------------------------------------------------------------------\r\n", ch); ch_printf(ch, "&CDescription\r\n&W%s\r\n", Idea->ideaDesc); send_to_char("&B----------------------------------------------------------------------\r\n", ch); if(!NULLSTR(Idea->usedBy)) { ch_printf(ch, "&CUsed by : &W%s\r\n", Idea->usedBy); ch_printf(ch, "&CWhen : &W%s\r\n", Idea->usedWhen); ch_printf(ch, "&CLevel : &W%s\r\n", ideaLevel(Idea->type)); ch_printf(ch, "&CRewarded: &W%s\r\n", Idea->reward ? "Yes" : "No"); if(Idea->bonus > 0) ch_printf(ch, "&CBonus : &W%s\r\n", Idea->bonus == 1 ? "+50%" : Idea->bonus == 2 ? "x2" : Idea->bonus > 2 ? "+50% x2" : "None"); send_to_char("&B----------------------------------------------------------------------\r\n", ch); ch_printf(ch, "&CNotes\r\n&W%s\r\n", Idea->useDesc); send_to_char("&B----------------------------------------------------------------------\r\n", ch); } return; } else if(!str_cmp(arg1, "use")) { char arg3[MIL]; char arg4[MIL]; argument = one_argument(argument, arg3); argument = one_argument(argument, arg4); if(NULLSTR(arg2)) { send_to_char("&WWhich idea has been used?\r\nSyntax: idea used <number> <level> <bonus>\r\n", ch); send_to_char("Level can be:\r\n nothing good great phenomenal\r\n", ch); send_to_char("Bonus can be either: &wnone bonus bonusx2 &Wor &wboth\r\n", ch); send_to_char("\r\n&RDo not set a idea as used until you are positive it has been fully implemented.\r\n", ch); return; } cnt = 0; for(Idea = firstIdea; Idea; Idea = Idea->next) { cnt++; if(cnt == atoi(arg2)) break; } if(!Idea) { send_to_char("No such idea.\r\n", ch); return; } if(NULLSTR(arg3) || ideaLevelArg(arg3) <= -1) { send_to_char("How good is the idea you are using?\r\nValid types are: nothing good great phenomenal\r\n", ch); return; } if(NULLSTR(arg4)) { send_to_char("Are you giving a bonus for this idea?\r\nValid types are: none bonus bonusx2 both\r\n", ch); return; } if(!str_cmp(arg4, "bonus")) Idea->bonus = 1; else if(!str_cmp(arg4, "bonusx2")) Idea->bonus = 2; else if(!str_cmp(arg4, "both")) Idea->bonus = 3; else if(!str_cmp(arg4, "none")) Idea->bonus = -1; else { send_to_char("If you're giving a bonus to the idea submitter, use bonus or bonusx2. If not, use none.\r\n", ch); return; } if(!NULLSTR(Idea->usedBy)) { send_to_char("That idea has already been used.\r\n", ch); return; } Idea->usedBy = STRALLOC(ch->name); Idea->usedWhen = STRALLOC(timeStamp()); Idea->type = ideaLevelArg(arg3); Idea->reward = FALSE; if(VLD_STR(argument)) { Idea->useDesc = STRALLOC(capitalize(argument)); send_to_char("Ok, the idea has been used and the player who submitted it will be notified.\r\n", ch); } else { send_to_char("Please enter a description of how the idea was implemented.\r\n", ch); if(ch->substate == SUB_REPEATCMD) ch->tempnum = SUB_REPEATCMD; else ch->tempnum = SUB_NONE; ch->substate = SUB_IDEA_USEDESC; ch->dest_buf = Idea; start_editing(ch, Idea->useDesc); } return; } else if(!str_cmp(arg1, "delete")) { if(NULLSTR(arg2)) { send_to_char("Delete which idea?\r\nSyntax: idea delete <number>\r\n", ch); return; } cnt = 0; for(Idea = firstIdea; Idea; Idea = Idea->next) { cnt++; if(cnt == atoi(arg2)) break; } if(!Idea) { send_to_char("No such idea.\r\n", ch); return; } ch_printf(ch, "Idea #%d deleted.\r\n", cnt); freeOneIdea(Idea); saveIdeas(); return; } else { send_to_char("\r\n&WSyntax: idea\r\nSyntax: idea submit\r\n" "Syntax: idea show <number>\r\nSyntax: idea use <number> <level> <bonus>\r\n", ch); return; } return; } void freeOneTypo(TYPO_DATA * typo) { UNLINK(typo, firstTypo, lastTypo, next, prev); STRFREE(typo->typoDesc); STRFREE(typo->foundBy); STRFREE(typo->foundWhen); STRFREE(typo->fixedBy); STRFREE(typo->fixedWhen); DISPOSE(typo); } void freeTypos(void) { TYPO_DATA *typo, *typo_next; for(typo = firstTypo; typo; typo = typo_next) { typo_next = typo->next; freeOneTypo(typo); } } void saveTypos(void) { FILE *fp = NULL; TYPO_DATA *typo = NULL; char fname[MFL]; snprintf(fname, MFL, "%s%s", SYSTEM_DIR, TYPO_FILE); if(!(fp = FileOpen(fname, "w"))) { bug("%s: Couldn't open %s for writing", __FUNCTION__, fname); return; } for(typo = firstTypo; typo; typo = typo->next) { fprintf(fp, "#TYPO\n"); fprintf(fp, "FoundBy %s~\n", typo->foundBy); fprintf(fp, "FoundWhen %s~\n", typo->foundWhen); fprintf(fp, "TypoDesc %s~\n", strip_cr(typo->typoDesc)); fprintf(fp, "Type %d\n", typo->type); if(typo->fixedBy) fprintf(fp, "FixedBy %s~\n", typo->fixedBy); if(typo->fixedWhen) fprintf(fp, "FixedWhen %s~\n", typo->fixedWhen); fprintf(fp, "Reward %d\n", typo->reward); fprintf(fp, "RewardBonus %d\n", typo->bonus); fprintf(fp, "Room %d\n", typo->room); fprintf(fp, "End\n\n"); } fprintf(fp, "#END\n"); FileClose(fp); return; } void fReadTypo(TYPO_DATA * typo, FILE * fp) { const char *word; bool fMatch; for(;;) { word = feof(fp) ? "End" : fread_word(fp); fMatch = FALSE; switch (UPPER(word[0])) { case '*': fMatch = TRUE; fread_to_eol(fp); break; case 'E': if(!str_cmp(word, "End")) { nstralloc(&typo->typoDesc); nstralloc(&typo->foundBy); nstralloc(&typo->foundWhen); nstralloc(&typo->fixedBy); nstralloc(&typo->fixedWhen); return; } break; case 'F': KEY("FixedBy", typo->fixedBy, fread_string(fp)); KEY("FixedWhen", typo->fixedWhen, fread_string(fp)); KEY("FoundBy", typo->foundBy, fread_string(fp)); KEY("FoundWhen", typo->foundWhen, fread_string(fp)); break; case 'R': KEY("Reward", typo->reward, fread_number(fp)); KEY("RewardBonus", typo->bonus, fread_number(fp)); KEY("Room", typo->room, fread_number(fp)); break; case 'T': KEY("Type", typo->type, fread_number(fp)); KEY("TypoDesc", typo->typoDesc, fread_string(fp)); break; } if(!fMatch) bug("%s: no match: %s", __FUNCTION__, word); } } void loadTypos(void) { char fname[MFL]; TYPO_DATA *typo; FILE *fp; firstTypo = NULL; lastTypo = NULL; snprintf(fname, MFL, "%s%s", SYSTEM_DIR, TYPO_FILE); if((fp = FileOpen(fname, "r")) != NULL) { for(;;) { char letter; const char *word; letter = fread_letter(fp); if(letter == '*') { fread_to_eol(fp); continue; } if(letter != '#') { bug("%s: # not found.", __FUNCTION__); break; } word = fread_word(fp); if(!str_cmp(word, "TYPO")) { CREATE(typo, TYPO_DATA, 1); fReadTypo(typo, fp); LINK(typo, firstTypo, lastTypo, next, prev); continue; } else if(!str_cmp(word, "END")) break; else { bug("%s: bad section: %s", __FUNCTION__, word); continue; } } FileClose(fp); } return; } const char *typoLevel(short type) { switch (type) { case 0: return "nothing"; break; case 1: return "misspelled"; break; case 2: return "misused"; break; case 3: return "offensive"; break; default: return "Unknown??"; break; } } short typoLevelArg(char *arg) { if(!str_cmp(arg, "misspelled")) return 1; else if(!str_cmp(arg, "nothing")) return 0; else if(!str_cmp(arg, "misused")) return 2; else if(!str_cmp(arg, "offensive")) return 3; else return -1; } void typoReward(CHAR_DATA *ch, TYPO_DATA * typo) { int gold = 0; int glory = 0; char buf1[MSL], buf2[MSL]; if(typo->reward) return; if(!str_cmp(typo->foundBy, ch->name)) { switch (typo->type) { case 0: gold = 0; glory = 0; break; case 1: gold = 1; glory = 1; break; case 2: gold = 3; glory = 3; break; case 3: gold = 5; glory = 5; break; default: break; } if(typo->bonus == 1) { gold = gold + (gold / 2); glory = glory + (glory / 2); } else if(typo->bonus == 2) { gold = gold * 2; glory = glory * 2; } else if(typo->bonus == 3) { gold = (gold * 2) + (gold / 2); glory = (glory * 2) + (glory / 2); } snprintf(buf1, MSL, "%s", num_punct(gold)); snprintf(buf2, MSL, "%s", num_punct(glory)); if(gold == 0 && glory == 0) { ch_printf(ch, "&CSomeone says, 'The STAFF did not find it fit to reward you for your reported typo!'\r\n"); ch_printf(ch, "&CSomeone says, 'The typo was probably submitted prior to your discovery. Keep looking though!'\r\n"); } else ch_printf(ch, "&CSomeone says, 'The STAFF have rewarded you %s gold and %s glory for finding %s typo!'\r\n", buf1, buf2, aoran(typoLevel(typo->type))); typo->reward = TRUE; ch->pcdata->num_typos++; ch->pcdata->typoReward1 += gold; ch->pcdata->typoReward2 += glory; GET_MONEY(ch, CURR_GOLD) += gold; ch->quest_curr += glory; send_to_pager("&CYour typo was:\r\n&B----------------------------------------------------------------------&W\r\n", ch); send_to_pager(typo->typoDesc, ch); send_to_pager("&C\r\nThanks!\r\n", ch); save_char_obj(ch); freeOneTypo(typo); saveTypos(); return; } return; } void do_typo(CHAR_DATA *ch, char *argument) { char arg1[MIL]; char arg2[MIL]; TYPO_DATA *typo = NULL, *nTypo; short cnt = 0; DESCRIPTOR_DATA *d; if(IS_NPC(ch)) { send_to_char("Huh?\r\n", ch); return; } switch (ch->substate) { default: break; case SUB_RESTRICTED: send_to_char("You cannot do this while in another command.\r\n", ch); return; case SUB_TYPO_DESC: nTypo = (TYPO_DATA *) ch->dest_buf; if(nTypo->typoDesc) STRFREE(nTypo->typoDesc); nTypo->typoDesc = copy_buffer(ch); stop_editing(ch); if(!VLD_STR(nTypo->typoDesc)) { send_to_char("&CSomeone says, 'Nothing was in the typo report so it has been discarded.'\r\n", ch); freeOneTypo(nTypo); } else { saveTypos(); ch->substate = ch->tempnum; send_to_char("&CSomeone says, 'Thanks, your typo report has been recorded.'\r\n", ch); send_to_char("&CSomeone says, 'You will be notified when the typo is fixed.'\r\n", ch); log_printf("%s has reported a typo.", ch->name); } ch->substate = ch->tempnum; return; } argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); if(NULLSTR(arg1)) { if(IS_IMMORTAL(ch)) { send_to_char("&WThe following are the known typos within the &CSIX DRAGONS&W realms&D\r\n", ch); send_to_char("&CNum Room Date Time Name\r\n", ch); send_to_char("&B--------------------------------------------------\r\n", ch); for(typo = firstTypo; typo; typo = typo->next) { cnt++; ch_printf(ch, "%s%3d> %-6d %-21s %-10s\r\n", NULLSTR(typo->fixedBy) ? "&R" : "&G", cnt, typo->room, typo->foundWhen, typo->foundBy); } if(cnt <= 0) { send_to_char("No typos have been reported.\r\n", ch); return; } send_to_char("&B--------------------------------------------------\r\n", ch); send_to_char("\r\n&WSyntax: typo <field> <number> <level> <bonus>\r\n", ch); send_to_char("\r\n&cField being : edit, delete, report, show, fixed\r\n", ch); send_to_char("&cNumber being : (what typo number)\r\n", ch); send_to_char("&cLevel being: nothing, misspelled, misused, offensive\r\n", ch); send_to_char("&cBonus being : none, bonus, bonusx2, both\r\n", ch); } else { send_to_char("&CTypos\r\nLv Degree Gold Glory\r\n", ch); send_to_char("&B--------------------------\r\n", ch); send_to_char("&W0 nothing 0 0\r\n", ch); send_to_char("&W1 misspelled 1 1\r\n", ch); send_to_char("&W2 misused 3 3\r\n", ch); send_to_char("&W3 offensive 5 5\r\n", ch); send_to_char("&B--------------------------\r\n", ch); send_to_char("&CTypos are words in the game that are either misspelled, misused, or offensive.\r\n", ch); send_to_char("&CThe STAFF of 6 Dragons will reward you based on the above criteria for\r\ntypos reported. The reward is automatically generated by the code once the typo is fixed.\r\n", ch); send_to_char("\r\nIf you want to report a typo, type &WTYPO REPORT&D\r\n", ch); } return; } if(!str_cmp(arg1, "report")) { CREATE(nTypo, TYPO_DATA, 1); LINK(nTypo, firstTypo, lastTypo, next, prev); nTypo->foundBy = STRALLOC(ch->name); nTypo->foundWhen = STRALLOC(timeStamp()); nTypo->type = -1; nTypo->reward = FALSE; nTypo->room = ch->in_room ? ch->in_room->vnum : -1; nTypo->fixedBy = NULL; nTypo->fixedWhen = NULL; nTypo->typoDesc = NULL; if(ch->substate == SUB_REPEATCMD) ch->tempnum = SUB_REPEATCMD; else ch->tempnum = SUB_NONE; ch->substate = SUB_TYPO_DESC; ch->dest_buf = nTypo; start_editing(ch, nTypo->typoDesc); return; } if(!IS_IMMORTAL(ch)) { send_to_char("Huh?\r\n", ch); return; } if(!str_cmp(arg1, "edit")) { cnt = 0; for(nTypo = firstTypo; nTypo; nTypo = nTypo->next) { cnt++; if(cnt == atoi(arg2)) break; } if(!nTypo) { send_to_char("No such typo.\r\n", ch); return; } if(ch->substate == SUB_REPEATCMD) ch->tempnum = SUB_REPEATCMD; else ch->tempnum = SUB_NONE; ch->substate = SUB_TYPO_DESC; ch->dest_buf = nTypo; start_editing(ch, nTypo->typoDesc); return; } else if(!str_cmp(arg1, "show")) { if(NULLSTR(arg2)) { send_to_char("Show which typo?\r\nSyntax: typo show <number>\r\n", ch); return; } cnt = 0; for(typo = firstTypo; typo; typo = typo->next) { cnt++; if(cnt == atoi(arg2)) break; } if(!typo) { send_to_char("No such typo.\r\n", ch); return; } send_to_char("&CNum Room Date Time Name\r\n", ch); send_to_char("&B----------------------------------------------------------------------\r\n", ch); ch_printf(ch, "%s%3d&C> &W%-6d %-21s %-10s\r\n", NULLSTR(typo->fixedBy) ? "&R" : "&W", cnt, typo->room, typo->foundWhen, typo->foundBy); send_to_char("&B----------------------------------------------------------------------\r\n", ch); ch_printf(ch, "&CDescription\r\n&W%s\r\n", typo->typoDesc); send_to_char("&B----------------------------------------------------------------------\r\n", ch); if(!NULLSTR(typo->fixedBy)) { ch_printf(ch, "&CUsed by : &W%s\r\n", typo->fixedBy); ch_printf(ch, "&CWhen : &W%s\r\n", typo->fixedWhen); ch_printf(ch, "&CLevel : &W%s\r\n", typoLevel(typo->type)); ch_printf(ch, "&CRewarded: &W%s\r\n", typo->reward ? "Yes" : "No"); if(typo->bonus > 0) ch_printf(ch, "&CBonus : &W%s\r\n", typo->bonus == 1 ? "+50%" : typo->bonus == 2 ? "x2" : typo->bonus > 2 ? "+50% x2" : "None"); } return; } else if(!str_cmp(arg1, "fixed")) { char arg3[MIL]; char arg4[MIL]; argument = one_argument(argument, arg3); argument = one_argument(argument, arg4); if(NULLSTR(arg2)) { send_to_char("&WWhich typo is fixed?\r\nSyntax: typo use <number> <level> <bonus>\r\n", ch); send_to_char("Level can be:\r\n &wnothing misspelled misused offensive\r\n", ch); send_to_char("&WBonus can be either: &wnone bonus bonusx2 &Wor &wboth\r\n", ch); send_to_char("\r\n&RDo not set a typo as fixed until you are positive it has been corrected.\r\n", ch); return; } cnt = 0; for(typo = firstTypo; typo; typo = typo->next) { cnt++; if(cnt == atoi(arg2)) break; } if(!typo) { send_to_char("No such typo.\r\n", ch); return; } if(NULLSTR(arg3) || typoLevelArg(arg3) == -1) { send_to_char("&WHow wrong was the typo you corrected?\r\nValid types are: &wnothing misspelled misused offensive\r\n", ch); return; } if(NULLSTR(arg4)) { send_to_char("&WAre you giving a bonus for this typo?\r\nValid types are: &wnone bonus bonusx2 both\r\n", ch); return; } if(!str_cmp(arg4, "bonus")) typo->bonus = 1; else if(!str_cmp(arg4, "bonusx2")) typo->bonus = 2; else if(!str_cmp(arg4, "both")) typo->bonus = 3; else if(!str_cmp(arg4, "none")) typo->bonus = -1; else { send_to_char("If you're giving a bonus to the typo reporter, use bonus, bonusx2 or both. If not, use none.\r\n", ch); return; } if(!NULLSTR(typo->fixedBy)) { send_to_char("That typo has already been used.\r\n", ch); return; } typo->fixedBy = STRALLOC(ch->name); typo->fixedWhen = STRALLOC(timeStamp()); typo->type = typoLevelArg(arg3); typo->reward = FALSE; send_to_char("Ok, the typo has been corrected and the player who reported it will be notified.\r\n", ch); saveTypos(); if(typo->foundBy) { for(d = first_descriptor; d; d = d->next) { if(!d->character) continue; if(!str_cmp(typo->foundBy, d->character->name) && !NULLSTR(typo->fixedBy)) { checkBuidty(d->character); break; } } } return; } else if(!str_cmp(arg1, "delete")) { if(NULLSTR(arg2)) { send_to_char("Delete which typo?\r\nSyntax: typo delete <number>\r\n", ch); return; } cnt = 0; for(typo = firstTypo; typo; typo = typo->next) { cnt++; if(cnt == atoi(arg2)) break; } if(!typo) { send_to_char("No such typo.\r\n", ch); return; } ch_printf(ch, "typo #%d deleted.\r\n", cnt); freeOneTypo(typo); saveTypos(); return; } else { send_to_char("\r\n&WSyntax: typo\r\nSyntax: typo report <typo>\r\n" "Syntax: typo show <number>\r\nSyntax: typo fixed <number> <level> <bonus>\r\n", ch); return; } return; } void checkBuidty(CHAR_DATA *ch) { BUG_DATA *Bug, *bug_next; IDEA_DATA *idea, *idea_next; TYPO_DATA *typo, *typo_next; int bcnt = 0, icnt = 0, tcnt = 0; if(!ch) { bug("%s: NULL ch!", __FUNCTION__); return; } for(Bug = firstBug; Bug; Bug = bug_next) { bug_next = Bug->next; if(NULLSTR(Bug->fixedBy)) { bcnt++; continue; } if(Bug->reward) continue; if(!str_cmp(Bug->foundBy, ch->name)) bugReward(ch, Bug); } for(idea = firstIdea; idea; idea = idea_next) { idea_next = idea->next; if(NULLSTR(idea->usedBy)) { icnt++; continue; } if(idea->reward) continue; if(!str_cmp(idea->madeBy, ch->name)) ideaReward(ch, idea); } for(typo = firstTypo; typo; typo = typo_next) { typo_next = typo->next; if(NULLSTR(typo->fixedBy)) { tcnt++; continue; } if(typo->reward) continue; if(!str_cmp(typo->foundBy, ch->name)) typoReward(ch, typo); } if(IS_IMMORTAL(ch)) { if(bcnt > 0) ch_printf(ch, "&R+++ &WThere are }R%d &d&Wgame issues that need resolving. Type &GBUG &Wto view. &R+++&D\r\n", bcnt); if(icnt > 0) ch_printf(ch, "&R+++ &WThere are }R%d &d&Wideas that need reviewing. Type &GIDEA &Wto view. &R+++&D\r\n", icnt); if(tcnt > 0) ch_printf(ch, "&R+++ &WThere are }R%d &d&Wtypos that need to be fixed. Type >YPO &Wto view. &R+++&D\r\n", tcnt); } } void pruneBuidty(void) { BUG_DATA *Bug = NULL; IDEA_DATA *Idea = NULL; TYPO_DATA *Typo = NULL; for(Bug = firstBug; Bug; Bug = Bug->next) { if(Bug && Bug->reward == TRUE) freeOneBug(Bug); } saveBugs(); for(Idea = firstIdea; Idea; Idea = Idea->next) { if(Idea && Idea->reward == TRUE) freeOneIdea(Idea); } saveIdeas(); for(Typo = firstTypo; Typo; Typo = Typo->next) { if(Typo && Typo->reward == TRUE) freeOneTypo(Typo); } saveTypos(); return; }