/* 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