mirror of
https://github.com/brazilofmux/tinymux
synced 2026-08-13 00:23:11 -04:00
The flip: FUNCTION/XFUNCTION/FUN::fun/delim_check and the module interfaces take `const UTF8 * const fargs[]`. Double-const is load-bearing: C++ qualification conversion needs const at both pointer levels, so builder-side `UTF8 *[]` arrays convert implicitly — the evaluator, the JIT marshaller, and every owner site need zero casts, and slot reassignment inside bodies becomes a compile error for free. The conversions: the flip landed first so the compiler enumerated every violation; this commit is that inventory worked to zero — ~250 sites across funceval, funceval2, functions, funmath, help, mail, session, powers, levels, predicates, conf, walkdb, stringutil, timeutil/ date_scan (regenerated, one-line diff), exp3, and mux_main, each classified per docs/campaign-2136-const-fargs.md's four recipes. New idioms (functions.h): trim_space_sep_n() — non-destructive trim for (pointer, length) consumers, so trim-then-scan sites need no copy at all; FargVec — the argv counterpart of FargCopy for CS_ARGV handlers. countwords() and DecodeListOfIntegers() rewritten non-destructive. The flip deleted more than it added: #2157's fun_munge list1 copy, the engine_com help-topic copy, fun_index's in-place NUL write, and five const_casts (process_sex x4, sha1_helper). const_cast budget: zero added. Trap recorded in the brief: an old-signature definition doesn't fail the build — it becomes a C++ overload, and the new-signature symbol stays undefined until dlopen(RTLD_NOW). delim_check, the conn_bridge bridges, the dbt_spike stub, and exp3::Call were all silently shadowed; muxscript was the only host that noticed, because netmux's own net.cpp resolved the flat-namespace lookup. After any signature flip, grep the old spelling. Verified: make test EXPECT_CONFIG="jit=yes" (35 passed / 0 failed) and make test-scenario, including the new tests/scenario/sidefx_fargs.py that live-probes the class-3 wrappers smoke never touches (pemit/ trigger/link/tel/wipe/destroy). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
885 lines
21 KiB
C++
885 lines
21 KiB
C++
/*! \file levels.cpp
|
||
* \brief Reality levels stuff.
|
||
*
|
||
* See mux/REALITY.SETUP in the distribution.
|
||
*/
|
||
|
||
#ifdef REALITY_LVLS
|
||
|
||
#include "copyright.h"
|
||
#include "autoconf.h"
|
||
#include "config.h"
|
||
#include "externs.h"
|
||
|
||
RLEVEL RxLevel(dbref thing)
|
||
{
|
||
const UTF8 *buff = atr_get_raw(thing, A_RLEVEL);
|
||
if ( nullptr == buff
|
||
|| strlen(reinterpret_cast<const char *>(buff)) != 17)
|
||
{
|
||
switch (Typeof(thing))
|
||
{
|
||
case TYPE_ROOM:
|
||
return(mudconf.def_room_rx);
|
||
|
||
case TYPE_PLAYER:
|
||
return(mudconf.def_player_rx);
|
||
|
||
case TYPE_EXIT:
|
||
return(mudconf.def_exit_rx);
|
||
|
||
default:
|
||
return(mudconf.def_thing_rx);
|
||
}
|
||
}
|
||
|
||
int i;
|
||
RLEVEL rx = 0;
|
||
for (i = 0; mux_isxdigit(buff[i]); i++)
|
||
{
|
||
rx = 16 * rx + mux_hex2dec(buff[i]);
|
||
}
|
||
return rx;
|
||
}
|
||
|
||
RLEVEL TxLevel(dbref thing)
|
||
{
|
||
const UTF8 *buff = atr_get_raw(thing, A_RLEVEL);
|
||
if ( nullptr == buff
|
||
|| strlen(reinterpret_cast<const char *>(buff)) != 17)
|
||
{
|
||
switch (Typeof(thing))
|
||
{
|
||
case TYPE_ROOM:
|
||
return(mudconf.def_room_tx);
|
||
|
||
case TYPE_PLAYER:
|
||
return(mudconf.def_player_tx);
|
||
|
||
case TYPE_EXIT:
|
||
return(mudconf.def_exit_tx);
|
||
|
||
default:
|
||
return(mudconf.def_thing_tx);
|
||
}
|
||
}
|
||
|
||
// Skip the first field.
|
||
//
|
||
int i;
|
||
for (i = 0; buff[i] && !mux_isspace(buff[i]); i++)
|
||
{
|
||
; // Nothing.
|
||
}
|
||
|
||
RLEVEL tx = 0;
|
||
if (buff[i])
|
||
{
|
||
// Skip space found above.
|
||
//
|
||
i++;
|
||
|
||
// Decode second field.
|
||
//
|
||
for ( ; mux_isxdigit(buff[i]); i++)
|
||
{
|
||
tx = 16 * tx + mux_hex2dec(buff[i]);
|
||
}
|
||
}
|
||
return tx;
|
||
}
|
||
|
||
void notify_except_rlevel
|
||
(
|
||
dbref loc,
|
||
dbref player,
|
||
dbref exception,
|
||
const UTF8 *msg,
|
||
int xflags
|
||
)
|
||
{
|
||
if ( loc != exception
|
||
&& IsReal(loc, player))
|
||
{
|
||
notify_check(loc, player, msg,
|
||
(MSG_ME_ALL | MSG_F_UP | MSG_S_INSIDE | MSG_NBR_EXITS_A| xflags));
|
||
}
|
||
|
||
dbref first;
|
||
DOLIST(first, Contents(loc))
|
||
{
|
||
if ( first != exception
|
||
&& IsReal(first, player)
|
||
&& !(isPlayer(first) && Alone(loc)))
|
||
{
|
||
notify_check(first, player, msg,
|
||
(MSG_ME | MSG_F_DOWN | MSG_S_OUTSIDE | xflags));
|
||
}
|
||
}
|
||
}
|
||
|
||
void notify_except2_rlevel
|
||
(
|
||
dbref loc,
|
||
dbref player,
|
||
dbref exc1,
|
||
dbref exc2,
|
||
const UTF8 *msg
|
||
)
|
||
{
|
||
if ( loc != exc1
|
||
&& loc != exc2
|
||
&& IsReal(loc, player))
|
||
{
|
||
notify_check(loc, player, msg,
|
||
(MSG_ME_ALL | MSG_F_UP | MSG_S_INSIDE | MSG_NBR_EXITS_A));
|
||
}
|
||
|
||
dbref first;
|
||
DOLIST(first, Contents(loc))
|
||
{
|
||
if ( first != exc1
|
||
&& first != exc2
|
||
&& IsReal(first, player)
|
||
&& !(isPlayer(first) && Alone(loc)))
|
||
{
|
||
notify_check(first, player, msg,
|
||
(MSG_ME | MSG_F_DOWN | MSG_S_OUTSIDE));
|
||
}
|
||
}
|
||
}
|
||
|
||
void notify_except2_rlevel2
|
||
(
|
||
dbref loc,
|
||
dbref player,
|
||
dbref exc1,
|
||
dbref exc2,
|
||
const UTF8 *msg
|
||
)
|
||
{
|
||
if ( loc != exc1
|
||
&& loc != exc2
|
||
&& IsReal(loc, player))
|
||
{
|
||
notify_check(loc, player, msg,
|
||
(MSG_ME_ALL | MSG_F_UP | MSG_S_INSIDE | MSG_NBR_EXITS_A));
|
||
}
|
||
|
||
dbref first;
|
||
DOLIST(first, Contents(loc))
|
||
{
|
||
if ( first != exc1
|
||
&& first != exc2
|
||
&& IsReal(first, player)
|
||
&& IsReal(first, exc2)
|
||
&& !(isPlayer(first) && Alone(loc)))
|
||
{
|
||
notify_check(first, player, msg,
|
||
(MSG_ME | MSG_F_DOWN | MSG_S_OUTSIDE));
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
* ---------------------------------------------------------------------------
|
||
* * rxlevel_description: Return an mbuf containing the RxLevels of the thing.
|
||
*/
|
||
|
||
UTF8 *rxlevel_description(dbref player, dbref target)
|
||
{
|
||
// Allocate the return buffer.
|
||
//
|
||
int otype = Typeof(target);
|
||
UTF8 *buff = alloc_mbuf("rxlevel_description");
|
||
UTF8 *bp = buff;
|
||
|
||
int i;
|
||
RLEVEL rl = RxLevel(target);
|
||
for (i = 0; i < mudconf.no_levels; ++i)
|
||
{
|
||
confdata::rlevel_def *rldef = &mudconf.reality_level[i];
|
||
if ((rl & rldef->value) == rldef->value)
|
||
{
|
||
safe_mb_chr(' ', buff, &bp);
|
||
safe_mb_str(rldef->name, buff, &bp);
|
||
}
|
||
}
|
||
|
||
// Terminate the string, and return the buffer to the caller.
|
||
//
|
||
*bp = '\0';
|
||
return buff;
|
||
}
|
||
|
||
/*
|
||
* ---------------------------------------------------------------------------
|
||
* * txlevel_description: Return an mbuf containing the TxLevels of the thing.
|
||
*/
|
||
|
||
UTF8 *txlevel_description(dbref player, dbref target)
|
||
{
|
||
// Allocate the return buffer.
|
||
//
|
||
int otype = Typeof(target);
|
||
UTF8 *buff = alloc_mbuf("txlevel_description");
|
||
UTF8 *bp = buff;
|
||
|
||
int i;
|
||
RLEVEL tl = TxLevel(target);
|
||
for (i = 0; i < mudconf.no_levels; ++i)
|
||
{
|
||
confdata::rlevel_def *rldef = &mudconf.reality_level[i];
|
||
if ((tl & rldef->value) == rldef->value)
|
||
{
|
||
safe_mb_chr(' ', buff, &bp);
|
||
safe_mb_str(rldef->name, buff, &bp);
|
||
}
|
||
}
|
||
|
||
// Terminate the string, and return the buffer to the caller.
|
||
//
|
||
*bp = '\0';
|
||
return buff;
|
||
}
|
||
|
||
RLEVEL find_rlevel(const UTF8 *name)
|
||
{
|
||
for (int i = 0; i < mudconf.no_levels; i++)
|
||
{
|
||
confdata::rlevel_def *rldef = &mudconf.reality_level[i];
|
||
if (mux_stricmp(name, rldef->name) == 0)
|
||
{
|
||
return rldef->value;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
void do_rxlevel
|
||
(
|
||
dbref executor,
|
||
dbref caller,
|
||
dbref enactor,
|
||
int eval,
|
||
int key,
|
||
int nargs,
|
||
UTF8 *object,
|
||
UTF8 *arg,
|
||
const UTF8 *cargs[],
|
||
int ncargs
|
||
)
|
||
{
|
||
UNUSED_PARAMETER(caller);
|
||
UNUSED_PARAMETER(enactor);
|
||
UNUSED_PARAMETER(eval);
|
||
UNUSED_PARAMETER(cargs);
|
||
UNUSED_PARAMETER(ncargs);
|
||
|
||
if (!arg || !*arg)
|
||
{
|
||
notify_quiet(executor, M_("I don’t know what you want to set!"));
|
||
return;
|
||
}
|
||
|
||
// Find thing.
|
||
//
|
||
dbref thing = match_controlled(executor, object);
|
||
if (NOTHING == thing)
|
||
{
|
||
return;
|
||
}
|
||
|
||
UTF8 lname[9];
|
||
RLEVEL ormask = 0;
|
||
RLEVEL andmask = ~ormask;
|
||
while (*arg)
|
||
{
|
||
int negate = 0;
|
||
while ( *arg != '\0'
|
||
&& mux_isspace(*arg))
|
||
{
|
||
arg++;
|
||
}
|
||
|
||
if (*arg == '!')
|
||
{
|
||
negate = 1;
|
||
++arg;
|
||
}
|
||
|
||
int i;
|
||
for (i = 0; *arg && !mux_isspace(*arg); arg++)
|
||
{
|
||
if (i < 8)
|
||
{
|
||
lname[i++] = *arg;
|
||
}
|
||
}
|
||
|
||
lname[i] = '\0';
|
||
if (!lname[0])
|
||
{
|
||
if (negate)
|
||
{
|
||
notify(executor, M_("You must specify a reality level to clear."));
|
||
}
|
||
else
|
||
{
|
||
notify(executor, M_("You must specify a reality level to set."));
|
||
}
|
||
return;
|
||
}
|
||
|
||
RLEVEL result = find_rlevel(lname);
|
||
if (!result)
|
||
{
|
||
notify(executor, M_("No such reality level."));
|
||
continue;
|
||
}
|
||
if (negate)
|
||
{
|
||
andmask &= ~result;
|
||
notify(executor, M_("Cleared."));
|
||
}
|
||
else
|
||
{
|
||
ormask |= result;
|
||
notify(executor, M_("Set."));
|
||
}
|
||
}
|
||
|
||
// Set the Rx Level.
|
||
//
|
||
LBuf buff = LBuf_Src("do_rxlevel");
|
||
mux_sprintf(buff.get(), LBUF_SIZE, T("%08X %08X"), RxLevel(thing) & andmask | ormask, TxLevel(thing));
|
||
atr_add_raw(thing, A_RLEVEL, buff);
|
||
}
|
||
|
||
|
||
void do_txlevel
|
||
(
|
||
dbref executor,
|
||
dbref caller,
|
||
dbref enactor,
|
||
int eval,
|
||
int key,
|
||
int nargs,
|
||
UTF8 *object,
|
||
UTF8 *arg,
|
||
const UTF8 *cargs[],
|
||
int ncargs
|
||
)
|
||
{
|
||
UNUSED_PARAMETER(caller);
|
||
UNUSED_PARAMETER(enactor);
|
||
UNUSED_PARAMETER(eval);
|
||
UNUSED_PARAMETER(cargs);
|
||
UNUSED_PARAMETER(ncargs);
|
||
|
||
if (!arg || !*arg)
|
||
{
|
||
notify_quiet(executor, M_("I don’t know what you want to set!"));
|
||
return;
|
||
}
|
||
|
||
// Find thing.
|
||
//
|
||
dbref thing = match_controlled(executor, object);
|
||
if (NOTHING == thing)
|
||
{
|
||
return;
|
||
}
|
||
|
||
UTF8 lname[9];
|
||
RLEVEL ormask = 0;
|
||
RLEVEL andmask = ~ormask;
|
||
while (*arg)
|
||
{
|
||
int negate = 0;
|
||
while ( *arg
|
||
&& mux_isspace(*arg))
|
||
{
|
||
arg++;
|
||
}
|
||
|
||
if (*arg == '!')
|
||
{
|
||
negate = 1;
|
||
++arg;
|
||
}
|
||
|
||
int i;
|
||
for (i = 0; *arg && !mux_isspace(*arg); arg++)
|
||
{
|
||
if (i < 8)
|
||
{
|
||
lname[i++] = *arg;
|
||
}
|
||
}
|
||
|
||
lname[i] = '\0';
|
||
if (!lname[0])
|
||
{
|
||
if (negate)
|
||
{
|
||
notify(executor, M_("You must specify a reality level to clear."));
|
||
}
|
||
else
|
||
{
|
||
notify(executor, M_("You must specify a reality level to set."));
|
||
}
|
||
return;
|
||
}
|
||
|
||
RLEVEL result = find_rlevel(lname);
|
||
if (!result)
|
||
{
|
||
notify(executor, M_("No such reality level."));
|
||
continue;
|
||
}
|
||
if (negate)
|
||
{
|
||
andmask &= ~result;
|
||
notify(executor, M_("Cleared."));
|
||
}
|
||
else
|
||
{
|
||
ormask |= result;
|
||
notify(executor, M_("Set."));
|
||
}
|
||
}
|
||
|
||
// Set the Tx Level.
|
||
//
|
||
LBuf buff = LBuf_Src("do_rxlevel");
|
||
mux_sprintf(buff.get(), LBUF_SIZE, T("%08X %08X"), RxLevel(thing), TxLevel(thing) & andmask | ormask);
|
||
atr_add_raw(thing, A_RLEVEL, buff);
|
||
}
|
||
|
||
/*
|
||
* ---------------------------------------------------------------------------
|
||
* * decompile_rlevels: Produce commands to set reality levels on target.
|
||
*/
|
||
|
||
void decompile_rlevels(dbref player, dbref thing, UTF8 *thingname)
|
||
{
|
||
UTF8 *buf = rxlevel_description(player, thing);
|
||
notify(player, tprintf(T("@rxlevel %s=%s"), thingname, buf));
|
||
free_mbuf(buf);
|
||
|
||
buf = txlevel_description(player, thing);
|
||
notify(player, tprintf(T("@txlevel %s=%s"), thingname, buf));
|
||
free_mbuf(buf);
|
||
}
|
||
|
||
#define NUM_DESC 33
|
||
typedef struct DESC_INFO
|
||
{
|
||
int n;
|
||
int descs[NUM_DESC];
|
||
} DESC_INFO;
|
||
|
||
DESC_INFO *desclist_match(dbref player, dbref thing)
|
||
{
|
||
static DESC_INFO descbuffer;
|
||
|
||
descbuffer.n = 0;
|
||
RLEVEL match = RxLevel(player) & TxLevel(thing);
|
||
for (int i = 0; i < mudconf.no_levels; i++)
|
||
{
|
||
confdata::rlevel_def *rldef = &mudconf.reality_level[i];
|
||
if ((match & rldef->value) == rldef->value)
|
||
{
|
||
ATTR *at = atr_str(rldef->attr);
|
||
if (nullptr != at)
|
||
{
|
||
bool bFound = false;
|
||
for (int j = 0; j < descbuffer.n; j++)
|
||
{
|
||
if (at->number == descbuffer.descs[j])
|
||
{
|
||
bFound = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ( !bFound
|
||
&& descbuffer.n < NUM_DESC-1)
|
||
{
|
||
descbuffer.descs[descbuffer.n] = at->number;
|
||
descbuffer.n++;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return &descbuffer;
|
||
}
|
||
|
||
UTF8 *get_rlevel_desc
|
||
(
|
||
dbref player,
|
||
dbref thing,
|
||
int *piDescUsed
|
||
)
|
||
{
|
||
dbref aowner;
|
||
int aflags;
|
||
UTF8 *buff = alloc_lbuf("get_rlevel_desc.");
|
||
UTF8 *bp = buff;;
|
||
reg_ref **preserve = nullptr;
|
||
bool need_pres = false;
|
||
bool bFirst = true;
|
||
|
||
// Get description list.
|
||
//
|
||
DESC_INFO *desclist = desclist_match(player, thing);
|
||
bool found_a_desc = false;
|
||
for (int i = 0; i < desclist->n; i++)
|
||
{
|
||
LBuf d = LBuf_Adopt(atr_pget(thing, desclist->descs[i], &aowner, &aflags));
|
||
if ('\0' != d[0])
|
||
{
|
||
found_a_desc = true;
|
||
if (!need_pres)
|
||
{
|
||
need_pres = true;
|
||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||
save_global_regs(preserve);
|
||
}
|
||
|
||
if (!bFirst)
|
||
{
|
||
safe_str(T("\r\n"), buff, &bp);
|
||
}
|
||
else
|
||
{
|
||
bFirst = false;
|
||
*piDescUsed = desclist->descs[i];
|
||
}
|
||
|
||
mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, thing, player,
|
||
AttrTrace(aflags, EV_FCHECK|EV_EVAL|EV_TOP),
|
||
nullptr, 0);
|
||
}
|
||
}
|
||
|
||
if (!found_a_desc)
|
||
{
|
||
LBuf d = LBuf_Adopt(atr_pget(thing, A_DESC, &aowner, &aflags));
|
||
if ('\0' != d[0])
|
||
{
|
||
found_a_desc = true;
|
||
if (!need_pres)
|
||
{
|
||
need_pres = true;
|
||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||
save_global_regs(preserve);
|
||
}
|
||
|
||
mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, thing, player,
|
||
AttrTrace(aflags, EV_FCHECK|EV_EVAL|EV_TOP),
|
||
nullptr, 0);
|
||
*bp = '\0';
|
||
|
||
*piDescUsed = A_DESC;
|
||
}
|
||
}
|
||
|
||
// If we preserved the state of the global registers, restore them.
|
||
//
|
||
if (need_pres)
|
||
{
|
||
restore_global_regs(preserve);
|
||
PopRegisters(preserve, MAX_GLOBAL_REGS);
|
||
}
|
||
|
||
*bp = '\0';
|
||
return buff;
|
||
}
|
||
|
||
/* ---------------------------------------------------------------------------
|
||
* did_it_rlevel: Have player do something to/with thing, watching the
|
||
* attributes. 'what' is actually ignored, the desclist match being used
|
||
* instead.
|
||
*/
|
||
void did_it_rlevel
|
||
(
|
||
dbref player,
|
||
dbref thing,
|
||
int what,
|
||
const UTF8 *def,
|
||
int owhat,
|
||
const UTF8 *odef,
|
||
int awhat,
|
||
int ctrl_flags,
|
||
const UTF8 *args[],
|
||
int nargs
|
||
)
|
||
{
|
||
if (alarm_clock.alarmed)
|
||
{
|
||
return;
|
||
}
|
||
|
||
UTF8 *d, *buff, *act, *charges, *bp;
|
||
dbref aowner;
|
||
int64_t num;
|
||
int aflags;
|
||
int i;
|
||
bool found_a_desc;
|
||
|
||
reg_ref **preserve = nullptr;
|
||
bool need_pres = false;
|
||
|
||
// Message to player.
|
||
//
|
||
if (0 < what)
|
||
{
|
||
// Get description list.
|
||
//
|
||
DESC_INFO *desclist = desclist_match(player, thing);
|
||
found_a_desc = false;
|
||
for (i = 0; i < desclist->n; i++)
|
||
{
|
||
// Ok, if it's A_DESC, we need to check against A_IDESC.
|
||
//
|
||
if ( A_IDESC == what
|
||
&& A_DESC == desclist->descs[i])
|
||
{
|
||
d = atr_pget(thing, A_IDESC, &aowner, &aflags);
|
||
}
|
||
else
|
||
{
|
||
d = atr_pget(thing, desclist->descs[i], &aowner, &aflags);
|
||
}
|
||
|
||
if ('\0' != d[0])
|
||
{
|
||
// No need for the 'def' message.
|
||
//
|
||
found_a_desc = true;
|
||
if (!need_pres)
|
||
{
|
||
need_pres = true;
|
||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||
save_global_regs(preserve);
|
||
}
|
||
buff = bp = alloc_lbuf("did_it.1");
|
||
mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, thing, player,
|
||
AttrTrace(aflags, EV_EVAL|EV_FIGNORE|EV_TOP),
|
||
args, nargs);
|
||
*bp = '\0';
|
||
|
||
if ( A_HTDESC == desclist->descs[i]
|
||
&& Html(player))
|
||
{
|
||
safe_str(T("\r\n"), buff, &bp);
|
||
*bp = '\0';
|
||
notify_html(player, buff);
|
||
}
|
||
else
|
||
{
|
||
notify(player, buff);
|
||
}
|
||
free_lbuf(buff);
|
||
}
|
||
free_lbuf(d);
|
||
}
|
||
|
||
if (!found_a_desc)
|
||
{
|
||
// No desc found... try the default desc (again).
|
||
// A_DESC or A_HTDESC... the worst case we look for it twice.
|
||
//
|
||
d = atr_pget(thing, what, &aowner, &aflags);
|
||
if ('\0' != d[0])
|
||
{
|
||
// No need for the 'def' message
|
||
//
|
||
found_a_desc = true;
|
||
if (!need_pres)
|
||
{
|
||
need_pres = true;
|
||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||
save_global_regs(preserve);
|
||
}
|
||
buff = bp = alloc_lbuf("did_it.1");
|
||
mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, thing, player,
|
||
AttrTrace(aflags, EV_EVAL|EV_FIGNORE|EV_TOP),
|
||
args, nargs);
|
||
*bp = '\0';
|
||
|
||
if ( A_HTDESC == what
|
||
&& Html(player))
|
||
{
|
||
safe_str(T("\r\n"), buff, &bp);
|
||
*bp = '\0';
|
||
notify_html(player, buff);
|
||
}
|
||
else
|
||
{
|
||
notify(player, buff);
|
||
}
|
||
free_lbuf(buff);
|
||
}
|
||
else if (def)
|
||
{
|
||
notify(player, def);
|
||
}
|
||
free_lbuf(d);
|
||
}
|
||
}
|
||
else if ( what < 0
|
||
&& def)
|
||
{
|
||
notify(player, def);
|
||
}
|
||
|
||
if (isPlayer(thing))
|
||
{
|
||
d = atr_pget(mudconf.master_room, get_atr(T("ASSET_DESC")), &aowner, &aflags);
|
||
if (*d)
|
||
{
|
||
if (!need_pres)
|
||
{
|
||
need_pres = true;
|
||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||
save_global_regs(preserve);
|
||
}
|
||
buff = bp = alloc_lbuf("did_it.1");
|
||
mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, thing, player,
|
||
AttrTrace(aflags, EV_EVAL|EV_FIGNORE|EV_TOP),
|
||
args, nargs);
|
||
*bp = '\0';
|
||
notify(player, buff);
|
||
free_lbuf(buff);
|
||
}
|
||
free_lbuf(d);
|
||
}
|
||
|
||
// Message to neighbors.
|
||
//
|
||
dbref loc;
|
||
if ( 0 < owhat
|
||
&& Has_location(player)
|
||
&& Good_obj(loc = Location(player)))
|
||
{
|
||
d = atr_pget(thing, owhat, &aowner, &aflags);
|
||
if (*d)
|
||
{
|
||
if (!need_pres)
|
||
{
|
||
need_pres = true;
|
||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||
save_global_regs(preserve);
|
||
}
|
||
buff = bp = alloc_lbuf("did_it.2");
|
||
mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, thing, player,
|
||
AttrTrace(aflags, EV_EVAL|EV_FIGNORE|EV_TOP),
|
||
args, nargs);
|
||
*bp = '\0';
|
||
|
||
if (*buff)
|
||
{
|
||
if (aflags & AF_NONAME)
|
||
{
|
||
notify_except2_rlevel2(loc, player, player, thing, buff);
|
||
}
|
||
else
|
||
{
|
||
notify_except2_rlevel2(loc, player, player, thing,
|
||
tprintf(T("%s %s"), Name(player), buff));
|
||
}
|
||
}
|
||
free_lbuf(buff);
|
||
}
|
||
else if (odef)
|
||
{
|
||
if (ctrl_flags & VERB_NONAME)
|
||
{
|
||
notify_except2_rlevel2(loc, player, player, thing, odef);
|
||
}
|
||
else
|
||
{
|
||
notify_except2_rlevel2(loc, player, player, thing,
|
||
tprintf(T("%s %s"), Name(player), odef));
|
||
}
|
||
}
|
||
free_lbuf(d);
|
||
}
|
||
else if ( owhat < 0
|
||
&& odef
|
||
&& Has_location(player)
|
||
&& Good_obj(loc = Location(player)))
|
||
{
|
||
if (ctrl_flags & VERB_NONAME)
|
||
{
|
||
notify_except2_rlevel2(loc, player, player, thing, odef);
|
||
}
|
||
else
|
||
{
|
||
notify_except2_rlevel2(loc, player, player, thing,
|
||
tprintf(T("%s %s"), Name(player), odef));
|
||
}
|
||
}
|
||
|
||
// If we preserved the state of the global registers, restore them.
|
||
//
|
||
if (need_pres)
|
||
{
|
||
restore_global_regs(preserve);
|
||
PopRegisters(preserve, MAX_GLOBAL_REGS);
|
||
}
|
||
|
||
// Do the action attribute.
|
||
//
|
||
if ( awhat > 0
|
||
&& IsReal(thing, player))
|
||
{
|
||
act = atr_pget(thing, awhat, &aowner, &aflags);
|
||
if (*act != '\0')
|
||
{
|
||
charges = atr_pget(thing, A_CHARGES, &aowner, &aflags);
|
||
if (*charges)
|
||
{
|
||
// int64_t, not int (#1402).
|
||
//
|
||
num = mux_atoi64(charges);
|
||
if (num > 0)
|
||
{
|
||
buff = alloc_sbuf("did_it.charges");
|
||
mux_i64toa(num - 1, buff);
|
||
atr_add_raw(thing, A_CHARGES, buff);
|
||
free_sbuf(buff);
|
||
}
|
||
else
|
||
{
|
||
buff = atr_pget(thing, A_RUNOUT, &aowner, &aflags);
|
||
if (*buff != '\0')
|
||
{
|
||
free_lbuf(act);
|
||
act = buff;
|
||
}
|
||
else
|
||
{
|
||
free_lbuf(act);
|
||
free_lbuf(buff);
|
||
free_lbuf(charges);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
free_lbuf(charges);
|
||
|
||
CLinearTimeAbsolute lta;
|
||
wait_que(thing, player, player, AttrTrace(aflags, 0), false, lta,
|
||
NOTHING, 0,
|
||
act,
|
||
nargs, args,
|
||
mudstate.global_regs);
|
||
}
|
||
free_lbuf(act);
|
||
}
|
||
}
|
||
#endif // REALITY_LVLS
|