/**
* @changed Changed to use the sewing skill instead of weaving.
* - Sandoz, 10th July 2001.
* @changed Changed to charge guild points.
* - Sandoz, 16th October 2001.
* @changed Changed to a variable gp cost system.
* - Sandoz, 4th June 2003.
*/
#include <tasks.h>
#define SKILLS ({"crafts.materials.tanning", \
"crafts.materials.sewing", \
})
#define A_MAX 5
#define C_MAX 100
#define A_COND 5
#define C_COND 25
#define SCALE 50
#define MIN_GP_COST 5
#define MAX_GP_COST 60
inherit COMMAND_BASE;
/**
* This method is used to determine how much to give a rough
* estimate as to how much it will cost to fix a given item.
* @param player the person doing the fixing
* @param item the item being fixed
* @param costing whether or not the cost to fix is being estimated
* @param max the maximum condition of the item (optional)
* @param cond the current condition of the item (optional)
* @param low the lowest condition of the item (optional)
* @return the cost in brass coins to repair the item
*/
varargs int query_fix_cost( object player, object item, int costing,
int max, int cond, int low ) {
int cost, diff, per;
max = max || item->query_max_cond();
cond = cond || item->query_cond();
low = low || item->query_lowest_cond();
diff = max - cond;
per = 100 - ENV( player )->query_discount( player );
if( per < 0 )
per = 0;
cost = ( diff * sqrt( item->query_full_value() ) ) / max;
cost *= A_MAX + ( C_MAX * ( max - low ) ) / max;
cost *= A_COND + ( C_COND * ( cond - low ) ) / ( cond + !cond );
cost /= SCALE;
if( costing )
cost *= 2;
else
cost += roll_MdN( 4, cost / 4 );
cost = ( cost * per ) / 100;
cost = ( cost < 100 ? 100 : cost );
return cost;
} /* query_fix_cost() */
/**
* This returns whether or not a given item is considered to be 'fixed'
* or not. This means it is in 98% of its maximum condition.
* @param item the item to test for fixedness.
* @return 1 if the item is fixed, 0 if it is not
*/
int test_fixed( object item ) {
return ( 100 * item->query_cond() > 98 * item->query_max_cond() );
} /* test_fixed() */
/** @ignore yes */
int cmd( object *things, int costing ) {
int bonus, cond, low, max, diff, cost, gp_cost, per, val, pl;
string place, tmp;
object thing;
if( TP->query_fighting() ) {
add_failed_mess("You cannot $V anything in the heat of battle.\n");
return 0;
}
if( !ENV(TP)->query_property("leatherwork") ) {
add_failed_mess("You are not in a leatherworking shop, "
"so you cannot repair anything.\n");
return 0;
}
if( sizeof(things) > 1 ) {
add_failed_mess("You can only repair one thing at a time.\n");
return 0;
}
place = ENV(TP)->query_property("place") || "default";
thing = things[0];
pl = query_group(things);
if( thing->query_material() != "leather") {
add_failed_mess("$I "+({"is", "are"})[pl]+" not made of leather! "
"Wrong shop!\n", things );
return 0;
}
if( thing->query_worn_by() ) {
add_failed_mess("You should probably remove $I before you jab "
"yourself with a needle trying to patch "+
({"it", "them"})[pl]+" up while wearing.\n", things );
return 0;
}
if( test_fixed( thing ) ) {
add_failed_mess("$I "+({"is", "are"})[pl]+" already in top "
"condition.\n", things );
return 0;
}
if( ( per = 100 - ENV(TP)->query_discount(TP) ) < 0 )
per = 0;
val = TP->query_value_in( place );
if( place != "default")
val += TP->query_value_in("default");
max = thing->query_max_cond() || 1;
low = thing->query_lowest_cond() || 1;
cond = thing->query_cond();
cost = query_fix_cost( TP, thing, costing, max, cond, low );
if( ( gp_cost = MAX_GP_COST - MAX_GP_COST * cond / max ) < MIN_GP_COST )
gp_cost = MIN_GP_COST;
event( TP, "inform", sprintf("Cond: %i, Max Cond: %i, GP Cost: %i",
cond, max, gp_cost ), "debug");
diff = max - cond;
// Not very damaged. Simple sewing will do.
if( ( 100 * diff ) / max > 70 ) {
if( ( bonus = TP->query_skill_bonus( SKILLS[ 1 ] ) ) < 10 ) {
add_failed_mess("You stare at $I for a while, but give up after "
"a while of cogitating because you cannot decide where to "
"start.\n", things );
return 0;
}
if( costing ) {
add_succeeded_mess( ({"It would probably cost you about "+
MONEY_H->money_value_string( cost, place )+" to attempt to "
"repair $I.\n", ""}), things );
return 1;
}
if( val < cost ) {
add_failed_mess("You cannot afford the thread to repair $I.\n",
things );
return 0;
}
if( !TASKER->point_tasker( TP, "crafts", gp_cost ) ) {
add_failed_mess("You do not have enough energy to patch "
"up $I.\n", things );
return 0;
}
if( diff > bonus ) {
diff = 200 * diff / max;
switch( TASKER->perform_task( TP, SKILLS[ 1 ], diff,
TM_COMMAND ) ) {
case AWARD :
tell_object( TP, "%^YELLOW%^"+replace( ({
"As you begin to fix $I, you realise how to make better "
"use of the materials.",
"As you work on $I, you find that you're able to fix "+
({"it", "them"})[pl]+" completely.", "You discover that "
"you can fix $I more effectively." })[ random( 3 ) ],
"$I", thing->the_short() )+"%^RESET%^\n");
case SUCCEED :
XP_H->handle_xp( TP, gp_cost, 1 );
diff = max - cond;
break;
default :
XP_H->handle_xp( TP, gp_cost, 0 );
diff = bonus;
}
}
thing->adjust_cond( diff );
TP->pay_money( MONEY_H->create_money_array( cost, place ), place );
if( test_fixed(thing) )
tmp = "You sew up all the holes in $I, bringing "+
({"it", "them"})[pl]+" to top condition.";
else
tmp = "You manage to sew up some of the holes in $I, but a few "
"pop back open due to poor stitching.";
add_succeeded_mess( ({ tmp + "\nThe thread and sinew costs you "+
MONEY_H->money_value_string( cost, place )+".\n",
"$N fix$es up $I.\n" }), things );
return 1;
} else {
if( ( bonus = TP->query_skill_bonus( SKILLS[ 0 ] ) ) < 10 ) {
add_failed_mess("You stare at $I for a while, but give up after "
"a while of cogitating because you cannot decide where to "
"start.\n", things );
return 0;
}
if( costing ) {
add_succeeded_mess( ({"It would probably cost you about "+
MONEY_H->money_value_string( cost, place )+" to attempt to "
"repair $I.\n", ""}), things );
return 1;
}
if( val < cost ) {
add_failed_mess("You cannot afford the thread to repair $I.\n",
things );
return 0;
}
if( !TASKER->point_tasker( TP, "crafts", gp_cost ) ) {
add_failed_mess("You do not have enough energy to patch "
"up $I.\n", things );
return 0;
}
if( !cond ) {
add_succeeded_mess( ({"You begin to work on $I when "+
({"it", "they"})[pl]+" fall"+({"s", ""})[pl]+" apart! "+
({"It", "They"})[pl]+" must have been too damaged to "
"repair.\n", "$N begin$s to work on $I when "+
({"it", "they"})[pl]+" fall"+({"s", ""})[pl]+" to "
"scraps!\n"}), things );
thing->break_me();
return 1;
}
if( diff > bonus ) {
diff = 200 * diff / max;
switch( TASKER->perform_task( TP, SKILLS[ 0 ], diff,
TM_COMMAND) ) {
case AWARD :
tell_object( TP, "%^YELLOW%^"+replace( ({
"As you begin to cut and sew the leather patches for $I, "
"you realise how to make better use of the leather.",
"As you work on $I, you find that you're able to repair "+
({"it", "them"})[pl]+" completely.",
"You discover that you can repair $I more effectively.",
})[ random( 3 ) ], "$I", thing->the_short() )+
"%^RESET%^\n");
case SUCCEED :
XP_H->handle_xp( TP, gp_cost, 1 );
diff = max - cond;
break;
default :
XP_H->handle_xp( TP, gp_cost, 0 );
diff = bonus;
}
}
thing->adjust_cond( diff );
TP->pay_money( MONEY_H->create_money_array( cost, place ), place );
if( test_fixed(thing) )
tmp = "Your patching of $I goes quite well, and you bring "+
({"it", "them"})[pl]+" to top condition.";
else
tmp = "You manage to create reasonably good patches for $I, "
"but the size wasn't quite right, and the stitching "
"doesn't look like it will hold very well.";
add_succeeded_mess( ({ tmp + "\nThe repair materials cost you "+
MONEY_H->money_value_string( cost, place )+".\n",
"$N fix$es up $I.\n" }), things );
return 1;
}
} /* cmd() */
/** @ignore yes */
mixed *query_patterns() {
return ({ "<indirect:object:me>", (: cmd( $1, 0 ) :),
"cost <indirect:object:me>", (: cmd( $1, 1 ) :) });
} /* query_patterns() */