home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
games
/
tinymud2.zip
/
MOVE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-09-02
|
9KB
|
332 lines
#include "copyright.h"
#include "db.h"
#include "config.h"
#include "interface.h"
#include "match.h"
#include "externs.h"
void moveto(dbref what, dbref where)
{
dbref loc;
/* remove what from old loc */
if((loc = db[what].location) != NOTHING) {
db[loc].contents = remove_first(db[loc].contents, what);
}
/* test for special cases */
switch(where) {
case NOTHING:
db[what].location = NOTHING;
return; /* NOTHING doesn't have contents */
case HOME:
where = db[what].exits; /* home */
break;
}
/* now put what in where */
PUSH(what, db[where].contents);
db[what].location = where;
}
static void send_contents(dbref loc, dbref dest)
{
dbref first;
dbref rest;
first = db[loc].contents;
db[loc].contents = NOTHING;
/* blast locations of everything in list */
DOLIST(rest, first) {
db[rest].location = NOTHING;
}
while(first != NOTHING) {
rest = db[first].next;
if(Typeof(first) != TYPE_THING) {
moveto(first, loc);
} else {
moveto(first, (db[first].flags & STICKY) ? HOME : dest);
}
first = rest;
}
db[loc].contents = reverse(db[loc].contents);
}
void maybe_dropto(dbref loc, dbref dropto)
{
dbref thing;
if(loc == dropto) return; /* bizarre special case */
/* check for players */
DOLIST(thing, db[loc].contents) {
if(Typeof(thing) == TYPE_PLAYER) return;
}
/* no players, send everything to the dropto */
send_contents(loc, dropto);
}
void enter_room(dbref player, dbref loc)
{
dbref old;
dbref dropto;
char buf[BUFFER_LEN];
/* check for room == HOME */
if(loc == HOME) loc = db[player].exits; /* home */
/* get old location */
old = db[player].location;
/* check for self-loop */
/* self-loops don't do move or other player notification */
/* but you still get autolook and penny check */
if(loc != old) {
if(old != NOTHING) {
/* notify others unless DARK */
if(!Dark(old) && !Dark(player)) {
sprintf(buf, "%s has left.", db[player].name);
notify_except(db[old].contents, player, buf);
}
}
/* go there */
moveto(player, loc);
/* if old location has STICKY dropto, send stuff through it */
if(old != NOTHING
&& (dropto = db[old].location) != NOTHING
&& (db[old].flags & STICKY)) {
maybe_dropto(old, dropto);
}
/* tell other folks in new location if not DARK */
if(!Dark(loc) && !Dark(player)) {
sprintf(buf, "%s has arrived.", db[player].name);
notify_except(db[loc].contents, player, buf);
}
}
/* autolook */
look_room(player, loc);
/* check for pennies */
if(!controls(player, loc)
&& db[player].pennies <= MAX_PENNIES
&& random() % PENNY_RATE == 0) {
notify(player, "You found a penny!");
db[player].pennies++;
}
}
void send_home(dbref thing)
{
switch(Typeof(thing)) {
case TYPE_PLAYER:
/* send his possessions home first! */
/* that way he sees them when he arrives */
send_contents(thing, HOME);
enter_room(thing, db[thing].exits); /* home */
break;
case TYPE_THING:
moveto(thing, db[thing].exits); /* home */
break;
default:
/* no effect */
break;
}
}
int can_move(dbref player, const char *direction)
{
if(!string_compare(direction, "home")) return 1;
/* otherwise match on exits */
init_match(player, direction, TYPE_EXIT);
match_exit();
return(last_match_result() != NOTHING);
}
void do_move(dbref player, const char *direction)
{
dbref exit;
dbref loc;
char buf[BUFFER_LEN];
if(!string_compare(direction, "home")) {
/* send him home */
/* but steal all his possessions */
if((loc = db[player].location) != NOTHING) {
/* tell everybody else */
sprintf(buf, "%s goes home.", db[player].name);
notify_except(db[loc].contents, player, buf);
}
/* give the player the messages */
notify(player, "There's no place like home...");
notify(player, "There's no place like home...");
notify(player, "There's no place like home...");
notify(player, "You wake up back home, without your possessions.");
send_home(player);
} else {
/* find the exit */
init_match_check_keys(player, direction, TYPE_EXIT);
match_exit();
switch(exit = match_result()) {
case NOTHING:
notify(player, "You can't go that way.");
break;
case AMBIGUOUS:
notify(player, "I don't know which way you mean!");
break;
default:
/* we got one */
/* check to see if we got through */
if(can_doit(player, exit, "You can't go that way.")) {
enter_room(player, db[exit].location);
}
break;
}
}
}
void do_get(dbref player, const char *what)
{
dbref loc;
dbref thing;
init_match_check_keys(player, what, TYPE_THING);
match_neighbor();
match_exit();
if(Wizard(player)) match_absolute(); /* the wizard has long fingers */
if((thing = noisy_match_result()) != NOTHING) {
if(db[thing].location == player) {
notify(player, "You already have that!");
return;
}
switch(Typeof(thing)) {
case TYPE_THING:
if(can_doit(player, thing, "You can't pick that up.")) {
moveto(thing, player);
notify(player, "Taken.");
}
break;
case TYPE_EXIT:
if(!controls(player, thing)) {
notify(player, "You can't pick that up.");
} else if(db[thing].location != NOTHING) {
notify(player, "You can't pick up a linked exit.");
#ifdef RESTRICTED_BUILDING
} else if(!Builder(player)) {
notify(player, "Only authorized builders may pick up exits.");
#endif /* RESTRICTED_BUILDING */
} else {
/* take it out of location */
if((loc = getloc(player)) == NOTHING) return;
if(!member(thing, db[loc].exits)) {
notify(player,
"You can't pick up an exit from another room.");
return;
}
db[loc].exits = remove_first(db[loc].exits, thing);
PUSH(thing, db[player].contents);
db[thing].location = player;
notify(player, "Exit taken.");
}
break;
default:
notify(player, "You can't take that!");
break;
}
}
}
void do_drop(dbref player, const char *name)
{
dbref loc;
dbref thing;
char buf[BUFFER_LEN];
int reward;
if((loc = getloc(player)) == NOTHING) return;
init_match(player, name, TYPE_THING);
match_possession();
switch(thing = match_result()) {
case NOTHING:
notify(player, "You don't have that!");
break;
case AMBIGUOUS:
notify(player, "I don't know which you mean!");
break;
default:
if(db[thing].location != player &&
!(Typeof(thing) == TYPE_EXIT) && db[thing].location == NOTHING) {
/* Should not ever happen. */
notify(player, "You can't drop that.");
} else if(Typeof(thing) == TYPE_EXIT) {
/* special behavior for exits */
if(!controls(player, loc)) {
notify(player, "You can't put an exit down here.");
return;
}
/* else we can put it down */
moveto(thing, NOTHING); /* take it out of the pack */
PUSH(thing, db[loc].exits);
notify(player, "Exit dropped.");
} else if(db[loc].flags & TEMPLE) {
/* sacrifice time */
send_home(thing);
sprintf(buf,
"%s is consumed in a burst of flame!", db[thing].name);
notify(player, buf);
#ifndef TINKER
sprintf(buf, "%s sacrifices %s.", db[player].name, db[thing].name);
#else TINKER
sprintf(buf, "%s donates %s.", db[player].name, db[thing].name);
#endif TINKER
notify_except(db[loc].contents, player, buf);
/* check for reward */
if(!controls(player, thing)) {
reward = db[thing].pennies;
if(reward < 1 || db[player].pennies > MAX_PENNIES) {
reward = 1;
} else if(reward > MAX_OBJECT_ENDOWMENT) {
reward = MAX_OBJECT_ENDOWMENT;
}
db[player].pennies += reward;
sprintf(buf,
"You have received %d %s for your donation.",
reward,
reward == 1 ? "penny" : "pennies");
notify(player, buf);
}
} else if(db[thing].flags & STICKY) {
send_home(thing);
notify(player, "Dropped.");
} else if(db[loc].location != NOTHING && !(db[loc].flags & STICKY)) {
/* location has immediate dropto */
moveto(thing, db[loc].location);
notify(player, "Dropped.");
} else if((db[thing].flags & DARK) && !can_link_to(player,Typeof(thing),loc)) {
notify(player, "You cannot drop that DARK object here.");
} else {
moveto(thing, loc);
notify(player, "Dropped.");
sprintf(buf, "%s dropped %s.", db[player].name, db[thing].name);
notify_except(db[loc].contents, player, buf);
}
break;
}
}