/* * MusicMUD - Quests module * Copyright (C) 19982-2003 Abigail Brady * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <ctype.h> #include <algorithm> #include "musicmud.h" #include "util.h" #include "verbs.h" #include "State.h" #include "Player.h" #include "paths.h" #include "flags.h" #include "pflags.h" #include "zoneload.h" #include "misc.h" #include "hooks.h" #include "nations.h" #define MODULE "quests" #define MINIS (COUNT_MINIS?COUNT_MINIS():0) static const char *mname(MudObject *what) { if (what->get("mname")) return what->get("mname"); if (what->get("name")) return what->get("name"); return what->id; } static string mname_href(MudObject *what) { return ssprintf("\3send href='minfo %s'\4%s\3/send\4", mname(what), mname(what)); } static bool verb_minfo(MudObject *who, int argc, const char **argv); struct mname_cmp { bool operator()(MudObject *a, MudObject *b) { const char *m1 = a->get("mname"); const char *m2 = b->get("mname"); if (!m1 && !m2) return 0; if (!m2) return 1; if (!m1) return 0; return strcmp(m1, m2) < 0; } }; set<MudObject*, mname_cmp> get_quests() { extern set<MudObject*> s_quests; set<MudObject*, mname_cmp> s; typeof(s_quests.begin()) i = s_quests.begin(); while (i != s_quests.end()) { s.insert(*i); i++; } return s; } static bool verb_mstatus(MudObject *who, int argc, const char **argv) { if (argc>1) return verb_minfo(who, argc, argv); set<MudObject*, mname_cmp> quests = get_quests(); int HOWMANY = (columns(who)-1)/26; int m = 0; int total = 0; who->printf("%s\n\n", title_for("Mission Status", who).c_str()); for (typeof(quests.begin()) i=quests.begin();i!=quests.end();i++) { MudObject *q_id = *i; if (q_id && (!q_id->get_flag(FL_PRIVATE) || IS_CAPTAIN(who))) { char *status = "???"; if (q_id->get_flag(FL_DONE)) { status = "^RDone^n"; } else if (q_id->owner == planet->get("empty")) { status = "^RRuin^n"; } else if (is_player(q_id->owner)) { status = "^YProg^n"; } else if (q_id->get_flag(FL_TAMPERED)) { status = "^YProg^n"; } else { status = "^GFree^n"; } who->printf("%s%-12s %-6s (^G%i^n) ", q_id->get_flag(FL_PRIVATE) ? "^r" : "", mname_href(q_id).c_str(), status, q_id->get_int("questpoints")); if (!q_id->get_flag(FL_PRIVATE)) { total += q_id->get_int("questpoints"); } m++; if ((m % HOWMANY)==0) { who->printf("\n"); } } } if ((m % HOWMANY) != 0) who->printf("\n"); who->printf("\nTotal points available : ^G%i^n + ^G%i^n = ^G%i^n\n\n", total, MINIS, total+MINIS); who->printf("%s\n", footer_for(who).c_str()); return true; } static int tobool(const char *yesno) { if (!yesno) return -1; char l = toupper(*yesno); if (l=='0' || l == 'N' || l == 'F') return 0; if (l=='1' || l == 'Y' || l == 'T') return 1; return -1; } static const char *can_access(const MudObject *who, const MudObject *what) { if (what->get_flag(FL_PRIVATE)) { return "^R!"; } if (what->get_flag(FL_INVISIBLE)) { return "^R?"; } MudObject *quest_needed = what->get_object("quest_needed"); if (quest_needed) { if (!quest_done(who, quest_needed)) { return "^y|"; } } return " "; } static bool verb_missions(MudObject *who, int argc, const char **argv) { int m = 0; OfflinePlayer whose(who); if (argc > 1) { whose.grab(who, argv[1]); if (!whose) { who->printf("Can't find : %s.\n", argv[1]); return true; } if (whose != who && !who->get_priv(PFL_SEESTATS)) { who->printf("You cannot do that on others.\n"); return true; } if (is_mobile(whose)) { who->printf("%#M is a mobile, and is too lazy to do missions.\n", whose); return true; } } int HOWMANY = (columns(who)-1)/14; if (argc > 2) { MudObject *qob = find_questob(argv[2]); if (!qob) { who->printf("No such mission as '%s'.\n", argv[2]); return true; } if (argc > 3 && who->get_priv(PFL_CHQUEST)) { MudObject *o = whose.on(); if (!o) { who->printf("Can't set missions on people who aren't logged in.\n"); return true; } int which = tobool(argv[3]); if (which == -1) { who->printf("Set it to what?\n"); return true; } if (which) { quest_set(o, qob->get("mname")); } else { quest_unset(o, qob->get("mname")); } who->printf("Done.\n"); o->interpret("calc_level loud"); return true; } if (who == whose) who->printf("You have %sdone the %s mission.\n", quest_done(whose, qob) ? "" : "not ", qob->get("mname")); else who->printf("%#M has %sdone the %s mission.\n", whose, quest_done(whose, qob) ? "" : "not ", qob->get("mname")); return true; } who->printf("Player: %M\n\n", whose); who->printf("^WCompleted missions^n\n\n"); set<MudObject*, mname_cmp> quests = get_quests(); iforeach(i, quests) { MudObject *q_id = *i; if (q_id && quest_done(whose, q_id) && (!q_id->get_flag(FL_PRIVATE) || IS_CAPTAIN(who))) { const char *cl = can_access(whose, q_id); who->printf("%s%-12s%s ", cl, mname_href(q_id).c_str(), "^n"); m++; if ((m % HOWMANY)==0) { who->printf("\n"); } } } if (m == 0) { who->printf(" None!\n"); } if ((m % HOWMANY) != 0) who->printf("\n"); who->printf("\n"); m = 0; iforeach(i, quests) { MudObject *q_id = *i; if (q_id && !quest_done(whose, q_id) && (!q_id->get_flag(FL_PRIVATE) || IS_CAPTAIN(who))) { const char *cl = can_access(whose,q_id); if (m == 0) who->printf("^WYet to do^n\n\n"); who->printf("%s%-12s%s ", cl, mname_href(q_id).c_str(), "^n"); m++; if ((m % HOWMANY)==0) { who->printf("\n"); } } } if ((m % HOWMANY) != 0) who->printf("\n"); who->printf("\n"); m = 0; m = DONE_MINIS?DONE_MINIS(whose):0; if (m==MINIS) { who->printf("^W%#P^W %[has/have] completed ^Gall^W types of minimission.^n\n", whose, MINIS); } else { who->printf("^W%#P^W %[has/have] completed ^G%i^W type%s of minimission out of the ^R%i^W available.^n\n", whose, m, m==1?"":"s", MINIS); } return true; } static bool verb_minfo(MudObject *who, int argc, const char **argv) { if (argc<2) { who->printf("Which mission?\n"); return true; } MudObject *qob = find_questob(argv[1]); if (!qob) { who->printf("No such mission as '%s'.\n", argv[1]); return true; } Header h(who, ssprintf("^M%s^n", qob->get("mname")).c_str(), 1); int points = qob->get_int("questpoints"); if (const char *rwd=qob->get("reward")) who->printf("Reward : %s\n", rwd); else who->printf("Reward : %i mission point%s\n", points, points==1?"":"s"); MudObject *mx = qob->get_object("mutex"); if (is_player(qob->owner)) { who->printf("Status : Accepted by %M\n", qob->owner); } else { if (qob->get_flag(FL_DONE)) { who->printf("Status : Done\n"); } else if (streq(qob->owner->id, "empty")) { who->printf("Status : Ruined\n"); } else if (qob->get_flag(FL_TAMPERED)) { who->printf("Status : In progress\n"); } else if (mx && is_player(mx->owner)) { who->printf("Status : Unavailable as %M is doing ^M%s^n\n", mx->owner, mx->get("mname")); } else { who->printf("Status : Available at %s missions boards.\n", prettynation(nation(qob))); } } string prs = ""; MudObject *prq = qob->get_object("quest_needed"); if (prq) prs = ssprintf("done ^M%s^n", prq->get("mname")); if (prs.length()) { who->printf("You must have : %s\n", prs.c_str()); } const char *b = qob->get("short_brief"); if (!b) b = qob->get("desc"); if (b) who->printf("Description : ^Z^{g%s^}\n", b); return true; } static string nicestime(int secs) { return ssprintf("%02i:%02i:%02i", secs / 3600, (secs / 60) % 60, secs % 60); } static bool verb_mrecords(MudObject *who, int argc, const char **argv) { who->printf("%s\n\n", title_for("Mission records", who).c_str()); auto(quests, get_quests()); int v = 0; iforeach(i, quests) { MudObject *q = *i; if (q && !q->get_flag(FL_PRIVATE)) { const char *dby = q->get("$recordholder"); int rtm = q->get_int("$recordtime"); if (dby && rtm>0) { who->printf("%12s - %-12s %-10s", mname_href(q).c_str(), lookup_name(dby).c_str(), nicestime(rtm).c_str()); } else { who->printf("%12s %-12s %-10s", mname_href(q).c_str(), "", ""); } v++; if (!(v&1)) { who->printf("\n"); } else who->printf(" "); } } who->printf("\n%s\n", footer_for(who).c_str()); return true; } #include "verbmodule.h" void startup() { AUTO_VERB(missions, 1, 0, PFL_NONE); AUTO_VERB(mstatus, 2, 0, PFL_NONE); AUTO_VERB(mrecords, 2, 0, PFL_NONE); ADD_ALIAS(quests, 1, missions); ADD_ALIAS(qstatus, 2, mstatus); ADD_ALIAS(mdone, 2, mstatus); ADD_ALIAS(qdone, 2, mstatus); ADD_ALIAS(minfo, 2, mstatus); ADD_ALIAS(qinfo, 2, mstatus); }