[CODE] [LONG] Refueling Light Sources

From: Haddixx (haddixx@megamed.com)
Date: 10/04/96


If you are like me you are probably sick of having to carry around a
thousand lanterns because when the fuel runs out in the one you have its
only use is as a paper weight.  I also dislike the idea of infinite light
sources so I decided to allow certain light sources to be refueled.  Its
actually not that hard to do but you do need to change a few key parameters.
Here is how I did it.  
I do not guarantee it to be bug proof so if you find a bug or two an email
explaining the bug would be appreciated.  If you have any problems getting
this to work let me know.  I cannot program it into your mud for you but I
can give you some advice on what may be causing the error.  Ok, here it is:

First a brief overview of what needs to be done:
1)  You need to add a few more values to the light sources so that the MUD
will know if it is a refuelable light source or not, what the maximum amount
of fuel the item can take, and what type of fuel it uses.
2)  You need to define a new type of object.  I called it ITEM_FUEL.  This
type of object will be used to refuel a refuelable light source.   The
values that this object will have are fuel type and amount of fuel.
3)  Finally, you will need some way to refuel the light source.  I created a
command called 'refuel' to do this.

Here are the vales that the new ITEM_LIGHT and ITEM_FUEL will have:

LIGHT (Type Flag 1)
     value 0: Refuelable? (0 = not refuelable)
     value 1: Type of Fuel
     value 2: Capacity of light in hours.
                0: Burned out light.
               -1: Eternal light source.
     value 3: Max Capacity of light in hours.

FUEL (Type Flag 24)
     value 0: Amount of Fuel
     value 1: Type of Fuel
     value 2: unused
     value 3: unused

Ok, now to the code:

First, in structs.h the you need to add a new object type which I called
ITEM_FUEL as follows:

#define ITEM_FOUNTAIN  23	/* Item is a fountain		*/
#define ITEM_FUEL      24       /* Item is fuel for light       */

Also in structs.h I defined a few types of fuel:
#define FUEL_OIL	0
#define FUEL_COAL	1
#define FUEL_FAT	2

In constants.c I named these fuel types:

/* FUEL_x */
const char *fuels[] =
{
  "oil",
  "coal",
  "fat",
  "\n"
};

I defined some utilities in utils.h to make my code more readable:

/* Lantern related utils */
#define GET_FUEL_TYPE(obj)	((obj)->obj_flags.value[1])
#define GET_MAX_FUEL(obj)	((obj)->obj_flags.value[3])
#define GET_CUR_FUEL(obj)	((obj)->obj_flags.value[2])


Ok, now for the actual code that refuels the objects:

At the top of act.item.c declare the following:

extern char *fuels[];

Then add this function, or something similar:

ACMD(do_refuel)
{
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  char mesg[256];
  struct obj_data *from_obj = NULL, *to_obj = NULL;
  int amount, found;

  two_arguments(argument, arg1, arg2);

  if (!*arg1) /* no arguments */
  {		
    send_to_char("What do you want to refuel?  And what are you filling it
with?\r\n", ch);
    return;
  }
  if (!(to_obj = get_obj_in_list_vis(ch, arg1, ch->carrying))) 
  {
    send_to_char("You can't find it!", ch);
    return;
  }
  /* make sure item is a lightsource and refuelable */
  if (GET_OBJ_TYPE(to_obj) != ITEM_LIGHT && GET_OBJ_VAL(to_obj, 1) != 0) 
  {
    act("You can't refuel $p!", FALSE, ch, to_obj, 0, TO_CHAR);
    return;
  }
  if (!*arg2) /* no 2nd argument */
  {		
    act("What do you want to refuel $p with?", FALSE, ch, to_obj, 0, TO_CHAR);
    return;
  }
  if (!(from_obj = get_obj_in_list_vis(ch, arg2, ch->carrying))) 
  {
    send_to_char("You can't find it!", ch);
    return;
  }
  /* make sure second item is a fuel source */
  if(GET_OBJ_TYPE(from_obj) != ITEM_FUEL) 
  {
    act("You can't refuel something with $p.", FALSE, ch, from_obj, 0, TO_CHAR);
    return;
  }
 /* make sure it is the correct type of fuel */
  if( GET_FUEL_TYPE(from_obj) != GET_FUEL_TYPE(to_obj))
  {
    act("That is the wrong type of fuel for $p!", FALSE, ch, to_obj, 0,
TO_CHAR);
    return;      
  }
  /* check if the light source even needs fuel */
  if( GET_CUR_FUEL(to_obj) >= GET_MAX_FUEL(to_obj) )
  {
    act("$p is already fully fueled.", FALSE, ch, to_obj, 0, TO_CHAR);
    return;        
  }
/* make sure there is still fuel available in the fuel source. */
  if( (found = GET_OBJ_VAL(from_obj, 0)) <= 0 )
  {
    act("But $p is empty.", FALSE, ch, from_obj, 0, TO_CHAR);
    return;        
  }
  amount = GET_MAX_FUEL(to_obj) - GET_CUR_FUEL(to_obj);
  
  /* More fuel than light source can handle */
  if(amount < found)
  {
     GET_CUR_FUEL(to_obj) = GET_MAX_FUEL(to_obj);
     GET_OBJ_VAL(from_obj, 0) -= amount;
     sprintf(mesg, "You refuel $p with %s from %s.", 
             fuels[GET_FUEL_TYPE(from_obj)], GET_OBJ_NAME(from_obj));
     act(mesg, FALSE, ch, to_obj, 0, TO_CHAR);
     act("$p is completely refueled.", FALSE, ch, to_obj, 0, TO_CHAR);    
     return;
  }
  else
  {
     GET_CUR_FUEL(to_obj) += found;
     GET_OBJ_VAL(from_obj, 0) = 0;
     sprintf(mesg, "You refuel $p with %s from %s.", 
             fuels[GET_FUEL_TYPE(from_obj)], GET_OBJ_NAME(from_obj));
     act(mesg, FALSE, ch, to_obj, 0, TO_CHAR);
     return;     
  }	  
    
}

That should do it.  You will have to add a new command into that huge array
in interpreter.c to recognize do_fuel.  And, you will have to convert over
your current light sources and create a few fuel objects.  Again, I'm not
sure if this is totally bug proof.  I haven't fully debugged it. I just made
sure it worked properly.  Oh, one other thing.  You may want to change
do_stat_object in act.wizard.c to allow you to more effectively stat LIGHT
and FUEL objects.  Good luck!

-Haddixx
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |     -=-=- AVALANCHE MUD -=-=-               | Haddixx               |
 + Running at: 143.207.31.45 port 8000         + Brian M. Menges       +
 | Imps: Haddixx [haddixx@megamed.com]         |                       |
 +       Devon [cthompso@chat.carleton.ca]     +                       +
 | Web Site: http://www.megamed.com/~haddixx   |                       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


+-----------------------------------------------------------+
| Ensure that you have read the CircleMUD Mailing List FAQ: |
|   http://cspo.queensu.ca/~fletcher/Circle/list_faq.html   |
+-----------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/18/00 PST