/
LIB3/
LIB3/D/ADMIN/
LIB3/D/ADMIN/OBJ/
LIB3/D/ADMIN/ROOM/W/
LIB3/D/HOME/
LIB3/D/HOME/CITY/ARENA/
LIB3/D/HOME/CITY/ITEMS/
LIB3/D/HOME/CITY/POSTOFFI/
LIB3/DOC/
LIB3/GLOBAL/SPECIAL/
LIB3/GLOBAL/VIRTUAL/
LIB3/NET/
LIB3/NET/CONFIG/
LIB3/NET/DAEMON/CHARS/
LIB3/NET/GOPHER/
LIB3/NET/INHERIT/
LIB3/NET/OBJ/
LIB3/NET/SAVE/
LIB3/NET/VIRTUAL/
LIB3/OBJ/B_DAY/
LIB3/OBJ/HANDLERS/TERM_TYP/
LIB3/PLAYERS/B/
LIB3/PLAYERS/N/
LIB3/ROOM/
LIB3/SAVE/
LIB3/SAVE/BOARDS/
LIB3/SAVE/ENVIRON/
LIB3/SAVE/POST/
LIB3/STD/COMMANDS/SHADOWS/
LIB3/STD/CREATOR/
LIB3/STD/DOM/
LIB3/STD/EFFECTS/
LIB3/STD/EFFECTS/HEALING/
LIB3/STD/EFFECTS/OTHER/
LIB3/STD/EFFECTS/POISONS/
LIB3/STD/ENVIRON/
LIB3/STD/GUILDS/
LIB3/STD/LIQUIDS/
LIB3/STD/ROOM/
LIB3/STD/TRIGGER/SHADOW/
LIB3/W/
LIB3/W/BANNOR/
LIB3/W/NEWSTYLE/
inherit "/std/room";
#include "path.h"
#define SAVEFILE POSTOFFICE+"parcels"
#define MONEY "/obj/handlers/money_handler"
#include "move_failures.h"

static string who;
static int fee;
mapping parcels;


void    create()
{
    ::create();
    restore_object(SAVEFILE, 1);
   if(!parcels) parcels = ([ ]);
}

void dest_me()
{
   save_object(SAVEFILE, 1);
   ::dest_me();
}

int query_parcels(object person)
{
   string *things;

   if(!(things = parcels[ (string)person->query_name() ]) )
     return 0;
  else
  return (sizeof(things)/3);
}

setup()
{
    set_short( "The parcel office" );
    set_long( "This is the parcel collection and delivery office, where "
	      + "it is possible to mail things to other people, for "
	      + "a fee, of course. A desk divides the room in two. Behind "
	      + "the desk sits a bored looking post-office clerk, and "
+"behind him is a rack of parcels. A small sign sits on the desk.\n");
add_sign("A small sign, sitting on the desk. It gives instructions on "
+"how to use the parcel-post.\n", "To use the parcel post, type:\n\n"+
"     send <thing(s)> to <person>    -  To send a parcel.\n"
+"     collect                        - To collect anything sent to you.\n", 0, "sign");
    add_item( ({ "desk", "table", "counter" }),
	      "The counter is made of polished wood, and sags slightly "
	      + "in the middle. Whether this is due to the weight of the "
	      + "parcels which have passed over it, or the weight of the "
	      + "clerk resting his elbow on it, you can't tell.\n" );
    add_item( ({ "clerk", "person", "worker", "post-office clerk",
		 "post office clerk", "clark" }),
	      "The clerk has one of those expressive faces, worn "
	      + "by the worries of many years toil. But right now "
	      + "it is expressing boredom, as is the rest of him.\n" );
    add_item( ({ "rack", "stand" }),
	      "The rack is really a section of shelving divided unevenly "
	      + "into separate 'boxes'. Some of the boxes contain parcels.\n" );
    add_item( ({ "box", "parcel" }),
	      "The parcels on the rack range in size from small boxes "
	      + "though long, thin, pole-shapes ones, right past square "
	      + "flat ones, and up to bing round bouncy ones. Some of them "
	      + "are wrapped in brown paper, and some have a small layer "
	      + "of dust on them.\n" );
    set_light( 70 );
    set_zone( "post office" );
add_exit("west", "post", "door");
}

void    init()
{
    ::init();
    add_action( "send_parcel", "mail" );
    add_action( "send_parcel", "post" );
    add_action( "send_parcel", "send" );
    add_action( "collect_parcel", "collect" );
}

void add_to_store(object ob)
{
  if(!parcels[who])
    parcels[who] = "/global/auto_load"->create_auto_load( ({ ob }) );
  else
    parcels[who] += "/global/auto_load"->create_auto_load( ({ ob }) );
  ob->dest_me();
}

void move_all_to_store(object *obs)
{
   int i;

  if(!parcels[who])
    parcels[who] = "/global/auto_load"->create_auto_load( obs );
  else
    parcels[who] += "/global/auto_load"->create_auto_load( obs );
  for(i=0;i<sizeof(obs);i++)
     obs[i]->dest_me();
}

mixed *make_fee(object ob)
{
  return (mixed *)MONEY->create_money_array(1000);
}

object *move_and_check( object *things, object dest )
/* Returns a list of things moved sucessfully, */
{
    int     i, j;
    object *ret;
mixed cost;

    ret = ({ });
    for( i = 0; i < sizeof( things ); i++ )
    {
cost = make_fee( things[i] );
if(this_player()->pay_money( cost ))
  fee += (int)MONEY->query_total_value(cost);
else
{
write("You cannot afford the "+
(string)MONEY->money_string(cost)
+" needed to send your "+things[i]->query_short()+".\n");
continue;
}
	j = (int)things[ i ]->move( dest );
	switch( j )
	{
	    case MOVE_OK:
/*
        write( capitalize( (string)things[ i ]->query_short() ) + " sent sucessfully.\n" );
*/
		ret += ({ things[ i ] });
		break;
	    case MOVE_NO_DROP:
		write( "You don't seem to be able to drop your " + things[ i ]->query_short() + ".\n" );
		break;
	    case MOVE_NO_GET:
		write( "The courier cannot pick up the " + things[ i ]->query_short() + "!\n" );
		break;
	    case MOVE_TOO_HEAVY:
		tell_object( dest, "A post-office courier tries to give you a " +
			     things[ i ]->query_short() + ", but it is too heavy for you. He "
			     + "wanders off again, muttering something about you having to "
			     + "collect it yourself from the parcel-office.\n" );
        add_to_store(things[i]);
        break;
	    default:
		write( "The clerk smiles annoyingly and tells you that "
		       + "there has been a problem sending your " + things[ i ] +
		       ". It has been returned to you, and your money refunded.\n" );
	}
    }
    return ret;
}

int     send_parcel( string str )
{
    string  what;
    object *things, target;

    notify_fail( "Useage: send <object> to <person>\n" );
    who = 0;
    if( !str )
	return 0;
    if( sscanf( str, "%s to %s", what, who ) != 2 )
	return 0;

    things = find_match( what, this_player() );
fee = 0;
who = (string)this_player()->expand_nickname( who );
    if( !sizeof( things ) )
    {
	notify_fail( "You have no " + what + " to send to " + who + ".\n" );
	return 0;
    }
    if( !"/secure/login"->test_user( who ) )
    {
    notify_fail( "The clerk mutters : Never 'eard of any "+ who + ".\n" );
	return 0;
    }

    if( !(target = find_player( who )) )
things = move_and_check( things, this_object() );
    else
      things = move_and_check( things, target );
    if( sizeof( things ) )
    {
write("You pay the clerk, and a courier accepts "
+query_multiple_short(things) +" from you.\n");
	if( sizeof( things ) == 1 )
	    say( "A post-office courier wanders up to " + this_player()->query_cap_name() +
		 " and accepts a parcel from " + this_player()->query_objective() + ".\n" );
	else
	    say( "A post-office courier wanders up to " + this_player()->query_cap_name() +
		 " and accepts a number of parcels from " + this_player()->query_objective() + ".\n" );
	if( target )
	{
tell_object( target, "A post-office courier wanders up to you and hands you "+
query_multiple_short(things)+", muttering something about a delivery from "
+this_player()->query_cap_name()+".\n");
	    tell_room( environment( target ),
		       "A post office courier wanders up to " + target->query_cap_name() +
		       " and hands " + target->query_objective() + " something.\n",
		       ({ target }) );
	}
else
 move_all_to_store( things );

	return 1;
    }
    return 0;
}

int     collect_parcel()
{
    string *things;

    things = parcels[(string)this_player()->query_name()];
    if( !things || !sizeof( things ) )
    {
	notify_fail( "There have been no parcels left here for you.\n" );
	return 0;
    }
    if( sizeof( things ) )
    {
    "/global/auto_load"->load_auto_load(things, this_player());
write(" You collect "+ (sizeof(things)/3) + " parcels.\n");
parcels = m_delete(parcels, (string)this_player()->query_name() );
	say( this_player()->query_cap_name() + " collects some parcels.\n" );
    }
    return 1;
}