/* * Rather large conglomeration of move/misc/values * - Allowing negative weights, though we'll regret it. * Wonderflug, 1997. */ #include "move_failures.h" #include "money.h" /* Use a hook to refer to weight all through here, unless modifying. * There's a fairly good reason for this. */ #define WEIGHT this_object()->query_weight() inherit "/std/basic/light"; static int weight=0; /* weight of the object */ static int droppable=1; /* whether the object may be dropped */ static int gettable=1; /* whether the object may be picked up */ int value=0; /* value of the object */ int resale_value=0; /* resale value of the object */ int stolen_modifier=0; /* devaluation when stolen */ /****** Some misc garbage */ static object prev; /* last location visited by the object.. really * this isn't necessary in EVERY object, should * be in player.c or creator.c */ object query_prev() { return prev; } /* this too */ /****** Initialization */ void create() { } /****** Modifiers/accessors for droppable/gettable */ void reset_get() { gettable = 0; } /* can't be gotten */ void set_get() { gettable = 1; } /* can be gotten */ void reset_drop(){ droppable = 0; } /* can't be dropped */ void set_drop() { droppable = 1; } /* can be dropped */ int droppable() { if(TO->query_property("cursed")) return 0; return droppable; } int gettable() { return gettable; } /****** Weight stuff */ void adjust_weight(int w) { weight += w; if (environment()) { environment()->adjust_contained_weight( w ); environment()->rebalance( ({ this_object() }) ); } } void set_weight(int w) { adjust_weight( w - weight ); } int query_weight() { return weight; } int test_adjust_weight( int w ) { if ( environment() ) return environment()->test_adjust_contained_weight( w ); else return 1; } /****** Movement stuff */ /* these get re-defined in container.c; the default, however, is that * an object may not add or remove objects to itself. */ int test_add_object( object ob ) { return MOVE_INVALID_DEST; } int test_remove_object( object ob ) { return MOVE_INVALID_DEST; } /* This is the nice, completely error-checking version of move. * Expected to be used by builders and elsewhere in mudlib. * Return code SHOULD be checked; see move_failures.h */ varargs int move(mixed dest, mixed messin, mixed messout) { int i; if (!objectp(dest)) { if ( stringp(dest) ) catch( dest = load_object(dest) ); else return MOVE_BAD_DEST ; if ( !objectp(dest) ) return MOVE_UNLOADABLE_DEST ; } prev = environment(); /* dest is now guaranteed to be an object, the destination; * prev is now the previous environment */ /* check that no weight constraints will be violated by the move * Note when moving an object into/out of a container to the environment * of the container, we must be careful.. * Also here, gettable/droppable checks are done, hidden in the * test_ calls. */ if ( prev ) { if ( dest == environment(prev) ) { /* moving an object out of a container */ if ( (i = prev->test_expell_object(this_object())) != MOVE_OK ) return i; } else if ( prev == environment( dest ) ) { /* putting an object from an env into a container in same env */ if ( (i = dest->test_swallow_object( this_object() )) != MOVE_OK ) return i; } else { /* moving an object from two unrelated containers */ if ( (i = prev->test_remove_object( this_object() )) != MOVE_OK ) return i; if ( (i = dest->test_add_object( this_object() )) != MOVE_OK ) return i; } } /* if ( prev ) */ else { /* only need check that the destination weight is not exceeded */ if ( (i=dest->test_add_object( this_object() )) ) return i; } /* now perform the actual move */ if (prev) { event(prev, "exit", messout, dest); prev->adjust_contained_weight(-WEIGHT); /* no need to rebalance; if there were, the tests would have failed */ prev->adjust_light(-query_light()); } move_object(dest); event(dest, "enter", messin, prev); /* no need for the environment check, really.. */ if(environment()) { environment()->adjust_contained_weight( WEIGHT ); /* no need to rebalance; if there were, the tests would have failed */ environment()->adjust_light(query_light()); } return MOVE_OK; } /* This is a mudlib handle; NOT to be used in ANY domain code. */ void mudlib_move(object dest) { if ( environment() ) { environment()->adjust_contained_weight( -WEIGHT ); environment()->adjust_light(-query_light()); } move_object(dest); if ( environment() ) { environment()->adjust_contained_weight( WEIGHT ); environment()->adjust_light(query_light()); } } /****** Destruction, cleanup stuff */ void dest_me() { object* obs; object ob; int i; // Destruct contents of this object obs = all_inventory(this_object()); for(i = 0; i < sizeof(obs); i++) if(obs[i]) obs[i]->dest_me(); // Add weight/light to the environment, if it's there if (environment()) { environment()->adjust_contained_weight(-WEIGHT); environment()->rebalance( ({ }) ); set_light(0); event(environment(), "dest_me"); } // Destruct shadows of this object, Wonderflug 96 obs = ({ }); ob = shadow(this_object(), 0); while ( ob ) { obs += ({ ob }); ob = shadow(ob, 0); } for ( i=0; i<sizeof(obs); i++ ) if ( obs[i] ) destruct(obs[i]); efun::destruct(this_object()); } /* Do not I repeat do not mask this function. * is used when all else fails to dest the object... * If we find you masking this function... We will cut you up * into little bits... slowly */ nomask mixed dwep() { efun::destruct(this_object()); return "Destruct With Extreme Prejuce"; } /****** Value/money stuff */ varargs int adjust_money(mixed amt, string type) { if (pointerp(amt)) { value += (int)MONEY_HAND->query_total_value(amt); if (value < 0) value = 0; return value; } amt = (int)MONEY_HAND->query_total_value( ({ type, amt }) ); value += amt; if (value < 0) value = 0; return value; } int adjust_value(int i) { return (value += i); } mixed* query_money_array() { return (mixed *)MONEY_HAND->create_money_array(value); } int query_money(string type) { int i; mixed* m_a; m_a = (mixed *)MONEY_HAND->create_money_array(value); if ((i=member_array(type, m_a)) == -1) return 0; return m_a[i+1]; } void set_value(int i) { value = i; } int query_value() { return value; } /* resale value functions by Hamlet, August 1995 */ /* These are the price a shop will offer for an object. */ void set_resale_value(int i) { resale_value = i; } int adjust_resale_value(int i) { return( resale_value += i); } int query_resale_value() { if(TO->query_property("cursed")) return -1; return resale_value; } void prevent_resale() { resale_value = -1; } void allow_resale() { resale_value = 0; } /* These are for how much the shop will offer for the item if it has been stolen. -- Hamlet */ int set_stolen_modifier(int i) { if(i > 100) i = 100; if(i < -1) i = -1; stolen_modifier = i; return i; } int query_stolen_modifier() { return stolen_modifier; } void no_sell_if_stolen() { stolen_modifier = -1; }