musicmud-2.1.6/data/
musicmud-2.1.6/data/help/
musicmud-2.1.6/data/policy/
musicmud-2.1.6/data/wild/
musicmud-2.1.6/data/world/
musicmud-2.1.6/doc/
musicmud-2.1.6/src/ident/
musicmud-2.1.6/src/lua/
musicmud-2.1.6/src/lua/include/
musicmud-2.1.6/src/lua/src/lib/
musicmud-2.1.6/src/lua/src/lua/
musicmud-2.1.6/src/lua/src/luac/
/* 
 * 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);

}