/* -*- LPC -*- */ /* * $Locker: $ * $Id: get.c,v 1.63 2002/02/22 00:48:08 ceres Exp $ */ #include <obj_parser.h> #include <move_failures.h> #include <player.h> // These were determined empirically (with my hand :) -- Jeremy #define DROP_H 40 #define PINCH_H 120 #define MAX_GET_NUMBER 20 inherit "/cmds/base"; #define TP this_player() object* find_matching_obs(string match_str, object dob) { class obj_match result; result = (class obj_match)match_objects_in_environments(match_str, dob); if (result->result != OBJ_PARSER_SUCCESS) { add_failed_mess(match_objects_failed_mess(result)); return 0; } return result->objects; } mixed cmd(object * obs, string dir, string indir, mixed *args) { object *dest; object ob; object dob; object *fail_dest; object *too_many; mixed *fail; mixed *ret; mixed amt; string sh; string hand_unit; string match_str; int i; int num; int cap; int perc; int handful; int total_num; mixed we; object env; object *bing; fail_dest = ({ }); cap = (int) TP->query_max_weight(); if (indir && sizeof(obs) > 10) { add_failed_mess("Please be more specific as to what you want " "to get from.\n"); return 0; } if (indir) { match_str = args[0]; dest = obs; } else { if (environment(TP)->query_mirror_room()) { dest = ({ environment(TP), environment(TP)->query_mirror_room() }); } else { dest = ({ environment(TP) }); } } too_many = ({ }); foreach(dob in dest) { if (!is_in_me_or_environment(dob, this_player())) { fail_dest += ({ dob }); continue; } if (dob->cannot_get_stuff() || dob->query_closed()) { fail_dest += ({ dob }); continue; } if (living(dob) && !dob->allowed_to_loot(this_player())) { fail_dest += ({ dob }); continue; } else if (indir) { obs = find_matching_obs(match_str, dob); } if (!obs) { continue; } if (total_num + sizeof(obs) > MAX_GET_NUMBER) { if (total_num > MAX_GET_NUMBER) { too_many += obs; obs = ({ }); } else { too_many += obs[MAX_GET_NUMBER - total_num..]; obs = obs[0..MAX_GET_NUMBER - total_num - 1]; } } total_num += sizeof(obs); ret = ({ ([ ]), ([ ]), ([ ]), ([ ]), ([ ]), }); fail = ({ }); foreach(ob in obs) { env = environment(ob); // If the environment of the object & the direct object are different // something is wrong. It'll either be that it's a collective object // that is in the wrong place or someone's using 'get xxx in yyy' if(env != dob) { if(ob->query_collective()) ob->move(dob); else dob = env; } if ((living(dob) && !dob->allowed_to_loot(this_player(), ob)) || (ob->query_liquid() && ob->query_food_object())) { fail += ({ ob }); num++; continue; } if (ob->query_continuous()) { // Can only get a handful at a time. // Id like to make it so you need to have a free hand, // but I'm not sure if it's worth it... //if (!TP->query_free_limbs()) // continue; amt = ob->query_amount_types(); if (amt["handful"]) { hand_unit = "handful"; handful = amt["handful"][0]; } else if ((amt["drop"]) && (ob->query_liquid())) { hand_unit = "drops"; handful = amt["drop"][0] * DROP_H; } else if (amt["pinch"]) { hand_unit = "pinches"; handful = amt["pinch"][0] * PINCH_H; } else { // Dunno what to do here - I guess give it to them handful = ob->query_amount(); } if (ob->query_amount() > handful) { // Knock it down to a carryable amount // (I hope this is right...) if (!match_str) { match_str = ob->query_name(); } if (i = strsrch(match_str, "of") >= 0) { i += 3; } if (hand_unit == "handful") { handful = 1; } match_str = handful + " " + hand_unit + " of " + match_str[i..]; fail += ({ "all of the " + ob->short() }); ob = ob->query_parse_id(({ handful, match_str })); if (!ob) { continue; } num++; } } if (function_exists("do_get", ob) || function_exists("command_control", ob)) { if (function_exists("do_get", ob)) { we = (int) call_other(ob, "do_get", dob, 0, match_str, ({ 0, match_str }), "<direct:object> from <indirect:object>"); } else { we = ob->command_control("get", dob, 0, match_str, ({ 0, match_str }), "<direct:object> from <indirect:object>"); } if (!objectp(we)) { if (we) { we = (int) ob->query_weight(); perc = (we * 100) / cap; if (perc >= 95) { i = 4; } else { i = perc / 25; } if (!ret[i][env]) { ret[i][env] = ({ ob }); } else { ret[i][env] += ({ ob }); } } else { if (member_array(ob, this_player()->query_succ_mess_indir()) == -1 && !query_notify_fail() && !living(ob)) { fail += ({ ob }); } num++; } continue; } else { ob = we; } } #ifndef __DISTRIBUTION_LIB__ if(interactive(TP) && PLAYER_MULTIPLAYER_HANDLER->check_multiplayers("get", TP, ob)) { fail += ({ ob }); num++; } else #endif if ((int) ob->move(TP) == MOVE_OK) { we = (int) ob->query_weight(); perc = (we * 100) / cap; if (perc >= 95) { i = 4; } else { i = perc / 25; } if (!ret[i][env]) { ret[i][env] = ({ ob }); } else { ret[i][env] += ({ ob }); } } else { fail += ({ ob }); num++; } } /* Print out the different weight messages */ for (i = 0; i < sizeof(ret); i++) { if (sizeof(ret[i])) { /* Print out the different environments for the weights. */ foreach(env, bing in ret[i]) { if (this_player()->query_succ_mess_dir()) { bing -= this_player()->query_succ_mess_dir(); } if (sizeof(bing)) { sh = query_multiple_short(bing); write("You " + ({ "get", "get with a bit of difficulty", "struggle somewhat to get", "find it very difficult to get", "use all your strength and just barely manage to get" }) [i] + " " + sh + " from " + inside_the_short(dob) + ".\n"); say(capitalize((string) TP->one_short()) + " " + ({ "gets", "gets with a bit of difficulty", "struggles somewhat to get", "finds it very difficult to get", "uses all " + TP->query_possessive() + " strength and just barely manages to get" })[i] + " " + sh + " from " + inside_a_short(dob) + ".\n"); } } } } if (sizeof(fail)) { add_failed_mess("You cannot get $I.\n", fail); } } // // This means everything failed. // if (num == total_num) { if (query_notify_fail()) { return 0; } if (indir) { //if (!num) { //add_failed_mess("There is no " + match_str + " in $I.\n", dest); //} if (sizeof(fail_dest)) { add_failed_mess("You cannot get anything from $I.\n", fail_dest); } } else { add_failed_mess("You cannot get $I.\n", obs); } return -1; } else { // // Success! // if (sizeof(too_many)) { add_succeeded_mess(({ "You cannot pick up more than " + query_num(MAX_GET_NUMBER) + " objects at a time; " "discarding $I.\n", "" }), too_many); } } return 1; } /* cmd() */ mixed * query_patterns() { return ({ "<indirect:object:here>", (: cmd($1, 0, 0, 0) :), "<string> from <indirect:object>", (: cmd($1, $2, $3, $4) :) }); } /* query_patterns() */