2007-01-03 03:11:53 +00:00
|
|
|
|
/*! \file move.cpp
|
|
|
|
|
|
* \brief Routines for moving about.
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
|
|
|
|
|
#include "copyright.h"
|
|
|
|
|
|
#include "autoconf.h"
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
#include "externs.h"
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------
|
|
|
|
|
|
* process_leave_loc: Generate messages and actions resulting from leaving a
|
|
|
|
|
|
* place.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
static void process_leave_loc(dbref thing, dbref dest, dbref cause, bool canhear, int hush)
|
|
|
|
|
|
{
|
|
|
|
|
|
dbref loc = Location(thing);
|
|
|
|
|
|
if ((loc == NOTHING) || (loc == dest))
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (dest == HOME)
|
|
|
|
|
|
{
|
|
|
|
|
|
dest = Home(thing);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (Html(thing))
|
|
|
|
|
|
{
|
2007-03-14 22:33:04 +00:00
|
|
|
|
notify_html(thing, T("<xch_page clear=links>"));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Run the LEAVE attributes in the current room if we meet any of
|
|
|
|
|
|
// following criteria:
|
|
|
|
|
|
//
|
|
|
|
|
|
// - The current room has wizard privs.
|
|
|
|
|
|
// - Neither the current room nor the moving object are dark.
|
|
|
|
|
|
// - The moving object can hear and does not hav wizard privs.
|
|
|
|
|
|
//
|
|
|
|
|
|
// EXCEPT if we were called with the HUSH_LEAVE key.
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef REALITY_LVLS
|
|
|
|
|
|
bool quiet = ( (hush & HUSH_LEAVE) || !IsReal(loc, thing)
|
|
|
|
|
|
#else
|
|
|
|
|
|
bool quiet = ( (hush & HUSH_LEAVE)
|
2006-11-27 05:25:42 +00:00
|
|
|
|
#endif // REALITY_LVLS
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|| ( !Wizard(loc)
|
|
|
|
|
|
&& ( Dark(thing)
|
|
|
|
|
|
|| Dark(loc))
|
|
|
|
|
|
&& ( !canhear
|
2026-03-04 15:00:05 -07:00
|
|
|
|
|| ( Can_Dark(thing)
|
2006-09-01 22:59:23 +00:00
|
|
|
|
&& Dark(thing)))));
|
|
|
|
|
|
|
|
|
|
|
|
int oattr = quiet ? 0 : A_OLEAVE;
|
2026-03-03 20:55:31 -07:00
|
|
|
|
int aattr = A_ALEAVE;
|
2026-03-03 20:52:23 -07:00
|
|
|
|
int pattr = (quiet || (!mudconf.terse_movemsg && Terse(thing))) ? 0 : A_LEAVE;
|
2018-10-03 17:54:51 +00:00
|
|
|
|
did_it(thing, loc, pattr, nullptr, oattr, nullptr, aattr, 0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
|
|
|
|
|
// Do OXENTER for receiving room
|
|
|
|
|
|
//
|
|
|
|
|
|
if ((dest != NOTHING) && !quiet)
|
|
|
|
|
|
{
|
2018-10-03 17:54:51 +00:00
|
|
|
|
did_it(thing, dest, 0, nullptr, A_OXENTER, nullptr, 0, 0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Display the 'has left' message if we meet any of the following
|
|
|
|
|
|
// criteria:
|
|
|
|
|
|
//
|
|
|
|
|
|
// - Neither the current room nor the moving object are dark.
|
|
|
|
|
|
// - The object can hear and is not a dark wizard.
|
|
|
|
|
|
//
|
|
|
|
|
|
if ( !quiet
|
|
|
|
|
|
&& !Blind(thing)
|
|
|
|
|
|
&& !Blind(loc))
|
|
|
|
|
|
{
|
|
|
|
|
|
if ( ( !Dark(thing)
|
|
|
|
|
|
&& !Dark(loc))
|
|
|
|
|
|
|| ( canhear
|
2026-03-04 15:00:05 -07:00
|
|
|
|
&& !(Can_Dark(thing) && Dark(thing))))
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
#ifdef REALITY_LVLS
|
|
|
|
|
|
notify_except2_rlevel(loc, thing, thing, cause,
|
|
|
|
|
|
#else
|
|
|
|
|
|
notify_except2(loc, thing, thing, cause,
|
2006-11-27 05:25:42 +00:00
|
|
|
|
#endif // REALITY_LVLS
|
nls: mark move/walk/help/guest/quota/power notify prose with M_() (#1670)
Phase 3 coverage slice. Player and staff notify paths that still used
T() (cast-only) now use M_() so they extract into the catalogue:
move arrive/leave, get/drop, teleport failures, home
walk destination, blocked, patrol
help missing topic, match list, file errors
guest busy/create errors, listing total
quota Quota/Used display templates
powers Power not found, @power echo, Powers: header
session Poll / Doing
Attribute names, flag/power registry keys, logs, HTML, and softcode
machine tokens stay T()/S_(). Regenerates pot (670 -> 704) and xx.po.
2026-07-27 23:30:41 -06:00
|
|
|
|
tprintf(M_("%s has left."), Moniker(thing)));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
|
* process_enter_loc: Generate messages and actions resulting from entering
|
|
|
|
|
|
* a place.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
static void process_enter_loc(dbref thing, dbref src, dbref cause, bool canhear, int hush)
|
|
|
|
|
|
{
|
|
|
|
|
|
dbref loc = Location(thing);
|
|
|
|
|
|
if ( loc == NOTHING
|
|
|
|
|
|
|| loc == src)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
show_vrml_url(thing, loc);
|
|
|
|
|
|
|
|
|
|
|
|
// Run the ENTER attributes in the current room if we meet any of following
|
|
|
|
|
|
// criteria:
|
|
|
|
|
|
//
|
|
|
|
|
|
// - The current room has wizard privs.
|
|
|
|
|
|
// - Neither the current room nor the moving object are dark.
|
|
|
|
|
|
// - The moving object can hear and does not have wizard privs.
|
|
|
|
|
|
//
|
|
|
|
|
|
// EXCEPT if we were called with the HUSH_ENTER key.
|
|
|
|
|
|
//
|
|
|
|
|
|
#ifdef REALITY_LVLS
|
|
|
|
|
|
bool quiet = ( (hush & HUSH_ENTER) || !IsReal(loc, thing)
|
|
|
|
|
|
#else
|
|
|
|
|
|
bool quiet = ( (hush & HUSH_ENTER)
|
2006-11-27 05:25:42 +00:00
|
|
|
|
#endif // REALITY_LVLS
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|| ( !Wizard(loc)
|
|
|
|
|
|
&& ( Dark(thing)
|
|
|
|
|
|
|| Dark(loc))
|
|
|
|
|
|
&& ( !canhear
|
2026-03-04 15:00:05 -07:00
|
|
|
|
|| ( Can_Dark(thing)
|
2006-09-01 22:59:23 +00:00
|
|
|
|
&& Dark(thing)))));
|
|
|
|
|
|
|
|
|
|
|
|
int oattr = quiet ? 0 : A_OENTER;
|
2026-03-03 20:55:31 -07:00
|
|
|
|
int aattr = A_AENTER;
|
2026-03-03 20:52:23 -07:00
|
|
|
|
int pattr = (quiet || (!mudconf.terse_movemsg && Terse(thing))) ? 0 : A_ENTER;
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
2018-10-03 17:54:51 +00:00
|
|
|
|
did_it(thing, loc, pattr, nullptr, oattr, nullptr, aattr, 0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
|
|
|
|
|
// Do OXLEAVE for sending room.
|
|
|
|
|
|
//
|
|
|
|
|
|
if ( src != NOTHING
|
|
|
|
|
|
&& !quiet)
|
|
|
|
|
|
{
|
2018-10-03 17:54:51 +00:00
|
|
|
|
did_it(thing, src, 0, nullptr, A_OXLEAVE, nullptr, 0, 0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Display the 'has arrived' message if we meet all of the following
|
|
|
|
|
|
// criteria:
|
|
|
|
|
|
//
|
|
|
|
|
|
// - The moving object can hear.
|
|
|
|
|
|
// - The object is not a dark wizard.
|
|
|
|
|
|
//
|
|
|
|
|
|
if ( !quiet
|
|
|
|
|
|
&& canhear
|
|
|
|
|
|
&& !Blind(thing)
|
|
|
|
|
|
&& !Blind(loc)
|
2026-03-04 15:00:05 -07:00
|
|
|
|
&& !(Dark(thing) && Can_Dark(thing)))
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
#ifdef REALITY_LVLS
|
|
|
|
|
|
notify_except2_rlevel(loc, thing, thing, cause,
|
|
|
|
|
|
#else
|
|
|
|
|
|
notify_except2(loc, thing, thing, cause,
|
2006-11-27 05:25:42 +00:00
|
|
|
|
#endif // REALITY_LVLS
|
nls: mark move/walk/help/guest/quota/power notify prose with M_() (#1670)
Phase 3 coverage slice. Player and staff notify paths that still used
T() (cast-only) now use M_() so they extract into the catalogue:
move arrive/leave, get/drop, teleport failures, home
walk destination, blocked, patrol
help missing topic, match list, file errors
guest busy/create errors, listing total
quota Quota/Used display templates
powers Power not found, @power echo, Powers: header
session Poll / Doing
Attribute names, flag/power registry keys, logs, HTML, and softcode
machine tokens stay T()/S_(). Regenerates pot (670 -> 704) and xx.po.
2026-07-27 23:30:41 -06:00
|
|
|
|
tprintf(M_("%s has arrived."), Moniker(thing)));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------
|
|
|
|
|
|
* move_object: Physically move an object from one place to another.
|
|
|
|
|
|
* Does not generate any messages or actions.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
void move_object(dbref thing, dbref dest)
|
|
|
|
|
|
{
|
|
|
|
|
|
dbref src = Location(thing);
|
|
|
|
|
|
|
|
|
|
|
|
// Remove from the source location
|
|
|
|
|
|
//
|
|
|
|
|
|
if (src != NOTHING)
|
|
|
|
|
|
{
|
|
|
|
|
|
s_Contents(src, remove_first(Contents(src), thing));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Special check for HOME
|
|
|
|
|
|
//
|
|
|
|
|
|
if (dest == HOME)
|
|
|
|
|
|
{
|
|
|
|
|
|
dest = Home(thing);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Add to destination location
|
|
|
|
|
|
//
|
|
|
|
|
|
if (dest != NOTHING)
|
|
|
|
|
|
{
|
|
|
|
|
|
s_Contents(dest, insert_first(Contents(dest), thing));
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
s_Next(thing, NOTHING);
|
|
|
|
|
|
}
|
|
|
|
|
|
s_Location(thing, dest);
|
|
|
|
|
|
|
2026-04-03 19:51:01 -06:00
|
|
|
|
// Preload the destination synchronously so look_in() doesn't pay
|
|
|
|
|
|
// cold misses, then defer BFS neighbors for later.
|
2026-03-05 08:34:03 -07:00
|
|
|
|
//
|
|
|
|
|
|
if (Good_obj(dest))
|
|
|
|
|
|
{
|
2026-04-03 19:51:01 -06:00
|
|
|
|
bool bUnlimited = (mudconf.max_cache_size < 0);
|
|
|
|
|
|
cache_preload_obj(dest, bUnlimited);
|
|
|
|
|
|
if (bUnlimited && mudconf.cache_preload_depth > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
cache_preload_deferred_bfs(dest, mudconf.cache_preload_depth);
|
|
|
|
|
|
}
|
2026-03-05 08:34:03 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2006-09-01 22:59:23 +00:00
|
|
|
|
// Look around and do the penny check
|
|
|
|
|
|
//
|
|
|
|
|
|
look_in(thing, dest, (LK_SHOWEXIT | LK_OBEYTERSE));
|
|
|
|
|
|
if ( isPlayer(thing)
|
|
|
|
|
|
&& mudconf.payfind > 0
|
|
|
|
|
|
&& Pennies(thing) < mudconf.paylimit
|
|
|
|
|
|
&& !Controls(thing, dest)
|
|
|
|
|
|
&& RandomINT32(0, mudconf.payfind-1) == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
giveto(thing, 1);
|
nls: mark move/walk/help/guest/quota/power notify prose with M_() (#1670)
Phase 3 coverage slice. Player and staff notify paths that still used
T() (cast-only) now use M_() so they extract into the catalogue:
move arrive/leave, get/drop, teleport failures, home
walk destination, blocked, patrol
help missing topic, match list, file errors
guest busy/create errors, listing total
quota Quota/Used display templates
powers Power not found, @power echo, Powers: header
session Poll / Doing
Attribute names, flag/power registry keys, logs, HTML, and softcode
machine tokens stay T()/S_(). Regenerates pot (670 -> 704) and xx.po.
2026-07-27 23:30:41 -06:00
|
|
|
|
notify(thing, tprintf(M_("You found a %s!"), mudconf.one_coin));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// move_the_exit: Move an exit silently from its location to its destination
|
|
|
|
|
|
//
|
|
|
|
|
|
static void move_the_exit(dbref thing, dbref dest)
|
|
|
|
|
|
{
|
|
|
|
|
|
dbref exitloc = Exits(thing);
|
|
|
|
|
|
s_Exits(exitloc, remove_first(Exits(exitloc), thing));
|
|
|
|
|
|
s_Exits(dest, insert_first(Exits(dest), thing));
|
|
|
|
|
|
s_Exits(thing, dest);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------
|
|
|
|
|
|
* send_dropto, process_sticky_dropto, process_dropped_dropto,
|
|
|
|
|
|
* process_sacrifice_dropto: Check for and process droptos.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
// send_dropto: Send an object through the dropto of a room
|
|
|
|
|
|
//
|
|
|
|
|
|
static void send_dropto(dbref thing, dbref player)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!Sticky(thing))
|
|
|
|
|
|
{
|
|
|
|
|
|
move_via_generic(thing, Dropto(Location(thing)), player, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
move_via_generic(thing, HOME, player, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
divest_object(thing);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// process_sticky_dropto: Call when an object leaves the room to see if
|
|
|
|
|
|
// we should empty the room
|
|
|
|
|
|
//
|
|
|
|
|
|
static void process_sticky_dropto(dbref loc, dbref player)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Do nothing if checking anything but a sticky room
|
|
|
|
|
|
//
|
2008-05-31 17:23:15 +00:00
|
|
|
|
if ( !Good_obj(loc)
|
|
|
|
|
|
|| !Has_dropto(loc)
|
|
|
|
|
|
|| !Sticky(loc))
|
|
|
|
|
|
{
|
2006-09-01 22:59:23 +00:00
|
|
|
|
return;
|
2008-05-31 17:23:15 +00:00
|
|
|
|
}
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
|
|
|
|
|
// Make sure dropto loc is valid
|
|
|
|
|
|
//
|
2008-05-31 17:23:15 +00:00
|
|
|
|
dbref dropto = Dropto(loc);
|
|
|
|
|
|
if ( NOTHING == dropto
|
|
|
|
|
|
|| dropto == loc)
|
|
|
|
|
|
{
|
2006-09-01 22:59:23 +00:00
|
|
|
|
return;
|
2008-05-31 17:23:15 +00:00
|
|
|
|
}
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
|
|
|
|
|
// Make sure no players hanging out
|
|
|
|
|
|
//
|
2008-05-31 17:23:15 +00:00
|
|
|
|
dbref thing;
|
2006-09-01 22:59:23 +00:00
|
|
|
|
DOLIST(thing, Contents(loc))
|
|
|
|
|
|
{
|
2008-05-31 17:23:15 +00:00
|
|
|
|
if ( Connected(Owner(thing))
|
|
|
|
|
|
&& Hearer(thing))
|
|
|
|
|
|
{
|
2006-09-01 22:59:23 +00:00
|
|
|
|
return;
|
2008-05-31 17:23:15 +00:00
|
|
|
|
}
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Send everything through the dropto
|
|
|
|
|
|
//
|
2008-05-31 17:23:15 +00:00
|
|
|
|
dbref next;
|
2006-09-01 22:59:23 +00:00
|
|
|
|
s_Contents(loc, reverse_list(Contents(loc)));
|
|
|
|
|
|
SAFE_DOLIST(thing, next, Contents(loc))
|
|
|
|
|
|
{
|
|
|
|
|
|
send_dropto(thing, player);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// process_dropped_dropto: Check what to do when someone drops an object.
|
|
|
|
|
|
//
|
|
|
|
|
|
static void process_dropped_dropto(dbref thing, dbref player)
|
|
|
|
|
|
{
|
|
|
|
|
|
// If STICKY, send home
|
|
|
|
|
|
//
|
|
|
|
|
|
if (Sticky(thing))
|
|
|
|
|
|
{
|
|
|
|
|
|
move_via_generic(thing, HOME, player, 0);
|
|
|
|
|
|
divest_object(thing);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Process the dropto if location is a room and is not STICKY
|
|
|
|
|
|
//
|
|
|
|
|
|
dbref loc = Location(thing);
|
|
|
|
|
|
if (Has_dropto(loc) && (Dropto(loc) != NOTHING) && !Sticky(loc))
|
|
|
|
|
|
send_dropto(thing, player);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------
|
|
|
|
|
|
* move_via_generic: Generic move routine, generates standard messages and
|
|
|
|
|
|
* actions.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
void move_via_generic(dbref thing, dbref dest, dbref cause, int hush)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (dest == HOME)
|
|
|
|
|
|
{
|
|
|
|
|
|
dest = Home(thing);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
dbref src = Location(thing);
|
|
|
|
|
|
bool canhear = Hearer(thing);
|
|
|
|
|
|
process_leave_loc(thing, dest, cause, canhear, hush);
|
|
|
|
|
|
move_object(thing, dest);
|
2018-10-03 17:54:51 +00:00
|
|
|
|
did_it(thing, thing, A_MOVE, nullptr, A_OMOVE, nullptr, A_AMOVE, 0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
process_enter_loc(thing, src, cause, canhear, hush);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------
|
|
|
|
|
|
* move_via_exit: Exit move routine, generic + exit messages + dropto check.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
static void move_via_exit(dbref thing, dbref dest, dbref cause, dbref exit, int hush)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (dest == HOME)
|
|
|
|
|
|
{
|
|
|
|
|
|
dest = Home(thing);
|
|
|
|
|
|
}
|
|
|
|
|
|
dbref src = Location(thing);
|
|
|
|
|
|
bool canhear = Hearer(thing);
|
|
|
|
|
|
|
|
|
|
|
|
// Dark wizards don't trigger OSUCC/ASUCC
|
2026-03-04 15:00:05 -07:00
|
|
|
|
bool quiet = ( (Can_Dark(thing) && Dark(thing))
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|| (hush & HUSH_EXIT));
|
|
|
|
|
|
int aattr = quiet ? 0 : A_ASUCC;
|
|
|
|
|
|
|
|
|
|
|
|
int oattr = quiet ? 0 : A_OSUCC;
|
|
|
|
|
|
int pattr = (!mudconf.terse_movemsg && Terse(thing)) ? 0 : A_SUCC;
|
2018-10-03 17:54:51 +00:00
|
|
|
|
did_it(thing, exit, pattr, nullptr, oattr, nullptr, aattr, 0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
process_leave_loc(thing, dest, cause, canhear, hush);
|
|
|
|
|
|
move_object(thing, dest);
|
|
|
|
|
|
|
|
|
|
|
|
aattr = quiet ? 0 : A_ADROP;
|
|
|
|
|
|
|
|
|
|
|
|
oattr = quiet ? 0 : A_ODROP;
|
|
|
|
|
|
pattr = (!mudconf.terse_movemsg && Terse(thing)) ? 0 : A_DROP;
|
2018-10-03 17:54:51 +00:00
|
|
|
|
did_it(thing, exit, pattr, nullptr, oattr, nullptr, aattr, 0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
2018-10-03 17:54:51 +00:00
|
|
|
|
did_it(thing, thing, A_MOVE, nullptr, A_OMOVE, nullptr, A_AMOVE, 0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
|
|
|
|
|
process_enter_loc(thing, src, cause, canhear, hush);
|
|
|
|
|
|
process_sticky_dropto(src, thing);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------
|
|
|
|
|
|
* move_via_teleport: Teleport move routine, generic + teleport messages +
|
|
|
|
|
|
* divestiture + dropto check.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
bool move_via_teleport(dbref thing, dbref dest, dbref cause, int hush)
|
|
|
|
|
|
{
|
|
|
|
|
|
dbref curr;
|
|
|
|
|
|
int count;
|
2007-03-14 22:33:04 +00:00
|
|
|
|
const UTF8 *failmsg;
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
|
|
|
|
|
dbref src = Location(thing);
|
2008-05-31 17:23:15 +00:00
|
|
|
|
if ( HOME != dest
|
|
|
|
|
|
&& Good_obj(src))
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
curr = src;
|
|
|
|
|
|
for (count = mudconf.ntfy_nest_lim; count > 0; count--)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!could_doit(thing, curr, A_LTELOUT))
|
|
|
|
|
|
{
|
2008-05-31 17:23:15 +00:00
|
|
|
|
if ( thing == cause
|
|
|
|
|
|
|| NOTHING == cause)
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
nls: mark move/walk/help/guest/quota/power notify prose with M_() (#1670)
Phase 3 coverage slice. Player and staff notify paths that still used
T() (cast-only) now use M_() so they extract into the catalogue:
move arrive/leave, get/drop, teleport failures, home
walk destination, blocked, patrol
help missing topic, match list, file errors
guest busy/create errors, listing total
quota Quota/Used display templates
powers Power not found, @power echo, Powers: header
session Poll / Doing
Attribute names, flag/power registry keys, logs, HTML, and softcode
machine tokens stay T()/S_(). Regenerates pot (670 -> 704) and xx.po.
2026-07-27 23:30:41 -06:00
|
|
|
|
failmsg = M_("You can’t teleport out!");
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
nls: mark move/walk/help/guest/quota/power notify prose with M_() (#1670)
Phase 3 coverage slice. Player and staff notify paths that still used
T() (cast-only) now use M_() so they extract into the catalogue:
move arrive/leave, get/drop, teleport failures, home
walk destination, blocked, patrol
help missing topic, match list, file errors
guest busy/create errors, listing total
quota Quota/Used display templates
powers Power not found, @power echo, Powers: header
session Poll / Doing
Attribute names, flag/power registry keys, logs, HTML, and softcode
machine tokens stay T()/S_(). Regenerates pot (670 -> 704) and xx.po.
2026-07-27 23:30:41 -06:00
|
|
|
|
failmsg = M_("You can’t be teleported out!");
|
2026-07-26 21:52:48 -06:00
|
|
|
|
notify_quiet(cause, M_("You can’t teleport that out!"));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
2008-05-31 17:23:15 +00:00
|
|
|
|
|
2006-09-01 22:59:23 +00:00
|
|
|
|
did_it(thing, src,
|
2018-10-03 17:54:51 +00:00
|
|
|
|
A_TOFAIL, failmsg, A_OTOFAIL, nullptr,
|
|
|
|
|
|
A_ATOFAIL, 0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2008-05-31 17:23:15 +00:00
|
|
|
|
|
2006-09-01 22:59:23 +00:00
|
|
|
|
if (isRoom(curr))
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
curr = Location(curr);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (isExit(thing))
|
|
|
|
|
|
{
|
|
|
|
|
|
move_the_exit(thing, dest);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2008-05-31 17:23:15 +00:00
|
|
|
|
|
2006-09-01 22:59:23 +00:00
|
|
|
|
if (dest == HOME)
|
|
|
|
|
|
{
|
|
|
|
|
|
dest = Home(thing);
|
|
|
|
|
|
}
|
2008-05-31 17:23:15 +00:00
|
|
|
|
|
2006-09-01 22:59:23 +00:00
|
|
|
|
bool canhear = Hearer(thing);
|
|
|
|
|
|
if (!(hush & HUSH_LEAVE))
|
|
|
|
|
|
{
|
2018-10-03 17:54:51 +00:00
|
|
|
|
did_it(thing, thing, 0, nullptr, A_OXTPORT, nullptr, 0,
|
|
|
|
|
|
0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
process_leave_loc(thing, dest, NOTHING, canhear, hush);
|
|
|
|
|
|
|
|
|
|
|
|
move_object(thing, dest);
|
|
|
|
|
|
|
|
|
|
|
|
if (!(hush & HUSH_ENTER))
|
|
|
|
|
|
{
|
2018-10-03 17:54:51 +00:00
|
|
|
|
did_it(thing, thing, A_TPORT, nullptr, A_OTPORT, nullptr, A_ATPORT,
|
|
|
|
|
|
0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
2018-10-03 17:54:51 +00:00
|
|
|
|
did_it(thing, thing, A_MOVE, nullptr, A_OMOVE, nullptr, A_AMOVE,
|
|
|
|
|
|
0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
|
|
|
|
|
process_enter_loc(thing, src, NOTHING, canhear, hush);
|
|
|
|
|
|
divest_object(thing);
|
|
|
|
|
|
process_sticky_dropto(src, thing);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------
|
|
|
|
|
|
* move_exit: Try to move a player through an exit.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
static dbref get_exit_dest(dbref executor, dbref exit)
|
|
|
|
|
|
{
|
|
|
|
|
|
dbref aowner;
|
|
|
|
|
|
int aflags;
|
2007-03-14 00:55:08 +00:00
|
|
|
|
UTF8 *atr_gotten = atr_pget(exit, A_EXITVARDEST, &aowner, &aflags);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
Migrate 22 alloc_lbuf/free_lbuf sites to LBuf RAII
Replace manual alloc_lbuf/free_lbuf pairs with LBuf RAII wrappers
in 12 engine source files: rob, walk, quota, wiz, session, object,
log, match, move, create, flags, boolexp. This eliminates ~40
explicit free_lbuf calls on error paths that are now handled by
destructors, removing leak risk in early-return and multi-exit
functions (boolexp alone had 13 exit-path frees across two
functions). Buffers returned by atr_get/atr_pget or to callers
are left manual since LBuf cannot adopt externally-allocated
buffers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 17:46:22 -06:00
|
|
|
|
LBuf result = LBuf_Src("get_exit_dest");
|
|
|
|
|
|
UTF8 *ref = result.get();
|
2026-03-07 19:57:24 -07:00
|
|
|
|
mux_exec(atr_gotten, LBUF_SIZE-1, result, &ref, exit, executor, executor,
|
2018-10-03 17:54:51 +00:00
|
|
|
|
AttrTrace(aflags, EV_TOP|EV_FCHECK|EV_EVAL), nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
free_lbuf(atr_gotten);
|
2007-04-14 04:26:38 +00:00
|
|
|
|
*ref = '\0';
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
|
|
|
|
|
dbref dest = NOTHING;
|
|
|
|
|
|
if (*result == NUMBER_TOKEN)
|
|
|
|
|
|
{
|
fix(win32): migrate the remaining mux_atol callers to mux_atoi64 (#1373)
Completes the sweep the issue called for. mux_atol returns long, which
is 32-bit on LLP64, so every caller silently truncated on Windows. Two
of those were real defects (the truthiness family and cf_size, fixed in
the preceding commits); the rest were latent, waiting for a value large
enough to matter.
Rather than audit 290 sites for whether each can reach 2^31 today, use
the 64-bit parser everywhere and remove the class. A dbref cannot
overflow now, but nothing stops a later caller passing that same site a
timestamp or a byte count.
Pure 1:1 substitution: 285 lines changed, and every removed line
contained mux_atol while every added line contains mux_atoi64. No
control flow, no types, no behaviour beyond the wider parse.
This is a NO-OP on LP64 -- long is already 64-bit on Linux and macOS, so
the generated code there is unchanged. It only widens the parse on
Windows. Narrowing destinations are unaffected either way: `int x =
mux_atoi64(s)` truncates exactly as `int x = mux_atol(s)` did, on both
models.
Left alone: mux_atol itself in mathutil, its declaration, and three
comments that name it. Callers that genuinely want 32-bit semantics can
still ask for them; none appear to.
Verified on Windows: full solution builds clean with no new warnings,
smoke is 1418 passed / 16 failed / 0 crashes / 306 of 306 dispatched --
identical to before the sweep, with the same 16 build-configuration
failures (exp3 module not loaded, hmac/digest behind UNIX_DIGEST).
Spot checks after the change: the boolean family returns 1 for multiples
of 2^32, cf_size round-trips 3000000000 and still reads -1 as unlimited,
and arithmetic, string and list functions are unchanged.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 10:03:45 -06:00
|
|
|
|
dest = mux_atoi64(result + 1);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return dest;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2007-03-14 00:55:08 +00:00
|
|
|
|
void move_exit(dbref player, dbref exit, bool divest, const UTF8 *failmsg, int hush)
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
int oattr, aattr;
|
|
|
|
|
|
bool bDoit = false;
|
|
|
|
|
|
|
|
|
|
|
|
dbref loc = Location(exit);
|
2018-10-03 17:54:51 +00:00
|
|
|
|
if (atr_get_raw(exit, A_EXITVARDEST) != nullptr)
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
loc = get_exit_dest(player, exit);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (loc == HOME)
|
|
|
|
|
|
{
|
|
|
|
|
|
loc = Home(player);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef WOD_REALMS
|
|
|
|
|
|
if (Good_obj(loc) && (REALM_DO_HIDDEN_FROM_YOU != DoThingToThingVisibility(player, exit, ACTION_IS_MOVING)))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isShroud(player))
|
|
|
|
|
|
{
|
|
|
|
|
|
bDoit = true;
|
2007-03-14 22:33:04 +00:00
|
|
|
|
int iShroudWarded = get_atr(T("SHROUD_WARDED"));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
if (iShroudWarded > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
int owner, flags;
|
2007-03-14 00:55:08 +00:00
|
|
|
|
UTF8 *buff = atr_pget(exit, iShroudWarded, &owner, &flags);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
if (buff)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (*buff)
|
|
|
|
|
|
{
|
|
|
|
|
|
bDoit = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
free_lbuf(buff);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!bDoit && isUmbra(player))
|
|
|
|
|
|
{
|
|
|
|
|
|
bDoit = true;
|
2007-03-14 22:33:04 +00:00
|
|
|
|
int iUmbraWarded = get_atr(T("UMBRA_WARDED"));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
if (iUmbraWarded > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
int owner, flags;
|
2007-03-14 00:55:08 +00:00
|
|
|
|
UTF8 *buff = atr_pget(exit, iUmbraWarded, &owner, &flags);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
if (buff)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (*buff)
|
|
|
|
|
|
{
|
|
|
|
|
|
bDoit = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
free_lbuf(buff);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!bDoit && could_doit(player, exit, A_LOCK))
|
|
|
|
|
|
{
|
|
|
|
|
|
bDoit = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-03-03 21:08:57 -07:00
|
|
|
|
#else
|
|
|
|
|
|
#ifdef REALITY_LVLS
|
|
|
|
|
|
if (Good_obj(loc) && IsReal(exit, player) && could_doit(player, exit, A_LOCK))
|
2006-09-01 22:59:23 +00:00
|
|
|
|
#else
|
|
|
|
|
|
if (Good_obj(loc) && could_doit(player, exit, A_LOCK))
|
2026-03-03 21:08:57 -07:00
|
|
|
|
#endif
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
bDoit = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if (bDoit)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (Typeof(loc))
|
|
|
|
|
|
{
|
|
|
|
|
|
case TYPE_ROOM:
|
|
|
|
|
|
move_via_exit(player, loc, NOTHING, exit, hush);
|
|
|
|
|
|
if (divest)
|
|
|
|
|
|
divest_object(player);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case TYPE_PLAYER:
|
|
|
|
|
|
case TYPE_THING:
|
|
|
|
|
|
if (Going(loc))
|
|
|
|
|
|
{
|
2026-07-26 21:52:48 -06:00
|
|
|
|
notify(player, M_("You can’t go that way."));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
move_via_exit(player, loc, NOTHING, exit, hush);
|
|
|
|
|
|
divest_object(player);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case TYPE_EXIT:
|
2026-07-26 21:52:48 -06:00
|
|
|
|
notify(player, M_("You can’t go that way."));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2026-03-04 15:00:05 -07:00
|
|
|
|
if ((Can_Dark(player) && Dark(player)) || (hush & HUSH_EXIT))
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
oattr = 0;
|
|
|
|
|
|
aattr = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
oattr = A_OFAIL;
|
|
|
|
|
|
aattr = A_AFAIL;
|
|
|
|
|
|
}
|
2018-10-03 17:54:51 +00:00
|
|
|
|
did_it(player, exit, A_FAIL, failmsg, oattr, nullptr, aattr, 0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------
|
|
|
|
|
|
* do_move: Move from one place to another via exits or 'home'.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2007-09-02 13:48:10 -07:00
|
|
|
|
void do_move(dbref executor, dbref caller, dbref enactor, int eval, int key, UTF8 *direction, const UTF8 *cargs[], int ncargs)
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
UNUSED_PARAMETER(caller);
|
|
|
|
|
|
UNUSED_PARAMETER(enactor);
|
2006-09-06 06:17:46 +00:00
|
|
|
|
UNUSED_PARAMETER(eval);
|
2007-09-02 13:48:10 -07:00
|
|
|
|
UNUSED_PARAMETER(cargs);
|
|
|
|
|
|
UNUSED_PARAMETER(ncargs);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
2007-03-14 22:33:04 +00:00
|
|
|
|
if (!string_compare(direction, T("home")))
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
2023-08-22 02:56:35 -06:00
|
|
|
|
dbref loc = Location(executor);
|
|
|
|
|
|
dbref dest = Home(executor);
|
|
|
|
|
|
if ( NOTHING != loc
|
|
|
|
|
|
&& NOTHING != dest
|
|
|
|
|
|
&& loc == dest)
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
2026-07-27 01:58:14 +00:00
|
|
|
|
notify(executor, M_("You are already home."));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
2023-08-22 02:56:35 -06:00
|
|
|
|
else
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
2023-08-22 02:56:35 -06:00
|
|
|
|
// Go home w/o stuff.
|
2006-09-01 22:59:23 +00:00
|
|
|
|
//
|
2023-08-22 02:56:35 -06:00
|
|
|
|
if ( ( Fixed(executor)
|
|
|
|
|
|
|| Fixed(Owner(executor)))
|
|
|
|
|
|
&& !(WizRoy(executor)))
|
|
|
|
|
|
{
|
|
|
|
|
|
notify(executor, mudconf.fixed_home_msg);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2007-03-14 00:55:08 +00:00
|
|
|
|
|
2023-08-22 02:56:35 -06:00
|
|
|
|
if ( NOTHING != loc
|
|
|
|
|
|
&& !Blind(executor)
|
|
|
|
|
|
&& !Blind(loc)
|
|
|
|
|
|
&& !Dark(executor)
|
|
|
|
|
|
&& !Dark(loc))
|
|
|
|
|
|
{
|
|
|
|
|
|
// Tell all
|
|
|
|
|
|
//
|
nls: mark move/walk/help/guest/quota/power notify prose with M_() (#1670)
Phase 3 coverage slice. Player and staff notify paths that still used
T() (cast-only) now use M_() so they extract into the catalogue:
move arrive/leave, get/drop, teleport failures, home
walk destination, blocked, patrol
help missing topic, match list, file errors
guest busy/create errors, listing total
quota Quota/Used display templates
powers Power not found, @power echo, Powers: header
session Poll / Doing
Attribute names, flag/power registry keys, logs, HTML, and softcode
machine tokens stay T()/S_(). Regenerates pot (670 -> 704) and xx.po.
2026-07-27 23:30:41 -06:00
|
|
|
|
notify_except(loc, executor, executor, tprintf(M_("%s goes home."), Moniker(executor)), 0);
|
2023-08-22 02:56:35 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Give the player the messages
|
|
|
|
|
|
//
|
|
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
|
|
{
|
2026-07-26 21:52:48 -06:00
|
|
|
|
notify(executor, M_("There’s no place like home..."));
|
2023-08-22 02:56:35 -06:00
|
|
|
|
}
|
|
|
|
|
|
move_via_generic(executor, HOME, NOTHING, 0);
|
|
|
|
|
|
divest_object(executor);
|
|
|
|
|
|
process_sticky_dropto(loc, executor);
|
2007-03-14 00:55:08 +00:00
|
|
|
|
}
|
2006-09-01 22:59:23 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Find the exit.
|
|
|
|
|
|
//
|
|
|
|
|
|
init_match_check_keys(executor, direction, TYPE_EXIT);
|
|
|
|
|
|
match_exit();
|
|
|
|
|
|
|
2023-08-22 02:56:35 -06:00
|
|
|
|
int quiet;
|
|
|
|
|
|
dbref exit = match_result();
|
2006-09-01 22:59:23 +00:00
|
|
|
|
switch (exit)
|
|
|
|
|
|
{
|
|
|
|
|
|
case NOTHING: // Try to force the object
|
2026-07-26 21:52:48 -06:00
|
|
|
|
notify(executor, M_("You can’t go that way."));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case AMBIGUOUS:
|
2026-07-26 21:52:48 -06:00
|
|
|
|
notify(executor, M_("I don’t know which way you mean!"));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
quiet = 0;
|
|
|
|
|
|
if ((key & MOVE_QUIET) && Controls(executor, exit))
|
|
|
|
|
|
quiet = HUSH_EXIT;
|
2026-07-26 21:52:48 -06:00
|
|
|
|
move_exit(executor, exit, false, M_("You can’t go that way."), quiet);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------
|
|
|
|
|
|
* do_get: Get an object.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2007-09-02 13:48:10 -07:00
|
|
|
|
void do_get(dbref executor, dbref caller, dbref enactor, int eval, int key, UTF8 *what, const UTF8 *cargs[], int ncargs)
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
UNUSED_PARAMETER(caller);
|
|
|
|
|
|
UNUSED_PARAMETER(enactor);
|
2006-09-06 06:17:46 +00:00
|
|
|
|
UNUSED_PARAMETER(eval);
|
2007-09-02 13:48:10 -07:00
|
|
|
|
UNUSED_PARAMETER(cargs);
|
|
|
|
|
|
UNUSED_PARAMETER(ncargs);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
|
|
|
|
|
dbref playerloc;
|
|
|
|
|
|
if ( !Has_location(executor)
|
|
|
|
|
|
|| !Good_obj(playerloc = Location(executor)))
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// You can only pick up things in rooms and ENTER_OK objects/players.
|
|
|
|
|
|
//
|
|
|
|
|
|
if ( !isRoom(playerloc)
|
|
|
|
|
|
&& !Enter_ok(playerloc)
|
|
|
|
|
|
&& !Controls(executor, playerloc))
|
|
|
|
|
|
{
|
|
|
|
|
|
notify(executor, NOPERM_MESSAGE);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Look for the thing locally.
|
|
|
|
|
|
//
|
|
|
|
|
|
init_match_check_keys(executor, what, TYPE_THING);
|
|
|
|
|
|
match_neighbor();
|
|
|
|
|
|
match_exit();
|
|
|
|
|
|
if (Long_Fingers(executor))
|
|
|
|
|
|
{
|
|
|
|
|
|
match_absolute();
|
|
|
|
|
|
}
|
|
|
|
|
|
dbref thing = match_result();
|
|
|
|
|
|
|
|
|
|
|
|
// Look for the thing in other people's inventories.
|
|
|
|
|
|
//
|
|
|
|
|
|
if (!Good_obj(thing))
|
|
|
|
|
|
{
|
|
|
|
|
|
thing = match_status(executor, match_possessed(executor, executor, what,
|
|
|
|
|
|
thing, true));
|
|
|
|
|
|
|
|
|
|
|
|
if (!Good_obj(thing))
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If we found it, check to see if we can get it.
|
|
|
|
|
|
//
|
|
|
|
|
|
dbref thingloc = Location(thing);
|
|
|
|
|
|
if (Good_obj(thingloc))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!could_doit(executor, thingloc, A_LGET))
|
|
|
|
|
|
{
|
|
|
|
|
|
notify(executor, NOPERM_MESSAGE);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If we can get it, get it.
|
|
|
|
|
|
//
|
2007-03-14 00:55:08 +00:00
|
|
|
|
const UTF8 *failmsg;
|
2006-09-01 22:59:23 +00:00
|
|
|
|
int oattr, aattr;
|
|
|
|
|
|
bool quiet = false;
|
|
|
|
|
|
switch (Typeof(thing))
|
|
|
|
|
|
{
|
|
|
|
|
|
case TYPE_PLAYER:
|
|
|
|
|
|
case TYPE_THING:
|
|
|
|
|
|
|
|
|
|
|
|
// You can't take what you already have.
|
|
|
|
|
|
//
|
|
|
|
|
|
if (thingloc == executor)
|
|
|
|
|
|
{
|
2026-07-27 01:58:14 +00:00
|
|
|
|
notify(executor, M_("You already have that!"));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ( (key & GET_QUIET)
|
|
|
|
|
|
&& Controls(executor, thing))
|
|
|
|
|
|
{
|
|
|
|
|
|
quiet = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (thing == executor)
|
|
|
|
|
|
{
|
2026-07-27 01:58:14 +00:00
|
|
|
|
notify(executor, M_("You cannot get yourself!"));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
else if (could_doit(executor, thing, A_LOCK))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (thingloc != playerloc)
|
|
|
|
|
|
{
|
nls: mark move/walk/help/guest/quota/power notify prose with M_() (#1670)
Phase 3 coverage slice. Player and staff notify paths that still used
T() (cast-only) now use M_() so they extract into the catalogue:
move arrive/leave, get/drop, teleport failures, home
walk destination, blocked, patrol
help missing topic, match list, file errors
guest busy/create errors, listing total
quota Quota/Used display templates
powers Power not found, @power echo, Powers: header
session Poll / Doing
Attribute names, flag/power registry keys, logs, HTML, and softcode
machine tokens stay T()/S_(). Regenerates pot (670 -> 704) and xx.po.
2026-07-27 23:30:41 -06:00
|
|
|
|
notify(thingloc, tprintf(M_("%s was taken from you."),
|
2006-09-01 22:59:23 +00:00
|
|
|
|
Moniker(thing)));
|
|
|
|
|
|
}
|
|
|
|
|
|
move_via_generic(thing, executor, executor, 0);
|
2026-07-27 01:58:14 +00:00
|
|
|
|
notify(thing, M_("Taken."));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
oattr = quiet ? 0 : A_OSUCC;
|
|
|
|
|
|
aattr = quiet ? 0 : A_ASUCC;
|
nls: finish the five half-marked strings in move.cpp (#1419)
Five literals were marked M_() at one site and left T() at another, so the
same message was translatable in one context and not the other:
Dropped. Taken. You can't drop that.
You can't go that way. You can't leave.
rob.cpp had none of this; move.cpp had all five.
Taken. shows why it matters. The marked copy went to the OBJECT, while the
copy the PLAYER reads was still T():
notify(thing, M_("Taken.")); // to the thing
did_it(executor, thing, A_SUCC, T("Taken."), ...); // `def` -> the player
did_it's fourth argument is the default shown to the player when the object
has no @success, so with "Taken." in a catalog, mux_gettext returned the
translation while `take widget` printed English.
Half-marked is worse than unmarked. Unmarked is honestly untranslated;
half-marked means a translator translates the string and then sees it appear
in their language in one context and English in another, with nothing in the
catalog to distinguish them.
The five promoted sites are all player-facing defaults:
674 move_exit(..., "You can't go that way.")
781 did_it(..., A_SUCC, "Taken.")
888 did_it(..., A_DFAIL, "You can't drop that.")
911 did_it(..., A_DROP, "Dropped.")
1057 did_it(..., A_LFAIL, "You can't leave.")
The msgid set is unchanged -- these are the same strings already in the
catalog -- so only the reference comments in tinymux.pot move. Verified by
diffing the sorted msgid lists before and after: identical.
Verified with a catalog carrying the two confirmations plus an identifier and
an ABI token:
before take widget -> Taken. (untranslated)
after take widget -> [xx] Taken.
drop widget -> [xx] Dropped.
ABI=#-1 DIVIDE BY ZERO (intact)
FN=5 (abs() still resolves)
English smoke on the NLS build: 1505 passed, 0 failed, 316/316.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 20:25:28 -06:00
|
|
|
|
did_it(executor, thing, A_SUCC, M_("Taken."), oattr, nullptr,
|
2018-10-03 17:54:51 +00:00
|
|
|
|
aattr, 0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
oattr = quiet ? 0 : A_OFAIL;
|
|
|
|
|
|
aattr = quiet ? 0 : A_AFAIL;
|
|
|
|
|
|
if (thingloc != playerloc)
|
|
|
|
|
|
{
|
nls: mark move/walk/help/guest/quota/power notify prose with M_() (#1670)
Phase 3 coverage slice. Player and staff notify paths that still used
T() (cast-only) now use M_() so they extract into the catalogue:
move arrive/leave, get/drop, teleport failures, home
walk destination, blocked, patrol
help missing topic, match list, file errors
guest busy/create errors, listing total
quota Quota/Used display templates
powers Power not found, @power echo, Powers: header
session Poll / Doing
Attribute names, flag/power registry keys, logs, HTML, and softcode
machine tokens stay T()/S_(). Regenerates pot (670 -> 704) and xx.po.
2026-07-27 23:30:41 -06:00
|
|
|
|
failmsg = M_("You can’t take that from there.");
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
nls: mark move/walk/help/guest/quota/power notify prose with M_() (#1670)
Phase 3 coverage slice. Player and staff notify paths that still used
T() (cast-only) now use M_() so they extract into the catalogue:
move arrive/leave, get/drop, teleport failures, home
walk destination, blocked, patrol
help missing topic, match list, file errors
guest busy/create errors, listing total
quota Quota/Used display templates
powers Power not found, @power echo, Powers: header
session Poll / Doing
Attribute names, flag/power registry keys, logs, HTML, and softcode
machine tokens stay T()/S_(). Regenerates pot (670 -> 704) and xx.po.
2026-07-27 23:30:41 -06:00
|
|
|
|
failmsg = M_("You can’t pick that up.");
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
2018-10-03 17:54:51 +00:00
|
|
|
|
did_it(executor, thing, A_FAIL, failmsg, oattr, nullptr, aattr,
|
|
|
|
|
|
0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case TYPE_EXIT:
|
|
|
|
|
|
|
|
|
|
|
|
// You can't take what you already have.
|
|
|
|
|
|
//
|
|
|
|
|
|
thingloc = Exits(thing);
|
|
|
|
|
|
if (thingloc == executor)
|
|
|
|
|
|
{
|
2026-07-27 01:58:14 +00:00
|
|
|
|
notify(executor, M_("You already have that!"));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// You must control either the exit or the location.
|
|
|
|
|
|
//
|
|
|
|
|
|
if ( !Controls(executor, thing)
|
|
|
|
|
|
&& !Controls(executor, playerloc))
|
|
|
|
|
|
{
|
|
|
|
|
|
notify(executor, NOPERM_MESSAGE);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Do it.
|
|
|
|
|
|
//
|
|
|
|
|
|
s_Exits(thingloc, remove_first(Exits(thingloc), thing));
|
|
|
|
|
|
s_Exits(executor, insert_first(Exits(executor), thing));
|
|
|
|
|
|
s_Exits(thing, executor);
|
|
|
|
|
|
if (!Quiet(executor))
|
|
|
|
|
|
{
|
2026-07-27 01:58:14 +00:00
|
|
|
|
notify(executor, M_("Exit taken."));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
2026-07-26 21:52:48 -06:00
|
|
|
|
notify(executor, M_("You can’t take that!"));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------
|
|
|
|
|
|
* do_drop: Drop an object.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2007-09-02 13:48:10 -07:00
|
|
|
|
void do_drop(dbref executor, dbref caller, dbref enactor, int eval, int key, UTF8 *name, const UTF8 *cargs[], int ncargs)
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
UNUSED_PARAMETER(caller);
|
|
|
|
|
|
UNUSED_PARAMETER(enactor);
|
2006-09-06 06:17:46 +00:00
|
|
|
|
UNUSED_PARAMETER(eval);
|
2007-09-02 13:48:10 -07:00
|
|
|
|
UNUSED_PARAMETER(cargs);
|
|
|
|
|
|
UNUSED_PARAMETER(ncargs);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
|
|
|
|
|
dbref loc = Location(executor);
|
|
|
|
|
|
if (!Good_obj(loc))
|
2008-05-31 17:23:15 +00:00
|
|
|
|
{
|
2006-09-01 22:59:23 +00:00
|
|
|
|
return;
|
2008-05-31 17:23:15 +00:00
|
|
|
|
}
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
|
|
|
|
|
dbref exitloc, thing;
|
Migrate 22 alloc_lbuf/free_lbuf sites to LBuf RAII
Replace manual alloc_lbuf/free_lbuf pairs with LBuf RAII wrappers
in 12 engine source files: rob, walk, quota, wiz, session, object,
log, match, move, create, flags, boolexp. This eliminates ~40
explicit free_lbuf calls on error paths that are now handled by
destructors, removing leak risk in early-return and multi-exit
functions (boolexp alone had 13 exit-path frees across two
functions). Buffers returned by atr_get/atr_pget or to callers
are left manual since LBuf cannot adopt externally-allocated
buffers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 17:46:22 -06:00
|
|
|
|
UTF8 *bp;
|
2006-09-01 22:59:23 +00:00
|
|
|
|
int oattr, aattr;
|
|
|
|
|
|
bool quiet;
|
|
|
|
|
|
|
|
|
|
|
|
init_match(executor, name, TYPE_THING);
|
|
|
|
|
|
match_possession();
|
|
|
|
|
|
match_carried_exit();
|
|
|
|
|
|
|
|
|
|
|
|
switch (thing = match_result())
|
|
|
|
|
|
{
|
|
|
|
|
|
case NOTHING:
|
2026-07-26 21:52:48 -06:00
|
|
|
|
notify(executor, M_("You don’t have that!"));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
return;
|
2008-05-31 17:23:15 +00:00
|
|
|
|
|
2006-09-01 22:59:23 +00:00
|
|
|
|
case AMBIGUOUS:
|
2026-07-26 21:52:48 -06:00
|
|
|
|
notify(executor, M_("I don’t know which you mean!"));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch (Typeof(thing))
|
|
|
|
|
|
{
|
|
|
|
|
|
case TYPE_THING:
|
|
|
|
|
|
case TYPE_PLAYER:
|
|
|
|
|
|
|
|
|
|
|
|
// You have to be carrying it.
|
|
|
|
|
|
//
|
|
|
|
|
|
if ( ( Location(thing) != executor
|
|
|
|
|
|
&& !Wizard(executor))
|
|
|
|
|
|
|| !could_doit(executor, thing, A_LDROP))
|
|
|
|
|
|
{
|
2026-07-26 21:52:48 -06:00
|
|
|
|
did_it(executor, thing, A_DFAIL, M_("You can’t drop that."),
|
2018-10-03 17:54:51 +00:00
|
|
|
|
A_ODFAIL, nullptr, A_ADFAIL, 0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Move it
|
|
|
|
|
|
//
|
|
|
|
|
|
move_via_generic(thing, Location(executor), executor, 0);
|
2026-07-27 01:58:14 +00:00
|
|
|
|
notify(thing, M_("Dropped."));
|
2008-05-31 17:23:15 +00:00
|
|
|
|
|
2006-09-01 22:59:23 +00:00
|
|
|
|
quiet = false;
|
2008-05-31 17:23:15 +00:00
|
|
|
|
if ( (key & DROP_QUIET)
|
|
|
|
|
|
&& Controls(executor, thing))
|
|
|
|
|
|
{
|
2006-09-01 22:59:23 +00:00
|
|
|
|
quiet = true;
|
2008-05-31 17:23:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
Migrate 22 alloc_lbuf/free_lbuf sites to LBuf RAII
Replace manual alloc_lbuf/free_lbuf pairs with LBuf RAII wrappers
in 12 engine source files: rob, walk, quota, wiz, session, object,
log, match, move, create, flags, boolexp. This eliminates ~40
explicit free_lbuf calls on error paths that are now handled by
destructors, removing leak risk in early-return and multi-exit
functions (boolexp alone had 13 exit-path frees across two
functions). Buffers returned by atr_get/atr_pget or to callers
are left manual since LBuf cannot adopt externally-allocated
buffers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 17:46:22 -06:00
|
|
|
|
{
|
|
|
|
|
|
LBuf buf = LBuf_Src("do_drop.did_it");
|
|
|
|
|
|
bp = buf.get();
|
nls: mark move/walk/help/guest/quota/power notify prose with M_() (#1670)
Phase 3 coverage slice. Player and staff notify paths that still used
T() (cast-only) now use M_() so they extract into the catalogue:
move arrive/leave, get/drop, teleport failures, home
walk destination, blocked, patrol
help missing topic, match list, file errors
guest busy/create errors, listing total
quota Quota/Used display templates
powers Power not found, @power echo, Powers: header
session Poll / Doing
Attribute names, flag/power registry keys, logs, HTML, and softcode
machine tokens stay T()/S_(). Regenerates pot (670 -> 704) and xx.po.
2026-07-27 23:30:41 -06:00
|
|
|
|
safe_tprintf_str(buf, &bp, M_("dropped %s."), Moniker(thing));
|
Migrate 22 alloc_lbuf/free_lbuf sites to LBuf RAII
Replace manual alloc_lbuf/free_lbuf pairs with LBuf RAII wrappers
in 12 engine source files: rob, walk, quota, wiz, session, object,
log, match, move, create, flags, boolexp. This eliminates ~40
explicit free_lbuf calls on error paths that are now handled by
destructors, removing leak risk in early-return and multi-exit
functions (boolexp alone had 13 exit-path frees across two
functions). Buffers returned by atr_get/atr_pget or to callers
are left manual since LBuf cannot adopt externally-allocated
buffers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 17:46:22 -06:00
|
|
|
|
oattr = quiet ? 0 : A_ODROP;
|
|
|
|
|
|
aattr = quiet ? 0 : A_ADROP;
|
nls: finish the five half-marked strings in move.cpp (#1419)
Five literals were marked M_() at one site and left T() at another, so the
same message was translatable in one context and not the other:
Dropped. Taken. You can't drop that.
You can't go that way. You can't leave.
rob.cpp had none of this; move.cpp had all five.
Taken. shows why it matters. The marked copy went to the OBJECT, while the
copy the PLAYER reads was still T():
notify(thing, M_("Taken.")); // to the thing
did_it(executor, thing, A_SUCC, T("Taken."), ...); // `def` -> the player
did_it's fourth argument is the default shown to the player when the object
has no @success, so with "Taken." in a catalog, mux_gettext returned the
translation while `take widget` printed English.
Half-marked is worse than unmarked. Unmarked is honestly untranslated;
half-marked means a translator translates the string and then sees it appear
in their language in one context and English in another, with nothing in the
catalog to distinguish them.
The five promoted sites are all player-facing defaults:
674 move_exit(..., "You can't go that way.")
781 did_it(..., A_SUCC, "Taken.")
888 did_it(..., A_DFAIL, "You can't drop that.")
911 did_it(..., A_DROP, "Dropped.")
1057 did_it(..., A_LFAIL, "You can't leave.")
The msgid set is unchanged -- these are the same strings already in the
catalog -- so only the reference comments in tinymux.pot move. Verified by
diffing the sorted msgid lists before and after: identical.
Verified with a catalog carrying the two confirmations plus an identifier and
an ABI token:
before take widget -> Taken. (untranslated)
after take widget -> [xx] Taken.
drop widget -> [xx] Dropped.
ABI=#-1 DIVIDE BY ZERO (intact)
FN=5 (abs() still resolves)
English smoke on the NLS build: 1505 passed, 0 failed, 316/316.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 20:25:28 -06:00
|
|
|
|
did_it(executor, thing, A_DROP, M_("Dropped."), oattr, buf,
|
Migrate 22 alloc_lbuf/free_lbuf sites to LBuf RAII
Replace manual alloc_lbuf/free_lbuf pairs with LBuf RAII wrappers
in 12 engine source files: rob, walk, quota, wiz, session, object,
log, match, move, create, flags, boolexp. This eliminates ~40
explicit free_lbuf calls on error paths that are now handled by
destructors, removing leak risk in early-return and multi-exit
functions (boolexp alone had 13 exit-path frees across two
functions). Buffers returned by atr_get/atr_pget or to callers
are left manual since LBuf cannot adopt externally-allocated
buffers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 17:46:22 -06:00
|
|
|
|
aattr, 0, nullptr, 0);
|
|
|
|
|
|
}
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
|
|
|
|
|
// Process droptos
|
|
|
|
|
|
//
|
|
|
|
|
|
process_dropped_dropto(thing, executor);
|
|
|
|
|
|
break;
|
2008-05-31 17:23:15 +00:00
|
|
|
|
|
2006-09-01 22:59:23 +00:00
|
|
|
|
case TYPE_EXIT:
|
|
|
|
|
|
|
|
|
|
|
|
// You have to be carrying it.
|
|
|
|
|
|
//
|
2008-05-31 17:23:15 +00:00
|
|
|
|
if ( Exits(thing) != executor
|
|
|
|
|
|
&& !Wizard(executor))
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
2026-07-26 21:52:48 -06:00
|
|
|
|
notify(executor, M_("You can’t drop that."));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2008-05-31 17:23:15 +00:00
|
|
|
|
|
2006-09-01 22:59:23 +00:00
|
|
|
|
if (!Controls(executor, loc))
|
|
|
|
|
|
{
|
|
|
|
|
|
notify(executor, NOPERM_MESSAGE);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2008-05-31 17:23:15 +00:00
|
|
|
|
// Do it.
|
2006-09-01 22:59:23 +00:00
|
|
|
|
//
|
|
|
|
|
|
exitloc = Exits(thing);
|
|
|
|
|
|
s_Exits(exitloc, remove_first(Exits(exitloc), thing));
|
|
|
|
|
|
s_Exits(loc, insert_first(Exits(loc), thing));
|
|
|
|
|
|
s_Exits(thing, loc);
|
|
|
|
|
|
|
|
|
|
|
|
if (!Quiet(executor))
|
2008-05-31 17:23:15 +00:00
|
|
|
|
{
|
2026-07-27 01:58:14 +00:00
|
|
|
|
notify(executor, M_("Exit dropped."));
|
2008-05-31 17:23:15 +00:00
|
|
|
|
}
|
2006-09-01 22:59:23 +00:00
|
|
|
|
break;
|
2008-05-31 17:23:15 +00:00
|
|
|
|
|
2006-09-01 22:59:23 +00:00
|
|
|
|
default:
|
2026-07-26 21:52:48 -06:00
|
|
|
|
notify(executor, M_("You can’t drop that."));
|
2008-05-31 17:23:15 +00:00
|
|
|
|
break;
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------
|
|
|
|
|
|
* do_enter, do_leave: The enter and leave commands.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
void do_enter_internal(dbref player, dbref thing, bool quiet)
|
|
|
|
|
|
{
|
|
|
|
|
|
int oattr, aattr;
|
|
|
|
|
|
|
|
|
|
|
|
if (!Enter_ok(thing) && !Controls(player, thing))
|
|
|
|
|
|
{
|
|
|
|
|
|
oattr = quiet ? 0 : A_OEFAIL;
|
|
|
|
|
|
aattr = quiet ? 0 : A_AEFAIL;
|
|
|
|
|
|
did_it(player, thing, A_EFAIL, NOPERM_MESSAGE,
|
2018-10-03 17:54:51 +00:00
|
|
|
|
oattr, nullptr, aattr, 0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
else if (player == thing)
|
|
|
|
|
|
{
|
2026-07-26 21:52:48 -06:00
|
|
|
|
notify(player, M_("You can’t enter yourself!"));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
else if (could_doit(player, thing, A_LENTER))
|
|
|
|
|
|
{
|
|
|
|
|
|
dbref loc = Location(player);
|
|
|
|
|
|
oattr = quiet ? HUSH_ENTER : 0;
|
|
|
|
|
|
move_via_generic(player, thing, NOTHING, oattr);
|
|
|
|
|
|
divest_object(player);
|
|
|
|
|
|
process_sticky_dropto(loc, player);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
oattr = quiet ? 0 : A_OEFAIL;
|
|
|
|
|
|
aattr = quiet ? 0 : A_AEFAIL;
|
nls: mark move/walk/help/guest/quota/power notify prose with M_() (#1670)
Phase 3 coverage slice. Player and staff notify paths that still used
T() (cast-only) now use M_() so they extract into the catalogue:
move arrive/leave, get/drop, teleport failures, home
walk destination, blocked, patrol
help missing topic, match list, file errors
guest busy/create errors, listing total
quota Quota/Used display templates
powers Power not found, @power echo, Powers: header
session Poll / Doing
Attribute names, flag/power registry keys, logs, HTML, and softcode
machine tokens stay T()/S_(). Regenerates pot (670 -> 704) and xx.po.
2026-07-27 23:30:41 -06:00
|
|
|
|
did_it(player, thing, A_EFAIL, M_("You can’t enter that."),
|
2018-10-03 17:54:51 +00:00
|
|
|
|
oattr, nullptr, aattr, 0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2007-09-02 13:48:10 -07:00
|
|
|
|
void do_enter(dbref executor, dbref caller, dbref enactor, int eval, int key, UTF8 *what, const UTF8 *cargs[], int ncargs)
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
UNUSED_PARAMETER(caller);
|
|
|
|
|
|
UNUSED_PARAMETER(enactor);
|
2006-09-06 06:17:46 +00:00
|
|
|
|
UNUSED_PARAMETER(eval);
|
2007-09-02 13:48:10 -07:00
|
|
|
|
UNUSED_PARAMETER(cargs);
|
|
|
|
|
|
UNUSED_PARAMETER(ncargs);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
|
|
|
|
|
init_match(executor, what, TYPE_THING);
|
|
|
|
|
|
match_neighbor();
|
|
|
|
|
|
if (Long_Fingers(executor))
|
|
|
|
|
|
match_absolute(); // the wizard has long fingers
|
|
|
|
|
|
|
|
|
|
|
|
dbref thing = noisy_match_result();
|
|
|
|
|
|
bool bQuiet = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (thing == NOTHING)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
switch (Typeof(thing))
|
|
|
|
|
|
{
|
|
|
|
|
|
case TYPE_PLAYER:
|
|
|
|
|
|
case TYPE_THING:
|
|
|
|
|
|
if ((key & MOVE_QUIET) && Controls(executor, thing))
|
|
|
|
|
|
bQuiet = true;
|
|
|
|
|
|
do_enter_internal(executor, thing, bQuiet);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
notify(executor, NOPERM_MESSAGE);
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2007-09-02 11:03:02 -07:00
|
|
|
|
void do_leave(dbref executor, dbref caller, dbref enactor, int eval, int key)
|
2006-09-01 22:59:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
UNUSED_PARAMETER(caller);
|
|
|
|
|
|
UNUSED_PARAMETER(enactor);
|
2007-09-02 11:03:02 -07:00
|
|
|
|
UNUSED_PARAMETER(eval);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
|
|
|
|
|
|
dbref loc = Location(executor);
|
|
|
|
|
|
dbref newLoc = loc;
|
|
|
|
|
|
|
|
|
|
|
|
if ( !Good_obj(loc)
|
|
|
|
|
|
|| Going(loc)
|
|
|
|
|
|
|| !Has_location(loc)
|
|
|
|
|
|
|| !Good_obj(newLoc = Location(loc))
|
|
|
|
|
|
|| Going(newLoc))
|
|
|
|
|
|
{
|
2026-07-26 21:52:48 -06:00
|
|
|
|
notify(executor, M_("You can’t leave."));
|
2006-09-01 22:59:23 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
int quiet = 0;
|
|
|
|
|
|
if ( (key & MOVE_QUIET)
|
|
|
|
|
|
&& Controls(executor, loc))
|
|
|
|
|
|
{
|
|
|
|
|
|
quiet = HUSH_LEAVE;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (could_doit(executor, loc, A_LLEAVE))
|
|
|
|
|
|
{
|
|
|
|
|
|
move_via_generic(executor, newLoc, NOTHING, quiet);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
int oattr = quiet ? 0 : A_OLFAIL;
|
|
|
|
|
|
int aattr = quiet ? 0 : A_ALFAIL;
|
2026-07-26 21:52:48 -06:00
|
|
|
|
did_it(executor, loc, A_LFAIL, M_("You can’t leave."),
|
2018-10-03 17:54:51 +00:00
|
|
|
|
oattr, nullptr, aattr, 0, nullptr, 0);
|
2006-09-01 22:59:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|