[LONG] Help...

From: melen (melen@mindcryme.com)
Date: 02/18/97


I've coded in room flags for underwater, lava, etc... and would like the
player to take damage every tick if certain things aren't satisfied. For
instance, for underwater I've created a WATERBREATH flag for obj's. Works
fine. But for some reason my 'hurt' code crashes. Nothing of use in GDB.
Here's my point_update:

/* Update PCs, NPCs, and objects */
void point_update(void)
{
  void update_char_objects(struct char_data * ch);	/* handler.c */
  void extract_obj(struct obj_data * obj);	/* handler.c */
  struct char_data *i, *next_char;
  struct obj_data *j, *next_thing, *jj, *next_thing2;

  /* characters */
  for (i = character_list; i; i = next_char) {
    next_char = i->next;
    if (GET_POS(i) >= POS_STUNNED) {
      GET_HIT(i) = MIN(GET_HIT(i) + hit_gain(i), GET_MAX_HIT(i));
      GET_MANA(i) = MIN(GET_MANA(i) + mana_gain(i), GET_MAX_MANA(i));
      GET_MOVE(i) = MIN(GET_MOVE(i) + move_gain(i), GET_MAX_MOVE(i));
      if (IS_AFFECTED(i, AFF_POISON))
	damage(i, i, 2, SPELL_POISON);
      if (GET_POS(i) <= POS_STUNNED)
	update_pos(i);
    } else if (GET_POS(i) == POS_INCAP)
      damage(i, i, 1, TYPE_SUFFERING);
    else if (GET_POS(i) == POS_MORTALLYW)
      damage(i, i, 2, TYPE_SUFFERING);
    if (!IS_NPC(i)) {
      update_char_objects(i);
      if (GET_LEVEL(i) < LVL_GOD)
	check_idling(i);
    }
    if (IS_AFFECTED(i, AFF_BURNING) &&
      SECT(i->in_room) == SECT_UNDERWATER) {
      REMOVE_BIT(AFF_FLAGS(i), AFF_BURNING);
    }
     if (IS_AFFECTED(i, AFF_ACIDED) &&
      SECT(i->in_room) == SECT_UNDERWATER) {
      REMOVE_BIT(AFF_FLAGS(i), AFF_ACIDED);
    }
     if (IS_AFFECTED(i, AFF_FREEZING) &&
      SECT(i->in_room) == SECT_LAVA) {
      REMOVE_BIT(AFF_FLAGS(i), AFF_FREEZING);
    }
    if (IS_AFFECTED(i, AFF_BURNING) && !(IS_AFFECTED(i, AFF_PROT_FIRE)) && GET_LEVEL(i) < LVL_GOD && !IS_NPC(i)) {
       send_to_char("You're burning!!\r\n", i);
       GET_HIT(i) -= number(5, 15);
        if (GET_HIT(i) < 4) {
         send_to_char("\\c01The heat completely overcomes you.\\c00\r\n", i);
         send_to_char("\\c08You are dead!\\c00\r\n", i);
         GET_POS(i) = POS_MORTALLYW;
         damage(i, i, 2, TYPE_SUFFERING);
       }
      }
     if (IS_AFFECTED(i, AFF_FREEZING) && !(IS_AFFECTED(i, AFF_PROT_COLD)) && GET_LEVEL(i) < LVL_GOD && !IS_NPC(i)) {
       send_to_char("You're freezing!!\r\n", i);
       GET_HIT(i) -= number(3, 10);
        if (GET_HIT(i) < 4) {
         send_to_char("\\c11The cold gets to you and your heart freezes!\\c00\r\n", i);
         send_to_char("\\c08You are dead!\\c00\r\n", i);
         GET_POS(i) = POS_MORTALLYW;
         damage(i, i, 2, TYPE_SUFFERING);
       }
     }
     if (AFF_FLAGGED(i, AFF_ACIDED) && GET_LEVEL(i) < LVL_GOD && !IS_NPC(i)) {
       send_to_char("You're dissolving!!\r\n", i);
       GET_HIT(i) -= LAVA_DAMAGE;
        if (GET_HIT(i) < 4) {
         send_to_char("\\c11The acid eats through your bones!\\c00\r\n", i);
         send_to_char("\\c08You are dead!\\c00\r\n", i);
         GET_POS(i) = POS_MORTALLYW;
         damage(i, i, 2, TYPE_SUFFERING);
       }
     }
    if ((SECT(i->in_room) == SECT_UNDERWATER) && !can_underwater(i) && GET_LEVEL(i) < LVL_GOD && !IS_NPC(i)) {
     ^^^^^^^^^^^^^^^^^^^^ *This is the line it crashes on!*
       send_to_char("You're drowning!!\r\n", i);
       GET_HIT(i) -= number(50, 60);
        if (GET_HIT(i) < 4) {
         send_to_char("\\c04You are no longer able to hold your breath!\\c00\r\n", i);
         send_to_char("\\c08You are dead!\\c00\r\n", i);
         GET_POS(i) = POS_MORTALLYW;
         damage(i, i, 2, TYPE_SUFFERING);
       }
    }
    if ((SECT(i->in_room) == SECT_QUICKSAND) && !can_fly(i) && GET_LEVEL(i) < LVL_GOD && !IS_NPC(i)) {
       send_to_char("\\c03You're sinking in quicksand!!\\c00\r\n", i);
       GET_HIT(i) -= number(14, 34);
        if (GET_HIT(i) < 4) {
         send_to_char("\\c03You sink into the quicksand until you can no longer breath.\\c00\r\n", i);
         send_to_char("\\c08You are dead!\\c00\r\n", i);
         GET_POS(i) = POS_MORTALLYW;
         damage(i, i, 2, TYPE_SUFFERING);
       }
    }
   gain_condition(i, FULL, -1);
    gain_condition(i, DRUNK, -1);
    gain_condition(i, THIRST, -1);
  }

  /* objects */
  for (j = object_list; j; j = next_thing) {
    next_thing = j->next;	/* Next in object list */

    /* If this is a corpse */
    if ((GET_OBJ_TYPE(j) == ITEM_CONTAINER) && GET_OBJ_VAL(j, 3)) {
      /* timer count down */
      if (GET_OBJ_TIMER(j) > 0)
	GET_OBJ_TIMER(j)--;

      if (!GET_OBJ_TIMER(j)) {

	if (j->carried_by)
	  act("$p decays in your hands.", FALSE, j->carried_by, j, 0, TO_CHAR);
	else if ((j->in_room != NOWHERE) && (world[j->in_room].people)) {
	  act("A quivering horde of maggots consumes $p.",
	      TRUE, world[j->in_room].people, j, 0, TO_ROOM);
	  act("A quivering horde of maggots consumes $p.",
	      TRUE, world[j->in_room].people, j, 0, TO_CHAR);
	}
	for (jj = j->contains; jj; jj = next_thing2) {
	  next_thing2 = jj->next_content;	/* Next in inventory */
	  obj_from_obj(jj);

	  if (j->in_obj)
	    obj_to_obj(jj, j->in_obj);
	  else if (j->carried_by)
	    obj_to_room(jj, j->carried_by->in_room);
	  else if (j->in_room != NOWHERE)
	    obj_to_room(jj, j->in_room);
	  else
	    assert(FALSE);
	}
	extract_obj(j);
      }
    }
    if (GET_OBJ_VNUM(j) == 1019)
    {
      if (GET_OBJ_VAL(j,0) > 0)
        GET_OBJ_VAL(j,0)--;
      if (GET_OBJ_VAL(j,0) == 1)
      {
        if ((j->in_room != NOWHERE) &&(world[j->in_room].people)) {
	  act("$p starts to fade!", 
  	    FALSE, world[j->in_room].people, j, 0, TO_ROOM);
	  act("$p starts to fade!", 
	    FALSE, world[j->in_room].people, j, 0, TO_CHAR);
        }
      }
      if (GET_OBJ_VAL(j,0) == 0)
      {
        if ((j->in_room != NOWHERE) &&(world[j->in_room].people)) {
    	  act("$p vanishes in a cloud of smoke!", 
	    FALSE, world[j->in_room].people, j, 0, TO_ROOM);
	  act("$p vanishes in a cloud of smoke!", 
	    FALSE, world[j->in_room].people, j, 0, TO_CHAR);
        }
        extract_obj(j);
      }
    }
  }
}

And here is my can_underwater:

int can_underwater(struct char_data *ch)
{
  struct obj_data *obj;
  int i;

  /* non-wearable underwater object in inventory will do it */
  for (obj = ch->carrying; obj; obj = obj->next_content)
    if (GET_OBJ_TYPE(obj) == ITEM_WATERBREATH && (find_eq_pos(ch, obj,
NULL) < 0))
      return 1;
  /* and any flight object you're wearing will do it too */
  for (i = 0; i < NUM_WEARS; i++)
    if (GET_EQ(ch, i) && GET_OBJ_TYPE(GET_EQ(ch, i)) == ITEM_WATERBREATH)
      return 1;

  return 0;
}

I'm lost... I've worked on this for a month and it still causes
unexplained crashes. It'll work for a half hour or so, then crash and
reference that one line.

Thanks...

Melen
Allanthya MUD: mindcryme.com port 4000


+-----------------------------------------------------------+
| Ensure that you have read the CircleMUD Mailing List FAQ: |
|   http://cspo.queensu.ca/~fletcher/Circle/list_faq.html   |
|    Or send 'info circle' to majordomo@cspo.queensu.ca     |
+-----------------------------------------------------------+



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