#include <stdio.h> #include <strings.h> #include <ctype.h> #include "teeny.h" /* Copyright(C) 1990, Andrew Molitor, All Rights Reserved. This software may be freely used, modified, and redistributed, as long as this copyright message is left intact, and this software is not used to develop any commercial product, or used in any product that is provided on a pay-for-use basis. No warranties whatsoever. This is not guaranteed to compile, nor, in the event that it does compile to binaries, are these binaries guaranteed to perform any function whatsoever. */ /* Building/Creating commands */ /* Buffer from cmds.c */ extern char cmdwork[]; do_create(player,argone,argtwo) int player; char *argone,*argtwo; { int obj,next,count,home,here; int cost; int ret; char *p; if(argone == NULL){ notify_player(player,"You need to specify a name.\n"); return; } if(argtwo != NULL){ /* Try to get a numeric value */ if(isdigit(*argtwo)){ cost = atoi(argtwo); cost = (cost < 10 ? 10 : cost); } else { /* Oh shit. Player probably wanted a literal */ /* = in the name. Tough shit. */ notify_player(player,"No \'=\' allowed in name.\n"); notify_player(player,"Use @name after @create.\n"); } } else { cost = 10; } /* Bill the player */ ret = bill_player(player,cost); cost = (cost / 5) - 1; /* Object value */ if(ret == -1) goto createbomb; if(ret == 0) return; /* Go to it */ obj = create_obj(TYP_THING); if(set_str_elt(obj,NAME,argone) == -1) goto createbomb; if(set_int_elt(obj,OWNER,player) == -1) goto createbomb; if(set_int_elt(obj,LOC,player) == -1) goto createbomb; if(set_int_elt(obj,PENNIES,cost) == -1) goto createbomb; if(get_int_elt(player,LOC,&here) == -1) goto createbomb; if(controls(player,here)){ home = here; } else { if(get_int_elt(player,HOME,&home) == -1) goto createbomb; } if(set_int_elt(obj,HOME,home) == -1) goto createbomb; if(get_int_elt(player,CONTENTS,&next) == -1) goto createbomb; if(set_int_elt(player,CONTENTS,obj) == -1) goto createbomb; if(set_int_elt(obj,NEXT,next) == -1) goto createbomb; /* Tell the player */ p = cmdwork; count = 0; strcpy(p,"Object "); p += 7; count += 7; while(*argone && count < BUFFSIZ - 32){ *p++ = *argone++; count++; } strcpy(p," created with number #"); p += 22; p = ty_itoa(p,obj); *p++ = '.'; *p++ = '\n'; *p = '\0'; notify_player(player,cmdwork); return; createbomb: notify_bad(player); return; } do_dig(player,arg) int player; char *arg; { int room,count; int ret; char *p; if(arg == NULL){ notify_player(player,"You need to specify a name.\n"); return; } ret = bill_player(player,10); if(ret == -1) goto digbomb; if(ret == 0) return; room = create_obj(TYP_ROOM); if(set_int_elt(room,OWNER,player) == -1) goto digbomb; if(set_str_elt(room,NAME,arg) == -1) goto digbomb; /* Tell the player */ p = cmdwork; count = 0; strcpy(p,"Room "); p += 5; count += 5; while(*arg && count < BUFFSIZ - 32){ *p++ = *arg++; count++; } strcpy(p," dug with number #"); p += 18; p = ty_itoa(p,room); *p++ = '.'; *p++ = '\n'; *p = '\0'; notify_player(player,cmdwork); return; digbomb: notify_bad(player); return; } do_set_string(player,argone,argtwo,code) int player; char *argone,*argtwo; int code; { int obj,flags; char *oldname; char *givenpwd,ch; /* Find the thing to set the string ON */ if(argone == NULL){ notify_player(player,"Set what on what?\n"); return; } if((obj = resolve_object(player,argone,0)) == -1){ notify_player(player,"I don't see that here.\n"); return; } if(!controls(player,obj)){ notify_player(player,"You can't do that!\n"); return; } /* We *might* be setting a player name. Gotta be careful */ if(code == NAME){ /* Check out the name */ if(argtwo == NULL || strlen(argtwo) == 0){ notify_player(player,"bad name.\n"); return; } if(get_int_elt(obj,FLAGS,&flags) == -1){ warning("do_set_string","cannot get flags"); goto namebomb; } if( (flags & TYPE_MASK) == TYP_PLAYER){ if(ispunct(*argtwo) || strlen(argtwo) > 64){ notify_player(player,"Bad player name.\n"); return; } /* skip to pwd in given name */ givenpwd = argtwo; while(!isspace(*givenpwd) && *givenpwd) givenpwd++; ch = *givenpwd; *givenpwd = '\0'; /* Let's see if there's alreay a player of this name */ if(match_player(argtwo) != -1){ notify_player(player ,"You can't give a player that name.\n"); return; } *givenpwd = ch; while(isspace(*givenpwd)) givenpwd++; /* Ok. Hack around. */ if(get_str_elt(obj,NAME,&oldname) == -1){ goto namebomb; } /* Skip to password in oldname */ while(!isspace(*oldname) && *oldname) oldname++; while(isspace(*oldname)) oldname++; if(strcmp(oldname,givenpwd) != 0){ notify_player(player,"Wrong password.\n"); return; } /* argtwo has a valid name/pwd pair */ } } if(set_str_elt(obj,code,argtwo) == -1) goto namebomb; notify_player(player,"Ok.\n"); return; namebomb: notify_bad(player); return; } do_lock(player,argone,argtwo) int player; char *argone,*argtwo; { int obj,*exp; if(argtwo == NULL){ notify_player(player,"Lock what to what?\n"); return; } obj = resolve_object(player,argone,0); /* NO *<playername> */ if(obj == -1){ notify_player(player,"I don't see that here.\n"); return; } if(!controls(player,obj)){ notify_player(player,"You can't do that!\n"); return; } /* OK. We can mess with the lock on this thing. */ exp = bool_parse(player,argtwo); if(exp == NULL) return; /* bool_parse() already told the player off. */ if(set_lock_elt(obj,LOCK,exp) == -1){ notify_bad(player); return; } notify_player(player,"Locked.\n"); } do_unlock(player,arg) int player; char *arg; { int obj; obj = resolve_object(player,arg,0); /* NO *<playername> */ if(obj == -1){ notify_player(player,"I don't see that here.\n"); return; } if(!controls(player,obj)){ notify_player(player,"You can't do that!\n"); return; } if(set_lock_elt(obj,LOCK,(int *) NULL) == -1){ notify_bad(player); return; } notify_player(player,"Unlocked.\n"); } do_open(player,argone,argtwo) int player; char *argone,*argtwo; { int here,exit,list,dest,flags; int count,ret; extern int total_objects; char *p; if(argone == NULL){ notify_player(player,"You must specify a name.\n"); return; } ret = bill_player(player,1); if(ret == -1) goto openbomb; if(ret == 0) return; if(get_int_elt(player,LOC,&here) == -1) goto openbomb; if(!controls(player,here)){ notify_player(player,"You can't open an exit here!\n"); return; } exit = create_obj(TYP_EXIT); if(set_str_elt(exit,NAME,argone) == -1) goto openbomb; if(set_int_elt(exit,OWNER,player) == -1) goto openbomb; if(set_int_elt(exit,LOC,here) == -1) goto openbomb; if(get_int_elt(here,EXITS,&list) == -1) goto openbomb; if(set_int_elt(exit,NEXT,list) == -1) goto openbomb; if(set_int_elt(here,EXITS,exit) == -1) goto openbomb; /* Tell the player about this exit */ p = cmdwork; count = 0; strcpy(p,"Exit "); p += 5; count += 5; while(*argone && count < BUFFSIZ - 32){ *p++ = *argone++; count++; } strcpy(p," opened with number #"); p += 21; p = ty_itoa(p,exit); *p++ = '.'; *p++ = '\n'; *p = '\0'; notify_player(player,cmdwork); if(argtwo != NULL){ /* Try to link this */ if(strcmp(argtwo,"home") == 0){ dest = -3; } else if(strcmp(argtwo,"here") == 0){ dest = here; } else { if(*argtwo != '#' || !isdigit(argtwo[1])){ notify_player(player ,"I don't grok your destination.\n"); return; } dest = atoi(argtwo+1); } notify_player(player,"Trying to link..\n"); /* Can we link there? */ if(dest != -3 && !exists_object(dest)){ notify_player(player,"Bad destination.\n"); return; } if(dest != -3 && get_int_elt(dest,FLAGS,&flags) == -1){ notify_player(player,"Can't find destination.\n"); return; } if(dest != -3 && (TYPE_MASK & flags) != TYP_ROOM){ notify_player(player,"That's not a room!\n"); return; } if(!controls(player,dest) && !(flags & LINK_OK)){ notify_player(player,"Can't link to destination.\n"); return; } /* OK. We can link there. */ if(set_int_elt(exit,DESTINATION,dest) == -1) goto openbomb; notify_player(player,"Linked.\n"); } return; openbomb: notify_bad(player); return; } do_link(player,argone,argtwo) int player; char *argone,*argtwo; { int dest,flags,thing,here,location; int code,foo; char *msg; if(argtwo == NULL){ notify_player(player,"Link what to where?\n"); return; } if(get_int_elt(player,LOC,&here) == -1) goto linkbomb; /* Find the destination, thing to link to */ if(strcmp(argtwo,"home") == 0){ dest = -3; /* Abstract db ref to home */ } else if(strcmp(argtwo,"here") == 0) { dest = here; } else { if(*argtwo != '#' || !isdigit(argtwo[1])){ notify_player(player, "I don't understand that destination.\n"); return; } dest = atoi(argtwo+1); } /* Can we link there? */ if(dest != -3 && !exists_object(dest)){ notify_player(player,"Bad destination.\n"); return; } if(dest != -3 && get_int_elt(dest,FLAGS,&flags) == -1){ notify_player(player,"Can't find destination.\n"); return; } if(dest != -3 && (flags & TYPE_MASK) != TYP_ROOM){ notify_player(player,"That's not a room!\n"); return; } if(!controls(player,dest) && !(flags & LINK_OK)){ notify_player(player,"Can't link to destination.\n"); return; } /* OK. We can link there. Try to get the thing to link */ thing = resolve_object(player,argone,0); /* No *<playername> */ if(thing == -1){ notify_player(player,"I don't see that here.\n"); return; } if(get_int_elt(thing,FLAGS,&flags) == -1) goto linkbomb; /* What sort of thing is it? */ switch(flags & TYPE_MASK){ case TYP_PLAYER: case TYP_THING: msg = "Home set.\n"; code = HOME; break; case TYP_ROOM: msg = "Dropto set.\n"; code = DROPTO; break; case TYP_EXIT: msg = "Linked.\n"; code = DESTINATION; /* Check to see if the exit is in the room */ if(get_int_elt(thing,LOC,&location) == -1) goto linkbomb; if(location != here){ notify_player(player,"That exit's not in this room.\n"); return; } /* Check that the exit is unlinked */ if(get_int_elt(thing,DESTINATION,&foo) == -1) goto linkbomb; if(foo != -1){ notify_player(player,"That exit is linked.\n"); return; } else { if(set_int_elt(thing,OWNER,player) == -1) goto linkbomb; } notify_player(player,"Trying to link..\n"); break; default: notify_player(player,"I don't understand that.\n"); warning("do_link","bad type field detected"); return; } if(!controls(player,thing)){ notify_player(player,"You don't own that!\n"); return; } /* Link it up. */ if(set_int_elt(thing,code,dest) == -1) goto linkbomb; notify_player(player,msg); return; linkbomb: notify_bad(player); return; } do_unlink(player,arg) int player; char *arg; { int obj,flags,code; char *msg; if(arg == NULL){ notify_player(player,"Unlink what?\n"); return; } obj = resolve_object(player,arg,0); /* 0 == NO *<playername> */ if(obj == -1){ notify_player(player,"I can't find that.\n"); return; } if(!controls(player,obj)){ notify_player(player,"You can't unlink that!\n"); return; } /* Unlink it. */ if(get_int_elt(obj,FLAGS,&flags) == -1) goto unlinkbomb; switch(flags & TYPE_MASK){ case TYP_PLAYER: case TYP_THING: notify_player(player,"Can't unset an object's home!\n"); return; break; case TYP_EXIT: code = DESTINATION; msg = "Exit unlinked.\n"; break; case TYP_ROOM: code = DROPTO; msg = "DropTo unset.\n"; break; default: notify_player(player,"I don't understand that.\n"); return; } if(set_int_elt(obj,code,-1) == -1) goto unlinkbomb; notify_player(player,msg); return; unlinkbomb: notify_bad(player); return; } do_recycle(player,arg) int player; char *arg; { int obj,flags,loc; /* int list,next; */ obj = resolve_object(player,arg,0); if(obj == -1){ notify_player(player,"I can't find that.\n"); return; } if(!controls(player,obj)){ notify_player(player,"You don't own that!\n"); return; } if(obj == 0){ notify_player(player,"Cannot recycle object Zero.\n"); return; } if(get_int_elt(obj,FLAGS,&flags) == -1) goto recbomb; if(get_int_elt(obj,LOC,&loc) == -1) goto recbomb; switch(flags & TYPE_MASK){ case TYP_PLAYER: notify_player(player,"Can't recycle players.\n"); return; case TYP_ROOM: notify_player(player,"Cannot recycle rooms.\n"); return; /* There's a BIG fucking problem here. You have to unlink */ /* all the *inbound* exits. This means unfreezing like half */ /* of your DB, (all the exits, basically). Actually, you must */ /* peer at, at least, the flags on every goddamn db element. */ /* Nuke the exits. Ownership? Who cares. */ /* if(get_int_elt(obj,EXITS,&list) == -1) goto recbomb; while(list != -1){ if(get_int_elt(list,NEXT,&next) == -1) goto recbomb; destroy_obj(list); list = next; } */ /* Try to send everything here home. Nuke what's left */ /* I.E. Anything homed here will get nuked. BOOM! */ /* if(get_int_elt(obj,CONTENTS,&list) == -1) goto recbomb; while(list != -1){ if(get_int_elt(list,NEXT,&next) == -1) goto recbomb; */ /* If this is a player homed here, set home to zero */ /* if(get_int_elt(list,FLAGS,&flags) == -1) goto recbomb; if((flags & TYPE_MASK) == TYP_PLAYER){ int home; if(get_int_elt(list,HOME,&home) == -1) goto recbomb; if(home == obj){ if(set_int_elt(list,HOME,0) == -1) goto recbomb; } } send_home(list,obj); list = next; } if(get_int_elt(obj,CONTENTS,&list) == -1) goto recbomb; while(list != -1){ if(get_int_elt(list,NEXT,&next) == -1) goto recbomb; destroy_obj(list); list = next; } */ /* nuke the room itself. */ /* destroy_obj(obj); */ /* Skip over the DB checking all exits, and unlinking the */ /* ones that come here. Ugh. This is expensive as hell. */ break; case TYP_EXIT: list_drop(obj,loc,0); destroy_obj(obj); break; case TYP_THING: list_drop(obj,loc,1); destroy_obj(obj); break; default: notify_player(player,"Eeek! Unknown object type!\n"); return; } notify_player(player,"Thank you for recycling.\n"); return; recbomb: notify_bad(player); return; }