static void open_exit(dbref player, dbref loc, char *direction, char *linkto, int key) { dbref exit; char *tpr_buff, *tprp_buff; if (!Good_obj(loc)) return; if (!direction || !*direction) { notify_quiet(player, "Open where?"); return; } else if (!controls(player, loc) && !could_doit(player, loc, A_LOPEN, 0, 0)) { notify_quiet(player, "Permission denied."); return; } exit = create_obj(player, TYPE_EXIT, direction, 0); if (exit == NOTHING) return; /* Initialize everything and link it in. */ s_Exits(exit, loc); s_Next(exit, Exits(loc)); s_Exits(loc, exit); /* and we're done */ if ( !(key & SIDEEFFECT ) ) notify_quiet(player, "Opened."); /* See if we should do a link */ if (!linkto || !*linkto) return; loc = parse_linkable_room(player, linkto); if (loc != NOTHING) { /* Make sure the player passes the link lock */ if ((loc != HOME) && !could_doit(player, loc, A_LLINK, 1, 0)) { notify_quiet(player, "You can't link to there."); return; } /* Link it if the player can pay for it */ if (!payfor(player, mudconf.linkcost)) { tprp_buff = tpr_buff = alloc_lbuf("open_exit"); notify_quiet(player, safe_tprintf(tpr_buff, &tprp_buff, "You don't have enough %s to link.", mudconf.many_coins)); free_lbuf(tpr_buff); } else { s_Location(exit, loc); if ( !(key & SIDEEFFECT ) ) notify_quiet(player, "Linked."); } } }
void do_open(dbref player, dbref cause, int key, char *direction, char *links[], int nlinks) { dbref loc, destnum; char *dest, *dir2; char spam_chr[32]; memset(spam_chr, 0, sizeof(spam_chr)); if ( (key & SIDEEFFECT) && !SideFX(player) ) { notify(player, "#-1 FUNCTION DISABLED"); return; } if (Immortal(player) && (*direction == '#')) { dir2 = get_free_num(player, direction); } else { dir2 = direction; } /* Create the exit and link to the destination, if there is one */ if (nlinks >= 1) dest = links[0]; else dest = NULL; if ((key == OPEN_INVENTORY) || ((Typeof(player) == TYPE_ROOM) && (mudconf.rooms_can_open == 1))) loc = player; else { if ( mudstate.store_loc != NOTHING ) loc = mudstate.store_loc; else loc = Location(player); } open_exit(player, loc, dir2, dest, key); /* Open the back link if we can */ if (nlinks >= 2) { destnum = parse_linkable_room(player, dest); if (destnum != NOTHING) { /* For some reason unsafe_tprintf() doesn't work right here */ sprintf(spam_chr, "%d", loc); open_exit(player, destnum, links[1], spam_chr, key); } } }
void do_link(dbref player, dbref cause, int key, char *what, char *where) { dbref thing, room; char *buff; int nomtest; if ( (key & SIDEEFFECT) && !SideFX(player) ) { notify(player, "#-1 FUNCTION DISABLED"); return; } /* Find the thing to link */ init_match(player, what, TYPE_EXIT); match_everything(0); thing = noisy_match_result(); if (thing == NOTHING) return; nomtest = ((NoMod(thing) && !WizMod(player)) || (DePriv(player,Owner(thing),DP_MODIFY,POWER7,NOTHING) && (Owner(thing) != Owner(player))) || (Backstage(player) && NoBackstage(thing) && !Immortal(player))); /* Allow unlink if where is not specified */ if (!where || !*where) { if (!nomtest) do_unlink(player, cause, key, what); else notify(player,"Permission denied."); return; } switch (Typeof(thing)) { case TYPE_EXIT: /* Set destination */ room = parse_linkable_room(player, where); if (room != NOTHING) { if (!nomtest) link_exit(player, thing, room, key); else notify(player,"Permission denied."); } break; case TYPE_PLAYER: case TYPE_THING: /* Set home */ if (!Controls(player, thing) || nomtest) { notify_quiet(player, "Permission denied."); break; } init_match(player, where, NOTYPE); match_everything(MAT_NO_EXITS); room = noisy_match_result(); if (!Good_obj(room)) break; if (!Has_contents(room)) { notify_quiet(player, "Can't link to an exit."); break; } if (!can_set_home(player, thing, room) || !could_doit(player, room, A_LLINK, 1, 0)) { notify_quiet(player, "Permission denied."); } else if (room == HOME) { notify_quiet(player, "Can't set home to home."); } else { s_Home(thing, room); if (!(Quiet(player) || (key & SIDEEFFECT)) ) notify_quiet(player, "Home set."); } break; case TYPE_ROOM: /* Set dropto */ if (!Controls(player, thing) || nomtest) { notify_quiet(player, "Permission denied."); break; } room = parse_linkable_room(player, where); if (!Good_obj(room) && (room != HOME)) { notify_quiet(player, "Permission denied."); break; } if ((room != HOME) && !isRoom(room)) { notify_quiet(player, "That is not a room!"); } else if ((room != HOME) && ((!controls(player, room) && !Link_ok(room)) || !could_doit(player, room, A_LLINK, 1, 0))) { notify_quiet(player, "Permission denied."); } else { s_Dropto(thing, room); if (!Quiet(player)) notify_quiet(player, "Dropto set."); } break; default: STARTLOG(LOG_BUGS, "BUG", "OTYPE") buff = alloc_mbuf("do_link.LOG.badtype"); sprintf(buff, "Strange object type: object #%d = %d", thing, Typeof(thing)); log_text(buff); free_mbuf(buff); ENDLOG } }
/** Create an exit. * This function opens an exit and optionally links it. * \param player the enactor. * \param direction the name of the exit. * \param linkto the room to link to, as a string. * \param pseudo a phony location for player if a back exit is needed. This is bpass by do_open() as the source room of the back exit. * \return dbref of the new exit, or NOTHING. */ dbref do_real_open(dbref player, const char *direction, const char *linkto, dbref pseudo) { dbref loc = (pseudo != NOTHING) ? pseudo : (IsExit(player) ? Source(player) : (IsRoom(player) ? player : Location(player))); dbref new_exit; char *flaglist, *flagname; char flagbuff[BUFFER_LEN]; char *name = NULL; char *alias = NULL; if (!command_check_byname(player, "@dig")) { notify(player, T("Permission denied.")); return NOTHING; } if ((loc == NOTHING) || (!IsRoom(loc))) { notify(player, T("Sorry, you can only make exits out of rooms.")); return NOTHING; } if (Going(loc)) { notify(player, T("You can't make an exit in a place that's crumbling.")); return NOTHING; } if (!*direction) { notify(player, T("Open where?")); return NOTHING; } else if (ok_object_name ((char *) direction, player, NOTHING, TYPE_EXIT, &name, &alias) < 1) { notify(player, T("That's a strange name for an exit!")); if (name) mush_free(name, "name.newname"); if (alias) mush_free(alias, "name.newname"); return NOTHING; } if (!Open_Anywhere(player) && !controls(player, loc)) { notify(player, T("Permission denied.")); } else if (can_pay_fees(player, EXIT_COST)) { /* create the exit */ new_exit = new_object(); /* initialize everything */ set_name(new_exit, name); if (alias && *alias != ALIAS_DELIMITER) atr_add(new_exit, "ALIAS", alias, player, 0); Owner(new_exit) = Owner(player); Zone(new_exit) = Zone(player); Source(new_exit) = loc; Type(new_exit) = TYPE_EXIT; Flags(new_exit) = new_flag_bitmask("FLAG"); strcpy(flagbuff, options.exit_flags); flaglist = trim_space_sep(flagbuff, ' '); if (*flaglist != '\0') { while (flaglist) { flagname = split_token(&flaglist, ' '); twiddle_flag_internal("FLAG", new_exit, flagname, 0); } } mush_free(name, "name.newname"); if (alias) mush_free(alias, "name.newname"); /* link it in */ PUSH(new_exit, Exits(loc)); /* and we're done */ notify_format(player, T("Opened exit %s"), unparse_dbref(new_exit)); /* check second arg to see if we should do a link */ if (linkto && *linkto != '\0') { notify(player, T("Trying to link...")); if ((loc = check_var_link(linkto)) == NOTHING) loc = parse_linkable_room(player, linkto); if (loc != NOTHING) { if (!payfor(player, LINK_COST)) { notify_format(player, T("You don't have enough %s to link."), MONIES); } else { /* it's ok, link it */ Location(new_exit) = loc; notify_format(player, T("Linked exit #%d to #%d"), new_exit, loc); } } } current_state.exits++; local_data_create(new_exit); queue_event(player, "OBJECT`CREATE", "%s", unparse_objid(new_exit)); return new_exit; } if (name) mush_free(name, "name.newname"); if (alias) mush_free(alias, "name.newname"); return NOTHING; }
/** Link an exit, room, player, or thing. * \verbatim * This is the top-level function for @link, which is used to link an * exit to a destination, set a player or thing's home, or set a * drop-to on a room. * * Linking an exit usually seizes ownership of the exit and costs 1 penny. * 1 penny is also transferred to the former owner. * \endverbatim * \param player the enactor. * \param name the name of the object to link. * \param room_name the name of the link destination. * \param preserve if 1, preserve ownership and zone data on exit relink. */ void do_link(dbref player, const char *name, const char *room_name, int preserve) { /* Use this to link to a room that you own. * It usually seizes ownership of the exit and costs 1 penny, * plus a penny transferred to the exit owner if they aren't you. * You must own the linked-to room AND specify it by room number. */ dbref thing; dbref room; if (!room_name || !*room_name) { do_unlink(player, name); return; } if (!IsRoom(player) && GoodObject(Location(player)) && IsExit(Location(player))) { notify(player, T("You somehow wound up in a exit. No biscuit.")); return; } if ((thing = noisy_match_result(player, name, TYPE_EXIT, MAT_EVERYTHING)) != NOTHING) { switch (Typeof(thing)) { case TYPE_EXIT: if ((room = check_var_link(room_name)) == NOTHING) room = parse_linkable_room(player, room_name); if (room == NOTHING) return; if (GoodObject(room) && !can_link_to(player, room)) { notify(player, T("Permission denied.")); break; } /* We may link an exit if it's unlinked and we pass the link-lock * or if we control it. */ if (!(controls(player, thing) || ((Location(thing) == NOTHING) && eval_lock(player, thing, Link_Lock)))) { notify(player, T("Permission denied.")); return; } if (preserve && !Wizard(player)) { notify(player, T("Permission denied.")); return; } /* handle costs */ if (Owner(thing) == Owner(player)) { if (!payfor(player, LINK_COST)) { notify_format(player, T("It costs %d %s to link this exit."), LINK_COST, ((LINK_COST == 1) ? MONEY : MONIES)); return; } } else { if (!payfor(player, LINK_COST + EXIT_COST)) { int a = LINK_COST + EXIT_COST; notify_format(player, T("It costs %d %s to link this exit."), a, ((a == 1) ? MONEY : MONIES)); return; } else if (!preserve) { /* pay the owner for his loss */ giveto(Owner(thing), EXIT_COST); chown_object(player, thing, player, 0); } } /* link has been validated and paid for; do it */ if (!preserve) { Owner(thing) = Owner(player); Zone(thing) = Zone(player); } Location(thing) = room; /* notify the player */ notify_format(player, T("Linked exit #%d to %s"), thing, unparse_object(player, room)); break; case TYPE_PLAYER: case TYPE_THING: if ((room = noisy_match_result(player, room_name, NOTYPE, MAT_EVERYTHING)) == NOTHING) { notify(player, T("No match.")); return; } if (IsExit(room)) { notify(player, T("That is an exit.")); return; } if (thing == room) { notify(player, T("You may not link something to itself.")); return; } /* abode */ if (!controls(player, room) && !Abode(room)) { notify(player, T("Permission denied.")); break; } if (!controls(player, thing)) { notify(player, T("Permission denied.")); } else if (room == HOME) { notify(player, T("Can't set home to home.")); } else { /* do the link */ Home(thing) = room; /* home */ if (!Quiet(player) && !(Quiet(thing) && (Owner(thing) == player))) notify(player, T("Home set.")); } break; case TYPE_ROOM: if ((room = parse_linkable_room(player, room_name)) == NOTHING) return; if ((room != HOME) && (!IsRoom(room))) { notify(player, T("That is not a room!")); return; } if (!controls(player, thing)) { notify(player, T("Permission denied.")); } else { /* do the link, in location */ Location(thing) = room; /* dropto */ notify(player, T("Dropto set.")); } break; default: notify(player, T("Internal error: weird object type.")); do_log(LT_ERR, NOTHING, NOTHING, "Weird object! Type of #%d is %d", thing, Typeof(thing)); break; } } }