/** * This is the file containing extra controls for the player run * craft shop. We will assume that all player run craft shops will be * rooms and not npcs. * @author Pinkfish * @started Fri Apr 21 13:37:44 PDT 2000 */ inherit "/std/shops/inherit/craft_shop_category"; inherit "/std/shops/inherit/expression_util"; inherit "/std/shops/inherit/person_expressions"; inherit "/std/shops/inherit/object_expressions"; #include <player.h> #include <money.h> #include <move_failures.h> #include <shops/craft_shop.h> #include <player_handler.h> #include <clubs.h> #define EXPRESSION_NO_CLASSES #include <expressions.h> #include <mail.h> #include <nroff.h> #include <player_handler.h> //#define PRESTO_DEBUG #define PLAYER_CRAFT_SHOP_CHECK_PROP "player craft shop check" #define PLAYER_CRAFT_SHOP_SELL 1 #define PLAYER_CRAFT_SHOP_SELL_AUTO 2 #define PLAYER_CRAFT_SHOP_BUY 3 #define PLAYER_CRAFT_SHOP_APPROVE 4 #define PLAYER_CRAFT_SHOP_EXPR_DENY 1 #define PLAYER_CRAFT_SHOP_EXPR_ACCEPT 2 class approval_item { mixed value; string list_name; int markup; int final_cost; } class expression_type { int type; class parse_node* condition; class parse_node* value; string list_name; } class approval { mixed hairy; class expression_type* expressions; int low_cost; int high_cost; mapping items; int num_allowed; int high_cost_deny; } class approval_obs { string seller; string category; int value; string name; int* saved; int enter_time; int* checkout; string* shorts; } #if USE_TRANSACTIONS class shop_transaction { int time; string person; string objects; string name_cat; int type; int amount; mixed extra; } #endif class shop_stats { int num_sold; int value_sold; string seller; string name; } class helper_stats { int num_approved; int total_cost; int num_rejected; mapping items_approved; } class item_stats { int num_sold; int total_cost; int total_made; int num_bought; } class weekly_stats { int num_sold; int total_cost; int total_made; int num_bought; mapping items; mapping helper; } class seller_information { int max_sellable; int value_limit; int deny_value_limit; } private class approval_obs* _waiting_for_approval; private class approval_obs* _approved; private class approval _automatic_approval; // This is the list of allowable list names. private string* _list_names; private int _automatic_percentage; private int _current_save_num; private int _total_outgoing; private int _total_ingoing; private int _time_of_mail; private class parse_node *_tax_expression; #if USE_TRANSACTIONS private class shop_transaction* _transactions; #endif private mapping _sold_stats; private int _stats_start; private mapping _sellers; private mapping _num_checked_so_far; private string* _helpers; private class weekly_stats _weekly_stats; private nosave string _parcel_post; private nosave int _something_checkedout; private nosave int _maximum_inventory; private nosave int _round_value; private nosave int _max_list_names; private nosave int _max_items_in_queue; protected void confirm_approval(string answer, class approval_obs approve, int final_cost); private object* variable_objects(string seller, int cost, object* ob); private int variable_sale_cost(string seller, int cost, object* ob, string name, string category); private string variable_sale_name(string seller, int cost, object* ob, string name, string category); private string variable_sale_category(string seller, int cost, object* ob, string name, string category); private int function_inventory_number(string short, string seller, int cost, object* ob); /* * This methods must be defined in an upper level class. */ string query_owner(); int is_allowed(string person); void event_save(object thing); int is_open_for(string type, string name); void create() { _round_value = 1; if (!_waiting_for_approval) { _waiting_for_approval = ({ }); } if (!_approved) { _approved = ({ }); } if (!_list_names) { _list_names = ({ }); } if (!_automatic_approval) { _automatic_approval = new(class approval); //_automatic_approval->sellers = ({ }); //_automatic_approval->categories = ([ ]); _automatic_approval->expressions = ({ }); _automatic_approval->items = ([ ]); } if (!_automatic_percentage) { _automatic_percentage = 10; } #if USE_TRANSACTIONS if (!_transactions) { _transactions = ({ }); } #endif if (!_sold_stats) { _sold_stats = ([ ]); } if (!_helpers) { _helpers = ({ }); } if (!_stats_start) { _stats_start = time(); } if (!_sellers) { _sellers = ([ ]); } if (!_num_checked_so_far) { _num_checked_so_far = ([ ]); } if (!_tax_expression) { _tax_expression = ({ }); } if (!_weekly_stats) { _weekly_stats = new(class weekly_stats); _weekly_stats->items = ([ ]); _weekly_stats->helper = ([ ]); } // // Set it up so that selling it the normal way gets no money. // set_cut(100); _max_items_in_queue = 100; craft_shop_category::create(); expression_util::create(); set_always_ask_price(1); add_allowed_variable("objects", EXPRESSION_TYPE_OBJECT + EXPRESSION_TYPE_ARRAY_OFFSET, (: variable_objects :) ); add_allowed_variable("salecost", EXPRESSION_TYPE_MONEY, (: variable_sale_cost :) ); add_allowed_variable("salename", EXPRESSION_TYPE_STRING, (: variable_sale_name :) ); add_allowed_variable("salencategory", EXPRESSION_TYPE_STRING, (: variable_sale_category :) ); set_expression_type("shop"); object_expressions::create(); person_expressions::create(); set_no_royalty_commands(1); } /* create() */ /** * This method checks to see if the specifgied person is a helper in the * shop or not. * @param person the person to check if they are a helper * @return 1 if they are a helper, 0 if not */ int is_helper(string person) { if (!_helpers) { _helpers = ({ }); } return member_array(person, _helpers) != -1 || is_allowed(person); } /* is_helper() */ /** * This method strips off enclosing quotation marks, if any * @param str the srtring to strip of quotes * @return the string stripped of quotes */ private string strip_quotes(string str) { if (str) { if (str[0] == '\"') str = str[1 .. ]; if (str[<1] == '\"') str = str[0 .. <2]; } return str; } /** * This method sets the maximum inventory size for the shop. * @param size the maximum inventory size */ void set_maximum_waiting_queue_size(int size) { _max_items_in_queue = size; } /* set_maximum_waiting_queue_size() */ /** * This method returns the maximum inventory size for the shop. * @return the maximum inventory size */ int query_maximum_waiting_queue_size() { return _max_items_in_queue; } /* query_maximum_waiting_queue_size() */ /** * This method sets the maximum inventory size for the shop. * @param size the maximum inventory size */ void set_maximum_inventory_size(int size) { _maximum_inventory = size; } /* set_maximum_inventory_size() */ /** * This method returns the maximum inventory size for the shop. * @return the maximum inventory size */ int query_maximum_inventory_size() { return _maximum_inventory; } /* query_maximum_inventory_size() */ /** * This method sets the parcel post to use for rejecting items. * @param parcel the parcel post office */ void set_parcel_post(string parcel) { _parcel_post = parcel; } /* set_parcel_post() */ /** * This method tells us the current parcel post used for rejecting items. * @return the current parcel post */ string query_parcel_post() { return _parcel_post; } /* query_parcel_post() */ /** * This method figures out the royalty. * @return the royalty */ int query_royalty(string person) { return query_controller()->query_royalty(person); } /* query_royalty() */ /** * This method figures out the owner's money. * @return the owners money */ int query_owners_money() { return query_royalty(query_owner()); } /* query_owners_money() */ /** * This method changes the royalty. * @param person the person to change * @param amount the amount to change by */ void adjust_royalty(string person, int amount) { query_controller()->adjust_royalty(person, amount); } /* query_royalty() */ /** * This method adjusts out the owner's money. * @param amount the amount to adjust it by */ int adjust_owners_money(int amount) { return adjust_royalty(query_owner(), amount); } /* adjust_owners_money() */ /** * THis method sets the amount to round all the sell values for. THis is * deal with annoying currencies like AM money which does not have a * '1' item. * @param round the price to round at */ void set_round_price(int round) { _round_value = round; } /* set_round_price() */ /** * This method returns the amount to round all sell values for. * @return the round price */ int query_round_prices() { return _round_value; } /* query_round_prices() */ /** * This method returns the current approval list for the shop. */ class approval_obs* query_approval_list(int approved) { if (approved) { return _approved; } else { return _waiting_for_approval; } } /* query_approval_list() */ /** * This method returns the number of items currently in the shop by * the specified person. This includes items waiting for approval. */ int query_number_of_items_listed(string name) { int num; class approval_obs bing; name = lower_case(name); num = sizeof(query_controller()->query_owner_sellables(name)); foreach (bing in _waiting_for_approval) { if (lower_case(bing->seller) == name) { num += sizeof(bing->saved); } } return num; } /* query_number_of_items_listed() */ /** * This method checks to see if the specified item is approved. * @param seller the name of the seller * @param value the amount it is sold for * @param name the name of the item being solde * @param sellables the sold items * @param category the category of the sold item * @param final_cost the final cost of the item * @return 1 if is approved, 0 if not, -1 if denied, string if it is approved * with a list name */ mixed is_item_approved(string seller, int value, string name, object* sellables, string category, int ref final_cost) { string short; object ob; int item_approval; class expression_type bing; class parse_node frog; int cost; mixed item; final_cost = ((value * (100 + _automatic_percentage)) / 100); value = value - (cost % _round_value); if (is_allowed(seller) || is_helper(seller)) { // Owners sell for the exact amount the specified. final_cost = value; return 1; } // // This is the value we don't automatically accept at. // seller = lower_case(seller); if (_sellers[seller] && _sellers[seller]->deny_value_limit) { if (_sellers[seller]->deny_value_limit < value) { return -1; } } else if (_automatic_approval->high_cost_deny && _automatic_approval->high_cost_deny <= value) { return -1; } // // Check through the automatic approval stuff to see if we should // approve it. // foreach (ob in sellables) { if (!ob) { // Always deny things with broken objects references. return -1; } short = ob->query_short(); if (_automatic_approval->items[short]) { if (classp(_automatic_approval->items[short])) { item = ((class approval_item)_automatic_approval->items[short])->value; } else { item = _automatic_approval->items[short]; } if (pointerp(item)) { frog = evaluate_expression(item, seller, value, ({ ob }), name, category); cost = frog->value - (frog->value % _round_value); if (cost < value) { item_approval = 0; break; } item_approval++; } else if (item < value) { item_approval = 0; break; } else { item_approval++; } } } if (item_approval) { if (classp(_automatic_approval->items[short])) { class approval_item womble; womble = _automatic_approval->items[short]; if (sizeof(womble) == 3) { _automatic_approval->items[short] = new(class approval_item, markup : womble->markup, value : womble->value, list_name : womble->list_name, final_cost : 0); womble = _automatic_approval->items[short]; } if (womble->markup) { final_cost = ((value * (100 + womble->markup)) / 100); } else if (womble->final_cost) { final_cost = womble->final_cost; } if (womble->list_name) { return womble->list_name; } else { return 1; } } else { return 1; } } // // Then check any setup expressions. // if (!pointerp(_automatic_approval->expressions)) { _automatic_approval->expressions = ({ }); } foreach (bing in _automatic_approval->expressions) { if (evaluate_expression(bing->condition, seller, value, sellables, name, category)->value) { if (bing->type == PLAYER_CRAFT_SHOP_EXPR_ACCEPT) { frog = evaluate_expression(bing->value, seller, value, sellables, name, category); cost = frog->value - (frog->value % _round_value); if (cost >= value) { if (bing->list_name) { return bing->list_name; } else if (classp(_automatic_approval->items[short])) { return ((class approval_item)_automatic_approval->items[short])->list_name; } else { return 1; } } } else { return -1; } } } if (_sellers[seller] && _sellers[seller]->value_limit) { if (_sellers[seller]->value_limit < value) { return 0; } else if (classp(_automatic_approval->items[short])) { return ((class approval_item)_automatic_approval->items[short])->list_name; } else return 1; } else if (_automatic_approval->high_cost && _automatic_approval->high_cost < value) { return 0; } if (_automatic_approval->low_cost && _automatic_approval->low_cost >= value) { if (classp(_automatic_approval->items[short])) { return ((class approval_item)_automatic_approval->items[short])->list_name; } else return 1; } return 0; } /* is_item_approved() */ /** * This method checks to see if the shop is a closed shop and then checks * to see if the person is allowed. * @param person the person to check to see if they are allowed * @return 1 if they are allowed, 0 if not */ int is_allowed_to_use_shop(string person) { return (is_allowed(person) || is_helper(person) || is_open_for("use", person)); } /* is_allowed_to_use_shop() */ /** * @ignore yes */ int check_open(object player, string type) { if (!::check_open(player)) { return 0; } // Make sure that can only sell stuff if the waiting list is not full. if (type == "sell") { if (sizeof(query_approval_list(0)) + sizeof(query_approval_list(1)) >= _max_items_in_queue) { add_failed_mess("Unable to sell things, the shop is full.\n"); return 0; } } if (!is_allowed_to_use_shop(player->query_name())) { add_failed_mess("The shop is currently closed.\n"); return 0; } return 1; } /* check_open() */ /** * @ignore yes */ void set_controller(string name) { ::set_controller(name); query_controller()->set_dont_use_name(1); } /* set_controller() */ /** * @ignore yes */ int is_allowed_to_sell(object *obs, string name, string *sellable_names) { int num; int max; if (_automatic_approval->num_allowed || _sellers[name]) { num = query_number_of_items_listed(name) + sizeof(obs); if (_sellers[name] && _sellers[name]->max_sellable) { max = _sellers[name]->max_sellable; } else { max = _automatic_approval->num_allowed; } if (num > max) { add_failed_mess("You cannot have more than " + max + " items " "listed at " + the_short() + ", with this sale you " "would have " + num + ".\n"); return 0; } } if (sizeof(filter(obs, (: $1->query_property("money") :))) > 0) { add_failed_mess("You cannot sell money.\n"); return 0; } // // Otherwise see if we are over the shops total maximum size. // num = sizeof(query_controller()->query_sell_list_obs()); if (num + sizeof(obs) > query_maximum_inventory_size()) { add_failed_mess("The shop is full, it can only hold " + query_maximum_inventory_size() + " items and it currently " "holds " + num + " items.\n"); return 0; } return 1; } /* is_allowed_to_sell() */ /** * This method finds out the maximum value that this item is allowed * to be sold for based on the current settings of the shop. * @param person the person doing the selling * @param items the item being sold * @return ({ queue limit, deny limit }) */ int* query_maximum_sale_value_both(string person, object item) { int max_deny; int max_accept; string short; class expression_type stuff; mixed app_item; if (_sellers[person]) { if (_sellers[person]->value_limit) { max_accept = _sellers[person]->value_limit; } if (_sellers[person]->deny_value_limit) { max_deny = _sellers[person]->deny_value_limit; } } if (!max_accept) { max_accept = _automatic_approval->high_cost; } if (!max_deny) { max_deny = _automatic_approval->high_cost_deny; } if (!item) { return ({ 0, 0 }); } short = item->query_short(); if (_automatic_approval->items[short]) { if (classp(_automatic_approval->items[short])) { app_item = ((class approval_item)_automatic_approval->items[short])->value; } else { app_item= _automatic_approval->items[short]; } if (pointerp(app_item)) { max_accept = evaluate_expression(app_item, person, 0, ({ item }), 0, 0)->value; } else if (app_item < max_deny) { max_accept = app_item; } } foreach (stuff in _automatic_approval->expressions) { if (evaluate_expression(stuff->condition, person, 0, ({ }), 0, 0)->value) { if (stuff->type == PLAYER_CRAFT_SHOP_EXPR_DENY) { max_deny = evaluate_expression(stuff->value, person, 0, ({ item }), 0, 0)->value; } else { max_accept = evaluate_expression(stuff->value, person, 0, ({ item }), 0, 0)->value; } } } max_accept -= max_accept % _round_value; max_deny -= max_deny % _round_value; return ({ max_accept, max_deny }); } /* query_maximum_sale_value() */ /** * This method will return the maximum value at which the set of items * will be denied. * @param person the person selling the item * @param obs the set of objects * @return the deny value */ int query_maximum_sale_value(string person, object* obs) { int* stuff; object ob; int cur_deny; foreach (ob in obs) { stuff = query_maximum_sale_value_both(person, ob); if (!cur_deny && stuff[1]) { cur_deny = stuff[1]; } else if (cur_deny && cur_deny > stuff[1]) { cur_deny = stuff[1]; } } return cur_deny; } /* query_maximum_sale_value() */ /** @ignore yes */ string query_extra_price_information(string seller, object *obs) { int* max; int* max_tmp; string ret; string place; object ob; max = ({ 0, 0 }); foreach (ob in obs) { max_tmp = query_maximum_sale_value_both(seller, ob); if (max_tmp[0] && max[0] > max_tmp[0]) { max[0] = max_tmp[0]; } if (max_tmp[1] && max[1] > max_tmp[1]) { max[1] = max_tmp[1]; } } ret = ""; place = query_property("place"); if (!place) { place = "default"; } if (max[0]) { ret += "the maximum price you can sell this straight into the " "inventory for is " + MONEY_HAND->money_value_string(max[0], place); } if (max[1]) { if (max[0]) { ret += " and "; } ret += "the maximum price you can sell the item for at all is " + MONEY_HAND->money_value_string(max[1], place); } return capitalize(ret) + ".\n"; } /* query_extra_price_information() */ /** * This method creates a save file for the specified objects autoloading * capability. If the number to write to is non-null then it will * write to that object. * @param ob the object to get an autoload number for * @param fixed_num the file number to write to * @return the auto load number * @see save_it() */ protected int create_auto_load_file(mixed ob, int fixed_num) { mixed *auto_load; string tmp; if (objectp(ob)) { if (this_player()) { catch(auto_load = this_player()->create_auto_load(({ ob }))); } if (!auto_load) { catch(auto_load = PLAYER_OB->create_auto_load(({ ob }))); } if (!auto_load) { // Make it error on the last one... auto_load = AUTO_LOAD_OB->create_auto_load(({ ob })); } } else if (pointerp(ob)) { auto_load = ob; } else { printf("Error! Dammit!\n"); } if (!fixed_num) { do { tmp = do_read_file(CRAFT_SHOP_DATA_SAVE_FILE, "app_" + _current_save_num); if (tmp) { _current_save_num++; } } while (tmp); fixed_num = _current_save_num; } do_save_file(CRAFT_SHOP_DATA_SAVE_FILE, auto_load, "app_" + fixed_num); return fixed_num; } /* create_auto_load_file() */ /** * This method creates a real object from the save file number. * @param num the save file number * @return the nice shiny new object * @see create_auto_load_file() */ protected object create_real_auto_load_object(int num, object player) { string auto_load; object *obs; auto_load = do_read_file(CRAFT_SHOP_DATA_SAVE_FILE, "app_" + num); if (userp(player)) { obs = player->load_auto_load_to_array(auto_load, player); } else if (this_player()) { obs = this_player()->load_auto_load_to_array(auto_load, player); } else { obs = PLAYER_OB->load_auto_load_to_array(auto_load, player); } if (sizeof(obs)) { return obs[0]; } return 0; } /* create_object_from_auto_load() */ /** * This method turns all the specified id into an item to be checked. * @param id the id of the object to create * @param player the player to use for autoloading */ object create_checkout_object(class approval_obs approve, int id, object player) { object ob; int i; ob = create_real_auto_load_object(id, player); if (ob) { ob->add_effect("/std/effects/object/no_save"); ob->add_property(PLAYER_CRAFT_SHOP_CHECK_PROP, ({ approve, id })); i = member_array(id, approve->saved); approve->checkout[i] = 1; event_save(this_object()); _something_checkedout++; } return ob; } /* create_checkout_object() */ /** * This method updates the checked out item and changes to to be what * we now have... * @param ob the object to destroy */ int destroy_checkout_object(object ob) { int id; int *ids; int i; class approval_obs approve; if (!ob) { return 0; } // Make sure we don't end up recursively messing with the same object. ob->add_property("destroy checkout object", 1, 2); if (ob->move("/room/rubbish") != MOVE_OK) { return 0; } debug_printf("Destroying the checkout object %O\n", ob); // // Zap the effect too. // ids = ob->effects_matching("/std/effects/object/no_save"->query_classification()); foreach (id in ids) { ob->delete_effect(id); } id = ob->query_property(PLAYER_CRAFT_SHOP_CHECK_PROP)[1]; approve = ob->query_property(PLAYER_CRAFT_SHOP_CHECK_PROP)[0]; i = member_array(id, approve->saved); approve->checkout[i] = 0; ob->remove_property(PLAYER_CRAFT_SHOP_CHECK_PROP); create_auto_load_file(ob, id); event_save(this_object()); _something_checkedout--; if (_something_checkedout < 0) { _something_checkedout = 0; } return 1; } /* destroy_checkout_object() */ /** * This method checks to see if the specified item is a checked out * item. * @param ob the object to check * @return 1 if it is, 0 if not */ int is_checkout_object(object ob) { return ob->query_property(PLAYER_CRAFT_SHOP_CHECK_PROP); } /* is_checkout_object() */ /** * This method adds an item to the list of items that need to be approved. * @param seller name of the player * @param sellables the list of items to sell * @param value the cost of the item * @param name the name of the items * @param category the category of the item * @param approved a flag to say if this was approved or not * @return obs the objects we bought */ object* add_to_approval_list(string seller, object* sellables, int value, string name, string category, int approved) { class approval_obs stuff; object ob; object* obs; obs = ({ }); foreach (stuff in query_approval_list(approved)) { if (lower_case(stuff->name) == lower_case(name) && stuff->seller == seller && stuff->value == value) { stuff->category = category; foreach (ob in sellables) { if (ob->move("/room/rubbish") == MOVE_OK) { stuff->saved += ({ create_auto_load_file(ob, 0) }); stuff->checkout += ({ 0 }); stuff->shorts += ({ ob->query_short() }); obs += ({ ob }); } } if (sizeof(obs)) { event_save(this_object()); } return obs; } } stuff = new(class approval_obs); stuff->seller = seller; stuff->value = value; stuff->name = name; stuff->category = category; stuff->saved = ({ }); stuff->shorts = ({ }); stuff->enter_time = time(); foreach (ob in sellables) { if (ob->move("/room/rubbish") == MOVE_OK) { stuff->saved += ({ create_auto_load_file(ob, 0) }); stuff->shorts += ({ ob->query_short() }); obs += ({ ob }); } } stuff->checkout = allocate(sizeof(stuff->saved)); if (sizeof(obs)) { if (approved) { _approved += ({ stuff }); } else { _waiting_for_approval += ({ stuff }); } event_save(this_object()); } return obs; } /* add_to_approval_list() */ /** * This method removes the item from the approval list. * @param approve the item to remove */ void remove_from_approval_list(class approval_obs approve) { int i; int pos; for (i = 0; i < sizeof(_approved); i++) { if (_approved[i] == approve) { // // Zap the files... // foreach (pos in approve->saved) { do_save_file(CRAFT_SHOP_REMOVE_DATA_SAVE_FILE, 0, "app_" + pos); } _approved = _approved[0..i-1] + _approved[i+1..]; event_save(this_object()); return ; } } for (i = 0; i < sizeof(_waiting_for_approval); i++) { if (_waiting_for_approval[i] == approve) { // // Zap the files... // foreach (pos in approve->saved) { do_save_file(CRAFT_SHOP_REMOVE_DATA_SAVE_FILE, 0, "app_" + pos); } _waiting_for_approval = _waiting_for_approval[0..i-1] + _waiting_for_approval[i+1..]; event_save(this_object()); return ; } } } /* remove_from_approval_list() */ /** * This method adds in transaction into the transaction list. * @param person the person doing the thing * @param objects the string name of the objects * @param type the type of the transaction * @param amount the cost of the transaction * @param name_cat the name/category of the item * @param extra anything extra about the transaction */ void add_transaction(string person, object* objects, int type, int amount, string name_cat, mixed extra) { #if USE_TRANSACTIONS class shop_transaction bing; string str; str = query_multiple_short(objects, 0, 1); bing = new(class shop_transaction); bing->time = time(); bing->person = person; bing->objects = str; bing->type = type; bing->amount = amount; bing->name_cat = name_cat; bing->extra = extra; _transactions += ({ bing }); event_save(this_object()); #endif } /* add_transaction() */ #if USE_TRANSACTIONS /** * This method truns a transaction into a string. * @param trans the transaction * @return the transaction as a string */ string query_transaction_string(class shop_transaction trans) { string ret; string amt; string place; place = query_property("place"); if (!place) { place = "default"; } amt = MONEY_HAND->money_value_string(trans->amount, place); ret = ctime(trans->time)[4..<9] + ": " + trans->person; switch (trans->type) { case PLAYER_CRAFT_SHOP_SELL : ret += " sells " + trans->objects + " (" + trans->name_cat + ") for " + amt; break; case PLAYER_CRAFT_SHOP_SELL_AUTO : ret += " sells " + trans->objects + " (" + trans->name_cat + ") [accepted] for " + amt; break; case PLAYER_CRAFT_SHOP_APPROVE : ret += " approves " + trans->objects + " (" + trans->name_cat + ") sold by " + trans->extra + " for " + amt; break; case PLAYER_CRAFT_SHOP_BUY : ret += " buys " + trans->objects + " (" + trans->name_cat + ") sold by " + trans->extra + " for " + amt; break; } return ret; } /* query_transaction_string() */ #endif /** * This method is called to complete the sale completely. It is split * up into a second function to allow the extra sell stuff * to work neatly. * @param value the value of the objects to sell * @param name the list name * @param sellable the list of objects to sell * @param category the category of the object, 0 if none * @ignore yes */ protected void complete_sale(int value, string name, object *sellable, string category) { string place; object *bought; mixed approve; int final_cost; place = query_property("place"); if (!place) { place = "default"; } // // Make sure we mess with the price before we do any of the approval // things. // _num_checked_so_far = ([ ]); approve = is_item_approved(this_player()->query_name(), value, name, sellable, category, ref final_cost); if (approve == -1) { write("This item is denied sale here, it is not something the " "owner wishes to buy.\n"); say(this_player()->query_cap_name() + " finished attempting to sell " + query_multiple_short(sellable) + " to " + the_short() + ".\n"); return ; } if (approve == 1 || stringp(approve)) { if (stringp(approve)) { name = approve; } } write("Waiting for approval from the shop owner for the items " + query_multiple_short(sellable) + " with the name '" + name + "' selling for " + MONEY_HAND->money_value_string(value, place) + " in category " + category + ".\nIf the item is accepted the " "money will be paid into your royalty pool.\n"); bought = add_to_approval_list(this_player()->query_cap_name(), sellable, value, name, category, approve != 0); if (sizeof(bought)) { add_transaction(this_player()->query_name(), bought, PLAYER_CRAFT_SHOP_SELL, value * sizeof(sellable), name + " in " + category, 0); if (sizeof(bought) != sizeof(sellable)) { write("Unable to sell " + query_multiple_short(sellable - bought) + " to " + the_short() + ".\n"); } say(this_player()->the_short() + " completes selling something " "to the shop.\n"); } else { write("Unable to sell " + query_multiple_short(sellable) + " to " + the_short() + ".\n"); } } /* complete_sale() */ /** * This method returns the position as a two letter value. * @param pos the position to mangle * @return the letter value */ string query_letter_value(int pos) { return sprintf("%c%c", 'A' + (pos / 26), 'A' + (pos % 26)); } /* query_letter_value() */ /** * This method goes from a letter value to a number. * @param letter the letters * @return the number */ int query_number_value(string letter) { if (!strlen(letter)) { return -1; } letter = lower_case(letter); if (strlen(letter) < 2) { if (letter[0] >= 'a' && letter[0] <= 'z') { return letter[0] - 'a'; } } if (strlen(letter) > 2) { return -1; } if (letter[0] >= 'a' && letter[0] <= 'z') { if (letter[1] >= 'a' && letter[1] <= 'z') { return (letter[0] - 'a') * 26 + (letter[1] - 'a'); } } return -1; } /* query_number_value() */ /** * This method returns the approval class from the string name. THis is * assumed to be called from inside a command. * @param name the string name * @param approved from the approved or waiting list * @return the approval object */ class approval_obs query_approval_class(string name) { int pos; if (name[0] == '-') { pos = query_number_value(name[1..]); } else { pos = query_number_value(name); } if (pos == -1) { add_failed_mess(name + " is not a valid number.\n"); return 0; } if (name[0] == '-') { if (!sizeof(query_approval_list(0))) { add_failed_mess("There is nothing in the approval list currently.\n"); return 0; } if (pos >= sizeof(query_approval_list(0))) { add_failed_mess("The " + name + " is out of range, must be " "between -AA and -" + query_letter_value(sizeof(query_approval_list(0)) - 1) + ".\n"); return 0; } return query_approval_list(0)[pos]; } if (pos >= sizeof(query_approval_list(1))) { add_failed_mess("The " + name + " is out of range, must be between AA-" + query_letter_value(sizeof(query_approval_list(1)) - 1) + ".\n"); return 0; } return query_approval_list(1)[pos]; } /* query_approval_class() */ /** @ignore yes */ int ownership_change(string old_owner, string new_owner) { class parse_node* expr; if (old_owner == new_owner) { return 0; } // // Setup all the defaults. // _automatic_approval = new(class approval); //_automatic_approval->sellers = ({ }); //_automatic_approval->categories = ([ ]); _automatic_approval->items = ([ ]); _automatic_approval->expressions = ({ }); _automatic_percentage = 10; #if USE_TRANSACTIONS _transactions = ({ }); #endif _sold_stats = ([ ]); _stats_start = time(); _sellers = ([ ]); expr = parse_boolean_string("false"); } /* ownership_change() */ /** @ignore yes */ void inform_of_buy(int value, object *obs, object player, string *sellers, string *names, string *cats, int *values) { string name_cat; int i; class shop_stats stat; _total_ingoing += value; adjust_royalty(query_owner(), value); for (i = 0; i < sizeof(obs); i++) { name_cat = names[i] + " in " + cats[i]; add_transaction(this_player()->query_name(), obs[i..i], PLAYER_CRAFT_SHOP_BUY, values[i], name_cat, sellers[i]); if (!_sold_stats) { _sold_stats = ([ ]); } stat = _sold_stats[sellers[i] + " - " + name_cat]; if (!stat) { stat = new(class shop_stats); stat->name = name_cat; stat->seller = sellers[i]; } stat->num_sold++; stat->value_sold += values[i]; _sold_stats[sellers[i] + " - " + name_cat] = stat; // Weekly stats. /* if (!_weekly_stats->items[names[i]]) { _weekly_stats->items[names[i]] = new(class item_stats); } _weekly_stats->items[names[i]]->num_sold++; _weekly_stats->items[names[i]]->total_made += values[i]; */ } // // Weekly stats data management. // _weekly_stats->total_made += value; } /* inform_of_buy() */ /** @ignore yes */ object* check_for_checkout(object ob) { object* obs = ({ }); if (_something_checkedout && ob) { // // Give them a look. // if (living(ob)) { obs = filter(deep_inventory(ob), (: is_checkout_object($1) :)); if (sizeof(obs)) { foreach (ob in obs) { if (!destroy_checkout_object(ob)) { obs -= ({ ob }); } } } } else { if (is_checkout_object(ob)) { call_out("verify_destroy_checkout_object", 2, ob); //obs = ({ ob }); } } return obs; } return ({ }); } /* check_for_checkout() */ /** @ignore yes */ void verify_destroy_checkout_object(object ob) { // If it is destroyed, tell people about it. if (destroy_checkout_object(ob)) { tell_room(environment(), ob->the_short() + " magically checks itself back in.\n"); } } /** @ignore yes */ void event_exit(object ob, string message, object to) { object *obs; // Already being checked if (ob->query_property("destroy checkout object")) { return ; } obs = check_for_checkout(ob); if (sizeof(obs)) { tell_object(ob, "You suddenly find the uncheckout items " + query_multiple_short(obs) + " check themselves " "back in.\n"); obs->move("/room/rubbish"); } } /* event_exit() */ /** @ignore yes */ void event_dest_me(object ob) { check_for_checkout(ob); } /* event_dest_me() */ /** * This method returns all the checkedout objects to the shop. */ void return_all_checkedout_objects() { object ob; object* obs; if (_something_checkedout) { obs = filter(deep_inventory(this_object()), (: is_checkout_object($1) :)); if (sizeof(obs)) { foreach (ob in obs) { destroy_checkout_object(ob); } } tell_room(this_object(), query_multiple_short(obs) + " mysteriously check themselves back in.\n"); } } /* return_all_checkedout_objects() */ /** @ignore yes */ void dest_me() { ::dest_me(); } /* dest_me() */ /** * @ignore yes * In a player run shop we change this so that only allowed people can change * an item once it is sold. */ int is_able_to_change(object ob) { return is_allowed(this_player()->query_name()) || is_helper(this_player()->query_name()); } /* is_able_change_ob() */ /** * @ignore yes */ int do_buy(object *obs, int force) { if (!is_open_for("buy", this_player()->query_name()) || !is_open_for("use", this_player()->query_name())) { add_failed_mess("You cannot buy anything at this shop.\n"); return 0; } return ::do_buy(obs, force); } /* do_buy() */ /** * This method runs through the objects and checks to see what sort of levels * they are allowed to sell them for to this shop. * @return 1 on success, 0 on failure */ int do_check_sell(object *obs) { int *stuff; object ob; string ret; string place; place = query_property("place"); if (!place) { place = "default"; } ret = ""; foreach (ob in obs) { stuff = query_maximum_sale_value_both(this_player()->query_name(), ob); ret += "$I$5=$C$" + the_short() + ": "; if (stuff[0]) { ret += "will be queued for more than " + MONEY_HAND->money_value_string(stuff[0], place); } if (stuff[0] && stuff[1]) { ret += " and "; } if (stuff[1]) { ret += "will be denied for more than " + MONEY_HAND->money_value_string(stuff[1], place); } ret += ".\n"; } write("$P$Check Sell$P$" + ret); add_succeeded_mess(({ "", "$N checks the sale of $I.\n" }), obs); return 1; } /* do_check_sell() */ /** * List the items for approval. */ int do_list_approval(int approved) { class approval_obs approve; int pos; int shown; int allowed; int checkout; string place; string ret; object* obs; object *current; object* result; string *possible_names; string start; mapping result_type; int i; int fluff; place = query_property("place"); if (!place) { place = "default"; } allowed = is_allowed(this_player()->query_name()) || is_helper(this_player()->query_name()); if (!allowed) { approved = 1; } if (!approved) { start = "-"; } else { start = ""; } result_type = ([ ]); ret = ""; while (allowed || approved) { if (approved == 2) { approved = 0; start = "-"; } foreach (approve in query_approval_list(approved)) { if (lower_case(approve->seller) == this_player()->query_name() || allowed) { checkout = sizeof(filter(approve->checkout, (: $1 :))); /* if (sizeof(approve) == 7) { possible_names = ({ "womble" }); } else { possible_names = approve->shorts; } */ obs = ({ }); for (i = 0; i < sizeof(approve->saved); i++) { fluff = approve->saved[i]; obs += ({ create_real_auto_load_object(fluff, this_player()) }); } obs -= ({ 0 }); possible_names = obs->query_short(); obs->move("/room/rubbish"); if (!result_type[lower_case(approve->name)]) { if (!current) { current = map(query_controller()->query_sell_list_obs(), (: query_controller()->query_short_of_shop_object($1) :)); } // Intersection. result = current & possible_names; /* filter(current, (: member_array($1->query_short(), $(possible_names)) > -1 :)); */ result_type[lower_case(approve->name)] = sizeof(result); } ret += start + query_letter_value(pos) + ") " + approve->seller + "'s " + approve->name + " for " + MONEY_HAND->money_value_string(approve->value, place) + " in " + approve->category + ", " + sizeof(approve->saved) + " objects (" + query_multiple_short(obs) + ") " + result_type[lower_case(approve->name)] + " in stock"; if (checkout) { ret += " and " + checkout + " checked out.\n"; } else { ret += ".\n"; } shown++; } pos++; } if (!allowed && approved) { approved = 2; pos = 0; } else { break; } } if (sizeof(current)) { current->dest_me(); } if (!shown) { add_failed_mess("No items to approve at the moment.\n"); return 0; } write("$P$Approval list$P$The current approval items are:\n" + ret); return 1; } /* do_list_approval() */ /** * This method returns the item to the person that started to sell it. * This only works before the item has been approved. * @param name the name of the item to return */ int do_return(string name) { object *obs; object *ok; object *here; object *fail; object *checkout; object money; class approval_obs approve; object ob; int pos; int i; int value; string place; approve = query_approval_class(name); if (!approve) { return 0; } if (lower_case(approve->seller) != this_player()->query_name()) { add_failed_mess("You must be the one that sold the item to return " "it.\n"); return 0; } obs = ({ }); checkout = ({ }); if (sizeof(filter(approve->checkout, (: $1 :))) > 0 && _something_checkedout) { // // Try and return it. // return_all_checkedout_objects(); } for (i = 0; i < sizeof(approve->saved); i++) { pos = approve->saved[i]; if (!approve->checkout[i]) { obs += ({ create_real_auto_load_object(pos, this_player()) }); } else { checkout += ({ create_real_auto_load_object(pos, this_player()) }); } } obs -= ({ 0 }); checkout -= ({ 0 }); if (sizeof(checkout)) { place = query_property("place"); if (!place) { place = "default"; } write("The items " + query_multiple_short(checkout) + " are currently checked out. You are reimbused the amount " "they would have cost to sell.\n"); value = approve->value * sizeof(checkout); money = MONEY_HAND->make_new_amount( value, place); money->move(this_player()); _total_outgoing += approve->value * sizeof(checkout); } ok = ({ }); here = ({ }); fail = ({ }); foreach (ob in obs) { if (ob->move(this_player()) == MOVE_OK) { ok += ({ ob }); } else if (ob->move(environment(this_player()))) { here += ({ ob }); } else { fail += ({ ob }); } } remove_from_approval_list(approve); if (sizeof(ok)) { add_succeeded_mess("$N return$s $I.\n", map(ok, (: $1->poss_short() :))); } if (sizeof(here)) { add_succeeded_mess("$N $V their $I and they get put on the floor.\n", map(ok, (: $1->poss_short() :))); } if (sizeof(fail)) { add_succeeded_mess( ({ "You find that $I do not want to be moved.\n", "" }), fail); } return 1; } /* do_return() */ /** * This method approves the specified item. */ int do_approve_item(string name, string money_str) { int cost; object *obs; class approval_obs approve; string place; int final_cost; int num; if (!is_allowed(this_player()->query_name()) && !is_helper(this_player()->query_name())) { add_failed_mess("You are not allowed to approve items.\n"); return 0; } approve = query_approval_class(name); if (!approve) { return 0; } place = query_property("place"); if (!place) { place = "default"; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } num = sizeof(query_controller()->query_sell_list_obs()); if (num + sizeof(approve->saved) > query_maximum_inventory_size()) { add_failed_mess("You cannot approve anything, the shop is already " "at the maximum number allowed.\n"); return 0; } cost = approve->value * sizeof(obs); if (this_player()->query_value_in(place) < cost) { add_failed_mess("You need at least " + MONEY_HAND->money_value_string(cost, place) + " to put this into the shop.\n"); return 0; } if (money_str) { final_cost = MONEY_HAND->value_from_string(money_str, place); if (!final_cost) { add_failed_mess("The amount " + money_str + " is not a valid " "money cost.\n"); return 0; } } if (sizeof(filter(approve->checkout, (: $1 :))) > 0 && _something_checkedout) { // // Try and return it. // write("One of these objects is still checkedout, do you wish to " "continue this without these items? "); input_to("confirm_approval", 0, approve, final_cost); add_succeeded_mess( ({ "", "$N approves something in the shop.\n" }) ); return 1; } confirm_approval("y", approve, final_cost); return 1; } /* do_approve_item() */ /** * This method resets all the weekly stats information back to zero. */ void reset_weekly_status() { _weekly_stats = new(class weekly_stats); _weekly_stats->num_sold = 0; _weekly_stats->total_cost = 0; _weekly_stats->total_made = 0; _weekly_stats->num_bought = 0; //_weekly_stats->items = ([ ]); _weekly_stats->helper = ([ ]); } /* reset_weekly_stats() */ /** * This method returns a nice string representation of the weekly stats. * @return the string representation of the weekly stats */ string query_weekly_status_string() { string ret; string place; string player; class helper_stats helpers; class item_stats items; string* item_bits; string item; int num; place = query_property("place"); ret = "$I$0=Total Outgoing : " + MONEY_HAND->money_value_string(_weekly_stats->total_cost, place) + "\n"; ret += "$I$0=Total Incoming : " + MONEY_HAND->money_value_string(_weekly_stats->total_made, place) + "\n"; if (_weekly_stats->total_made > _weekly_stats->total_cost) { ret += "$I$0=Profit of : " + MONEY_HAND->money_value_string(_weekly_stats->total_made - _weekly_stats->total_cost, place) + "\n"; } else { ret += "$I$0=Loss of : " + MONEY_HAND->money_value_string(-(_weekly_stats->total_made - _weekly_stats->total_cost), place) + "\n"; } ret += "$I$0=Items : " + _weekly_stats->num_sold + " sold and " + _weekly_stats->num_bought + " bought.\n"; ret += "\n$I$0=Player summaries:\n"; foreach (player, helpers in _weekly_stats->helper) { item_bits = ({ }); if (sizeof(helpers->items_approved)) { foreach (item, num in helpers->items_approved) { item_bits += ({ num + " " + item }); } } else { item_bits = ({ "nothing" }); } ret += "$I$6= " + player + ": " + helpers->num_approved + " approved, " + helpers->num_rejected + " rejected, " + MONEY_HAND->money_value_string(helpers->total_cost, place) + " approved " + query_multiple_short(item_bits) + "\n"; } /* ret += "\n$I$0=Item Summaries:\n"; foreach (item, items in _weekly_stats->items) { ret += "$I$6= " + item + ": " + items->num_sold + " sold, " + items->num_bought + " bought. Cost " + MONEY_HAND->money_value_string(items->total_cost, place) + ", made " + MONEY_HAND->money_value_string(items->total_made, place) + ", profit " + MONEY_HAND->money_value_string(items->total_made - items->total_cost, place) + "\n"; } */ return ret; } /* query_weekly_stats_string() */ /** * This method is called when an item is approved so people can do whatever * they want to about it. In this case, we keep track of statistics. * @param name the name of the peron doing the approval * @param cost the cost it ws approved for * @param approve the approval class */ protected void inform_of_approved_item(string name, int cost, class approval_obs approve) { string str; // // Weekly stats data management. // if (!_weekly_stats) { _weekly_stats = new(class weekly_stats); _weekly_stats->items = ([ ]); _weekly_stats->helper = ([ ]); } _weekly_stats->total_cost += cost; str = approve->name; // + " in " + approve->category; /* if (!_weekly_stats->items[str]) { _weekly_stats->items[str] = new(class item_stats); } _weekly_stats->items[str]->num_bought++; _weekly_stats->items[str]->total_cost += cost; */ name = this_player()->query_name(); if (!_weekly_stats->helper[name]) { _weekly_stats->helper[name] = new(class helper_stats); _weekly_stats->helper[name]->items_approved = ([ ]); } _weekly_stats->helper[name]->num_approved++; _weekly_stats->helper[name]->total_cost += cost; if (!mapp(_weekly_stats->helper[name]->items_approved)) { _weekly_stats->helper[name]->items_approved = ([ ]); } _weekly_stats->helper[name]->items_approved[str]++; } /* inform_of_approved_items() */ /** * This method is called when an item is rejected so people can do whatever * they want to about it. In this case, we keep track of statistics. * @param name the name of the peron doing the rejection * @param approve the approval class */ protected void inform_of_rejected_item(string name, class approval_obs approve) { // // Weekly stats data management. // if (!_weekly_stats) { _weekly_stats = new(class weekly_stats); _weekly_stats->items = ([ ]); _weekly_stats->helper = ([ ]); } name = this_player()->query_name(); if (!_weekly_stats->helper[name]) { _weekly_stats->helper[name] = new(class helper_stats); } _weekly_stats->helper[name]->num_rejected++; } /* inform_of_rejected_items() */ /** @ignore yes */ protected void confirm_approval(string answer, class approval_obs approve, int final_cost) { int pos; int i; int bing; int cost; object *obs; object *bought; object *checkout; string place; if (strlen(answer) < 1 || lower_case(answer)[0] != 'y') { write("Ok, canceled the approval of the item.\n"); return ; } place = query_property("place"); if (!place) { place = "default"; } // // Approval means we create all the objects, remove them, and then // send them off to the main engine... // obs = ({ }); checkout = ({ }); for (i = 0; i < sizeof(approve->saved); i++) { pos = approve->saved[i]; if (!approve->checkout[i]) { obs += ({ create_real_auto_load_object(pos, this_player()) }); } else { checkout += ({ create_real_auto_load_object(pos, this_player()) }); } } obs -= ({ 0 }); checkout -= ({ 0 }); if (sizeof(checkout)) { write("The items " + query_multiple_short(checkout) + " were " "checked out and therefore lost.\n"); } if (!final_cost) { final_cost = ((approve->value * (100 + _automatic_percentage)) / 100); } final_cost -= final_cost % _round_value; obs->remove_property("dropped"); bought = query_controller()->buy_objects(obs, approve->name, final_cost, approve->seller, approve->category, 1); if (sizeof(bought)) { cost = approve->value * (sizeof(obs) + sizeof(checkout)); cost -= cost % _round_value; _total_outgoing += cost; remove_from_approval_list(approve); adjust_royalty(lower_case(approve->seller), cost); // // Try and remove from the cash float first. // if (query_owners_money() > 0) { if (query_owners_money() > cost) { adjust_owners_money(-cost); cost = 0; } else { cost -= query_owners_money(); adjust_owners_money(-query_owners_money()); } } if (cost > 0) { if (this_player()->query_value_in(place) > 0) { bing = this_player()->query_value_in(place); if (bing > cost) { bing = cost; cost = 0; } else { cost -= bing; } if (bing) { this_player()->pay_money(MONEY_HAND->create_money_array(bing, place), place); } } if (cost > 0) { adjust_owners_money(-cost); } } write("You approve " + query_multiple_short(obs) + " to be sold as " + approve->name + " in " + approve->category + " for " + MONEY_HAND->money_value_string(approve->value, place) + ".\n"); add_succeeded_mess( ({ "", "$N approves something in the shop.\n" }) ); // Statistics collection. cost = approve->value * (sizeof(obs) + sizeof(checkout)); cost -= cost % _round_value; inform_of_approved_item(this_player()->query_name(), cost, approve); add_transaction(this_player()->query_name(), obs, PLAYER_CRAFT_SHOP_APPROVE, approve->value * (sizeof(obs) + sizeof(checkout)), approve->name + " in " + approve->category, approve->seller); } else { write("Unable to move the items into the shops inventory, you " "will need to reject this item.\n"); } return ; } /* do_approve_item() */ /** * This method rejects the specified item. */ int do_approve_reject(string name, string mess, int reject_pos) { object *obs; object *ok; object *here; object *checkout; object ob; object play; class approval_obs approve; int pos; int i; int ret; string ob_mess; approve = query_approval_class(name); if (!approve) { return 0; } if (lower_case(approve->seller) == this_player()->query_name()) { // // Return the stuff to them. // return do_return(name); } if (!is_allowed(this_player()->query_name()) && !is_helper(this_player()->query_name())) { add_failed_mess("You're not allowed to reject items.\n"); return 0; } if (sizeof(filter(approve->checkout, (: $1 :))) > 0 && _something_checkedout) { // // Try and return it. // return_all_checkedout_objects(); } if (reject_pos != -1 && (reject_pos <= 0 || reject_pos > sizeof(approve->saved))) { add_failed_mess("You cannot reject the item of position " + reject_pos + " since there are only " + sizeof(approve->saved) + " items.\n"); return 0; } if (reject_pos != -1) { reject_pos--; } // // Approval means we create all the objects, remove them, and then // send them off to the main engine... // obs = ({ }); checkout = ({ }); for (i = 0; i < sizeof(approve->saved); i++) { if (reject_pos == -1 || reject_pos == i) { pos = approve->saved[i]; if (!approve->checkout[i]) { obs += ({ create_real_auto_load_object(pos, this_player()) }); } else { checkout += ({ create_real_auto_load_object(pos, this_player()) }); } } } obs = filter(obs, (: $1 && objectp($1) :)); checkout = filter(checkout, (: $1 && objectp($1) :)); if (member_array(0, obs) != -1) { add_failed_mess("There seems to be a problem with this rejection set, " "one of the items is 0.\n"); return 0; } if (reject_pos != -1 && sizeof(checkout)) { add_failed_mess("The item $I has been checked out, you cannot reject " "it.\n", checkout); return 0; } if (sizeof(checkout)) { write("The items " + query_multiple_short(checkout) + " were " "checked out and lost.\n"); adjust_royalty(lower_case(approve->seller), approve->value * sizeof(checkout)); AUTO_MAILER->auto_mail(lower_case(approve->seller), this_player()->query_name(), "Rejected items", "", sprintf("%-=75s", this_player()->query_name() + " lost your " + query_multiple_short(checkout, "the", 1) + ",so you have been paid but the items " "were not returned.\n")); } inform_of_rejected_item(this_player()->query_name(), approve); if (!sizeof(obs)) { write("Nothing to give back or send off.\n"); } else { // // They are here, so give it back. // play = find_player(lower_case(approve->seller)); if (play && environment(play) == this_object()) { ok = ({ }); here = ({ }); foreach (ob in obs) { if (ob) { if (ob->move(play) == MOVE_OK) { ok += ({ ob }); } else if (ob->move(environment(play)) == MOVE_OK) { here += ({ ob }); } } } if (sizeof(ok)) { tell_object(play, "Your items: " + query_multiple_short(obs) + " have been rejected " "and placed in your inventory.\n"); } if (sizeof(here)) { tell_object(play, "Your items: " + query_multiple_short(obs) + " have been rejected " "and placed on the floor here.\n"); } write("You reject the item.\n"); } else { if (!query_parcel_post()) { add_failed_mess("Eeek! No parcel post defined on this room.\n"); return 0; } else if(!load_object(query_parcel_post())) { add_failed_mess("Eeek! Parcel post cannot be loaded.\n"); return 0; } ob_mess = "The shop " + this_player()->convert_message(the_short()) + " rejected " + query_multiple_short(obs, "the", 1) + " because:\n"; if (!mess) { mess = "They didn't want to add a reject message."; } ret = query_parcel_post()->deposit_parcel(obs, lower_case(approve->seller), 1); if (ret != 1) { if (ret == -5) { write("The player " + approve->seller + " has been denied use " "of the parcel post system, tossing objects away.\n"); obs->move("/room/rubbish"); if (mess) { write("Still sending the message to the person.\n"); mess += "\nYou were denied use of the parcel post system " "so your objects were thrown away.\n"; } } else if (ret == -4) { write("You have been denied use of the postal system, perhaps " "you could try clearing this up with the creators?\n"); obs->move("/room/rubbish"); return 1; } else if (ret == -2) { write("The player " + approve->seller + " no longer exists, " "tossing objects away.\n"); obs->move("/room/rubbish"); } else { add_failed_mess("Unable to send the parcel for some reason (" + ret + ").\n"); obs->move("/room/rubbish"); return 0; } } if (ret != -2) { if (mess) { AUTO_MAILER->auto_mail(approve->seller, this_player()->query_name(), "Rejected items", "", ob_mess + mess); } else { write("You reject the item and it is parcel posted back to the " "person who " "sent it.\nWould you like to send them a note about it as well? "); obs -= ({ 0 }); input_to("check_reject_note", 0, ob_mess, approve->seller); } } } } if (reject_pos != -1) { approve->saved = approve->saved[0..reject_pos-1] + approve->saved[reject_pos+1..]; event_save(this_object()); if (!sizeof(approve->saved)) { reject_pos = -1; } } if (reject_pos == -1) { remove_from_approval_list(approve); } add_succeeded_mess(({ "", "$N reject$s a sellable object.\n" })); return 1; } /* do_approve_reject() */ /** * @ignore yes */ void check_reject_note(string str, string ob_str, string name) { str = lower_case(str); if (!strlen(str) || (str[0] != 'y' && str[0] != 'n')) { write("Please answer yes or no.\nWould you like to send them " "a note about it as well?"); input_to("check_reject_note", 0, ob_str, name); return ; } if (str[0] == 'n') { write("ok, bye then!\n"); return ; } this_player()->do_edit("Your items " + ob_str + " were rejected " "from " + the_short() + ".\n\n", "send_reject_note", this_object(), 0, name); } /* check_reject_note() */ /** @ignore yes */ void send_reject_note(string mess, string name) { if (!mess) { write("Aborted.\n"); return ; } //write("Sending to " + name + ".\n"); AUTO_MAILER->auto_mail(name, this_player()->query_name(), "Rejected items", "", mess); } /* send_reject_note() */ /** * This method browses the specified item. */ int do_approve_browse(string name) { object *obs; object ob; string read; string ret; string bits; class approval_obs approve; int pos; string place; approve = query_approval_class(name); if (!approve) { return 0; } if (lower_case(approve->seller) == this_player()->query_name()) { // // Return the stuff to them. // return do_return(name); } if (!is_allowed(this_player()->query_name()) && !is_helper(this_player()->query_name())) { add_failed_mess("You are not allowed to reject items.\n"); return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } place = query_property("place"); if (!place) { place = "default"; } // // Create the objects, browse them, kill them. // obs = ({ }); foreach (pos in approve->saved) { obs += ({ create_real_auto_load_object(pos, this_player()) }); } obs -= ({ 0 }); ret = ""; foreach (ob in obs) { ret += ob->the_short() + ": (Base cost " + MONEY_HAND->money_value_string(ob->query_base_value(), place) + "; scaled cost " + MONEY_HAND->money_value_string(ob->query_value(), place) + ")\n" + ob->long(); read = ob->query_readable_message(); if (read) { bits = ob->query_read_short(this_player()); if (!bits) { bits = "$name$"; } ret += "You read " + replace_string(ob->query_read_short(this_player()), "$name$", ob->a_short()) + ":\n" + ob->query_readable_message(); } } obs->move("/room/rubbish"); write("$P$Browse list$P$" + ret); add_succeeded_mess("$N browse$s an item waiting for approval.\n"); return 1; } /* do_approve_browse() */ /** * This method checks out the specified item. */ int do_approve_checkout(string name) { object *obs; object *bad; object *checkout; object ob; class approval_obs approve; int pos; int i; approve = query_approval_class(name); if (!approve) { return 0; } if (lower_case(approve->seller) == this_player()->query_name() && lower_case(approve->seller) != "pinkfish") { // // Return the stuff to them. // return do_return(name); } if (!is_allowed(this_player()->query_name()) && !is_helper(this_player()->query_name())) { add_failed_mess("You are not allowed to reject items.\n"); return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } // // Create the objects, browse them, kill them. // obs = ({ }); checkout = ({ }); for (i = 0; i < sizeof(approve->saved); i++) { pos = approve->saved[i]; if (!approve->checkout[i]) { ob = create_checkout_object(approve, pos, this_player()); if (!ob) { write("Unable to create " + pos + approve->name + ", weird...\n"); } else { obs += ({ ob }); } } else { checkout += ({ create_checkout_object(approve, pos, this_player()) }); } } checkout->move("/room/rubbish"); if (!sizeof(obs) && sizeof(checkout)) { if (sizeof(checkout) > 0) { add_failed_mess("$I are already checked out.\n", checkout); } else { add_failed_mess("$I is already checked out.\n", checkout); } return 0; } bad = ({ }); foreach (ob in obs) { if (ob->move(this_player()) != MOVE_OK) { bad += ({ ob }); destroy_checkout_object(ob); } } if (sizeof(bad)) { write("Unable to move " + query_multiple_short(bad) + " into your " "inventory for you to check.\n"); } obs -= bad; if (sizeof(obs)) { write("Moved " + query_multiple_short(obs) + " into your inventory " "for you to check.\n"); add_succeeded_mess("$N check$s out $I.\n", obs); } return 1; } /* do_approve_checkout() */ /** * This method checks in a checked out object. */ int do_approve_checkin(object* obs) { object ob; object* ok; ok = ({ }); foreach (ob in obs) { if (is_checkout_object(ob)) { destroy_checkout_object(ob); ok += ({ ob }); } } if (!sizeof(ok)) { add_failed_mess("None of $I have been checked out.\n", obs); return 0; } add_succeeded_mess("$N check$s $I back in.\n", ok); return 1; } /* do_approve_checkin() */ /** * This method changes the name of the item to be approved. * @param name the reference * @param new_name the new name for the item */ int do_approve_name_change(string name, string new_name) { class approval_obs approve; if (!is_allowed(this_player()->query_name()) && !is_helper(this_player()->query_name())) { add_failed_mess("You are not allowed to approve items.\n"); return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } approve = query_approval_class(name); if (!approve) return 0; write("You change the name of the item waiting to be approved from " + approve->name + " to " + new_name + ".\n"); approve->name = new_name; add_succeeded_mess( ({ "", "$N messes with the approval items.\n" })); event_save(this_object()); return 1; } /* do_approve_name_change() */ /** * This method changes the category of the item waiting to be approved. * @param name the reference * @param new_category the new category for the item */ int do_approve_category_change(string name, string new_category) { class approval_obs approve; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to approve items.\n"); return 0; } approve = query_approval_class(name); if (!approve) { return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } new_category = query_real_category_name(new_category); if (!new_category || !query_controller()->is_valid_category(new_category)) { add_failed_mess("You must choose a category that exists.\n"); return 0; } approve->category = new_category; add_succeeded_mess(({ "You change the category of the approval item " + name + ".\n", "$N messes with the approval items.\n" })); event_save(this_object()); return 1; } /* do_approve_category_change() */ /** * This method sets the automatic low acception level. * @param cost the cost to use a low level */ int do_approve_auto_low(string cost) { string place; int value; place = query_property("place"); if (!place) { place = "default"; } if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set automatic approval items.\n"); return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } value = value_from_string(cost, place); _automatic_approval->low_cost = value; event_save(this_object()); if (!value) { add_succeeded_mess(({ "You disable the automatic acception of items of " "low value.\n", "$N fiddle$s with something in the shop.\n" }) ); return 1; } add_succeeded_mess(({ "You set the shop to automatically accept any item " "costing less than " + MONEY_HAND->money_value_string(value, place) + ".\n", "$N fiddle$s with something in the shop.\n" }) ); return 1; } /* do_approve_auto_low() */ /** * This method sets the automatic high cut off level. * @param cost the cost to use a high cut off level */ int do_approve_auto_high(string cost) { string place; int value; place = query_property("place"); if (!place) { place = "default"; } if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set automatic approval items.\n"); return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } value = value_from_string(cost, place); if (!value) { _automatic_approval->high_cost = value; add_succeeded_mess(({ "You disable the automatic placing items into the " "approve list of items of high value.\n", "$N fiddle$s with something in the shop.\n" }) ); return 1; } _automatic_approval->high_cost = value; event_save(this_object()); add_succeeded_mess(({ "You set the shop to automatically put any item " "costing more than " + MONEY_HAND->money_value_string(value, place) + " into the approve list.\n", "$N fiddle$s with something in the shop.\n" }) ); return 1; } /* do_approve_auto_high() */ /** * This method sets the automatic high cut off level for denying sales. * @param cost the cost to use a high cut off level */ int do_approve_auto_high_deny(string cost) { string place; int value; place = query_property("place"); if (!place) { place = "default"; } if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set automatic approval items.\n"); return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } value = value_from_string(cost, place); if (!value) { _automatic_approval->high_cost_deny = 0; add_succeeded_mess(({ "You disable the automatic denying of items of " "high value.\n", "$N fiddle$s with something in the shop.\n" }) ); return 1; } _automatic_approval->high_cost_deny = value; event_save(this_object()); add_succeeded_mess(({ "You set the shop to automatically deny any item " "costing more than " + MONEY_HAND->money_value_string(value, place) + ".\n", "$N fiddle$s with something in the shop.\n" }) ); return 1; } /* do_approve_auto_high() */ /** * This method sets the automatic items to allow. * @param item the items short to allow */ int do_approve_auto_item_add(string item, string money, string list_name, int markup, string money_str) { int value; string place; int final_cost; mixed app_item; class approval_item new_app_item; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set automatic approval items.\n"); return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } place = query_property("place"); if (!place) { place = "default"; } value = value_from_string(money, place); if (!value) { add_failed_mess("The value " + money + " is invalid.\n"); return 0; } if (markup < 0) { markup = 0; } item = strip_quotes(item); list_name = strip_quotes(list_name); if (classp(_automatic_approval->items[item])) { app_item = ((class approval_item)_automatic_approval->items[item])->value; } else { app_item = _automatic_approval->items[item]; } if (app_item == value) { add_failed_mess("The item " + item + " already has a cut off " "value of " + MONEY_HAND->money_value_string(value, place) + ".\n"); return 0; } if (money_str) { final_cost = MONEY_HAND->value_from_string(money_str, place); if (!final_cost) { add_failed_mess(money_str + " is an invalid money value.\n"); return 0; } } new_app_item = new(class approval_item); new_app_item->list_name = list_name; new_app_item->value = value; new_app_item->markup = markup; new_app_item->final_cost = final_cost; _automatic_approval->items[item] = new_app_item; place = query_property("place"); event_save(this_object()); add_succeeded_mess(({ "You set the shop to automatically accept any item " "with a short of " + item + " up to a cost " "of " + MONEY_HAND->money_value_string(value, place) + (list_name ? " as \"" + list_name + "\"" : "") + (markup ? " with a markup of " + markup + "%" : "") + (final_cost ? " with a final cost of " + MONEY_HAND->money_value_string(final_cost, place) + "" : "") + ".\n", "$N fiddle$s with something in the shop.\n" }) ); return 1; } /* do_approve_auto_item_add() */ /** * This method sets the automatic items to allow. * @param item the items short to allow */ int do_approve_auto_item_add_object(object *obs, string money, string list_name, int markup, string money_str) { int value; string place; object ob; string name; object *ok; object *bad; mixed item; class approval_item new_item; int final_cost; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set automatic approval items.\n"); return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } place = query_property("place"); if (!place) { place = "default"; } value = value_from_string(money, place); if (!value) { add_failed_mess("The value " + money + " is invalid.\n"); return 0; } if (money_str) { final_cost = MONEY_HAND->value_from_string(money_str, place); if (!final_cost) { add_failed_mess(money_str + " is an invalid money value.\n"); return 0; } } if (markup < 0) { markup = 0; } bad = ({ }); ok = ({ }); list_name = strip_quotes(list_name); foreach (ob in obs) { name = ob->query_short(); if (classp(_automatic_approval->items[name])) { item = ((class approval_item)_automatic_approval->items[name])->value; } else { item = _automatic_approval->items[name]; } if (item == value) { bad += ({ name }); } else { new_item = new(class approval_item); new_item->value = value; new_item->list_name = list_name; new_item->markup = markup; new_item->final_cost = final_cost; _automatic_approval->items[name] = new_item; ok += ({ name }); } } event_save(this_object()); if (sizeof(ok)) { add_succeeded_mess(({ "You set the shop to automatically accept any of " "$I up to a cost " "of " + MONEY_HAND->money_value_string(value, place) + (list_name ? " as \"" + list_name + "\"" : "") + (markup ? " with a markup of " + markup + "%" : "") + (final_cost ? " with a final cost of " + MONEY_HAND->money_value_string(final_cost, place) + "" : "") + ".\n", "$N fiddle$s with something in the shop.\n" }), ok ); return 1; } else { add_failed_mess("You cannot set $I to a value limit of " + MONEY_HAND->money_value_string(value, place) + " since it already has this limit.\n"); return 0; } } /* do_approve_auto_item_add_object() */ /** * This method sets the automatic items to allow. * @param item the items short to allow */ int do_approve_auto_item_add_expr(string item, string expr, string list_name, int markup, string money_str) { class approval_item new_app_item; class parse_node* value; string place; int final_cost; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set automatic approval items.\n"); return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } place = query_property("place"); if (!place) { place = "default"; } value = parse_money_string(expr); if (!sizeof(value)) { add_failed_mess(query_last_expression_error() + ".\n"); return 0; } if (money_str) { final_cost = MONEY_HAND->value_from_string(money_str, place); if (!final_cost) { add_failed_mess(money_str + " is an invalid money value.\n"); return 0; } } if (markup < 0) { markup = 0; } item = strip_quotes(item); list_name = strip_quotes(list_name); new_app_item = new(class approval_item); new_app_item->list_name = list_name; new_app_item->value = value; new_app_item->markup = markup; new_app_item->final_cost = final_cost; _automatic_approval->items[item] = new_app_item; event_save(this_object()); add_succeeded_mess(({ "You set the shop to automatically accept any item " "with a short of " + item + " with an expression " "of " + query_expression_string(value, 1) + (list_name ? " as \"" + list_name + "\"" : "") + (markup ? " with a markup of " + markup + "%" : "") + (final_cost ? " with a final cost of " + MONEY_HAND->money_value_string(final_cost, place) + "" : "") + ".\n", "$N fiddle$s with something in the shop.\n" }) ); return 1; } /* do_approve_auto_item_add_expr() */ /** * This method sets the automatic items to allow. * @param item the items short to allow */ int do_approve_auto_item_add_object_expr(object *obs, string expr, string list_name, int markup, string money_str) { class parse_node* value; object ob; string name; class approval_item new_item; int final_cost; string place; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set automatic approval items.\n"); return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } value = parse_money_string(expr); if (!sizeof(value)) { add_failed_mess(query_last_expression_error() + ".\n"); return 0; } if (money_str) { place = query_property("place"); final_cost = MONEY_HAND->value_from_string(money_str, place); if (!final_cost) { add_failed_mess(money_str + " is an invalid money value.\n"); return 0; } } if (markup < 0) { markup = 0; } list_name = strip_quotes(list_name); foreach (ob in obs) { name = ob->query_short(); new_item = new(class approval_item); new_item->value = value; new_item->list_name = list_name; new_item->markup = markup; new_item->final_cost = final_cost; _automatic_approval->items[name] = new_item; } event_save(this_object()); add_succeeded_mess(({ "You set the shop to automatically accept any of " "$I with an expression " "of " + query_expression_string(value, 1) + (list_name ? " as \"" + list_name + "\"" : "") + (markup ? " with a markup of " + markup + "%" : "") + (final_cost ? " with a final cost of " + MONEY_HAND->money_value_string(final_cost, place) + "" : "") + ".\n", "$N fiddle$s with something in the shop.\n" }), obs ); return 1; } /* do_approve_auto_item_add_object_expr */ /** * This method checks to see if the specified object can really be sold or * not automatically. * @param obs the objects to test */ int do_approve_auto_item_test(object* obs) { object ob; string place; mixed cost; int found; int allowed; class expression_type stuff; class parse_node frog; allowed = is_allowed(this_player()->query_name()) || is_helper(this_player()->query_name()); place = query_property("place"); if (!place) { place = "default"; } foreach (ob in obs) { found = 0; cost = _automatic_approval->items[ob->query_short()]; if (classp(cost)) { cost = ((class approval_item)cost)->value; } if (cost) { if (pointerp(cost)) { frog = evaluate_expression(cost, this_player()->query_name(), 0, ({ ob }), 0, 0); if (allowed) { write("$I$5=The item " + ob->the_short() + " can be sold if it " "costs less than " + query_expression_string(cost, 1) + ";\n" + ob->query_short() + " - " + MONEY_HAND->money_value_string(frog->value, place) + ".\n"); } else { write("$I$5=The item " + ob->the_short() + " can be sold if it " "costs less than " + " " + MONEY_HAND->money_value_string(frog->value, place) + ".\n"); } } else { write("$I$5=The item " + ob->the_short() + " can be sold if it " "costs less than " + MONEY_HAND->money_value_string(cost, place) + " (" + ob->query_short() + ").\n"); } found |= 1; } foreach (stuff in _automatic_approval->expressions) { frog = evaluate_expression(stuff->condition, this_player()->query_name(), 0, ({ ob }), 0, 0); if (frog->value) { if (stuff->type == PLAYER_CRAFT_SHOP_EXPR_ACCEPT) { frog = evaluate_expression(stuff->value, this_player()->query_name(), 0, ({ ob }), 0, 0); if (allowed) { write("$I$5=The item " + ob->the_short() + " can be sold if it " "costs less than " + query_expression_string(stuff->value, 1) + ";\n" + ob->query_short() + " - " + MONEY_HAND->money_value_string(frog->value, place) + ".\n"); } else { write("$I$5=The item " + ob->the_short() + " can be sold if it " "costs less than " + MONEY_HAND->money_value_string(frog->value, place) + ".\n"); } found |= 2; } else { // Denied! found |= 4; } } } if (found & 4) { write("$I$5=The item " + ob->the_short() + " will be denied sale.\n"); } else if (!found) { write("$I$5=The item " + ob->the_short() + " will not be " "automatically accepted.\n"); } } add_succeeded_mess(({ "", "$N fiddle$s with something in the shop.\n" }) ); return 1; } /* do_approve_auto_item_test() */ /** * This method sets the automatic items to allow. * @param item the item to accept */ int do_approve_auto_item_remove(string item) { if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set automatic approval items.\n"); return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } item = strip_quotes(item); if (!_automatic_approval->items[item]) { add_failed_mess("The item " + item + " is not in the list.\n"); return 0; } map_delete(_automatic_approval->items, item); event_save(this_object()); add_succeeded_mess(({ "You remove the item " + item + " from the list of automatically accepted items.\n", "$N fiddle$s with something in the shop.\n" }) ); return 1; } /* do_approve_auto_item_remove() */ /** * This method sets the automatic items to allow. * @param item the item to accept */ int do_approve_auto_item_remove_object(object *obs) { object ob; object *bad; object *ok; string name; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set automatic approval items.\n"); return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } ok = ({ }); bad = ({ }); foreach (ob in obs) { name = ob->query_short(); if (!_automatic_approval->items[name]) { bad += ({ ob }); } else { ok += ({ ob }); map_delete(_automatic_approval->items, name); } } event_save(this_object()); if (sizeof(ok)) { add_succeeded_mess(({ "You remove $I from the list of " "automatically accepted items.\n", "$N fiddle$s with something in the shop.\n" }), ok ); return 1; } add_failed_mess("None of $I are in the shops allow item list for you " "to remove.\n", bad); return 0; } /* do_approve_auto_item_remove() */ /** * This method sets the automatic expressions to allow. * @param expression the expressions short to allow */ int do_approve_auto_expression_add(string expression, string value_str, int type, string list_name) { class parse_node* expr; class parse_node* value; class expression_type bing; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set automatic approval items.\n"); return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } expr = parse_boolean_string(expression); if (!sizeof(expr)) { add_failed_mess(query_last_expression_error() + ".\n"); return 0; } if (type == PLAYER_CRAFT_SHOP_EXPR_ACCEPT) { value = parse_money_string(value_str); if (!sizeof(value)) { add_failed_mess(query_last_expression_error() + ".\n"); return 0; } } list_name = strip_quotes(list_name); bing = new(class expression_type); bing->type = type; bing->condition = expr; bing->value = value; bing->list_name = list_name; _automatic_approval->expressions += ({ bing }); event_save(this_object()); if (type == PLAYER_CRAFT_SHOP_EXPR_ACCEPT) { add_succeeded_mess(({ "You set the shop to automatically accept any item " "matching the expression " + query_expression_string(expr, 0) + " with a cost " "of " + query_expression_string(value, 0) + " as '" + list_name + "'.\n", "$N fiddle$s with something in the shop.\n" }) ); } else { add_succeeded_mess(({ "You set the shop to automatically deny any item " "matching the expression " + query_expression_string(expr, 0) + ".\n", "$N fiddle$s with something in the shop.\n" }) ); } return 1; } /* do_approve_auto_expression_add() */ /** * This method removes an allowed expression * @param id the expression id to remove */ int do_approve_auto_expression_remove(string idstr) { class expression_type expr; int id; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set automatic approval items.\n"); return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } id = query_number_value(idstr); if (id == -1 || id >= sizeof(_automatic_approval->expressions)) { add_failed_mess("The id " + idstr + " is invalid.\n"); return 0; } expr = _automatic_approval->expressions[id]; _automatic_approval->expressions = _automatic_approval->expressions[0..id - 1] + _automatic_approval->expressions[id + 1..]; event_save(this_object()); add_succeeded_mess(({ "You remove the expression " + query_expression_string(expr->condition, 1) + " cost: " + query_expression_string(expr->value, 1) + " from the list of allowed expressions.\n", "$N fiddle$s with something in the shop.\n" }) ); return 1; } /* do_approve_auto_item_remove() */ /** * This method sets the percentage to add to the sell price. * @param num the number to set the percentage to */ int do_approve_percentage(mixed num) { if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set automatic approval items.\n"); return 0; } if (query_owners_money() < 0) { add_failed_mess("You cannot do this until the shop's deficit is payed " "off.\n"); return 0; } if (num <= 0) { add_failed_mess("The percentage to add must be greator than 0.\n"); return 0; } _automatic_percentage = num; add_succeeded_mess(({ "You set the percentage to add to the sale price " "to " + _automatic_percentage + ".\n", "$N fiddle$s with something in the shop.\n" }) ); return 1; } /* do_approve_percentage() */ /** * This method sets the limit on number of items sellable by all the players. * @param limit the default limit */ int do_approve_limit(string limit) { if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set any limits on selling " "items.\n"); return 0; } if (limit == "disable") { _automatic_approval->num_allowed = 0; add_succeeded_mess(({ "You disable the default number of sold items " "per person.\n", "$N fiddle$s with something in the shop.\n" }) ); return 1; } else if (to_int(limit) > 0) { _automatic_approval->num_allowed = to_int(limit); add_succeeded_mess(({ "You set the default number of sold items per " "person to " + _automatic_approval->num_allowed + ".\n", "$N fiddle$s with something in the shop.\n" }) ); return 1; } return 0; } /* do_approve_limit() */ /** * This method sets the limit per person to be a specified value. * @param person the person to set a limit on * @param value the limit to set */ int do_approve_limit_person_items(string name, string value) { int amt; class seller_information info; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set any limits on selling " "items.\n"); return 0; } name = lower_case(name); if (!PLAYER_HANDLER->test_user(name)) { add_failed_mess("The person " + name + " does not exist.\n"); return 0; } amt = to_int(value); info = _sellers[name]; if (!info) { info = new(class seller_information); } info->max_sellable = amt; if (info->value_limit || info->max_sellable || info->deny_value_limit) { _sellers[name] = info; } else { map_delete(_sellers, name); } if (amt) add_succeeded_mess(({ "You set the maximum number of items sellable by " + name + " to " + info->max_sellable + ".\n", "$N fiddle$s with something in the shop.\n" }) ); else add_succeeded_mess(({ "You remove the limit for the maximum number of " "items sellable by " + name + ".\n", "$N fiddle$s with something in the shop.\n" })); return 1; } /* do_approve_limit_person_items() */ /** * This method sets the limit at which a person can automatically sell * to the shop. * @param person the person to set a limit on * @param money the limit to set it to */ int do_approve_limit_person_value(string name, string money) { class seller_information info; int value; string place; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set any limits on selling " "items.\n"); return 0; } name = lower_case(name); if (!PLAYER_HANDLER->test_user(name)) { add_failed_mess("The person " + name + " does not exist.\n"); return -1; } money = lower_case(money); if (money == "disable" || money == "0") { value = 0; } else { place = query_property("place"); if (!place) { place = "default"; } value = value_from_string(money, place); if (!value) { add_failed_mess("The value " + value + " is invalid, please use " "'disable' to disable this feature for the person.\n"); return 0; } } info = _sellers[name]; if (!info) { info = new(class seller_information); } info->value_limit = value; if (info->value_limit || info->max_sellable || info->deny_value_limit) { _sellers[name] = info; } else { map_delete(_sellers, name); } if (value) { add_succeeded_mess(({ "You set the maximum cost of items automatically " "approved by " + name + " to " + MONEY_HAND->money_value_string(info->value_limit, place) + ".\n", "$N fiddle$s with something in the shop.\n" }) ); } else { add_succeeded_mess(({ "You disable the maximum cost of items " "automatically approved by " + name + ".\n", "$N fiddle$s with something in the shop.\n" }) ); } return 1; } /* do_approve_limit_person_value() */ /** * This method sets the limit at which a person can automatically sell * to the shop (deny limit). * @param person the person to set a limit on * @param money the limit to set it to */ int do_approve_limit_person_value_deny(string name, string money) { class seller_information info; int value; string place; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set any limits on selling " "items.\n"); return 0; } name = lower_case(name); if (!PLAYER_HANDLER->test_user(name)) { add_failed_mess("The person " + name + " does not exist.\n"); return -1; } money = lower_case(money); if (money == "disable" || money == "0") { value = 0; } else { place = query_property("place"); if (!place) { place = "default"; } value = value_from_string(money, place); if (!value) { add_failed_mess("The value " + value + " is invalid, please use " "'disable' to disable this feature for the person.\n"); return 0; } } info = _sellers[name]; if (!info) { info = new(class seller_information); } info->deny_value_limit = value; if (info->deny_value_limit || info->max_sellable || info->value_limit) { _sellers[name] = info; } else { map_delete(_sellers, name); } if (value) { add_succeeded_mess(({ "You set the maximum cost of items accepted by " + name + " to " + MONEY_HAND->money_value_string(info->deny_value_limit, place) + ".\n", "$N fiddle$s with something in the shop.\n" }) ); } else { add_succeeded_mess(({ "You disable the maximum cost of items to be sold by " + name + ".\n", "$N fiddle$s with something in the shop.\n" }) ); } return 1; } /* do_approve_limit_person_value() */ /** * This method removes any limits set on the player. * @param person the person to remove the limit on */ int do_approve_limit_person_remove(string name) { if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to remove limits " "off someone.\n"); return 0; } name = lower_case(name); if (!_sellers[name]) { add_failed_mess("The person " + name + " does not have any limits placed " "on them.\n"); return 0; } map_delete(_sellers, name); event_save(this_object()); add_succeeded_mess(({ "You remove any limits set on " + name + ".\n", "$N fiddle$s with something in the shop.\n" }) ); return 1; } /* do_approve_limit_person_remove() */ /** * This method shows the current status of the shop. * @param hint show the hints * @return return main status string */ string query_main_status(int hint) { string ret; string place; string name; class seller_information stuff; string *bits; if (!is_allowed(this_player()->query_name()) && !is_helper(this_player()->query_name())) { add_failed_mess("You are not allowed to see the status of this store.\n"); return 0; } place = query_property("place"); if (!place) { place = "default"; } ret = "$I$0=" + the_short() + "\n"; ret += "$I$6= The current percentage to automatically add to the buy price is: " + _automatic_percentage + "%\n"; if (hint) { ret += "$I$0= Hint: markup <percent>\n"; } ret += "$I$6= Limits on what can be sold.\n"; ret += "$I$6= Maximum number of items allowed in the shop : "; if (query_maximum_inventory_size()) { ret += query_maximum_inventory_size() + " currently " + sizeof(query_controller()->query_sell_list_obs()) + " (fixed).\n"; } else { ret += "disabled (fixed).\n"; } ret += "$I$6= Maximum number of items allowed per player : "; if (_automatic_approval->num_allowed) { ret += _automatic_approval->num_allowed + ".\n"; } else { ret += "disabled.\n"; } if (hint) { ret += "$I$0= Hint: set max number <number|disable>\n"; } ret += "$I$6= Automatically queue sales more than : "; if (_automatic_approval->high_cost) { ret += MONEY_HAND->money_value_string(_automatic_approval->high_cost, place) + ".\n"; } else { ret += "disabled.\n"; } if (hint) { ret += "$I$0= Hint: set high queue cost <cost|disable>\n"; } ret += "$I$6= Automatically deny sales more than : "; if (_automatic_approval->high_cost_deny) { ret += MONEY_HAND->money_value_string(_automatic_approval->high_cost_deny, place) + ".\n"; } else { ret += "disabled.\n"; } if (hint) { ret += "$I$0= Hint: set high deny cost <cost|disable>\n"; } ret += "$I$6= Helpers : "; if (sizeof(_helpers)) { ret += query_multiple_short(_helpers) + "\n"; } else { ret += "None at all.\n"; } if (hint) { ret += "$I$0= Hint: helper add <name>\n"; ret += "$I$0= Hint: helper remove <name>\n"; ret += "$I$0= Hint: helper list\n"; } if (sizeof(_sellers)) { ret += "$I$6= Limits set per player.\n"; ret += sprintf(" %-15s %-15s %-20s %s\n", "Name", "Max Sellable", "Approve Limit", "Deny limit (per item)"); bits = sort_array(keys(_sellers), 0); foreach (name in bits) { stuff = _sellers[name]; ret += sprintf(" %-15s %-15s %-20s %s\n", name, (stuff->max_sellable?stuff->max_sellable+"":"disabled"), (stuff->value_limit?MONEY_HAND->money_value_string(stuff->value_limit, place):"disabled"), (stuff->deny_value_limit?MONEY_HAND->money_value_string(stuff->deny_value_limit, place):"disabled")); } } else { ret += "$I$6= No limits set per player.\n"; } if (hint) { ret += "$I$0= Hint: set max number <max sellable|disable> for <player>\n"; ret += "$I$0= Hint: set high queue cost <cost|disable> for <player>\n"; ret += "$I$0= Hint: set high deny cost <cost|disable> for <player> to <cost|disable>\n"; //ret += "$I$0= Hint: approve limit remove <player>\n"; } ret += "\n$I$6= Automatically approve sales less than : "; if (_automatic_approval->low_cost) { ret += MONEY_HAND->money_value_string(_automatic_approval->low_cost, place) + ".\n"; } else { ret += "disabled.\n"; } if (hint) { ret += "$I$0= Hint: set low approve cost <cost|disable>\n"; } ret += "$I$0=Use 'expressions' to see the expressions.\n"; ret += "$I$0=Use 'functions shop' to see the user defined " "functions.\n"; return ret; } /* query_main_status() */ /** * Returns all the rexpression stuff as a string. * @param hint show the hitns * @return a string with the expression status in it */ string query_expression_status(int hint) { string ret; string place; mixed expr; string str; int pos; class expression_type bing; class expression_type binger; class approval_item approval; place = query_property("place"); if (!place) { place = "default"; } ret = ""; if (sizeof(_automatic_approval->items)) { ret += "$I$0=%^BOLD%^Automatically accept sales of items%^RESET%^\n"; foreach (str, expr in _automatic_approval->items) { if (classp(expr)) { approval = (class approval_item)expr; expr = ((class approval_item)expr)->value; } else { approval = new(class approval_item); } if (pointerp(expr) && intp(expr[0])) { map_delete(_automatic_approval->items, str); } else { ret += sprintf("$I$10= %-20s", "* " + str); if (sizeof(approval) == 3) { approval = new(class approval_item, markup : approval->markup, value : approval->value, list_name : approval->list_name, final_cost : 0); } if (approval->list_name) { ret += " listed as '" + approval->list_name + "'"; } if (approval->markup) { ret += " markup of " + approval->markup; } if (approval->final_cost) { ret += " final cost of " + MONEY_HAND->money_value_string(approval->final_cost, place); } ret += " max value:"; if (pointerp(expr)) { str = query_expression_string(expr, 0); if (strsrch(str, "\n") != -1) { ret += "\n" + str; } else { ret += str; } } else { ret += MONEY_HAND->money_value_string(expr, place); } ret += "\n"; } } } else { ret += "Automatically accept sales of : (none setup)\n"; } if (hint) { ret += "$I$0= Hint: auto add name <name> up to <value>\n"; ret += "$I$0= Hint: auto add name <name> up to <value> as <list name>\n"; ret += "$I$0= Hint: auto add name <name> up to <value> with markup <percentage>\n"; ret += "$I$0= Hint: auto add name <name> up to <value> with value <final cost>\n"; ret += "$I$0= Hint: auto add name <name> up to <value> as <list name> with markup <percentage>\n"; ret += "$I$0= Hint: auto add name <name> up to <value> as <list name> with value <final cost>\n"; ret += "$I$0= Hint: auto add name <name> with <expression>\n"; ret += "$I$0= Hint: auto add name <name> with <expression> as <list name>\n"; ret += "$I$0= Hint: auto add name <name> with <expression> and markup <percentage>\n"; ret += "$I$0= Hint: auto add name <name> with <expression> and value <final cost>\n"; ret += "$I$0= Hint: auto add name <name> with <expression> as <list name> with markup <percentage>\n"; ret += "$I$0= Hint: auto add object <object> up to <value>\n"; ret += "$I$0= Hint: auto add object <object> up to <value> as <list name>\n"; ret += "$I$0= Hint: auto add object <object> up to <value> with markup <percentage>\n"; ret += "$I$0= Hint: auto add object <object> up to <value> with value <final cost>\n"; ret += "$I$0= Hint: auto add object <object> up to <value> as <list name> with markup <percentage>\n"; ret += "$I$0= Hint: auto add object <object> up to <value> as <list name> with value <final cost>\n"; ret += "$I$0= Hint: auto add item object <object> with <expression>\n"; ret += "$I$0= Hint: auto add item object <object> with <expression> as <list name>\n"; ret += "$I$0= Hint: auto add item object <object> with <expression> with markup <percentage>\n"; ret += "$I$0= Hint: auto add item object <object> with <expression> with value <final cost>\n"; ret += "$I$0= Hint: auto add item object <object> with <expression> as <list name> with markup <percentage>\n"; ret += "$I$0= Hint: auto add item object <object> with <expression> as <list name> with value <final cost>\n"; ret += "$I$0= Hint: auto remove name <name>\n"; ret += "$I$0= Hint: auto remove object <object>\n"; } ret += "\n$I$0=%^BOLD%^Automatic approval expressions.%^RESET%^\n"; if (sizeof(_automatic_approval->expressions)) { //ret += "$I$0=Automatic approval expressions (if any of these evaluate as " //"true the item is accepted):\n"; pos = 0; foreach (bing in _automatic_approval->expressions) { if (sizeof(bing) == 3) { binger = new(class expression_type); binger->type = bing->type; binger->condition = bing->condition; binger->value = bing->value; bing = binger; event_save(this_object()); } if (bing->type != PLAYER_CRAFT_SHOP_EXPR_DENY) { str = query_expression_string(bing->value, 0); if (strsrch(str, "\n") != -1) { str = "\n" + str; } str = " accept value: " + str; if (bing->list_name) { str += " as " + bing->list_name; } } else { str = " -- deny item"; } ret += "$I$5=" + query_letter_value(pos) + ") " + query_expression_string(bing->condition, 0) + str + ".\n"; pos++; } } else { ret += "$I$0=No automatic approval expressions setup.\n"; } if (hint) { ret += "$I$0= Hint: auto add approve expression <condition> cost <value> as <list name>\n"; ret += "$I$0= Hint: auto deny expression <expression>\n"; ret += "$I$0= Hint: auto remove expression <id>\n"; } ret += "\n$I$0="; ret += "$I$0=Use 'functions shop' to see the user defined " "functions.\n"; return ret; } /* query_expression_status() */ /** * This method prints out the main status. */ int do_main_status(int hint) { if (!is_allowed(this_player()->query_name())) { add_failed_mess("Cannot do that!\n"); return 0; } write("$P$Status$P$" + query_main_status(hint)); add_succeeded_mess(({ "", "$N fiddle$s with something in the shop.\n" }) ); return 1; } /* do_main_status() */ /** * This method prints out the expressions status. */ int do_expression_status(int hint) { if (!is_allowed(this_player()->query_name())) { add_failed_mess("Cannot do that!\n"); return 0; } write("$P$Status$P$" + query_expression_status(hint)); add_succeeded_mess(({ "", "$N fiddle$s with something in the shop.\n" }) ); return 1; } /* do_expression_status() */ /** * This method pays off the cash deficit (if one exists). */ int do_approve_pay_deficit() { int cost; string place; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to pay off the deficit for " + the_short() + ".\n"); return 0; } if (query_owners_money() >= 0) { add_failed_mess("There is no deficit here to pay off.\n"); return 0; } place = query_property("place"); if (!place) { place = "default"; } cost = -query_owners_money(); if (this_player()->query_value_in(place) >= cost) { adjust_royalty(query_owner(), cost); this_player()->pay_money(MONEY_HAND->create_money_array(cost, place), place); add_succeeded_mess("$N pay$s off the deficit in " + the_short() + ".\n"); return 1; } add_failed_mess("You do not have enough money to pay off the deficit " "of " + MONEY_HAND->money_value_string(cost, place) + ".\n"); return 0; } /* do_approve_pay_deficit() */ /** * This method allows the player to add a new category to the list. * @param category the new category name */ int do_category_description(string category, string desc) { if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to add categories.\n"); return 0; } if (!query_controller()->is_valid_category(category)) { add_failed_mess("The category doesn't exists.\n"); return 0; } set_category_description(category, desc); add_succeeded_mess("$N set$s the description of " + category + ".\n"); return 1; } /* do_add_new_category() */ /** * This method allows the player to add a new category to the list. * @param category the new category name */ int do_category_information(string category, string desc) { if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to add categories.\n"); return 0; } if (!query_controller()->is_valid_category(category)) { add_failed_mess("The category doesn't exists.\n"); return 0; } set_category_information(category, desc); add_succeeded_mess("$N set$s the description of " + category + ".\n"); return 1; } /* do_add_new_category() */ /** * This method allows the player to add a new category to the list. * @param category the new category name */ int do_add_new_category(string category) { if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to add categories.\n"); return 0; } if (query_controller()->is_valid_category(category)) { add_failed_mess("The category already exists.\n"); return 0; } add_shop_category(category); add_succeeded_mess("$N add$s a new category.\n"); return 1; } /* do_add_new_category() */ /** * This method allows the player to remove a category from the list. * @param category the category to remove */ int do_remove_category(string category) { object* obs; string old_cat; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to remove categories.\n"); return 0; } old_cat = category; category = query_real_category_name(category); if (!category || !query_controller()->is_valid_category(category)) { add_failed_mess("The category " + old_cat + " does not exist.\n"); return 0; } if (category == query_default_category()) { add_failed_mess("You cannot remove the default category.\n"); return 0; } obs = query_controller()->query_sell_list_obs(); obs = filter(obs, (: query_controller()->query_category_of_shop_object($1) == $2:), category ); if (sizeof(obs)) { add_failed_mess("The category '" + category + "' is not empty " "and cannot be removed.\n"); return 0; } write("Do you wish to remove the category " + category + " from " + the_short() + " (y/n)?"); input_to("check_remove_category", 0, category); add_succeeded_mess(({ "", "$N removes a category from the shop.\n" })); return 1; } /* do_remove_category() */ /** * This method allows the player to remove a category from the list. * @param category the category to rename * @param new_category the new name of a category */ int do_rename_category(string category, string new_category) { object* obs; object ob; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to rename categories.\n"); return 0; } category = query_real_category_name(category); if (!category || !query_controller()->is_valid_category(category)) { add_failed_mess("The category " + category + " does not exist.\n"); return 0; } if (category == query_default_category()) { add_failed_mess("You cannot remove the default category.\n"); return 0; } add_shop_category(new_category); obs = query_controller()->query_sell_list_obs(); obs = filter(obs, (: query_controller()->query_category_of_shop_object($1) == $2:), category ); if (sizeof(obs)) { foreach (ob in obs) { query_controller()->change_category_of_shop_object(ob, new_category); } } remove_shop_category(category); add_succeeded_mess("$N rename$s category " + category + " to " + new_category + ".\n"); return 1; } /* do_rename_category() */ /** * This method is called into to check to see if we can remove the category. * @param answer their answer * @param category the category to remove */ protected void check_remove_category(string answer, string category) { class approval_obs approve; if (!strlen(answer) || lower_case(answer)[0] != 'y') { write("Aborting deleting the category " + category + ".\n"); return ; } remove_shop_category(category); write("Removed the shop category " + category + ".\n"); foreach (approve in query_approval_list(0)) { if (approve->category == category) { approve->category = query_default_category(); } } foreach (approve in query_approval_list(1)) { if (approve->category == category) { approve->category = query_default_category(); } } event_save(this_object()); return ; } /* check_remove_category() */ /** * This method sets the default category for the place. * @param default_cat the default category */ int do_set_default_category(string default_cat) { if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to set the default category.\n"); return 0; } default_cat = query_real_category_name(default_cat); if (!default_cat || !query_controller()->is_valid_category(default_cat)) { add_failed_mess("The category " + default_cat + " does not exist.\n"); return 0; } set_default_category(default_cat); add_succeeded_mess("$N set$s the default category for " + the_short() + ".\n"); event_save(this_object()); return 1; } /* do_set_default_category() */ /** * This method lists the current categories and shows us which one is * currently the default. */ int do_list_categories() { string cat; string ret; ret = ""; foreach (cat in query_controller()->query_categories()) { if (cat == query_default_category()) { ret += cat + " (default)\n"; } else { ret += cat + "\n"; } } write("$P$Category list$P$The current categories are:\n" + ret); add_succeeded_mess(({ "", "$N browses the categories.\n" })); return 1; } /* do_list_categories() */ /** * This method shows the stats on all the sold items, the number and value * of each one sold. * @param type the type of sorting to do */ int do_stats_items(int type) { class shop_stats stat; string ret; string *bits; string place; string name; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You cannot read " + the_short() + "'s ledger.\n"); return 0; } if (!sizeof(_sold_stats)) { add_failed_mess("Nothing has been sold in this transaction section " "yet.\n"); return 0; } place = query_property("place"); if (!place) { place = "default"; } switch (type) { case 1: bits = sort_array(keys(_sold_stats), (: _sold_stats[$1]->num_sold - _sold_stats[$2]->num_sold :)); break; case 2: bits = sort_array(keys(_sold_stats), (: _sold_stats[$1]->value_sold - _sold_stats[$2]->value_sold :)); break; case 3 : bits = sort_array(keys(_sold_stats), (: strcmp(((class shop_stats)_sold_stats[$1])->seller, ((class shop_stats)_sold_stats[$1])->seller) :)); break; case 4 : bits = sort_array(keys(_sold_stats), (: strcmp(((class shop_stats)_sold_stats[$1])->name, ((class shop_stats)_sold_stats[$1])->name) :)); break; default : bits = sort_array(keys(_sold_stats), 0); break; } ret = "Statistics for items sold since " + ctime(_stats_start) + ".\n"; foreach (name in bits) { stat = _sold_stats[name]; ret += name + ": " + stat->num_sold + " for " + MONEY_HAND->money_value_string(stat->value_sold, place) + ".\n"; } write("$P$Sold stats$P$" + ret); add_succeeded_mess(({ "", "$N looks at the ledger.\n" })); return 1; } /* do_stats_items() */ #if USE_TRANSACTIONS /** * This method shows a list of all the transactions that have occured in the * shop. */ int do_stats_transactions() { class shop_transaction bing; string ret; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You cannot read " + the_short() + "'s ledger.\n"); return 0; } ret = "Statistics for transactions since " + ctime(_stats_start) + ".\n"; foreach (bing in _transactions) { ret += "$I$5=" + query_transaction_string(bing) + "\n"; } write("$P$Sold stats$P$" + ret); add_succeeded_mess(({ "", "$N looks at the ledger.\n" })); return 1; } /* do_stats_transactions() */ #endif /** * This method shows stats about money and stuff in the shop. */ int do_stats_money() { string ret; int stock_value; string place; object ob; if (!is_allowed(this_player()->query_name())) { add_failed_mess("You cannot read " + the_short() + "'s ledger.\n"); return 0; } place = query_property("place"); if (!place) { place = "default"; } ret = ""; ret += "\nCurrent money spent " + MONEY_HAND->money_value_string(_total_outgoing, place) + " and money made " + MONEY_HAND->money_value_string(_total_ingoing, place) + ".\n"; foreach (ob in query_controller()->query_sell_list_obs()) { stock_value += ob->query_value(); } ret += "The current stock value is " + MONEY_HAND->money_value_string(stock_value, place) + ".\n"; ret += "\n"; if (query_owners_money() > 0) { ret += "The owner current has a cash float (royalties) of " + MONEY_HAND->money_value_string(query_owners_money(), place) + ".\n"; } else if (query_owners_money() < 0) { ret += "The owner current has a cash deficit of " + MONEY_HAND->money_value_string(-query_owners_money(), place) + ".\n"; } write(ret); add_succeeded_mess(({ "", "$N looks at the ledger.\n" })); return 1; } /* do_stats_money() */ /** @ignore yes */ int do_helper_list() { write("$I$3=The current helpers are: " + query_multiple_short(_helpers) + ".\n"); return 1; } /* do_helper_list() */ /** @ignore yes */ int do_helper_add(string helper) { if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to mess with the helpers.\n"); return 0; } helper = lower_case(helper); if (is_helper(helper)) { add_failed_mess(capitalize(helper) + " is already a helper.\n"); return 0; } if (!PLAYER_HANDLER->test_user(helper)) { add_failed_mess(capitalize(helper) + " is not a player.\n"); return 0; } _helpers += ({ helper }); add_succeeded_mess("$N add$s " + capitalize(helper) + " as a helper.\n"); return 1; } /* do_helper_add() */ /** @ignore yes */ int do_helper_remove(string helper) { if (!is_allowed(this_player()->query_name())) { add_failed_mess("You are not allowed to mess with the helpers.\n"); return 0; } helper = lower_case(helper); if (!is_helper(helper)) { add_failed_mess(capitalize(helper) + " is not a helper to remove.\n"); return 0; } _helpers -= ({ helper }); add_succeeded_mess("$N remove$s " + capitalize(helper) + " as a helper.\n"); return 1; } /* do_helper_remove() */ private object* variable_objects(string seller, int cost, object* obs) { return obs; } /* function_object_type() */ private string variable_sale_name(string seller, int cost, object* ob, string name, string category) { if (name) { return lower_case(name); } return ""; } /* variable_sale_name() */ private string variable_sale_category(string seller, int cost, object* ob, string name, string category) { if (category) { return lower_case(category); } return ""; } /* variable_sale_category() */ private int variable_sale_cost(string seller, int cost, object* ob, string name, string category) { return cost; } /* variable_sale_category() */ void init() { expression_util::init(); craft_shop_category::init(); add_command("waiting", "", (: do_list_approval(1) :)); add_command("waiting", "unapproved", (: do_list_approval(0) :)); add_command("reject", "<string'id'>", (: do_approve_reject($4[0], 0, -1) :)); add_command("retrieve", "<string'id'>", (: do_return($4[0]) :) ); add_command("return", "<string'id'>", (: do_return($4[0]) :) ); add_command("value", "<indirect:object>", (: do_approve_auto_item_test($1) :)); if (!is_helper(this_player()->query_name())) { return ; } add_command("approve", "<string'id'>", (: do_approve_item($4[0], 0) :)); add_command("approve", "<string'id'> for <string'value'>", (: do_approve_item($4[0], $4[1]) :)); add_command("reject", "<string'id'> position <number>", (: do_approve_reject($4[0], 0, $4[1]) :)); add_command("reject", "<string'id'> message <string'reject message'>", (: do_approve_reject($4[0], $4[1], -1) :)); add_command("reject", "<string'id'> position <number> message <string'reject message'>", (: do_approve_reject($4[0], $4[2], $4[1]) :)); add_command("browse", "waiting <string'id'>", (: do_approve_browse($4[0]) :)); add_command("checkout", "<string'id'>", (: do_approve_checkout($4[0]) :)); add_command("checkin", "<indirect:object:me-here>", (: do_approve_checkin($1) :)); if (!is_allowed(this_player()->query_name())) { return ; } add_command("set", "low approve cost <string'cost|disable'>", (: do_approve_auto_low($4[0]) :)); add_command("auto", "add approve expression <string'condition'> cost <string'value'> as <string'list name'>", (: do_approve_auto_expression_add($4[0], $4[1], PLAYER_CRAFT_SHOP_EXPR_ACCEPT, $4[2]) :)); add_command("auto", "add deny expression <string'condition'>", (: do_approve_auto_expression_add($4[0], 0, PLAYER_CRAFT_SHOP_EXPR_DENY, 0) :)); add_command("auto", "remove expression <string'id'>", (: do_approve_auto_expression_remove($4[0]) :)); add_command("markup", "<number'percentage'>", (: do_approve_percentage($4[0]) :)); add_command("auto", "add name <string'name'> up to <string'value'>", (: do_approve_auto_item_add($4[0], $4[1], 0, 0, 0) :)); add_command("auto", "add name <string'name'> up to <string'value'> with value <string'final cost'>", (: do_approve_auto_item_add($4[0], $4[1], 0, 0, $4[2]) :)); add_command("auto", "add name <string'name'> up to <string'value'> with markup <number'percentage'>", (: do_approve_auto_item_add($4[0], $4[1], 0, $4[2], 0) :)); add_command("auto", "add name <string'name'> up to <string'value'> as <string'list name'>", (: do_approve_auto_item_add($4[0], $4[1], $4[2], 0, 0) :)); add_command("auto", "add name <string'name'> up to <string'value'> as <string'list name'> with value <string'final cost'>", (: do_approve_auto_item_add($4[0], $4[1], $4[2], 0, $4[3]) :)); add_command("auto", "add name <string'name'> up to <string'value'> as <string'list name'> with markup <number'percentage'>", (: do_approve_auto_item_add($4[0], $4[1], $4[2], $4[3], 0) :)); add_command("auto", "add name <string'name'> with <string'expression'>", (: do_approve_auto_item_add_expr($4[0], $4[1], 0, 0, 0) :)); add_command("auto", "add name <string'name'> with <string'expression'> and markup <number'percentage'>", (: do_approve_auto_item_add_expr($4[0], $4[1], 0, $4[2], 0) :)); add_command("auto", "add name <string'name'> with <string'expression'> and value <string'final cost'>", (: do_approve_auto_item_add_expr($4[0], $4[1], 0, 0, $4[2]) :)); add_command("auto", "add name <string'name'> with <string'expression'> as <string'list name'>", (: do_approve_auto_item_add_expr($4[0], $4[1], $4[2], 0, 0) :)); add_command("auto", "add name <string'name'> with <string'expression'> as <string'list name'> and markup <number'percentage'>", (: do_approve_auto_item_add_expr($4[0], $4[1], $4[2], $4[3], 0) :)); add_command("auto", "add name <string'name'> with <string'expression'> as <string'list name'> and value <string'final cost'>", (: do_approve_auto_item_add_expr($4[0], $4[1], $4[2], 0, $4[3]) :)); add_command("auto", "add object <indirect:object> up to <string'value'>", (: do_approve_auto_item_add_object($1, $4[1], 0, 0, 0) :)); add_command("auto", "add object <indirect:object> up to <string'value'> with markup <number'percentage'>", (: do_approve_auto_item_add_object($1, $4[1], 0, $4[2], 0) :)); add_command("auto", "add object <indirect:object> up to <string'value'> with value <string'final cost'>", (: do_approve_auto_item_add_object($1, $4[1], 0, 0, $4[2]) :)); add_command("auto", "add object <indirect:object> up to <string'value'> as <string'list name'>", (: do_approve_auto_item_add_object($1, $4[1], $4[2], 0, 0) :)); add_command("auto", "add object <indirect:object> up to <string'value'> as <string'list name'> with markup <number'percentage'>", (: do_approve_auto_item_add_object($1, $4[1], $4[2], $4[3], 0) :)); add_command("auto", "add object <indirect:object> up to <string'value'> as <string'list name'> with value <string'final cost'>", (: do_approve_auto_item_add_object($1, $4[1], $4[2], 0, $4[3]) :)); add_command("auto", "add object <indirect:object> with <string'expression'>", (: do_approve_auto_item_add_object_expr($1, $4[1], 0, 0, 0) :)); add_command("auto", "add object <indirect:object> with <string'expression'> and markup <number'percentage'>", (: do_approve_auto_item_add_object_expr($1, $4[1], 0, $4[2], 0) :)); add_command("auto", "add object <indirect:object> with <string'expression'> and value <string'final cost'>", (: do_approve_auto_item_add_object_expr($1, $4[1], 0, 0, $4[2]) :)); add_command("auto", "add object <indirect:object> with <string'expression'> as <string'list name'>", (: do_approve_auto_item_add_object_expr($1, $4[1], $4[2], 0, 0) :)); add_command("auto", "add object <indirect:object> with <string'expression'> as <string'list name'> and markup <number'percentage'>", (: do_approve_auto_item_add_object_expr($1, $4[1], $4[2], $4[3], 0) :)); add_command("auto", "add object <indirect:object> with <string'expression'> as <string'list name'> and value <string'final cost'>", (: do_approve_auto_item_add_object_expr($1, $4[1], $4[2], 0, $4[3]) :)); add_command("auto", "remove name <string'name'>", (: do_approve_auto_item_remove($4[0]) :)); add_command("auto", "remove object <indirect:object>", (: do_approve_auto_item_remove_object($1) :)); add_command("set", "high queue cost <string'cost|disable'>", (: do_approve_auto_high($4[0]) :)); add_command("set", "high deny cost <string'cost|disable'>", (: do_approve_auto_high_deny($4[0]) :)); add_command("set", "max number <string'max sellable|disable'>", (: do_approve_limit($4[0]) :)); add_command("set", "max number <string'max sellable|disable'> for <string'player'>", (: do_approve_limit_person_items($4[1], $4[0]) :)); add_command("set", "high queue cost <string'cost|disable'> for <string'player'>", (: do_approve_limit_person_value($4[1], $4[0]) :)); add_command("set", "high deny cost <string'cost|disable'> for <string'player'>", (: do_approve_limit_person_value_deny($4[1], $4[0]) :)); add_command("approve", "limit remove <string'player'>", (: do_approve_limit_person_remove($4[0]) :)); add_command("expressions", "", (: do_expression_status(0) :)); add_command("expressions", "hints", (: do_expression_status(1) :)); add_command("pay", "deficit", (: do_approve_pay_deficit() :)); add_command("stats", "items by name", (: do_stats_items(4) :)); add_command("stats", "items by seller", (: do_stats_items(3) :)); add_command("stats", "items by number", (: do_stats_items(1) :)); add_command("stats", "items by value", (: do_stats_items(2) :)); #if USE_TRANSACTIONS add_command("stats", "transactions", (: do_stats_transactions() :)); #endif add_command("stats", "money", (: do_stats_money() :)); add_command("status", "<direct:object>", (: do_main_status(0) :)); add_command("status", "<direct:object> hints", (: do_main_status(1) :)); add_command("check", "sell <indirect:object>", (: do_check_sell($1) :)); add_command("category", "list", (: do_list_categories() :)); add_command("category", "default <string'category'>", (: do_set_default_category($4[0]) :)); add_command("category", "add <string'category'>", (: do_add_new_category($4[0]) :)); add_command("category", "description <string'category'> <string:quoted'description'>", (: do_category_description($4[0], $4[1]) :)); add_command("category", "description <string'category'> remove", (: do_category_description($4[0], 0) :)); add_command("category", "information <string'category'> <string:quoted'information'>", (: do_category_information($4[0], $4[1]) :)); add_command("category", "information <string'category'> remove", (: do_category_information($4[0], 0) :)); add_command("category", "remove <string'category'>", (: do_remove_category($4[0]) :)); add_command("category", "rename <string'category'> to <string'category'>", (: do_rename_category($4[0], $4[1]) :)); add_command("helper", "list", (: do_helper_list() :)); add_command("helper", "add <string'helper'>", (: do_helper_add($4[0]) :)); add_command("helper", "remove <string'helper'>", (: do_helper_remove($4[0]) :)); add_command("buy", "force <indirect:object:" + file_name(query_controller()->query_sell_list()) + ">", (: do_buy($1, 1) :)); } /* init() */