From: Andy Hubbard <hub@leicester.ac.uk>
Subject: Damaged Objects 


--- act.informative.c ---

in ACMD(do_examine)
add to the end


 // don't report condition if npc/pc
 if ((tmp_char) && (!tmp_object)) {
  return;
 }

 // condition reports as a percentage now, so items can have different
 // starting tslots and cslots, eg. for wood and steel
 condition = (GET_OBJ_CSLOTS(tmp_object) * 100)/GET_OBJ_TSLOTS(tmp_object);

 if (condition == 0) {
   sprintf(buf, "This looks indestructable!\r\n");
   send_to_char(buf, ch);
   return;
   }
 if (condition <= 10) {
   sprintf(buf, "This looks in extremley poor condition.\r\n");
   send_to_char(buf, ch);
   return;
   }
 if (condition <= 20) {
   sprintf(buf, "This looks in poor condition.\r\n");
   send_to_char(buf, ch);
   return;
   }
 if (condition <= 30) {
   sprintf(buf, "This looks in fair condition.\r\n");
   send_to_char(buf, ch);
   return;
   }
 if (condition <= 40) {
   sprintf(buf, "This looks in moderate condition.\r\n");
   send_to_char(buf, ch);
   return;
   }
 if (condition <= 50) {
   sprintf(buf, "This looks in good condition.\r\n");
   send_to_char(buf, ch);
   return;
   }
 if (condition <= 60) {
   sprintf(buf, "This looks in very good condition.\r\n");
   send_to_char(buf, ch);
   return;
   }
 if (condition <= 70) {
   sprintf(buf, "This looks in excellent condition.\r\n");
   send_to_char(buf, ch);
   return;
   }
 if (condition <= 80) {
   sprintf(buf, "This looks in superior condition.\r\n");
   send_to_char(buf, ch);
   return;
   }
 if (condition <= 90) {
   sprintf(buf, "This looks in extremely superior
   condition.\r\n"); send_to_char(buf, ch);
   return;
   }
 else {
   sprintf(buf, "This looks as good as new!.\r\n");
   send_to_char(buf, ch);
   return;
 }

--- act.item.c ---

Add the repair skill to the end of the file


ACMD(do_repair)
{
 struct obj_data *repair;
 int percent, prob;

 if (GET_SKILL(ch, SKILL_REPAIR) <= 0) {
    send_to_char("You don't know how to repairs things!\r\n", ch);
    return;
  }

 one_argument(argument, arg);

 if (!*arg) {
  send_to_char("Repair what?\r\n", ch);
  return;
 }

 if (!(repair = get_obj_in_list_vis(ch, arg, ch->carrying))) {
    sprintf(buf, "You don't seem to have %s %s.\r\n", AN(arg), arg);
    send_to_char(buf, ch);
  return;
 }

 percent = number(1, 101);
 prob = GET_SKILL(ch, SKILL_REPAIR);

 if ((GET_OBJ_CSLOTS(repair) == 0) && (GET_OBJ_TSLOTS(repair) == 0)) {
  act("$p seems to be indestructable!", FALSE, ch, repair, 0,
  TO_CHAR); return;
 }

 if (GET_OBJ_CSLOTS(repair) == GET_OBJ_TSLOTS(repair)) {
  act("$p seems to be in perfect condition!", FALSE, ch, repair, 0,
  TO_CHAR); return;
 }

 if (GET_OBJ_CSLOTS(repair) < 0) {
  act("You completely ruin $p and it crumbles away!", FALSE, ch,
  repair, 0, TO_CHAR); act("$n tries to repair $p, but it crumbles
  away!", TRUE, ch, repair, 0, TO_ROOM); extract_obj(repair); return;
 }

 if (percent > prob) {
  act("Your clumsy attempt at repairing $p damages it even more!",
  FALSE, ch, repair, 0, TO_CHAR); act("$n tries to repair $p, but only
  makes it worse!", TRUE, ch, repair, 0, TO_ROOM);
  GET_OBJ_CSLOTS(repair) -= 2; GET_OBJ_TSLOTS(repair) -= 1; return;
 }
 else {
  act("You repair $s and it looks in excellent condition again!",
  FALSE, ch, repair, 0, TO_CHAR); act("$n repairs $p, making it as
  good as new again!", TRUE, ch, repair, 0, TO_ROOM);
  GET_OBJ_TSLOTS(repair) -= 1; GET_OBJ_CSLOTS(repair) =
  GET_OBJ_TSLOTS(repair); improve_skill(ch, SKILL_REPAIR); return;
 }

-- db.c --

change 
char *parse_object(FILE * obj_f, int nr)
at the top ..

int t[6], j, k;

further down ..

/* *** numeric data *** */
  if (!get_line(obj_f, line) ||
      (retval = sscanf(line, " %d %s %s", t, f1, f2)) != 3) {
    fprintf(stderr, "Format error in first numeric line (expecting 3
    args, got %d), %s\n", retval, buf2); exit(1);
  }
  obj_proto[i].obj_flags.type_flag = t[0];
  obj_proto[i].obj_flags.extra_flags = asciiflag_conv(f1);
  obj_proto[i].obj_flags.wear_flags = asciiflag_conv(f2);

 if (!get_line(obj_f, line) ||
  (retval = sscanf(line, "%d %d %d %d %d %d", t, t + 1, t 
   + 2, t + 3, t + 4, t + 5)) > 6) { // umm, still trying here!
    fprintf(stderr, "Format error in second numeric line (expecting 4
    or 6 args, got %d), %s\n", retval, buf2); exit(1);
 }

  obj_proto[i].obj_flags.value[0] = t[0];
  obj_proto[i].obj_flags.value[1] = t[1];
  obj_proto[i].obj_flags.value[2] = t[2];
  obj_proto[i].obj_flags.value[3] = t[3];
 if (t[4] < 0 || t[4] > 100) {
  obj_proto[i].obj_flags.curr_slots = 0;
  obj_proto[i].obj_flags.total_slots = 0;
 }
  else {
   obj_proto[i].obj_flags.curr_slots = t[4];
   obj_proto[i].obj_flags.total_slots = t[5];
 }


 if (t[5] < 0 || t[5] > 100) {
  obj_proto[i].obj_flags.curr_slots = 0;
  obj_proto[i].obj_flags.total_slots = 0;
 }
 else {
  obj_proto[i].obj_flags.curr_slots = t[4];
  obj_proto[i].obj_flags.total_slots = t[5];
 }


  if (!get_line(obj_f, line) ||

-- fight.c --

add into 
void perform_violence

/* Breakable ITEM Code -- Each round each equiped item is checked to
see if
 damage occurs. The check is based on how strong the material is
 initially, eg. if wood is assigned a tslot of 20, then there is a 1
 in 100 chance of damage, while steel of 100, has a 1 in 500 chance. 
 The chance of damage will increase the more an item is
 repaired ..... */

 int condition; // add at top of function

 for (j = 0; j < NUM_WEARS; j++) {
  if (ch->equipment[j]) {

   condition = GET_OBJ_TSLOTS(ch->equipment[j]) * 5;

   if (number(0, condition) == 1) {
    if (ch->equipment[j]->obj_flags.total_slots != 0) {
     ch->equipment[j]->obj_flags.curr_slots =
     ch->equipment[j]->obj_flags.curr_slots--;
     sprintf(buf, "%s just got DAMAGED during the combat!\r\n",
      ch->equipment[j]->short_description);
     send_to_char(buf, ch);
    }
   }

   if ((ch->equipment[j]->obj_flags.curr_slots == 0) &&
    (ch->equipment[j]->obj_flags.total_slots != 0)) {
    sprintf(buf, "%s crumbles to dust as it wears out!\r\n",
     ch->equipment[j]->short_description);
    send_to_char(buf, ch);
    extract_obj(ch->equipment[j]);
   }
  }

-- interpreter.c --

add 

ACMD(do_repair);

and

{ "repair"   , POS_STANDING, do_repair   , 0, 0 },

-- objsave.c --

// make sure we save damage object info so players
// don't reload with brand new gear!

in
struct obj_data *Obj_from_store_to

add

GET_OBJ_CSLOTS(obj) = object.curr_slots;
GET_OBJ_TSLOTS(obj) = object.total_slots;

in
int Obj_to_store_from

add

object.curr_slots = GET_OBJ_CSLOTS(obj);
object.total_slots = GET_OBJ_TSLOTS(obj);

-- spell.parser.c --

add

"repair",

and the 'spello' which I don't use quite as source ..

-- spells.c --

add to
ASPELL(spell_identify)

int condition;

and


  condition = (GET_OBJ_CSLOTS(obj) * 100)/GET_OBJ_TSLOTS(obj);

  if ((GET_OBJ_CSLOTS(obj) == 0) && (GET_OBJ_TSLOTS(obj) == 0)) {
        sprintf(buf, "Quality: INDESTRUCTABLE\r\n");
        found = 1;
        }
    if ((GET_LEVEL(ch) >= LVL_IMMORT) && (found == 0)) {
        sprintf(buf, "Quality: %d/%d\r\nCondition: %d percent\r\n",
     GET_OBJ_CSLOTS(obj), GET_OBJ_TSLOTS(obj), condition);
        found = 1;
        }
    if ((condition <= 10) && (found == 0)) {
        sprintf(buf, "Quality: Extremley Poor\r\n");
        found = 1;
        }
    if ((condition <= 20) && (found == 0)) {
        sprintf(buf, "Quality: Poor\r\n");
        found = 1;
        }
    if ((condition <= 30) && (found == 0)) {
        sprintf(buf, "Quality: Fair\r\n");
        found = 1;
        }
    if ((condition <= 40) && (found == 0)) {
        sprintf(buf, "Quality: Moderate\r\n");
        found = 1;
        }
    if ((condition <= 50) && (found == 0)) {
        sprintf(buf, "Quality: Good\r\n");
        found = 1;
        }
    if ((condition <= 60) && (found == 0)) {
        sprintf(buf, "Quality: Very Good\r\n");
        found = 1;
        }
    if ((condition <= 70) && (found == 0)) {
        sprintf(buf, "Quality: Excellent\r\n");
        found = 1;
    }
    if ((condition <= 80) && (found == 0)) {
        sprintf(buf, "Quality: Superior\r\n");
        found = 1;
    }
  if ((condition <= 90) && (found == 0)) {
        sprintf(buf, "Quality: Extremely Superior\r\n");
        found = 1;
    }
  if ((condition <= 100) && (found == 0)) {
        sprintf(buf, "Quality: Brand New\r\n");
        found = 1;
    }
    send_to_char(buf, ch);

-- structs.h --

add in
struct obj_flag_data {

int  curr_slots;     // Current amount of SLOTS obj has 
int  total_slots;    // Total amount of SLOTS an obj has

and in
struct obj_file_elem {

int  curr_slots;     // Current amount of SLOTS obj has 
int  total_slots;    // Total amount of SLOTS an obj has

-- utils.h --

add

#define GET_OBJ_CSLOTS(obj)     ((obj)->obj_flags.curr_slots)
#define GET_OBJ_TSLOTS(obj)     ((obj)->obj_flags.total_slots)

-----

assign the repair skill to whoever you want to get it, or use it in a 
spec_proc for a repair mobile.

As for the .obj file, you need two more numbers on the second numeric 
line to get the object condition in.
eg.

#1001
shield~
a small wooden shield~
There is a small shield made of wood dumped here.~
~
9 4096 513
5 0 0 0 20 20    // 20,20 for condition of object
5 30 0
E
shield~
This shield is worn on the forearm and gripped with the hand.  The
shield will offer some protection from a single frontal attack.
~

or

#1016
steel breastplate~
a steel breastplate~
You see a breastplate made of steel here.~
~
9 20480 9
15 0 0 0 100 100  // 100,100 for condition of object, steel a lot 
                  //         better then wood!
35 20000 0
E
steel breastplate~
This is a breast plate from a full set of plate armour, consisting of
shaped and fitted metal plates riveted and interlocked to cover your
torso.  This armour is perfectly manufactured to provide excellent
protection.
~

----
I hope I remembered everything :)

Andy
