/** * This is the effect skelton docs. This effect * has a classification of "mudlib.clothing.stat". * <p> * The argument to this effect should be a mapping with the set of * stat adjustments for the item and the item doing the adjusting. * ie: ({ ob, ([ "str" : 1, "dex" : -1 ]) }) * <p> * If you add the effect with the same object twice, the new set of * stat adjustments overrides the old ones. * @classification mudlib.clothing.stat * @see help::effects * @author Pinkfish */ #include "path.h" #include <effect.h> class stat_class { mapping current_adjustments; object* obs; mapping *adjs; object me; } private string *_stats; void create() { _stats = ({"str", "dex", "wis", "int", "con"}); } /* create() */ /** @ignore yes */ string query_classification() { return "mudlib.clothing.stat"; } /** * This method adjusts bonuses on the player based on the current * set of stats and things. * @param player the player to update the stats on * @param arg */ void update_adjustments( object player, class stat_class arg ) { mapping stats, bing; string stat; int i, num; if( sizeof(arg) == 4 && arg->me != player ) { arg->me = player; arg->current_adjustments = ([ ]); } for( i = 0; i < sizeof(arg->obs); i++ ) { if( !arg->obs[i] ) { arg->obs = arg->obs[0..i -1] + arg->obs[i+1..]; arg->adjs = arg->adjs[0..i -1] + arg->adjs[i+1..]; } } stats = ([ ]); foreach( stat in _stats ) { num = 0; for( i = 0; i < sizeof(arg->adjs); i++ ) { bing = arg->adjs[i]; if( bing[stat] > 0 ) { if( i > 0 ) num += bing[stat] / ( i + 1 ); else num += bing[stat]; } else if( bing[stat] < 0 ) { if( i > 1 ) num += bing[stat] * i; else num += bing[stat]; } else if( i > 0 ) { num -= i; } } stats[stat] = num; } foreach( stat in _stats ) { if( stats[stat] != arg->current_adjustments[stat] ) { call_other( player, "adjust_bonus_"+stat, stats[stat] - arg->current_adjustments[stat] ); arg->current_adjustments[stat] = stats[stat]; } } } /* update_adjustments() */ /** @ignore yes */ class stat_class beginning( object player, mixed arg, int id ) { class stat_class bing; bing = new( class stat_class ); bing->current_adjustments = ([ ]); bing->obs = ({ arg[0] }); bing->adjs = ({ arg[1] }); bing->me = player; update_adjustments( player, bing ); return bing; } /* begining() */ /** @ignore yes */ int query_indefinite() { return 1; } /** @ignore yes */ class stat_class merge_effect( object player, class stat_class old_arg, mixed *new_arg ) { int i; i = member_array( new_arg[0], old_arg->obs ); if( i != -1 ) { old_arg->adjs[i] = new_arg[1]; } else { old_arg->obs += ({ new_arg[0] }); old_arg->adjs += ({ new_arg[1] }); } update_adjustments( player, old_arg ); return old_arg; } /* merge_effect() */ /** @ignore yes */ void restart( object player, class stat_class edible ) { update_adjustments( player, edible ); } /* restart() */ /** @ignore yes */ void quiting( object player, class stat_class womble ) { womble->obs = ({ }); womble->adjs = ({ }); update_adjustments( player, womble ); } /* restart() */ /** @ignore yes */ void end( object player, class stat_class bing ) { bing->obs = ({ }); bing->adjs = ({ }); update_adjustments( player, bing ); } /* end() */ /** * This method is called to remove the stat adjusts for the specified * id. * @param player the player to remove the adjustments * @param ob the object to remove the stats */ void remove_stat_adjustment_ob( object player, object ob ) { class stat_class fluff; int *ids, i; if( sizeof( ids = player->effects_matching(query_classification()) ) ) { fluff = player->arg_of(ids[0]); for( i = 0; i < sizeof(fluff->obs); i++ ) { if( fluff->obs[i] == ob ) { fluff->adjs = fluff->adjs[0..i-1] + fluff->adjs[i+1..]; fluff->obs = fluff->obs[0..i-1] + fluff->obs[i+1..]; } } if( !sizeof(fluff->obs) ) { player->delete_effect(ids[0]); } else { update_adjustments( player, fluff ); player->set_arg_of( ids[0], fluff ); } } } /* remove_stat_adjustment_ob() */