CODE and re: Falling Air Rooms (another problem)

From: Brian Menges (menges@niesten.arc.nasa.gov)
Date: 07/18/96


  I used the suggestion of putting  the check in char_to_room and I have it
working fine now.  If a character goes into any air room for any reason and
doesn't have the fly ability they will plummet earthward.  I'm including the
code I have for anyone interested.  The only problem is that the act() function
uses the location of the primary character.  So, when a god trans a char to an
air room it will force the char to fall down when when the char_to_room routine
is called but will print the "<so-and-so> arrives in a puff of smoke."  at the
room where the character ended up.  Did that make any sense?  I'm not sure how
to get around this problem.  Any ideas?

Anyways, here is the code for those interested.

__

in handler.c

*
* Modify char_to_room to add a check for flying ability, etc:
*

/* place a character in a room */
void char_to_room(struct char_data * ch, int room)
{
  void fall_char(struct char_data *ch);

  if (!ch || room < 0 || room > top_of_world)
    log("SYSERR: Illegal value(s) passed to char_to_room");
  else
  {
    ch->next_in_room = world[room].people;
    world[room].people = ch;
    ch->in_room = room;

    if (GET_EQ(ch, WEAR_LIGHT))
      if (GET_OBJ_TYPE(GET_EQ(ch, WEAR_LIGHT)) == ITEM_LIGHT)
	if (GET_OBJ_VAL(GET_EQ(ch, WEAR_LIGHT), 2))	/* Light ON */
	  world[room].light++;
  }

+  if( (SECT(ch->in_room) == SECT_FLYING) &&
+    (!(IS_AFFECTED(ch, AFF_FLY))) && GET_LEVEL(ch) < LVL_DEMI )
+  {
+     /*
+      * Look at room character just eneter because (s)he is
+      * about to leave it :)
+      */
+     if (ch->desc != NULL)
+        look_at_room(ch, 0);
+     fall_char(ch);
+  }

}

*
* Here is the fall_char function
*

void fall_char(struct char_data *ch)
{
   int in_room, was_in, new_room;
   int falling = 0, distance = 0, damage = 0;
   int i;
  char buf2[256];

   while(EXIT(ch, DOWN) && SECT(ch->in_room) == SECT_FLYING)
   {
      if(falling)
         send_to_char("and fall...\r\n\r\n", ch);
      else
         send_to_char("You fall...\r\n\r\n", ch);

      sprintf(buf2, "$n plummets %s.", dirs[DOWN]);
      act(buf2, TRUE, ch, 0, 0, TO_ROOM);

      was_in = ch->in_room;
      new_room = world[was_in].dir_option[DOWN]->to_room;
      char_from_room(ch);

      /*
       *  Since this function can be called from within char_to_room
       *  I cut and paste the char_to_room routine here.
       */
      ch->next_in_room = world[new_room].people;
      world[new_room].people = ch;
      ch->in_room = new_room;

        if (GET_EQ(ch, WEAR_LIGHT))
          if (GET_OBJ_TYPE(GET_EQ(ch, WEAR_LIGHT)) == ITEM_LIGHT)
	    if (GET_OBJ_VAL(GET_EQ(ch, WEAR_LIGHT), 2))	/* Light ON */
	      world[new_room].light++;

      sprintf(buf2, "$n falls from %s.", arrive[DOWN]);
      act(buf2, TRUE, ch, 0, 0, TO_ROOM);

      if(!falling) falling = 1;
      distance++;
   }

   send_to_char("!!OUCH!! You slam into the ground!\r\n\r\n", ch);
   sprintf(buf2, "$n slams into the ground! OUCH! That had to hurt!");
   act(buf2, TRUE, ch, 0, 0, TO_ROOM);

   for(i = 0;i < distance;i++)
     damage += (dice(1, 10));

   GET_HIT(ch) -= damage;
   update_pos(ch);

   if(GET_POS(ch) > POS_STUNNED)
   {
      /*
       *  If not stunned look at new room.
       *
      if (ch->desc != NULL)
         look_at_room(ch, 0);*/
      GET_POS(ch) = POS_SITTING;
   }

  /* Use send_to_char -- act() doesn't send message if you are DEAD. */
  switch (GET_POS(ch))
  {
  case POS_MORTALLYW:
    act("$n is mortally wounded, and will die soon, if not aided.", TRUE, ch,
0, 0, TO_ROOM);
    send_to_char("You are mortally wounded, and will die soon, if not
aided.\r\n", ch);
    break;
  case POS_INCAP:
    act("$n is incapacitated and will slowly die, if not aided.", TRUE, ch, 0,
0, TO_ROOM);
    send_to_char("You are incapacitated an will slowly die, if not aided.\r\n",
ch);
    break;
  case POS_STUNNED:
    act("$n is stunned, but will probably regain consciousness again.", TRUE,
ch, 0, 0, TO_ROOM);
    send_to_char("You're stunned, but will probably regain consciousness
again.\r\n", ch);
    break;
  case POS_DEAD:
    act("$n is dead!  R.I.P.", FALSE, ch, 0, 0, TO_ROOM);
    send_to_char("You are dead!  Sorry...\r\n", ch);
  break;

  default:			/* >= POSITION SLEEPING */
    if (damage > (GET_MAX_HIT(ch) >> 2))
      act("That really did HURT!", FALSE, ch, 0, 0, TO_CHAR);

    if(GET_HIT(ch) < (GET_MAX_HIT(ch) >> 2))
      send_to_char("You wish that your wounds would stop BLEEDING so
much!\r\n", ch);
    break;
  }

  if (GET_POS(ch) == POS_DEAD)
  {
    if (!IS_NPC(ch))
    {
      sprintf(buf2, "%s died at %s in a fall from %d stories high!",
GET_NAME(ch),
              world[ch->in_room].name, distance);
      mudlog(buf2, BRF, LVL_DEMI, TRUE);
    }
    die(ch, NULL);
  }
}





I also put a check where affects where off and made a call to fall_char if the
character was in an air room and the affect wearing off was AFF_FLY.   If you
plan to use this code you will have to change a few things.  The thinks I know
about:

  LVL_DEMI is my LVL_IMMORT
  Add an AFF_FLY into structs.h  (And everything that goes along with that :)

Actually I think that might be it. I removed most of the other junk that I
added because my code is slightly modified from stock circle.  Yeah, and whose
isn't? :)

-brian aka Haddixx

__

-- 
"Take my advice and go back to the time	| Brian Menges
you came from.  The future isn't what 	| NASA Ames Research Center
it used to be."--G'kar, "The Long Dark" | Mail Stop: N262-2
	          0__0			| Phone: (415) 604-0069
=============ooO==(__)==Ooo=============| menges@eos.arc.nasa.gov



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