#include <stdio.h> #include "db.h" #include "config.h" #include "externs.h" int moveto(OBJ *what, OBJ *where) { return(enter_room(what, where)); } static int moveit(OBJ *what, OBJ *where) { OBJ *old; if(Typeof(what) == TYPE_ROOM) { log_error("Trying to move a room."); return(0); } if(Typeof(what) == TYPE_EXIT && Typeof(where) != TYPE_ROOM) { log_error("Trying to move an exit to something besides a room."); return(0); } if(Typeof(what) == TYPE_EXIT) { remove_exit(what, what->location); add_exit(what, where); } else { remove_content(what, what->location); add_content(what, where); } old = what->location; what->location = where; look_room(what, where); if(what != where && !(IS(what, TYPE_PLAYER, PLAYER_INVISIBLE))) did_it(what, old, "LEAVE", NULL, "PLEAVE"); atr_add(what, "LASTLOC", tprintf("%d", old->dbref)); if(old != where && !(IS(what, TYPE_PLAYER, PLAYER_INVISIBLE))) did_it(what, where, "ENTER", NULL, "PENTER"); return(1); } int enter_room(OBJ *player, OBJ *loc) { OBJ *old; if(Typeof(player) == TYPE_ROOM) { notify(player, perm_denied()); return(0); } if(Typeof(player) == TYPE_EXIT && Typeof(loc) != TYPE_ROOM) { notify(player, perm_denied()); return(0); } /* Fix so players can't get stuck in themselves */ if(Typeof(player) == TYPE_PLAYER) if(loc == player) { notify(player, perm_denied()); return(0); } old = player->location; if(!moveit(player, loc)) return(0); return(1); } void safe_tel(OBJ *player, OBJ *dest) { if(Typeof(player) == TYPE_ROOM) { notify(player, "I'm sorry, you're not allowed to move."); return; } if(Typeof(player) == TYPE_EXIT && Typeof(dest) != TYPE_ROOM) { notify(player, "Exits are only allowed in rooms."); return; } enter_room(player, dest); } static char *check_builtin_exits(OBJ *loc, char *str, OBJ **link) { char *s; if(!string_compare(str, "n") || !string_compare(str, "north")) if(*(s = atr_get(loc, "NORTH"))) if((*link = match_dbref(s, TYPE_ROOM))) return(pseudo_exit_name(loc, "NORTH")); if(!string_compare(str, "s") || !string_compare(str, "south")) if(*(s = atr_get(loc, "SOUTH"))) if((*link = match_dbref(s, TYPE_ROOM))) return(pseudo_exit_name(loc, "SOUTH")); if(!string_compare(str, "e") || !string_compare(str, "east")) if(*(s = atr_get(loc, "EAST"))) if((*link = match_dbref(s, TYPE_ROOM))) return(pseudo_exit_name(loc, "EAST")); if(!string_compare(str, "w") || !string_compare(str, "west")) if(*(s = atr_get(loc, "WEST"))) if((*link = match_dbref(s, TYPE_ROOM))) return(pseudo_exit_name(loc, "WEST")); if(!string_compare(str, "ne") || !string_compare(str, "northeast")) if(*(s = atr_get(loc, "NORTHEAST"))) if((*link = match_dbref(s, TYPE_ROOM))) return(pseudo_exit_name(loc, "NORTHEAST")); if(!string_compare(str, "nw") || !string_compare(str, "northwest")) if(*(s = atr_get(loc, "NORTHWEST"))) if((*link = match_dbref(s, TYPE_ROOM))) return(pseudo_exit_name(loc, "NORTHWEST")); if(!string_compare(str, "se") || !string_compare(str, "southeast")) if(*(s = atr_get(loc, "SOUTHEAST"))) if((*link = match_dbref(s, TYPE_ROOM))) return(pseudo_exit_name(loc, "SOUTHEAST")); if(!string_compare(str, "sw") || !string_compare(str, "southwest")) if(*(s = atr_get(loc, "SOUTHWEST"))) if((*link = match_dbref(s, TYPE_ROOM))) return(pseudo_exit_name(loc, "SOUTHWEST")); return(NULL); } int can_move(OBJ *player, char *direction) { OBJ *exit, *link; if(Typeof(player) == TYPE_ROOM || Typeof(player) == TYPE_EXIT) return(0); if(check_builtin_exits(player->location, direction, &link)) return(1); exit = match_object(player, direction, TYPE_EXIT); if(!exit || exit->location != player->location) return(0); return(1); } void do_move(OBJ *player, char *direction) { OBJ *exit = NULL, *old_exit; OBJ *loc = player->location; OBJ *thing; int deep; char *builtin_exit; OBJ *builtin_link; if(Typeof(player) == TYPE_ROOM || Typeof(player) == TYPE_EXIT) { notify(player, "Sorry, you aren't allowed to move."); return; } if(!string_compare(direction, "home")) { if(!power(player, POW_TELEPORT)) { notify(player, perm_denied()); return; } if(player->location == player->link) { notify(player, "But you're already there!"); return; } if(!IS(player, TYPE_PLAYER, PLAYER_INVISIBLE)) notify_in(loc, player, tprintf("%s goes home.", name(player))); safe_tel(player, player->link); return; } /* Find the exit */ if(!(builtin_exit = check_builtin_exits(loc, direction, &builtin_link))) { exit = match_object(player, direction, TYPE_EXIT); if(!exit || exit->location != loc || !exit->link) { notify(player, "You can't go that way."); return; } if(!could_doit(player, exit, "LOCK")) { did_it(player, exit, "FAIL", NULL, "PFAIL"); return; } did_it(player, exit, "SUCC", NULL, "PSUCC"); switch(Typeof(exit->link)) { case TYPE_ROOM: enter_room(player, exit->link); break; case TYPE_PLAYER: case TYPE_THING: safe_tel(player, exit->link); break; case TYPE_EXIT: old_exit = exit; for(deep = 0;Typeof(exit->link) == TYPE_EXIT;deep++) { exit = exit->link; if(deep > 99) /* Recursion check */ { log_error(tprintf("%s links to too many exits.", unparse_object(old_exit, old_exit))); notify(player, "You can't go that way."); return; } } enter_room(player, exit->link); break; } } else { enter_room(player, builtin_link); } for(thing = loc->contents;thing;thing = thing->next_con) { if(thing == player) continue; if(!builtin_exit) if(!could_doit(thing, exit, "LSEE")) continue; if(Typeof(player) == TYPE_PLAYER || (player->flags & PUPPET && !(player->flags & DARK))) { notify(thing, tprintf("%s goes through the exit marked %s.", name(player), (!builtin_exit)?name(exit):builtin_exit)); } } for(thing = (builtin_exit)?builtin_link->contents:exit->link->contents; thing;thing = thing->next_con) { if(thing == player) continue; if(!builtin_exit) if(!could_doit(thing, exit, "LSEE")) continue; if(Typeof(player) == TYPE_PLAYER || (player->flags & PUPPET && !(player->flags & DARK))) { notify(thing, tprintf("%s arrives from %s.", name(player), name(loc))); } } } void do_get(OBJ *player, char *what) { OBJ *thing; OBJ *loc = player->location; if(!*what) { notify(player, "Get what?"); return; } if(Typeof(player) == TYPE_EXIT) { notify(player, "You can't pick up things!"); return; } thing = match_object(player, what, TYPE_THING); if(!thing || (thing->location != loc && !controls(player, thing, POW_TELEPORT))) { notify(player, no_match(what)); return; } if(thing->location == player) { notify(player, "You already have that!"); return; } if(could_doit(player, thing, "LOCK")) { if(moveto(thing, player)) { notify(thing, tprintf("You have been picked up by %s.", unparse_object(thing, player))); did_it(player, thing, "SUCC", "Taken.", "PSUCC"); } } else did_it(player, thing, "FAIL", "You can't pick that up.", "PFAIL"); } void do_drop(OBJ *player, char *name) { OBJ *loc = player->location; OBJ *thing; if(!*name) { notify(player, "Drop what?"); return; } thing = match_object(player, name, TYPE_THING); if(!thing || thing->location != player) { notify(player, no_match(name)); return; } if(player->location->owner != player->owner && !Wizard(player)) { notify(player, perm_denied()); return; } notify(thing, "Dropped."); enter_room(thing, loc); did_it(player, thing, "DROP", "Dropped.", "PDROP"); } void do_enter(OBJ *player, char *what) { OBJ *thing; if(!Wizard(player)) { notify(player, perm_denied()); return; } thing = match_object(player, what, TYPE_THING|TYPE_PLAYER); if(!thing || thing->location != player->location) { notify(player, no_match(what)); return; } if(!could_doit(player, thing, "LENTER")) { did_it(player, thing, "EFAIL", "You can't enter that.", "PEFAIL"); return; } safe_tel(player, thing); } void do_leave(OBJ *player) { if(!Wizard(player) || Typeof(player->location) == TYPE_ROOM) { notify(player, "You can't leave."); return; } if(!could_doit(player, player->location, "LLEAVE")) { did_it(player, player->location, "LFAIL", "You can't leave.", "PLFAIL"); return; } enter_room(player, player->location->location); } /* Find the room the object/player is in */ OBJ *get_room(OBJ *thing) { OBJ *old; for(old = getloc(thing);getloc(old) != old;old = getloc(old)); return(old); } int bad_direction(char *dir) { char *dir_list[] = {"N", "S", "E", "W", "NE", "NW", "SE", "SW", "U", "D", "North", "South", "East", "West", "NorthEast", "NorthWest", "SouthEast", "SouthWest", "Up", "Down", "" }; int i; for(i = 0;*dir_list[i];++i) if(!string_compare(dir, dir_list[i])) return(1); return(0); }