/**
* The standard inheritable object for player-run shop counters.
* This object defines the section of the shop behind the counter,
* containing the register and sales log. The majority of player-shop
* functionality is handled from within the main office. See the
* header file for a complete description of the shop's workings.
* @see /include/player_shop.h
* @see /std/shops/player_shop/office.c
* @see /std/shops/player_shop/mgr_office.c
* @see /std/shops/player_shop/storeroom.c
* @see /std/shops/player_shop/shop_front.c
* @see /std/shops/player_shop/shopkeeper.c
* @author Ringo
* @started 1st August 1999
*/
#include <player_shop.h>
#include <money.h>
inherit ROOM_OBJ;
int do_calc( float, string, float );
int do_log( mixed * );
int do_correction( mixed * );
int action( string );
private nosave mixed *_money;
private nosave object _register = 0;
private nosave string _save_file = "",
_place = "???",
_office = "",
_storeroom = "",
_mgr_office = "",
_shop_front = "",
_store_dir = "",
_office_dir = "",
_shop_dir = "";
/** @ignore yes */
void create()
{
do_setup++;
::create();
do_setup--;
add_property( "no burial", 1 );
add_property( "determinate", "" );
if ( !do_setup )
{
this_object()->setup();
this_object()->reset();
}
add_item( "calculator", "A standard shop's calculator used to total "
"up all those difficult prices. To use, see \"syntax calc\"." );
}
/* create() */
/** @ignore yes */
void init()
{
::init();
if ( !_office || _office == "" )
{
return;
}
this_player()->command_override( (: action :) );
add_command( "calc", "<number> {+|-|*|/} <number>",
(: do_calc($4[0],$4[1],$4[2]) :) );
if ( _office->query_employee( this_player()->query_name() ) ||
creatorp(this_player()) )
{
add_command( "log",
"shop {bought|sold} <number> <string'item(s)'> for <word'amount'>",
(: do_log($4) :) );
add_command( "correction",
"shop {bought|sold} <number> <string'item(s)'> for <word'amount'>",
(: do_correction($4) :) );
}
}
/* init() */
/**
* Set the path of the main office.
* @param path The full path & filename.
*/
void set_office( string path )
{
object cash;
_office = path;
_storeroom = _office->query_storeroom();
_mgr_office = _office->query_mgr_office();
_shop_front = _office->query_shop_front();
_place = _office->query_place();
if ( _register )
{
return;
}
_register = clone_object( "/obj/misc/cash_register" );
_register->set_name( "register" );
_register->set_short( "cash register" );
_register->add_adjective( "cash" );
_register->set_long( "The cash register is really just an iron drawer "
"mounted underneath the counter. In a certain light, it almost "
"seems tongue-shaped.\n" );
_register->set_shop( this_object() );
add_hidden_object( _register );
_register->reset_get();
_money = _office->restore_register();
if ( !_money || sizeof( _money ) < 2 )
{
return;
}
cash = clone_object( MONEY_OBJECT );
cash->set_money_array( _money );
cash->move( _register );
}
/* set_office() */
/** @ignore yes */
void save_me( mixed *old, string word ) {
int difference;
string sign;
object cash;
if ( !_register )
{
return;
}
if ( member_array( _register, query_hidden_objects() ) == -1 )
{
tell_room( this_object(), "The register emerges from the counter "
"again.\n" );
add_hidden_object( _register );
}
cash = present( MONEY_ALIAS, _register );
if ( !cash )
{
_money = ({ });
}
else
{
_money = cash->query_money_array();
}
_office->save_register( _money );
difference =
((sizeof(_money) > 1) ?
(MONEY_HAND->query_total_value( _money, _place )) : 0) -
((sizeof(old) > 1) ? (MONEY_HAND->query_total_value( old, _place )) : 0);
if ( !difference )
{
return;
}
_office->adjust_takings( difference );
if ( difference < 0 )
{
sign = "-";
difference = -difference;
}
else
{
sign = "";
}
if ( !word || word == "" )
{
return;
}
if ( sign == "-" )
{
_office->shop_log( PURCHASE, word, "removed "+
MONEY_HAND->money_value_string( difference, _place )+
" from register" );
}
else
{
_office->shop_log( SALE, word, "added "+
MONEY_HAND->money_value_string( difference, _place )+
" to register" );
}
}
/* save_me() */
/** @ignore yes */
void save_register( int no_player )
{
string word;
if ( !no_player )
{
word = this_player()->query_name();
}
else
{
word = "shop";
}
if ( find_call_out( "save_me" ) == -1 )
{
call_out( "save_me", 3, _money, word );
tell_room( this_object(), "The register retracts into the counter.\n" );
remove_hidden_object( _register );
}
}
/* save_register() */
/** @ignore yes */
int action( string str ) {
string st1;
if ( _office->query_employee( this_player()->query_name() ) ||
creatorp(this_player()) ) {
return 0;
}
sscanf( str,"%s %s",str,st1 );
if( str == "get" || str == "take" ) {
if ( strsrch( st1, "register" ) != -1 )
{
tell_object( this_player(), "You are not an active employee here!\n" );
return 1;
}
}
}
/* action() */
/** @ignore yes */
int query_register() {
int value;
object cash;
value = 0;
cash = present( MONEY_ALIAS, _register );
if ( !cash )
{
return 0;
}
_money = cash->query_money_array() + ({ });
return MONEY_HAND->query_total_value( _money, _place );
}
/* query_register() */
/** @ignore yes */
int adjust_register( string player, int amount ) {
int value;
object cash, change;
if ( amount < 0 )
{
return 0;
}
cash = present( MONEY_ALIAS, _register );
if ( !cash ) {
return 0;
}
_money = cash->query_money_array() + ({ });
value = MONEY_HAND->query_total_value( _money, _place );
if ( value < amount ) {
amount = value;
}
change = MONEY_HAND->pay_amount_from( amount, cash, _place );
if ( change ) {
change->move( _register );
}
_office->shop_log( ACCOUNTS, player, "adjusted the register by "+
MONEY_HAND->money_value_string( amount, _place ) );
call_out( "save_register", 1, 1 );
return amount;
}
/* adjust_register() */
/** @ignore yes */
void add_money_ob( object money )
{
if ( !money ) {
return;
}
money->move( _register );
call_out( "save_register", 1, 1 );
}
/* adjust_register() */
/** @ignore yes */
int do_calc( float a, string sign, float b ) {
string result;
result = a+ " "+ sign+ " "+ b+ " = ";
switch ( sign ) {
case "+" :
result += sprintf( "%.2f", to_float(a + b) );
break;
case "-" :
result += sprintf( "%.2f", to_float(a - b) );
break;
case "*" :
result += sprintf( "%.2f", to_float(a * b) );
break;
case "/" :
if ( !b ) {
tell_object( this_player(),
"That is an invalid equation.\n" );
return 1;
}
result += sprintf( "%.2f", to_float(a / b) );
break;
}
result += "\n";
tell_object( this_player(), result );
add_succeeded_mess( "$N use$s the calculator.\n" );
return 1;
}
/* do_calc() */
/** @ignore yes */
int do_log( mixed *args ) {
_office->shop_log( LOG_ENTRY, this_player()->query_name(),
args[0]+ " "+ args[1]+ " "+ args[2]+ " for "+ args[3] );
add_succeeded_mess( "$N make$s an entry in the transaction log book.\n" );
return 1;
}
/* do_log() */
/** @ignore yes */
int do_correction( mixed *args ) {
_office->shop_log( LOG_ENTRY, this_player()->query_name(),
"ERROR IN LOG - correct entry follows:" );
_office->shop_log( LOG_ENTRY, this_player()->query_name(),
args[0]+ " "+ args[1]+ " "+ args[2]+ " for "+ args[3] );
add_succeeded_mess( "$N make$s a correction in the transaction log book.\n" );
return 1;
}
/* do_correction() */
/**
* Set the directions to other parts of the shop.
* This function is used by the npc shopkeeper to navigate
* around the shop, using the exits at the given directions.
* These directions should be the standard "north", "southeast" etc.
* @param office The direction to the office.
* @param storeroom The direction to the store room.
* @param shop The direction to the shop front.
*/
void set_directions( string office, string storeroom, string shop ) {
_office_dir = office;
_store_dir = storeroom;
_shop_dir = shop;
}
/* set_directions() */
/**
* Query the direction to another part of the shop.
* This function is used by the npc shopkeeper to navigate
* around the shop.
* @param place The full path to the destination.
* @return The direction, or "here" if already there.
*/
string directions_to( string place ) {
if ( place == _storeroom ) {
return _store_dir;
}
if ( place == _office ) {
return _office_dir;
}
if ( place == _shop_front ) {
return _shop_dir;
}
return "here";
}
/* directions_to() */
/**
* Someone has entered the room.
* This function will automatically fire an employee if they have
* teleported to this room. To avoid this happening, or to modify,
* mask this function.
*/
void event_enter( object ob, string message, object from ) {
_office->event_enter( ob, message, from );
}
/* event_enter() */
/**
* Someone has died.
* This function will automatically fire an employee if they have
* killed someone whilst on duty. It will also make a note of anyone
* who has killed an on-duty employee (including the npc shopkeeper). To
* avoid this happening, or to modify, mask this function.
*/
void event_death( object killed, object *others, object killer,
string rmess, string kmess ) {
_office->event_death( killed, others, killer );
}
/* event_death() */
/**
* @ignore yes
* Add standard stuff
*/
void set_long( string long_desc ) {
long_desc += "Employees of the shop can \"log\" transactions or "
"\"correction\"s here. The shop's cash register is under the "
"counter and there is a calculator next to that.\n";
::set_long( long_desc );
}
/* set_long() */