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 Daemon, version 1.0
 * Copyright (C) 1998-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 "musicmud.h"
#include "misc.h"
#include "Player.h"
#include "msi.h"
#include "util.h"
#include "musictok.h"
#include "units.h"

bool real_is_edible(MudObject *o) {
  return (o->get_int("food")!=-1 || o->get_int("alcohol")!=-1);
}

bool is_edible(MudObject *o) {
  if (!is_person(o->owner))
    return 0;

  if (real_is_edible(o)) 
    return 1;

  MudObject *substance = o->array_get_object("$fill", 0);
  if (!substance)
    return 0;
  int amount = used_volume(o);
  if (!amount)
    return 0;
  if (real_is_edible(substance))
    return 1;
  return 0;
}

TeleObject tsaton(MudObject *o) {
  MudObject *s = o->get_object(KEY_SITON);
  int n = o->get_int(KEY_SITONN, 0);

  return TeleObject(o->owner, s, n);
}

static NewWorld sitters(const TeleObject &what)
{
  NewWorld w;
  if (!what)
    return w;

  MudObject *o;
  int i;
  foreach(what.where->children, o, i) {
    if (tsaton(o)==what)
      w.add(*o);
  }
  return w;
}

static int sitters_n(const TeleObject &what)
{
  return sitters(what).getsize();
}

static int sitters_max(MudObject *what)
{
  if (what->get_flag(FL_ONEPERSON))
    return 1;
  if (what->get_flag(FL_TWOPERSON))
    return 2;
  return -1;
}

static bool is_sittable(const TeleObject &what)
{
  return sitters_n(what) < sitters_max(what.what);
}

string genref(MudObject *who, const TeleObject &o, tfn_t f=0)
{
  int idx = 1;
  const char *sh = o->get("short");
  if (!sh) return o->id;

  while (idx < 100) {
    string s = sh;
    if (idx != 1)
      s += ssprintf("%i", idx);

    const char *s2[] = { NULL, s.c_str() };

    if (o->owner == who)
      s2[0] = "my";
    else
      s2[0] = "that";

    TeleWorld b3 = multi_match(who, 2, s2, f, LOOK_BOTH|IGNORE_EXITS);
    if (b3.getsize()!=1)
      return "";
    TeleObject o2 = b3.get(0);
    if (o2 == o) {
      return ssprintf("%s %s", s2[0], s2[1]);
    }
    idx++;
  }
  return "";
}

static string escname(MudObject *who, const TeleObject &what, tfn_t fn=0) 
{
  string s = genref(who, what, fn);
  const char *t = s.c_str();
  string n = "";
  while (*t) 
    {
      if (*t=='\'') n += "&apos;";
      else if (*t=='>') n += "&gt;";
      else if (*t=='<') n += "&lt;";
      else if (*t=='"') n += "&quot;";
      else if (*t=='&') n += "&amp;";
      else n += *t;
      t++;
    }
  return n;
}

void make_href(MudObject *who, TeleObject obj, string &cmd, string &endc) {
  if (!is_player(who))
    return;

  Player *p = (Player *)who;
  if (!p->p)
    return;
  
  if (!p->p->mxp
#ifdef PUEBLO
 && !p->p->pueblo
#endif
)
    return;

  if (obj->get("link") && obj->get("short")) {
    cmd += ssprintf("|go %s", obj->get("short"));
  }
  
  bool can_access = obj.where == who || obj.where == who->owner;

  if (!obj->get_flag(FL_EXIT)) {
    if (obj.where == who || obj.where==who->owner || obj->get_flag(FL_FLOOR)) {
      cmd += ssprintf("|examine %s", escname(who, obj).c_str());
    }

    if (obj->get_object("fount") || (obj->get_flag(FL_DRINK) && is_edible(obj)) && can_access) {
      cmd += ssprintf("|drink %s", escname(who, obj).c_str());
    }
    if (!obj->get_flag(FL_DRINK) && is_edible(obj) && can_access) {
      cmd += ssprintf("|eat %s", escname(who, obj).c_str());
    }

    if (obj->get("wornon") && !obj->get(KEY_WORNBY) && obj.where==who) {
      cmd += ssprintf("|wear %s", escname(who, obj).c_str());
    }

    if (obj->get("wornon") && obj->get(KEY_WORNBY) && obj.where==who) {
      cmd += ssprintf("|remove %s", escname(who, obj).c_str());
    }
    
    if (who->get_object(KEY_WIELD)==obj) {
      cmd += ssprintf("|unwield %s", escname(who, obj).c_str());
    }

    if (who == obj.where && who->get_object(KEY_WIELD)!=obj && obj->get_int("damage")>1) {
      cmd += ssprintf("|wield %s", escname(who, obj).c_str());
    }

    if ((who == obj.where || who->owner==obj.where) &&  mount(who)!=obj && obj->get_flag(FL_MOUNT)) {
      cmd += ssprintf("|mount %s", escname(who, obj).c_str());
    }

    if (mount(who)==obj) {
      cmd += ssprintf("|dismount %s", escname(who, obj).c_str());
    }

    if (!obj->get_flag(FL_FIXED) && obj.where==who->owner && !obj->get_flag(FL_MOBILE) && 
	!is_player(obj.what)) {
      cmd += ssprintf("|take %s", escname(who, obj).c_str());
    }

    if (!obj->get_flag(FL_FIXED) && obj.where==who && floor(who->owner) && is_droppable(obj)) {
      cmd += ssprintf("|drop %s", escname(who, obj).c_str());      
      cmd += ssprintf("|put %s on floor", escname(who, obj).c_str());
    }
    
    if (obj->get_flag(FL_CANSITON) && obj.where==who->owner && !who->get_flag(FL_SITTING)) {
      cmd += ssprintf("|sit on %s", escname(who, obj, is_sittable).c_str());
    }
    
    if (obj->get_flag(FL_CONTAINER) && !state(obj) && can_access) {
      cmd += ssprintf("|look in %s", escname(who, obj).c_str());
    }

    if (obj->get_flag(FL_FRAGILE)) {
      cmd += ssprintf("|smash %s", escname(who, obj).c_str());
    }

    if (obj.where==who && who->owner->get_flag(FL_STORE)) {
      cmd += ssprintf("|sell %s", escname(who, obj).c_str());
    }

    if (obj->get_flag(FL_CANOPEN) && state(obj)) {
      cmd += ssprintf("|open %s", escname(who, obj).c_str());
    }

    if (obj->get_flag(FL_CANOPEN) && !state(obj)) {
      cmd += ssprintf("|close %s", escname(who, obj).c_str());
    }
  }

  if (is_person(obj)) {
    StrTok r(who->get("mxp-person"));
    while (const char *a = r.next(",")) {
      cmd += ssprintf("|%s %s", a, escname(who, obj).c_str());
    }
  }

  if (is_mobile(obj) && obj.where == who->owner) {
    cmd += ssprintf("|consider %s", escname(who, obj).c_str());
    //    cmd += ssprintf("|kill %s", escname(who, obj).c_str());

    if (obj->get_flag(FL_STORE) || who->owner->get_object("shopmob")==obj)
      cmd += ssprintf("|list from %s", escname(who, obj).c_str());
  }

  if (is_player(obj.what)) {
    //    cmd += ssprintf("|tell %s ", escname(who, obj).c_str());
    // not sure how to do this exactly.
  }

  /* if is_player(obj) give option to tell them something */
  
  if (cmd.length()) {
    cmd = cmd.substr(1);
    cmd = ssprintf("\3send href='%s'\4", cmd.c_str());
    endc = "\3/send\4";
  }
}