/** * This class keeps track of the condition of a particular object. It * handles damaging the object when it is hit and the lowest conditon to * which the object has been damaged. The lowest conditon keeps track of * how hard the object is to fix. If an object has been reduced to really * shaggy condition at one point, it will be a lot harder to fix from then * on. * @author Pinkfish */ #include <armoury.h> #include <move_failures.h> #define DAMAGE_NORM 100 nosave int cond, max_cond, lowest_cond, damage_chance, hide_cond; void create() { max_cond = 1; } /* create() */ /* This should be masked. */ /** * This method breaks the object. This moves it into the recycled * object section of the armoury or dests itself if this is not * possible. */ void break_me() { if( (int)TO->move( "/room/rubbish" ) != MOVE_OK ) move_object("/room/rubbish"); } /* break_me() */ /** * This method returns the current condition as a string. * @return the string value of the condition */ string cond_string() { string str; if( cond > max_cond ) cond = max_cond; if( hide_cond ) return ""; str = ({"It is", "They are"})[query_group(TO)]+" "; switch( ( 100 * cond ) / max_cond ) { case 91 .. 100 : return str + "in excellent condition.\n"; case 81 .. 90 : return str + "in very good condition.\n"; case 71 .. 80 : return str + "in good condition.\n"; case 61 .. 70 : return str + "in OK condition.\n"; case 51 .. 60 : return str + "in fairly good condition.\n"; case 41 .. 50 : return str + "in fairly poor condition.\n"; case 31 .. 40 : return str + "in poor condition.\n"; case 21 .. 30 : return str + "in really poor condition.\n"; case 11 .. 20 : return str + "in very poor condition.\n"; case 1 .. 10 : return str + "in atrocious condition.\n"; default : return str + "a complete wreck.\n"; } } /* cond_string() */ /** * This sets up how much damage an object can take before it * breaks. This should not be used in the actual object files * unless under special circumstances. In weapon files, use * new_weapon(). In armour files use setup_armour(). In * clothing files, use setup_clothing(). Use ::Setup:: in * clo, arm, and wep files. * <p> * The values may seem strange, as cloth can take more damage * per unit weight than steel. This is because steel weighs * so much, and cloth weighs so little. * <br><br> * o==================o=====================o<br> * | Material | Maximum Condition |<br> * | | per unit weight |<br> * o==================o=====================o<br> * | Cloth | 90 |<br> * | Hide | 80 |<br> * | Leather | 70 |<br> * | Wood | 60 |<br> * | Bone | 45 |<br> * o==================o=====================o<br> * | Copper | 30 |<br> * | Stone | 40 |<br> * | Bronze | 40 |<br> * | Iron | 50 |<br> * | Steel | 60 |<br> * | Klatchian Steel | 70 |<br> * | Octiron | 80 |<br> * o==================o=====================o * * @see new_weapon * @see setup_armour * @see setup_clothing * @see set_weight * @see set_damage_chance */ void set_max_cond(int i) { max_cond = i; } /** * This method sets the current condition of the object. If this is lower * than the current lowest conditon, then the lowest condition will be modified * to be this. * @param i the new condition * @see adjust_condition */ void set_cond( int i ) { cond = ( i < 0 ? 0 : i ); if( cond < lowest_cond ) lowest_cond = cond; if( cond <= 0 ) { if( ENV(TO) && !ENV(TO)->query_property("don't break contents") ) TO->break_me(); return 0; } } /* set_cond() */ /** * This method adjust the current condition by the given amount. If * resultant condition is less than the lowest condition, then the lowest * condition is set to this value. If it is greater than the maximum * condition. Then the condition is set to the maximum condition. If the * condition is less than or equal to 0, then the object is attempted to * be broken. * @param i the amount to adjust the condition by * @return the new condition * @see set_cond() */ int adjust_cond( int i ) { cond += i; if( cond < 0 ) cond = 0; if( cond < lowest_cond ) lowest_cond = cond; if( cond > max_cond ) cond = max_cond; if( cond <= 0 ) { if( ENV(TO) && !ENV(TO)->query_property( "don't break contents" ) ) TO->break_me(); return 0; } return cond; } /* adjust_cond() */ /** * This sets the lowest condition for the object. The lowest cond * variable is used for repairing the armour... * See where it was repaired to last time, this determines how difficult * repairs will be... * @param i the new lowest condition * @see adjust_cond() * @see set_cond() */ void set_lowest_cond(int i) { lowest_cond = i; } /** * This sets whether the condition string should be returned or not. This * is for objects what indicate their condition with different long * descriptions instead of the default condition string. * @param i set it to 1 to hide the condition string. */ void set_hide_cond(int i) { hide_cond = i; } /** * This method returns the current conditon. * @return the current condition */ int query_cond() { if( cond > max_cond ) cond = max_cond; return cond; } /* query_cond() */ /** * This method returns the current maximum conditon. * @return the current maximum condition */ int query_max_cond() { return max_cond; } /** * This method returns the current lowest conditon. * @return the current lowest condition */ int query_lowest_cond() { return lowest_cond; } /** * This method returns whether the condition string returns "" or something * meaning full. * @return the current lowest condition */ int query_hide_cond() { return hide_cond; } /** * This method is used to setup the objects condition. Once the maximum * condition has been set, this is used to set the maximum condition to * this percentage of the maximum condition. * It sets the lowest conditon a random value from 70-100% of the * current condition. * @param i the percentage condiion * @see /handlers/armoury.c * @see set_cond() * @see set_lowest_cond() * @see query_max_cond() */ void set_percentage(int i) { if( i > 100 ) i = 100; set_cond( ( query_max_cond() * i ) / 100 ); set_lowest_cond( ( query_cond() * ( random(30) + 70 ) ) / 100 ); } /* set_percentage() */ /** * This method returns the percentage of the damage which is done to the * object which will be carried through. * @return the damage chance * @see do_damage() */ int query_damage_chance() { return damage_chance; } /** * This method sets the percentage of the damage which is done to the * object which will be carried through. * <p> * Use the following chart to set the damage chance. * <br><br> * o==================o=====================o<br> * | Material | Damage Chance |<br> * o==================o=====================o<br> * | Cloth | 20 |<br> * | Hide | 17 |<br> * | Bone | 16 |<br> * | Leather | 15 |<br> * | Wood | 12 |<br> * | Copper | 10 |<br> * | Bronze | 8 |<br> * | Iron | 6 |<br> * | Steel | 5 |<br> * | Klatchian Steel | 3 |<br> * | Stone | 3 |<br> * | Octiron | 0 |<br> * o==================o=====================o * * @see new_weapon * @see setup_armour * @see setup_clothing * @see set_weight * @see set_max_cond * @see query_damage_chance() * @see do_damage() * @param number the new damage chance */ void set_damage_chance( int number ) { damage_chance = number; } /** * This method damages the object. The conditon is reduced by * the amount multiplied by 1 + 2 * random(damage_chance) ewhic * is then divided by 100. This means it does approximately * the percentage of of the damage done to the object to its condition. * @see set_damage_chance() * See query_damage_chance() */ void do_damage( string type, int amount ) { int wholes, parts; wholes = amount * ( 1 + random( damage_chance ) + random( damage_chance ) ); parts = wholes % DAMAGE_NORM; wholes /= DAMAGE_NORM; if( random( DAMAGE_NORM ) < parts ) wholes++; adjust_cond( -wholes ); } /* do_damage() */ /** @ignore */ mixed *stats() { return ({ ({ "condition", cond }), ({ "max cond", max_cond }), ({ "lowest cond", lowest_cond }), ({ "damage chance", damage_chance }), ({ "hide cond", hide_cond }), }); } /* stats() */ /** @ignore */ mapping query_static_auto_load() { mapping m; m = ([ ]); if( max_cond ) m["max cond"] = max_cond; if( damage_chance ) m["damage chance"] = damage_chance; if( hide_cond ) m["hide cond"] = hide_cond; return m; } /* query_static_auto_load */ /** @ignore */ void init_static_arg( mapping map ) { if( !undefinedp( map[ "max cond" ] ) ) max_cond = map[ "max cond" ]; if( !undefinedp( map[ "damage chance" ] ) ) damage_chance = map[ "damage chance" ]; if( !undefinedp( map[ "hide cond" ] ) ) hide_cond = map[ "hide cond" ]; } /* init_static_arg() */ /** @ignore */ mapping query_dynamic_auto_load() { mapping m; if( cond > max_cond ) cond = max_cond; if( lowest_cond > cond ) lowest_cond = cond; m = ([ ]); if( cond ) m["cond"] = cond; if( lowest_cond ) m["lowest cond"] = lowest_cond; return m; } /* query_dynamic_auto_load */ /** @ignore */ void init_dynamic_arg( mapping map ) { if( !undefinedp( map[ "cond" ] ) ) cond = map[ "cond" ]; if( !undefinedp( map[ "lowest cond" ] ) ) lowest_cond = map[ "lowest cond" ]; } /* init_dynamic_arg() */