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/
#include "musicmud.h"
#include "vsprintf.h"
#include "trap.h"
#include "nations.h"

#include <cmath>

const char *nation(const MudObject *o)
{
  return o->get("nation")?:MUD_DEFNATION;
}

MudObject *natobj(const MudObject *o)
{
  const char *nstr = nation(o);
  if (!nstr)
    return 0;

  return natobj(nstr);
}


MudObject *natobj(const string &nstr)
{
  MudObject *n=planet->get(ssprintf("nation_%s", nstr));
  if (n)
    return n;
  
  if (nstr.find(':')!=string::npos)
    return natobj(nstr.substr(0, nstr.find(':')));

  return 0;
}

MudObject *block(const MudObject *o)
{
  MudObject *nat = natobj(o);
  if (!nat)
    return 0;
  return nat->get_object("treatas")?:nat;
}

string prettynation(const string &s)
{
  string ns = s;
  const char *n = ns.c_str();
  const char *sub = 0;

  if ((sub=strchr(n, ':'))) {
    ns = string(n, sub);
    sub++;
  }
  
  MudObject *l = natobj(ns);
  if (!l)
    return "???";

  if (sub) {
    string sname = ssprintf("name.%s", sub);
    if (const char *s=l->get(sname.c_str()))
      return s;
  }

  if (const char *n=l->get("name")) {

    if (streq(sub, "mod"))   return ssprintf("%s Military", n);    
    if (streq(sub, "gov"))   return ssprintf("%s Civil Service", n);
    if (streq(sub, "und"))   return ssprintf("%s underworld", n);
    if (streq(sub, "intel")) return ssprintf("%s Intelligence", n);

    return n;
  }

  return "???";
}

World<MudObject> nations(bool onlyplayable) {
  World<MudObject> w;
  MudObject *nats = planet->get("nations_zone");
  if (!nats)
    return w;
  MudObject *o;
  int i;
  foreach(nats->children, o, i) {
    if (onlyplayable && !o->get_int("playable", 1))
      continue;
    if (o->get_object("start")==nats)
      w.add(o);
  }
  return w;
}

const char *getcurprop(const MudObject *who)
{
  return who?who->get("curprop")?:"":"";
}

int cash(const char *prop, const MudObject *who) 
{
  if (*prop)
    return who->get_int(ssprintf("$cash.%s", prop).c_str(), 0);
  else
    return who->get_int("$cash", 0);
}

void set_cash(const char *prop, MudObject *who, int amt) 
{
  if (*prop)
    who->set(ssprintf("$cash.%s", prop).c_str(), amt);
  else
    who->set("$cash", amt);
}

int cash(const MudObject *who, const MudObject *nation)
{
  return cash(getcurprop(nation), who);
}

void set_cash(MudObject *who, const Nation *nat, int amt) 
{
  set_cash(getcurprop(nat), who, amt);
}

string formatcash(int amt, MudObject *of, bool d)
{
  if (!of)
    return ssprintf("%i ???", amt);

  of->unset("!form");
  dotrap(E_ONFORMATCURRENCY, of, of, d?of:0, 0, ssprintf("%i", amt).c_str());
  if (const char *f=of->get("!form"))
    return f;

  if (of == natobj(MUD_DEFNATION))
    if (d)
      return ssprintf("^Y%i^n %s", amt, amt==1?MUD_CURSING:MUD_CURPLUR);
    else
      return ssprintf("%s^Y%i^n%s", MUD_CURPREF, amt, MUD_CURSUFF);

  return "???";
}

MudObject *currency(MudObject *who) {
  MudObject *n=natobj(who);
  if (n && n->get("curprop"))
    return n;
  n = block(who);
  if (n && n->get("curprop"))
    return n;
  return natobj(MUD_DEFNATION);
}

int convertcash(int amount, MudObject *from, MudObject *to)
{
  double amt = amount;
  if (from) {
    if (const char *r=from->get("currate")) {
      double rate = atof(r);
      amt *= rate;
    }
  }

  if (to) {
    if (const char *r=to->get("currate")) {
      double rate = atof(r);
      amt /= rate;
    }
  }
  
  return (int)std::floor(amt);
}

bool hascurr(MudObject *nat)
{
  return nat->get("curprop");
}

bool anycash(const MudObject *who)
{
  World<MudObject> nat = nations(0);
  iforeach(n, nat) {
    if (cash(who, n))
      return 1;
  }
  return 0;
}

int totalcash(const MudObject *who)
{
  World<MudObject> nat = nations(0);
  int amt = 0;
  iforeach(n, nat) {
    if (hascurr(n)) {
      amt += convertcash(cash(who, n), n, 0);
    }
  }
  return amt;
}

void wipe_cash(MudObject *who)
{
  World<MudObject> nat = nations(0);
  iforeach(n, nat) 
    if (hascurr(n)) 
      set_cash(who, n, 0);
}

string andize(const vector<string> &v)
{
  string tmp;
  size_t n = 0;
  iforeach(s, v) {
    n++;
    if (tmp.length())
      if (n==v.size())
	tmp += " and ";
      else
	tmp += ", ";
    tmp += *s;
  }
  return tmp;
}

int balance(const char *prop, const MudObject *who) 
{
  if (*prop)
    return who->get_int(ssprintf("$balance.%s", prop).c_str(), 0);
  else
    return who->get_int("$balance", 0);
}

void set_balance(const char *prop, MudObject *who, int amt) 
{
  if (*prop)
    who->set(ssprintf("$balance.%s", prop).c_str(), amt);
  else
    who->set("$balance", amt);
}

int balance(const MudObject *who, const MudObject *nation)
{
  return balance(getcurprop(nation), who);
}

void set_balance(MudObject *who, const Nation *nat, int amt) 
{
  set_balance(getcurprop(nat), who, amt);
}

void moveallcash(MudObject *from, MudObject *to)
{
  World<MudObject> nats = nations(0);
  iforeach(n, nats) {
    if (int v=cash(from, n)) {
      set_cash(to, n, v+cash(to, n));
      set_cash(from, n, 0);
    }
  }
}

cashinfo curmatch(int argc, const char **argv, MudObject *defcur)
{
  if (argc<1)
    return cashinfo();

  bool all = streq(argv[0], "all");
  char *e;
  double amt = strtod(argv[0], &e);
  
  if (!all & *e)
    return cashinfo();

  if (argc==1) {
    if (defcur)
      return cashinfo(defcur, int(amt*defcur->get_int("cur.0.value", 1)), all);
    return cashinfo();
  }
  
  if (argc==2) {
    World<MudObject> nats = nations(0);
    iforeach(n, nats) {
      for (int i=0;i<n->array_size("cur");i++) {
	string a = ssprintf("cur.%i", i);
	for (int j=0;j<n->array_size(a.c_str());j++) {
	  const char *c = n->array_get(a.c_str(), j);
	  if (streq(c, argv[1]))
	    return cashinfo(n, int(amt * 
			    n->array_get_int("cur", i, "value", 1)), all);
	}
	
      }
    }
  }

  return cashinfo();
}

string describe_cash(MudObject *pot) {
  World<MudObject> nat = nations(0);
  vector<string> s;
  iforeach(n, nat) if (hascurr(n)) {
    int amt = cash(pot, n);
    if (amt)
      s.push_back(formatcash(amt, n, 1));
  }

  if (s.size())
    return andize(s);

  return "";
}

void describe_pot(MudObject *pot) {
  string s = describe_cash(pot);
  if (s.size())
    pot->setf("short_desc", "%s in cash", s);
}

void fine(MudObject *who, int what, const char *crime, MudObject *j)
{
  if (!j)
    j=jurisdiction(who->owner);

  const char *rec = j?j->get("record")?:"$record":"$record";
  const char *fin = j?j->get("outstand")?:"crim.fine":"crim.fine";

  int rc = who->array_size(rec);
  who->array_set(rec, rc, crime);
  who->array_set(rec, rc, "fine", what);
  who->array_set(rec, rc, "when", now);

  who->set(fin, who->get_int(fin, 0)+what);

  rc++;
  who->set(ssprintf("%s.count", rec).c_str(), rc);
}


MudObject *jurisdiction(MudObject *where)
{
  MudObject *o = find_coproom(where);
  if (o) {
    MudObject *pol = get_flagged_object(o, FL_POLICE);
    return natobj(pol);
  }
  return natobj(MUD_DEFNATION);
}

string jname(MudObject *where)
{
  MudObject *j = jurisdiction(where);
  if (!j)
    return "???";
  return j->get("jname")?:j->get("name")?:"???";
}