/*
    Room.m  Class definition.
    Copyright (C) 1995  David Flater.

    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 "cheezmud.h"

@implementation Room

+ new
{
  self = [super new];
  contents = [OrdCltn new];
  n = s = e = w = u = d = NULL;
  return self;
}

- n: who
{
  assert (n);
  [[who getlocation] emote: who: "leave": "leaves": " north"];
  [who setlocation: n];
  [[who getlocation] emote: who: "arrive": "arrives": " from the south"];
  return self;
}

- s: who
{
  assert (s);
  [[who getlocation] emote: who: "leave": "leaves": " south"];
  [who setlocation: s];
  [[who getlocation] emote: who: "arrive": "arrives": " from the north"];
  return self;
}

- e: who
{
  assert (e);
  [[who getlocation] emote: who: "leave": "leaves": " east"];
  [who setlocation: e];
  [[who getlocation] emote: who: "arrive": "arrives": " from the west"];
  return self;
}

- w: who
{
  assert (w);
  [[who getlocation] emote: who: "leave": "leaves": " west"];
  [who setlocation: w];
  [[who getlocation] emote: who: "arrive": "arrives": " from the east"];
  return self;
}

- u: who
{
  assert (u);
  [[who getlocation] emote: who: "leave": "leaves": " up"];
  [who setlocation: u];
  [[who getlocation] emote: who: "arrive": "arrives": " from below"];
  return self;
}

- d: who
{
  assert (d);
  [[who getlocation] emote: who: "leave": "leaves": " down"];
  [who setlocation: d];
  [[who getlocation] emote: who: "arrive": "arrives": " from above"];
  return self;
}

/*  Link up the map. */
- setexit: (char *) direction: destination
{
  assert (direction);
  assert (destination);
  assert ([destination isKindOf: [Room class]]);
  switch (direction[0]) {
  case 'n':
    n = destination;
    break;
  case 's':
    s = destination;
    break;
  case 'e':
    e = destination;
    break;
  case 'w':
    w = destination;
    break;
  case 'u':
    u = destination;
    break;
  case 'd':
    d = destination;
    break;
  default:
    assert (0);
  }
  return self;
}

- free
{
  /*  Free is disallowed for rooms.  That way I don't have to worry about */
  /*  what happens to all the stuff that's in the room when it goes away */
  /*  and how to change the movement actions of adjoining rooms. */
  assert (0);
  return self;
}

- (float) priority: (char *) action: (int) numargs
{
  if (numargs == 1) {
    if (!strcmp (action, "n")) {
      if (n)
        return 10.0;
      else
        return -1.0;
    }
    if (!strcmp (action, "s")) {
      if (s)
        return 10.0;
      else
        return -1.0;
    }
    if (!strcmp (action, "e")) {
      if (e)
        return 10.0;
      else
        return -1.0;
    }
    if (!strcmp (action, "w")) {
      if (w)
        return 10.0;
      else
        return -1.0;
    }
    if (!strcmp (action, "u")) {
      if (u)
        return 10.0;
      else
        return -1.0;
    }
    if (!strcmp (action, "d")) {
      if (d)
        return 10.0;
      else
        return -1.0;
    }
  }
  /* Not supported */
  return -1.0;
}

- echo: (char *) text
{
  /*  A room echo is sent to everybody in the room. */
  int i,c;
  for(i=0,c=[contents size];i<c;i++) {
    id whatever = [contents at:i];
    [whatever echo: text];
  }
  return self;
}

- theres_a_fight_going_on
{
  [contents elementsPerform: @selector(theres_a_fight_going_on)];
  return self;
}

/*  Emote is like echo except that it distinguishes 2nd and 3rd person */
- emote: emoter: (char *) verb_you: (char *) verb_he: (char *) emotion
{
  int i,m;
  for(i=0,m=[contents size];i<m;i++) {
    char temp[160];
    id whatever = [contents at:i];
    if (emoter == whatever) {
      /*  Dirty kluge:  don't tell people "You arrive" every time they move! */
      if (!strcmp (verb_you, "arrive"))
        continue;
      sprintf (temp, "You %s%s.", verb_you, emotion);
    }
    else
      sprintf (temp, "%s %s%s.", capitalize ([emoter def]), verb_he,
        emotion);
    [whatever echo: temp];
  }
  return self;
}

- emote: emoter: (char *) verb_you: (char *) verb_he: dobj: (char *) emotion
{
  int i,m;
  for(i=0,m=[contents size];i<m;i++) {
    char temp[160], a2[80];
    id whatever = [contents at:i];
    if (dobj == whatever)
      strcpy (a2, "you");
    else
      strcpy (a2, [dobj def]);
    if (emoter == whatever)
      sprintf (temp, "You %s %s%s.", verb_you, a2, emotion);
    else
      sprintf (temp, "%s %s %s%s.", capitalize ([emoter def]), verb_he,
        a2, emotion);
    [whatever echo: temp];
  }
  return self;
}

/*  Same as emote, but doesn't add punctuation. */
- say: emoter: (char *) verb_you: (char *) verb_he: (char *) emotion
{
  int i,m;
  for(i=0,m=[contents size];i<m;i++) {
    char temp[160];
    id whatever = [contents at:i];
    if (emoter == whatever)
      sprintf (temp, "You %s%s", verb_you, emotion);
    else
      sprintf (temp, "%s %s%s", capitalize ([emoter def]), verb_he,
        emotion);
    [whatever echo: temp];
  }
  return self;
}

/*  Put somebody in the room. */
- add: somebody
{
  [contents add: somebody];
  return self;
}

/*  Take somebody out of the room. */
- remove: somebody
{
  [contents remove: somebody];
  return self;
}

/*  Echo contents to somebody, excluding the person looking. */
- listcontents: who
{
  int i,m;
  if ([contents includes: who]) {
    if ([contents size] < 2)
      return self;
  } else
    if ([contents isEmpty])
      return self;
  [who echo: "Also here:"];
  for(i=0,m=[contents size];i<m;i++) {
    id whatever = [contents at:i];
    if (who != whatever)
      [who echo: capitalize ([whatever indef])];
  }
  return self;
}

/*  Find something that is directly in the room. */
- find: (char *) what: (int) number
{
  return generic_find (contents, what, number);
}

- contents
{
  return contents;
}

- (int) capacity
{
  return 1000000;
}

- dirquery: (char) dir
{
  switch (dir) {
  case 'n':
    return n;
  case 's':
    return s;
  case 'e':
    return e;
  case 'w':
    return w;
  case 'u':
    return u;
  case 'd':
    return d;
  }
  assert (0);
  return self;
}

@end