#include "copyright.h"
/* Commands that create new objects */
#include "db.h"
#include "config.h"
#include "interface.h"
#include "externs.h"
#include "match.h"
/* utility for open and link */
static dbref parse_linkable_room (dbref player, object_flag_type thing,
const char *room_name)
{
dbref room;
/* skip leading NUMBER_TOKEN if any */
if (*room_name == NUMBER_TOKEN)
room_name++;
/* parse room */
if (!string_compare (room_name, "here")) {
room = db[player].location;
} else if (!string_compare (room_name, "home")) {
return HOME; /* HOME is always linkable */
} else {
room = parse_dbref (room_name);
}
/* check room */
if (room < 0 || room >= db_top || Typeof (room) != TYPE_ROOM) {
notify (player, "That's not a room!");
return NOTHING;
} else if (!can_link_to (player, thing, room)) {
notify (player, "You can't link to that.");
return NOTHING;
} else {
return room;
}
}
/* use this to create an exit */
void do_open (dbref player, const char *direction, const char *linkto)
{
dbref loc;
dbref exit;
#ifdef RESTRICTED_BUILDING
if (!Builder (player)) {
notify (player, "That command is restricted to authorized builders.");
return;
}
#endif /* RESTRICTED_BUILDING */
if ((loc = getloc (player)) == NOTHING)
return;
if (!*direction) {
notify (player, "Open where?");
return;
} else if (!ok_name (direction)) {
notify (player, "That's a strange name for an exit!");
return;
}
if (!controls (player, loc)) {
notify (player, "Permission denied.");
} else if (!payfor (player, EXIT_COST)) {
notify (player, "Sorry, you don't have enough pennies to open an exit.");
} else {
/* create the exit */
exit = new_object ();
/* initialize everything */
db[exit].name = alloc_string (direction);
db[exit].owner = player;
db[exit].flags = TYPE_EXIT;
/* link it in */
PUSH (exit, db[loc].exits);
/* and we're done */
notify (player, "Opened.");
/* check second arg to see if we should do a link */
if (*linkto != '\0') {
notify (player, "Trying to link...");
if ((loc = parse_linkable_room (player, TYPE_EXIT, linkto)) != NOTHING) {
if (!payfor (player, LINK_COST)) {
notify (player, "You don't have enough pennies to link.");
} else {
/* it's ok, link it */
db[exit].location = loc;
notify (player, "Linked.");
}
}
}
}
}
/* use this to link to a room that you own */
/* it seizes ownership of the exit */
/* 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 */
void do_link (dbref player, const char *name, const char *room_name)
{
dbref thing;
dbref room;
init_match (player, name, TYPE_EXIT);
match_exit ();
match_neighbor ();
match_possession ();
match_me ();
match_here ();
if (Wizard (player)) {
match_absolute ();
match_player ();
}
if ((thing = noisy_match_result ()) != NOTHING) {
if ((room = parse_linkable_room (player, Typeof (thing), room_name)) ==
NOTHING)
return;
switch (Typeof (thing)) {
case TYPE_EXIT:
/* we're ok, check the usual stuff */
if (db[thing].location != NOTHING) {
if (controls (player, thing)) {
/*
* Changed 5/18/90 Fuzzy - exits linked to *home*
* break 'Typeof() call'
*/
if (db[thing].location >= 0 &&
Typeof (db[thing].location) == TYPE_PLAYER) {
notify (player, "That exit is being carried.");
} else {
notify (player, "That exit is already linked.");
}
} else {
notify (player, "Permission denied.");
}
} else {
/* handle costs */
if (db[thing].owner == player) {
if (!payfor (player, LINK_COST)) {
notify (player, "It costs a penny to link this exit.");
return;
}
} else {
if (!payfor (player, LINK_COST + EXIT_COST)) {
notify (player, "It costs two pennies to link this exit.");
return;
#ifdef RESTRICTED_BUILDING
} else if (!Builder (player)) {
notify (player, "Only authorized builders may seize exits.");
#endif /* RESTRICTED_BUILDING */
} else {
/* pay the owner for his loss */
db[db[thing].owner].pennies += EXIT_COST;
}
}
/* link has been validated and paid for; do it */
db[thing].owner = player;
db[thing].location = room;
/* notify the player */
notify (player, "Linked.");
}
break;
case TYPE_PLAYER:
case TYPE_THING:
if (!controls (player, thing)) {
notify (player, "Permission denied.");
} else if (room == HOME) {
notify (player, "Can't set home to home.");
} else {
/* do the link */
db[thing].exits = room; /* home */
notify (player, "Home set.");
}
break;
case TYPE_ROOM:
if (!controls (player, thing)) {
notify (player, "Permission denied.");
} else {
/* do the link, in location */
db[thing].location = room; /* dropto */
notify (player, "Dropto set.");
}
break;
default:
notify (player, "Internal error: weird object type.");
writelog ("PANIC weird object: Typeof(%d) = %d\n",
thing, Typeof (thing));
break;
}
}
}
/* use this to create a room */
void do_dig (dbref player, const char *name)
{
dbref room;
char buf[BUFFER_LEN];
#ifdef RESTRICTED_BUILDING
if (!Builder (player)) {
notify (player, "That command is restricted to authorized builders.");
return;
}
#endif /* RESTRICTED_BUILDING */
/* we don't need to know player's location! hooray! */
if (*name == '\0') {
notify (player, "Dig what?");
} else if (!ok_name (name)) {
notify (player, "That's a silly name for a room!");
} else if (!payfor (player, ROOM_COST)) {
notify (player, "Sorry, you don't have enough pennies to dig a room.");
} else {
room = new_object ();
/* Initialize everything */
db[room].name = alloc_string (name);
db[room].owner = player;
db[room].flags = TYPE_ROOM;
sprintf (buf, "%s created with room number %d.", name, room);
notify (player, buf);
}
}
/* use this to create an object */
void do_create (dbref player, char *name, int cost)
{
dbref loc;
dbref thing;
#ifdef RESTRICTED_BUILDING
if (!Builder (player)) {
notify (player, "That command is restricted to authorized builders.");
return;
}
#endif /* RESTRICTED_BUILDING */
if (*name == '\0') {
notify (player, "Create what?");
return;
} else if (!ok_name (name)) {
notify (player, "That's a silly name for a thing!");
return;
} else if (cost < 0) {
notify (player, "You can't create an object for less than nothing!");
return;
} else if (cost < OBJECT_COST) {
cost = OBJECT_COST;
}
if (!payfor (player, cost)) {
notify (player, "Sorry, you don't have enough pennies.");
} else {
/* create the object */
thing = new_object ();
/* initialize everything */
db[thing].name = alloc_string (name);
db[thing].location = player;
db[thing].owner = player;
db[thing].pennies = OBJECT_ENDOWMENT (cost);
db[thing].flags = TYPE_THING;
/* endow the object */
if (db[thing].pennies > MAX_OBJECT_ENDOWMENT) {
db[thing].pennies = MAX_OBJECT_ENDOWMENT;
}
/* home is here (if we can link to it) or player's home */
if ((loc = db[player].location) != NOTHING && controls (player, loc)) {
db[thing].exits = loc; /* home */
} else {
db[thing].exits = db[player].exits; /* home */
}
/* link it in */
PUSH (thing, db[player].contents);
/* and we're done */
notify (player, "Created.");
}
}
#ifdef REGISTRATION
void do_pcreate (dbref player, char *newplayer, char *newpass)
{
dbref ptmp;
#ifdef GOD_MODE && GOD_ONLY_PCREATE
if (!God (player))
#ifndef TINKER
notify (player, "Only GOD can create a new player.");
#else /* TINKER */
notify (player, "Only the Master Tinker can create a new player.");
#endif /* TINKER */
#else /* GOD_MODE && GOD_ONLY_PCREATE */
if (!Wizard (player))
#ifndef TINKER
notify (player, "Only a Wizard can create a new player.");
#else /* TINKER */
notify (player, "Only a Tinker can create a new player.");
#endif /* TINKER */
#endif /* GOD_MODE && GOD_ONLY_PCREATE */
else if (!*newplayer || !*newpass)
notify (player, "You must specify name and password.");
else {
ptmp = create_player (newplayer, newpass);
if (ptmp == NOTHING) {
notify (player,
"Either there is already a player with that name, or that name is illegal.");
writelog ("FAILED CREATE %s by %s\n", newplayer, db[player].name);
} else {
char buf[512];
sprintf (buf, "%s created as object #%d.", db[ptmp].name, ptmp);
notify (player, buf);
writelog ("CREATED %s(%d) by %s\n", db[ptmp].name, ptmp,
db[player].name);
}
}
}
#endif /* REGISTRATION */