You could use events, either room or char events possibly... You will still have to check when fly unaffects to call the event, etc...
Which brings up the question, how do you kill someone within their own event if that event is cleared on death, BUT I don't want to extract the char?
Anyhow here is something I cooked up for falling because of lack of flying.
Code:
/* this function will check whether a char should fall or not based on
circumstances and whether the ch is flying */
bool char_should_fall(struct char_data *ch) {
int falling = FALSE;
if (!ch)
return FALSE;
if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_FLY_NEEDED) && EXIT(ch, DOWN))
falling = TRUE;
if (RIDING(ch) && AFF_FLAGGED(RIDING(ch), AFF_FLYING)) {
send_to_char(ch, "Your mount flies gracefully through the air...\r\n");
return FALSE;
}
if (AFF_FLAGGED(ch, AFF_FLYING)) {
send_to_char(ch, "You fly gracefully through the air...\r\n");
return FALSE;
}
return falling;
}
EVENTFUNC(event_falling)
{
struct mud_event_data *pMudEvent = NULL;
struct char_data *ch = NULL;
int height_fallen = 0;
char buf[50] = { '\0' };
/* This is just a dummy check, but we'll do it anyway */
if (event_obj == NULL)
return 0;
/* For the sake of simplicity, we will place the event data in easily
* referenced pointers */
pMudEvent = (struct mud_event_data *) event_obj;
/* nab char data */
ch = (struct char_data *) pMudEvent->pStruct;
/* dummy checks */
if (!ch) return 0;
if (!IS_NPC(ch) && !IS_PLAYING(ch->desc)) return 0;
/* retrieve svariables and convert it */
height_fallen += atoi((char *) pMudEvent->sVariables);
send_to_char(ch, "AIYEE!!! You have fallen %d feet!\r\n", height_fallen);
/* already checked if there is a down exit, lets move the char down */
do_simple_move(ch, DOWN, FALSE);
send_to_char(ch, "You fall into a new area!\r\n");
act("$n appears from above, arms flailing helplessly as $e falls...",
FALSE, ch, 0, 0, TO_ROOM);
height_fallen += 20; // 20 feet per room right now
/* can we continue this fall? */
if (!ROOM_FLAGGED(ch->in_room, ROOM_FLY_NEEDED) || !CAN_GO(ch, DOWN)) {
int dam = dice((height_fallen/5), 6) + 20;
send_to_char(ch, "You fall headfirst to the ground! OUCH!\r\n");
act("$n crashes into the ground headfirst, OUCH!", FALSE, ch, 0, 0, TO_ROOM);
GET_POS(ch) = POS_RECLINING;
SET_WAIT(ch, 4 * PULSE_VIOLENCE);
/* we have a special situation if you die, the event will get cleared */
if (dam >= GET_HIT(ch) + 9) {
GET_HIT(ch) = -999;
send_to_char(ch, "You attempt to scream in horror as your skull slams "
"into the ground, the very brief sensation of absolute pain "
"strikes you as all your upper-body bones shatter and your "
"head splatters all over the area!\r\n");
act("$n attempts to scream in horror as $s skull slams "
"into the ground. There is the sound like the cracking of a "
"ripe melon. You watch as all of $s upper-body bones shatter and $s "
"head splatters all over the area!\r\n",
FALSE, ch, 0, 0, TO_ROOM);
return 0;
} else {
damage(ch, ch, dam, TYPE_UNDEFINED, DAM_FORCE, FALSE);
return 0; //end event
}
}
/* hitting ground or fixing your falling situation is the only way to stop
* this event :P
* theoritically the player now could try to cast a spell, use an item, hop
* on a mount to fix his falling situation, so we gotta check if he's still
* falling every event call
* */
if (char_should_fall(ch)) {
send_to_char(ch, "You fall tumbling down!\r\n");
act("$n drops from sight.", FALSE, ch, 0, 0, TO_ROOM);
/* are we falling more? then we gotta increase the heigh fallen */
sprintf(buf, "%d", height_fallen);
pMudEvent->sVariables = strdup(buf);
return (1 * PASSES_PER_SEC);
} else { // stop falling!
send_to_char(ch, "You put a stop to your fall!\r\n");
act("$n turns on the air-brakes from a plummet!", FALSE, ch, 0, 0, TO_ROOM);
return 0;
}
return 0;