Events/
/* Ok! Here's a couple examples. 

/* On my MUD you had Crystals which you could charge
   with mana. Here's the event */


void event_charge( CHAR_DATA *ch, OBJ_DATA *crystal )
{	USE *use;
	int percent;
	static int last_percent;
	if( !( use = get_obj_use( crystal, UTYPE_CRYSTAL ) ) )
	{	send_to_char("This isn't a crystal.\n\r",ch);
		return;
	}

	if(use->value[2] >= use->value[1] )
	{	send_to_char("The crystal is fully charged.\n\r",ch);
		use->value[2] = use->value[1];
		return;
	}
	if( ch->mana == 0 )
	{	send_to_char ("Your out of mana!\n\r",ch);
		return;
	}
	ch->mana--;
	use->value[2]++;
	percent = (int)( ( (float)use->value[2] / (float)use->value[1] ) *100 );
	if(percent == 10 && last_percent != 10)
	{	send_to_char("The crystal begins to glow with a low glimmer.\n\r",ch);
		last_percent = 10;
	}
	else if (percent == 20 && last_percent != 20)
	{	send_to_char("The low glimmer of the crystal grows.\n\r",ch);
		last_percent = 20;
	}
	else if (percent == 40 && last_percent != 40)
	{	send_to_char("The crystal begins to glow softly.\n\r",ch);
		last_percent = 40;
	}
	else if (percent == 70 && last_percent != 70)
	{	send_to_char("The crystal glows brightly.\n\r",ch);
		last_percent = 70;
	}
	else if (percent == 90 && last_percent != 90)
	{	send_to_char("The crystal glows strongly, and hums.\n\r",ch);
		last_percent = 90;
	}
	event_to_char(ch, END_CHAR, (void *) crystal, 0, EVENT_CHARGE, 1 );
	return;
}

/* This is what was added to execute_char_event() */
		case EVENT_CHARGE:
			event_charge(ch, (OBJ_DATA *) event->arg );
			break;
/*Entry in the event_table */
	{ "charge", 	EVENT_CHARGE,	charge_cmdevent },

/*The charge_cmdevent */
/* These are command that you are allowed to execute while an event is pending. */
/* The stop command just purged all your events (purge_all_events()) which stopped */
/* the charging process. */
char *charge_cmdevent []=
{	 "stop",
	 "look",
	  NULL
};

/* This was the do_function that began the charging. */
/* The 'USE *use' is just basically my obj->value's and obj->item_type */
/* all rolled into one nifty little package so imagine UTYPE_WEAPON as ITEM_WEAPON */

void do_recharge( CHAR_DATA *ch, char *argument )
{       OBJ_DATA *staff;
        USE *use;

        if( !( staff = get_eq_char(ch, WEAR_WIELD ) ) )
        {       send_to_char("You don't have a staff to charge.\n\r",ch);
                return;
        }
        if( !( use = get_obj_use(staff, UTYPE_WEAPON ) ) || use->value[0] != WEAPON_STAFF)
        {       send_to_char("You must be wielding a staff to charge.\n\r",ch);
                return;
        }

        if(!staff->embedded)
        {       send_to_char("There is nothing embedded into this staff to charge.\n\r",ch);
                return;
        }

        if( !(use = get_obj_use(staff->embedded, UTYPE_CRYSTAL ) ) )
        {       send_to_char("Find the nearest Immortal, and complain.\n\r",ch);
                return;
        }

        printf_to_char(ch, "You begin to charge %s.\n\r", staff->embedded->short_descr);
        event_to_char(ch, END_CHAR, (void *) staff->embedded, 0, EVENT_CHARGE, 1 );
        return;
}

/* End of Charge Event */


/* This is an event for Objects, which involved heating them up slowly over time within a furnace */

void event_heat_obj(OBJ_DATA *obj, CHAR_DATA *holder, OBJ_DATA *furnace )
{	int origTmp = obj->temp;
	int ave;

	if(furnace->temp > obj->temp)
		obj->temp += 10;
	else
		obj->temp--;

	update_obj_state(obj, origTmp, obj->temp, TRUE, TRUE );
	ave = material_table[obj->material].smeltTmp - material_table[obj->material].meltTmp;
	ave /= 2;

	if(obj->temp >= material_table[obj->material].meltTmp + ave)
	{	printf_to_char(holder, "%s melts in %s and is lost!", obj->short_descr, furnace->short_descr );
		extract_obj(obj);
		purge_all_events(holder);
		return;
	}
	event_to_obj(obj, holder, END_CHAR, furnace,0, EVENT_HEAT_OBJ, 3);
	
	return;
}


/* What was added to execute_obj_event */

	case EVENT_HEAT_OBJ:
		event_heat_obj(pObj, event->ch, (OBJ_DATA *)event->arg);

/* This is the do_function that initiated the event */


void do_heat( CHAR_DATA *ch, char *argument )
{	OBJ_DATA *pObj;
	OBJ_DATA *hObj;
	OBJ_DATA *mat;
	char arg[MSL], arg2[MSL];
	bool found = FALSE;

	argument = one_argument(argument, arg);
	argument = one_argument(argument, arg2);
	if(arg[0] == '\0' )
	{	send_to_char("Syntax: heat <material> <hearth>\n\r",ch);
		send_to_char("                         Hearth is optional.\n\r",ch);
		return;
	}

	if(arg2[0] == '\0' )
	{	for( hObj = IN_ROOM(ch)->contents ; hObj ; hObj = hObj->next_content )
		{	if(get_obj_use(hObj, UTYPE_HEARTH) || get_obj_use(hObj, UTYPE_FURNACE ) )
			{	found = TRUE;
				break;
			}
		}
		if(!found)
		{	send_to_char("You need a hearth or a furnace to heat things.\n\r",ch);
			return;
		}
	}
	else
	{	if( ( hObj = get_obj_here(ch, NULL, arg2) ) == NULL )
		{	send_to_char("That hearth isn't here.\n\r",ch);
			return;
		}
	}
	if( ( pObj = get_eq_char(ch, WEAR_HOLD) ) == NULL )
	{	send_to_char("You arn't holding anything!\n\r",ch);
		return;
	}
	if( ( mat = get_obj_carry(ch, arg, ch) ) == NULL )
	{	send_to_char("You don't have that to put over in the hearth!\n\r",ch);
		return;
	}
	
	if(!get_specific_use(pObj->pIndexData, UTYPE_TONG) )
	{	send_to_char("You can't hold things while they're in the fire! Get some tongs.\n\r",ch);
		return;
	}
	
	act("You grab $p with your tongs and hold it over $P's flames.", ch, mat, hObj, TO_CHAR 
);
	pObj->holding = mat;
	event_to_obj(mat, ch, END_CHAR, hObj, 0, EVENT_HEAT_OBJ, 3);
	event_to_char(ch,END_CHAR, NULL, 0, EVENT_BUSY, 100 );
	return;
}

/* EVENT_BUSY was just a way to state that a player was, well, busy :).
 * The busy table was exactly like the one for charge, except it had retract
 * which allowed you to pull the object from the furnace so it doesn't disapear. */