84 lines
3.0 KiB
Plaintext
84 lines
3.0 KiB
Plaintext
Shadows are means to simulate the addition
|
|
of functions to an already existing object.
|
|
|
|
For example, one way to "enchant" a player might
|
|
be to make it so that any object that tries to
|
|
do damage to her fails. This would mean that
|
|
somehow you have to override eventReceiveDamage in
|
|
that player (there are other ways, but let's pretend
|
|
this is a good idea).
|
|
|
|
A shadow would do it. You could code an with
|
|
the following code:
|
|
|
|
varargs int eventReceiveDamage() {
|
|
return 0;
|
|
}
|
|
|
|
And then use the shadow() efun to attach it to
|
|
the player. Now when something tries to call the
|
|
eventReceiveDamage function on the player, the
|
|
shadow intercepts that call, and nothing happens at all.
|
|
|
|
Neat, huh?
|
|
|
|
There are, however, problems with shadows, which
|
|
we'll go over here:
|
|
|
|
1) SECURITY
|
|
-----------
|
|
The main problem with shadows is security. If anybody on
|
|
a mud can create shadows, then your mud basically
|
|
has no security at all, because a creator can enshadow
|
|
an admin (or some other privileged object) in such
|
|
a way as to elevate their own privilege.
|
|
|
|
This would be bad.
|
|
|
|
The way this is handled in Dead Souls is that the mud
|
|
won't allow an object to be shadowed unless the shadowing
|
|
object's code lives in /shadows. This means that it takes
|
|
an admin to put the code there so that at least there is
|
|
someone who *should* know what they're doing who is
|
|
responsible for putting this code into play.
|
|
|
|
This "only stuff in the /shadows directory" behavior
|
|
is defined in the valid_shadow() master apply.
|
|
|
|
2) MANAGEMENT
|
|
-------------
|
|
The other headache when it comes to shadows is managing
|
|
them. The MudOS shadow() efun is simple enough to use,
|
|
but suppose an object has more than one shadow and you
|
|
only want to remove one. This is problematic because
|
|
remove_shadow() doesn't distinguish between shadows...it'll
|
|
remove *all* shadows from an object. While this may sometimes
|
|
be desirable, it may not always be the right thing.
|
|
|
|
Starting in Dead Souls 2.5a8, a system for basic management
|
|
of multiple shadows is included. The system relies on the
|
|
following rules on a mud to work properly:
|
|
|
|
*) All shadows must inherit LIB_SHADOW.
|
|
*) Any shadow must be attached to an object via the eventShadow() lfun.
|
|
*) Any shadow must be removed via the eventUnshadow() lfun.
|
|
|
|
This is because tangible items (cans of spam, swords, players, etc)
|
|
now all inherit LIB_SHADOW_HOOK. What this means is that any shadow
|
|
that is to be attached to an item will first identify itself to
|
|
the item, and that item will maintain a list of objects that are
|
|
shadowing it. This allows you to query that item for its shadows,
|
|
and to then remove individual shadows. For example:
|
|
|
|
find_player("xyzzy")->GetShadows()
|
|
find_player("xyzzy")->eventUnshadow(find_object("/shadows/clan#9"))
|
|
|
|
So that only that specific shadow is removed from Xyzzy.
|
|
|
|
Note that this system does not prevent people from using
|
|
shadow() and remove_shadow() independently, so for things to
|
|
work properly, your mud needs to have it be a standard that
|
|
shadows are removed and attached according to the rules above.
|
|
|
|
For more information on shadows in general, please see: /doc/guide/chapter07
|