Author Topic: Improved drop verb  (Read 2000 times)

Offline z993126

  • BFF
  • ***
  • Posts: 128
    • View Profile
Improved drop verb
« on: December 30, 2011, 10:23:11 PM »
An improved version of /verbs/items/drop.c which allows a wider range of input referring to items you want to drop.  For instance, if you have five shirts that also have the id 'dress shirt' in addition to the name 'shirt', you can 'drop three shirts', 'drop a dress shirt', 'drop 4 shirt', and so forth.

Code: [Select]
/* /verbs/items/drop.c
 * from the Dead Souls Mud Library
 * drop OBJ
 * drop OBS
 * drop WRD WRD
 * created by Descartes of Borg 960113
 * 2011-Dec-30 T. Cook fixed drop <AMOUNT> <ITEM>
 *             T. Cook incoporated numeralize() to expand range of allowed input
 */
#include <lib.h>
#include <daemons.h>
#include "include/drop.h"

inherit LIB_VERB;

static void create() {
verb::create();
SetVerb( "drop" );
SetSynonyms( "put down", "set down" );
SetRules( "OBS", "WRD WRD" );
SetErrorMessage( "Drop what?" );
SetHelp(
"Syntax:  '%^B_WHITE%^%^BLACK%^drop <ITEM>%^RESET%^'\n"
"         '%^B_WHITE%^%^BLACK%^drop <AMOUNT> <ITEM>%^RESET%^'\n"
"         '%^B_WHITE%^%^BLACK%^drop <AMOUNT> <CURRENCY>%^RESET%^'\n"
"Drops something you have, one or more items, or amount of currency."
"See also:  get, put"
);
}

mixed can_drop_obj( object o_ob ){
return this_player()->CanManipulate();
}

mixed can_drop_wrd_wrd( mixed args... ){
string s_num, s_what, s_id;
string *sa_ids = ({});
int i_amt, i_total;
object o_ob, *oa_obs = ({});
mixed m_item;

s_num = args[0];
s_what = lower_case( args[1] );

if( o_ob = get_object( s_num + " " + s_what ) ){ return can_drop_obj( o_ob ); }

if( !s_num || !s_what ){ return 0; }
if( ( i_amt = numeralize( s_num ) ) < 1 ){ return "You cannot do that!"; }

/* this section is to enable reference to plural and item-id forms of an item */
foreach( m_item in all_inventory( this_player() ) ){
sa_ids = ({});
foreach( s_id in m_item->GetCanonicalId() + ({ m_item->GetName() }) ){
if( member_array( lower_case( s_id ), sa_ids ) == -1 ){
sa_ids += ({ lower_case( s_id ) });
}
}
foreach( s_id in sa_ids ){
if( member_array( m_item, oa_obs ) == -1 ){
if( s_what == s_id || s_what == pluralize( s_id ) ){ oa_obs += ({ m_item }); }
}
}
}
/*----*/

if( sizeof( oa_obs ) ){
if( sizeof( oa_obs ) < i_amt ){
return "You don't have that many " + s_what + ".";
}
}else{
if( this_player()->GetCurrency( s_what ) < i_amt ){
return "You don't have that many " + s_what + ".";
}
}
if( newbiep( this_player() ) ){ return "Newbies can't drop money."; }
return this_player()->CanManipulate();
}

mixed do_drop_obj( object o_ob ){
return o_ob->eventDrop( this_player() );
}

mixed do_drop_obs( mixed *res ){
object *o_obs, *eligible;
mixed tmp;

if( !sizeof( res ) ){
this_player()->eventPrint( "You don't have any to drop!" );
return 1;
}
o_obs = filter( res, (: objectp :) );
if( !sizeof(o_obs) ){
mixed *ua;

ua = unique_array( res, (: $1 :) );
foreach( string *list in ua ){ this_player()->eventPrint( list[0] ); }
return 1;
}
eligible = filter( o_obs, (: ( !( $1->GetWorn() ) && environment( $1 ) == this_player() ) :) );
if( !sizeof( eligible ) ){
write( "Remove or unwield items before trying to drop them." );
eligible = ({});
return 1;
}
foreach( object o_ob in eligible ){
if( ( tmp = o_ob->eventDrop( this_player() ) ) != 1 ){
if( stringp(tmp) ){
this_player()->eventPrint( tmp );
}else{
this_player()->eventPrint( "You cannot drop " + o_ob->GetShort() + "." );
}
        }
}
return 1;
}

mixed do_drop_wrd_wrd( mixed args... ){
string s_num, s_what, s_id;
string *sa_ids = ({});
int i_amt, i_total, i_count;
object o_ob, *oa_obs = ({}), o_pile, o_env;
mixed m_item;

s_num = args[0];
s_what = args[1];

if( o_ob = get_object( s_num + " " + s_what ) ){ return do_drop_obj( o_ob ); }

if( !s_num || !s_what ){ return 0; }
if( ( i_amt = numeralize( s_num ) ) < 1 ){ return "You cannot do that!"; }
o_env = environment( this_player() );

/* this section is to enable reference to plural and item-id forms of an item */
foreach( m_item in all_inventory( this_player() ) ){
sa_ids = ({});
foreach( s_id in m_item->GetCanonicalId() + ({ m_item->GetName() }) ){
if( member_array( lower_case( s_id ), sa_ids ) == -1 ){
sa_ids += ({ lower_case( s_id ) });
}
}
foreach( s_id in sa_ids ){
if( member_array( m_item, oa_obs ) == -1 ){
if( s_what == s_id || s_what == pluralize( s_id ) ){ oa_obs += ({ m_item }); }
}
}
}
/*----*/

if( member_array( s_what, ECONOMY_D->__QueryCurrencies() ) > -1 ){
o_pile = new( LIB_PILE );
o_pile->SetPile( s_what, i_amt );
if( !( o_pile->eventMove( o_env ) ) || this_player()->AddCurrency( s_what, -i_amt ) == -1 ){
this_player()->eventPrint( "Something prevents your action." );
o_pile->eventDestruct();
return 1;
}
}else if( sizeof( oa_obs ) ){
oa_obs = scramble_array( oa_obs );
for( i_count = 0; i_count < i_amt; i_count++ ){
oa_obs[i_count]->eventDrop( this_player() );
}
}else{
return 0;
}
if( !sizeof( oa_obs ) ){
this_player()->eventPrint( "You drop " + consolidate( i_amt, singularize( s_what ) ) + "." );
o_env->eventPrint( this_player()->GetName() + " drops some " + s_what + ".", this_player() );
}
return 1;
}
/* EOF */

(here's the numeralize() function, which I added to /secure/sefun/english.c)
Code: [Select]
int numeralize( string s_arg ){
string s_tens, s_ones, s_sign;
int i_number, i_sign = 1;
if( to_int( s_arg ) != 0 ){ return to_int( s_arg ); }
if( !s_arg || s_arg == "zero" || s_arg == "no" ){ return 0; }
if( s_arg[0..8] == "negative " ){ i_sign = -1; s_arg = s_arg[9..]; }
switch( s_arg ){
case "one": case "a": case "an": case "a single": case "a singular": i_number = 1; break;
case "two": case "a pair of": case "a duo of": i_number = 2; break;
case "three": case "a trio of": case "a triad of": case "a troika of": i_number = 3; break;
case "four": case "a quartet of": i_number = 4; break;
case "five": case "a quintet of": i_number = 5; break;
case "six": case "a sextet of": i_number = 6; break;
case "seven": case "a septet of": i_number = 7; break;
case "eight": case "an octet of": i_number = 8; break;
case "nine": i_number = 9; break;
case "ten": i_number = 10; break;
case "eleven": i_number = 11; break;
case "twelve": i_number = 12; break;
case "thirteen": i_number = 13; break;
case "fourteen": i_number = 14; break;
case "fifteen": i_number = 15; break;
case "sixteen": i_number = 16; break;
case "seventeen": i_number = 17; break;
case "eighteen": i_number = 18; break;
case "nineteen": i_number = 19; break;
case "twenty": i_number = 20; break;
case "thirty": i_number = 30; break;
case "forty": i_number = 40; break;
case "fifty": i_number = 50; break;
case "sixty": i_number = 60; break;
case "seventy": i_number = 70; break;
case "eighty": i_number = 80; break;
case "ninety": i_number = 90; break;
case "a hundred": case "one hundred": i_number = 100; break;
case "over nine thousand": i_number = 9001; break;
case "a bunch of": case "a lot of": i_number = random( 100 ); break;
default:
if( sscanf( s_arg, "%s-%s", s_tens, s_ones ) == 2 ){
switch( s_tens ){
case "twenty": i_number = 20; break;
case "thirty": i_number = 30; break;
case "forty": i_number = 40; break;
case "fifty": i_number = 50; break;
case "sixty": i_number = 60; break;
case "seventy": i_number = 70; break;
case "eighty": i_number = 80; break;
case "ninety": i_number = 90; break;
default: break;
}
switch( s_ones ){
case "one": i_number += 1; break;
case "two": i_number += 2; break;
case "three": i_number += 3; break;
case "four": i_number += 4; break;
case "five": i_number += 5; break;
case "six": i_number += 6; break;
case "seven": i_number += 7; break;
case "eight": i_number += 8; break;
case "nine": i_number += 9; break;
default: break;
}
}
break;
}
return i_number * i_sign;
}
« Last Edit: December 30, 2011, 10:25:19 PM by z993126 »

Offline z993126

  • BFF
  • ***
  • Posts: 128
    • View Profile
Re: Improved drop verb
« Reply #1 on: December 30, 2011, 10:29:42 PM »
Oh, something else about my changes--if you have several different items that share an id, such as "a red shirt", "a plaid shirt", "a chainmail shirt", and you do "drop 3 shirts", it will consider the total of all items that have that id and drop them.  In the case above, if you dropped two of the shirts, it would drop two shirts selected at random.