/*
Nonroom.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 Nonroom
+ new
{
self = [super new];
location = NULL;
return self;
}
- free
{
[location remove: self];
return [super free];
}
- logout
{
if (!loggedout) {
if (!dead)
[location emote: self: "disappear": "disappears":
" from the face of the Earth"];
[self setlocation: NULL];
[super logout];
}
return self;
}
- (int) level
{
return 0;
}
- getlocation
{
return location;
}
- setlocation: whereto
{
[location remove: self];
location = whereto;
[location add: self];
return self;
}
- teleport: whereto
{
[location emote: self: "vanish": "vanishes":
" into a cloud of magic smoke"];
[self setlocation: whereto];
[location emote: self: "appear": "appears":
" out of a cloud of magic smoke"];
return self;
}
- (float) priority: (char *) action: (int) numargs
{
/* Not supported */
return -1.0;
}
- resolve_action: (char *) action: (int) numargs
{
id actor = NULL;
float prio = -1.0, t_prio;
if ((t_prio = [self priority: action: numargs]) > prio) {
if (t_prio >= 0.0) {
prio = t_prio;
actor = self;
}
}
if (location && ((t_prio = [location priority: action: numargs]) > prio)) {
if (t_prio >= 0.0) {
prio = t_prio;
actor = location;
}
}
if ([self isKindOf: [Container class]]) {
int i,m;
id c = [self contents];
for(i=0,m=[c size];i<m;i++) {
id whatever = [c at:i];
if ((t_prio = [whatever priority: action: numargs]) > prio) {
if (t_prio >= 0.0) {
prio = t_prio;
actor = whatever;
}
}
}
}
return actor;
}
/* Do an action. This method is complicated, but it has a big job to do. */
- (int) act: (char *) someaction
{
SEL a;
int i,m;
id c,t, dobj = NULL;
char verb[80], directobject[80];
int numargs, number;
numargs = sscanf (someaction, "%s %s %d", verb, directobject, &number);
/* This is a crummy cheat to make take an alias for get. */
if (!strcmp (verb, "take"))
strcpy (verb, "get");
/* Ditto for l, look. */
if (!strcmp (verb, "look"))
strcpy (verb, "l");
switch (numargs) {
case 1:
number = 1;
break;
case 2:
number = 1;
/* Fall through */
case 3:
/* 3 args is just 2 args with a qualifier that goes away. The other */
/* functions will get confused if we leave numargs = 3. */
numargs = 2;
/* Get, drop, bag, and unbag are exceptions to the inventory + room */
/* contents resolution. Get only applies to room contents. Drop and */
/* bag only apply to inventory. Unbag only applies to bag contents. */
if ((!strcmp (verb, "drop")) || (!strcmp (verb, "bag"))) {
if (![self isKindOf: [Container class]])
return 0;
dobj = [self find: directobject: number];
} else if (!strcmp (verb, "get")) {
dobj = [location find: directobject: number];
} else if (!strcmp (verb, "unbag")) {
BOOL flag = YES;
if (![self isKindOf: [Container class]])
return 0;
c = [self contents];
for(i=0,m=[c size];(i<m) && flag;i++) {
id whatever = [c at:i];
if ([whatever isKindOf: [Sack class]]) {
dobj = generic_find_creturn ([whatever contents],
directobject, &number);
if (dobj)
flag = NO;
}
}
} else {
if ([self isKindOf: [Container class]])
dobj = generic_find_cascade ([self contents], [location contents],
directobject, number);
else
dobj = [location find: directobject: number];
}
if (!dobj) {
[self echo: "Not found."];
return 1;
}
break;
default:
return 0;
}
if ((t = [self resolve_action: verb: numargs])) {
char temp[80];
sprintf (temp, "%s:", verb);
if (numargs > 1)
strcat (temp, ":");
a = [Object findSel:temp];
if (numargs == 1)
[t perform: a with: self];
else
[t perform: a with: self with: dobj];
return 1;
}
/* Try to print a helpful message for missing args. */
if (numargs == 1) {
if ((t = [self resolve_action: verb: 2])) {
char temp[80];
sprintf (temp, "%s what?", capitalize (verb));
[self echo: temp];
return 1;
}
}
if (numargs == 2) {
if ((t = [self resolve_action: verb: 1])) {
[self echo: "That action does not get a direct object."];
return 1;
}
}
return 0;
}
- getread: who
{
char temp[80];
sprintf (temp, "%s is not legible.", capitalize (def));
[who echo: temp];
return self;
}
/* Clone this object. */
/* - clone */
/* { */
/* return [[[self class] new] describe: [self mudname]: */
/* [self indef]: [self def]: [self longdesc]]; */
/* } */
- hit: fromwho: (float) damage
{
[location emote: self: "suffer": "suffers": " no damage"];
[[fromwho getlocation] emote: fromwho: "": "":
"may need psychological help"];
[fromwho clue: self];
return self;
}
- (int) isdead
{
return dead;
}
- theres_a_fight_going_on
{
/* So what? */
return self;
}
/* These have to be here to get rid of stupid compiler warnings. */
- contents
{
assert (0);
return NULL;
}
- find: (char *) what: (int) number
{
assert (0);
return NULL;
}
@end