/* Show the 'Obvious Exits' list for a room. Used in 'look' and 'examine'. * \param player The player looking * \param loc room whose exits we're showing * \param exit_name "Obvious Exits" string * \param pe_info the pe_info to use for evaluating EXITFORMAT and interact locks */ static void look_exits(dbref player, dbref loc, const char *exit_name, NEW_PE_INFO *pe_info) { dbref thing; char *tbuf1, *tbuf2, *nbuf; char *s1, *s2; char *p; int exit_count, this_exit, total_count; int texits; ufun_attrib ufun; PUEBLOBUFF; /* make sure location is a room */ if (!IsRoom(loc)) return; tbuf1 = (char *) mush_malloc(BUFFER_LEN, "string"); tbuf2 = (char *) mush_malloc(BUFFER_LEN, "string"); nbuf = (char *) mush_malloc(BUFFER_LEN, "string"); if (!tbuf1 || !tbuf2 || !nbuf) mush_panic("Unable to allocate memory in look_exits"); s1 = tbuf1; s2 = tbuf2; texits = exit_count = total_count = 0; this_exit = 1; if (fetch_ufun_attrib ("EXITFORMAT", loc, &ufun, UFUN_IGNORE_PERMS | UFUN_REQUIRE_ATTR)) { char *arg, *buff, *bp; PE_REGS *pe_regs = pe_regs_create(PE_REGS_ARG, "look_exits"); arg = (char *) mush_malloc(BUFFER_LEN, "string"); buff = (char *) mush_malloc(BUFFER_LEN, "string"); if (!arg || !buff) mush_panic("Unable to allocate memory in look_exits"); bp = arg; DOLIST(thing, Exits(loc)) { if (((Light(loc) || Light(thing)) || !(Dark(loc) || Dark(thing))) && can_interact(thing, player, INTERACT_SEE, pe_info)) { if (bp != arg) safe_chr(' ', arg, &bp); safe_dbref(thing, arg, &bp); } } *bp = '\0'; pe_regs_setenv_nocopy(pe_regs, 0, arg); call_ufun(&ufun, buff, player, player, pe_info, pe_regs); pe_regs_free(pe_regs); notify_by(loc, player, buff); mush_free(tbuf1, "string"); mush_free(tbuf2, "string"); mush_free(nbuf, "string"); mush_free(arg, "string"); mush_free(buff, "string"); return; }
/** Take an action on an object and trigger attributes. * \verbatim * executes the @attr, @oattr, @aattr for a command - gives a message * to the enactor and others in the room with the enactor, and executes * an action. We optionally load pe_regs into the queue. * \endverbatim * * \param player the enactor. * \param thing object being triggered. * \param what message attribute for enactor. * \param def default message to enactor. * \param owhat message attribute for others. * \param odef default message to others. * \param awhat action attribute to trigger. * \param loc location in which action is taking place. * \param pe_regs the pe_regs arguments for the evaluation/queueing * \param flags flags controlling type of interaction involved. * \retval 0 no attributes were present, only defaults were used if given. * \retval 1 some attributes were evaluated and used. */ int real_did_it(dbref player, dbref thing, const char *what, const char *def, const char *owhat, const char *odef, const char *awhat, dbref loc, PE_REGS *pe_regs, int flags, int an_flags) { char buff[BUFFER_LEN], *bp; int attribs_used = 0; NEW_PE_INFO *pe_info = NULL; ufun_attrib ufun; if (!pe_info) { pe_info = make_pe_info("pe_info-real_did_it2"); } loc = (loc == NOTHING) ? Location(player) : loc; /* only give messages if the location is good */ if (GoodObject(loc)) { /* message to player */ if (what && *what) { if (fetch_ufun_attrib (what, thing, &ufun, UFUN_LOCALIZE | UFUN_REQUIRE_ATTR | UFUN_IGNORE_PERMS)) { attribs_used = 1; if (!call_ufun(&ufun, buff, thing, player, pe_info, pe_regs) && buff[0]) notify_by(thing, player, buff); } else if (def && *def) notify_by(thing, player, def); } /* message to neighbors */ if (!DarkLegal(player)) { if (owhat && *owhat && fetch_ufun_attrib(owhat, thing, &ufun, UFUN_LOCALIZE | UFUN_REQUIRE_ATTR | UFUN_IGNORE_PERMS | UFUN_NAME)) { attribs_used = 1; if (!call_ufun_int (&ufun, buff, thing, player, pe_info, pe_regs, (void *) AName(player, an_flags, NULL)) && buff[0]) notify_except2(player, loc, player, thing, buff, flags); } else if (odef && *odef) { bp = buff; safe_format(buff, &bp, "%s %s", AName(player, an_flags, NULL), odef); *bp = '\0'; notify_except2(player, loc, player, thing, buff, flags); } } } if (pe_info) { free_pe_info(pe_info); } if (awhat && *awhat) attribs_used = queue_attribute_base(thing, awhat, player, 0, pe_regs, 0) || attribs_used; return attribs_used; }
/** Given a thing, attribute, enactor and arguments for %0-%9, * call the ufun with appropriate permissions on values given for * wenv_args. The value returned is stored in the buffer pointed to * by ret, if given. * \param thing The thing that has the attribute to be called * \param attrname The name of the attribute to call. * \param ret If desired, a pointer to a buffer in which the results * of the process_expression are stored in. * \param enactor The enactor. * \param pe_info The pe_info passed to the FUNCTION * \param pe_regs Other arguments that may want to be added. This nests BELOW * the pe_regs created by call_ufun. (It is checked first) * \retval 1 success * \retval 0 No such attribute, or failed. */ bool call_attrib(dbref thing, const char *attrname, char *ret, dbref enactor, NEW_PE_INFO *pe_info, PE_REGS *pe_regs) { ufun_attrib ufun; if (!fetch_ufun_attrib(attrname, thing, &ufun, UFUN_LOCALIZE | UFUN_REQUIRE_ATTR | UFUN_IGNORE_PERMS)) { return 0; } return !call_ufun(&ufun, ret, thing, enactor, pe_info, pe_regs); }