Пример #1
0
/* Common routine for the Castle Twins. */
int castle_twin_proc(struct char_data *ch, int cmd, char *arg, int ctlnum, const char *twinname)
{
  struct char_data *king, *twin;

  if (!AWAKE(ch))
    return (FALSE);

  if (cmd)
    return block_way(ch, cmd, arg, castle_virtual(ctlnum), 1);

  if ((king = find_npc_by_name(ch, "King Welmar", 11)) != NULL) {
    char actbuf[MAX_INPUT_LENGTH];

    if (!ch->master)
      do_follow(ch, strcpy(actbuf, "King Welmar"), 0, 0);	/* strcpy: OK */
    if (FIGHTING(king))
      do_npc_rescue(ch, king);
  }

  if ((twin = find_npc_by_name(ch, twinname, strlen(twinname))) != NULL)
    if (FIGHTING(twin) && 2 * GET_HIT(twin) < GET_HIT(ch))
      do_npc_rescue(ch, twin);

  if (GET_POS(ch) != POS_FIGHTING)
    banzaii(ch);

  return (FALSE);
}
Пример #2
0
void loss_breath(struct char_data * ch, int breath)
{

	if (AFF2_FLAGGED(ch, AFF2_IRON_BODY))
		return;

	if (ROOM_AFFECTED(ch->in_room, RAFF_LIQUID_AIR)) {
		GET_OXI(ch) -= number(2, 10);
	}

	if(GET_LEVEL(ch) < LVL_IMMORT && breath > 0)
	{
		if(GET_OXI(ch) >= 1)
		{
			GET_OXI(ch) -= breath;
			send_to_char("Your breath becomes deeper and slower...\r\n", ch);
		} else {
			if(GET_HIT(ch) > 0)
			{
            	GET_HIT(ch) -= (GET_MAX_HIT(ch)*0.15);
            	send_to_char("&RYou need some oxygen, your life is almost extinguished!&n\r\n", ch);
			} else {
	           	GET_HIT(ch) = 0;
	           	send_to_char("&RYour breath becomes so slow that you die because of it.&n\r\n", ch);
            	raw_kill(ch, NULL);
			}
		}
	}
}
Пример #3
0
void mag_points(int level, struct char_data *ch, struct char_data *victim,
		     int spellnum, int savetype)
{
  int healing = 0, move = 0;

  if (victim == NULL)
    return;

  switch (spellnum) {
  case SPELL_CURE_LIGHT:
    healing = dice(1, 8) + 1 + (level / 4);
    send_to_char(victim, "You feel better.\r\n");
    break;
  case SPELL_CURE_CRITIC:
    healing = dice(3, 8) + 3 + (level / 4);
    send_to_char(victim, "You feel a lot better!\r\n");
    break;
  case SPELL_HEAL:
    healing = 100 + dice(3, 8);
    send_to_char(victim, "A warm feeling floods your body.\r\n");
    break;
  }
  GET_HIT(victim) = MIN(GET_MAX_HIT(victim), GET_HIT(victim) + healing);
  GET_MOVE(victim) = MIN(GET_MAX_MOVE(victim), GET_MOVE(victim) + move);
  update_pos(victim);
}
Пример #4
0
 /* Hey! Don't go calling this w/o making checks! */
static void
npc_regen(struct char_data * ch) {
  int regen_rate = 2;
  GET_HIT(ch) += GET_LEVEL(ch) * regen_rate;
  if(GET_HIT(ch) > GET_MAX_HIT(ch))
     GET_HIT(ch) = GET_MAX_HIT(ch);
}
Пример #5
0
/*
 * subtracts amount of hitpoints from ch's current and starts points event
 */
void alter_hit(struct char_data *ch, int amount)
{
  struct regen_event_obj *regen;
  long time;
  int gain;

  GET_HIT(ch) = MIN(GET_HIT(ch) - amount, GET_MAX_HIT(ch));

  if (GET_HIT(ch) <= HIT_INCAP||IS_AFFECTED(ch,AFF_TRAMORTITO))
    return;
  if (PLR_FLAGGED(ch, PLR_FANTASMA) && amount > 0)
    return;

  if (GET_HIT(ch) < GET_MAX_HIT(ch) && !GET_POINTS_EVENT(ch, REGEN_HIT)) {
    CREATE(regen, struct regen_event_obj, 1);	
    regen->ch = ch;
    regen->type = REGEN_HIT;
    gain = hit_gain(ch);
    time = PULSES_PER_MUD_HOUR / (gain ? gain : 1);
    GET_POINTS_EVENT(ch, REGEN_HIT) = event_create(points_event, regen, time);

    if (amount >= 0) {
	
      /*
       * if the character gained hp, update position and
       * restart mana and move regeneration if needed.
       */
      update_pos(ch);
      alter_mana(ch, 0);
      alter_move(ch, 0);
    }
  }
Пример #6
0
int
calculate_mob_aggression(struct creature *ch, struct creature *vict)
{
    // aggression is the average of the percent health of self and the
    // percent damage of the other
    return (GET_HIT(ch) * 100 / GET_MAX_HIT(ch)
        + (100 - GET_HIT(vict) * 100 / GET_MAX_HIT(vict))) / 2;
}
Пример #7
0
/*
** doInvigorate
*/
void
doInvigorate(CharData* ch)
{
   int gain = 0;

   gain += number(1, GET_LEVEL(ch)/3);
   gain += number(1, (GET_MAX_HIT(ch) - GET_LEVEL(ch)*12)/15);

   if (GET_HIT(ch) < GET_MAX_HIT(ch)) 
       GET_HIT(ch) = MIN( GET_MAX_HIT(ch), GET_HIT(ch) + gain );
}
Пример #8
0
void update_pos( struct char_data *victim )
{

	if ((GET_HIT(victim) > 0) && (GET_POS(victim) > POSITION_STUNNED)) return;
	else if (GET_HIT(victim) > 0 ) GET_POS(victim) = POSITION_STANDING;
	else if (GET_HIT(victim) <= -11) GET_POS(victim) = POSITION_DEAD;
	else if (GET_HIT(victim) <= -6) GET_POS(victim) = POSITION_MORTALLYW;
	else if (GET_HIT(victim) <= -3) GET_POS(victim) = POSITION_INCAP;
	else GET_POS(victim) = POSITION_STUNNED;

}
Пример #9
0
int Moribondo( struct char_data *pChar, int nCmd, const char *szArg,
               struct char_data *pMob, int nType )
{
  if( pMob == NULL || pChar == NULL )
  {
    mudlog( LOG_SYSERR, 
            "pMob == NULL || pChar == NULL in Moribondo( carceri.h )" );
    return FALSE;
  }

  if( nType == EVENT_TICK )
  {
    switch( pMob->generic )
    {
    case 0:
      GET_HIT( pMob ) = -3;
      GET_POS( pMob ) = POSITION_INCAP;
      pMob->generic = 1;
      break;
    case 1:
      if( GET_HIT( pMob ) > 0 && !pMob->specials.fighting )
      {
        do_say( pMob, "Grazie! Grazie! Chiunque sia stato.", 0 );
        if( pMob->player.description )
          free( pMob->player.description );
        pMob->player.description = strdup( "Il piccolo nano e` contento e "
                                           "grato a chi lo ha aiutato.\n\r" );
        pMob->generic = 2;
      }
      else if( !pMob->specials.fighting )
      {
        MakeNoise( pMob->in_room, NULL, "Senti qualcuno lamentarsi.\n\r" );
      }
      break;
    case 2:
      if( !pMob->specials.fighting )
      {
        do_say( pMob, 
                "Guardate vicino al letto. C'e` un passaggio segreto!", 0 );
        pMob->generic = 3;
      }
      break;
    default:
      if( !number( 0, 5 ) && !pMob->specials.fighting )
      {
        do_say( pMob, 
                "Guardate vicino al letto. C'e` un passaggio segreto!", 0 );
      }
      break;
    }
  }
  return FALSE;
}
Пример #10
0
//NPC damage. Used mainly for special MOBs who we don't want to run through the main damage function//
void dmg(Character *ch, Character *vict, int low, int high, int same_room)
{
	int dam;
	dam = MiscUtil::random(low, high);

	if(ch->in_room != vict->in_room && same_room)
		return;

	GET_HIT(vict) -= dam;

	if(GET_HIT(vict) <= 0)
		vict->Die(ch);

}
Пример #11
0
void check_berserk(CHAR_DATA * ch)
{
	AFFECT_DATA af;
	struct timed_type timed;
	int prob;

	if (affected_by_spell(ch, SPELL_BERSERK) &&
			(GET_HIT(ch) > GET_REAL_MAX_HIT(ch) / 2))
	{
		affect_from_char(ch, SPELL_BERSERK);
		send_to_char("Предсмертное исступление оставило Вас.\r\n", ch);
	}
//!IS_NPC(ch) &&
	if (can_use_feat(ch, BERSERK_FEAT) && ch->get_fighting() &&
			!timed_by_feat(ch, BERSERK_FEAT) && !AFF_FLAGGED(ch, AFF_BERSERK) &&
			(GET_HIT(ch) < GET_REAL_MAX_HIT(ch) / 4))
	{

//		if (!IS_NPC(ch)) {
//Gorrah: вроде бы у мобов скиллы тикают так же, так что глюков быть не должно
		timed.skill = BERSERK_FEAT;
		timed.time = 4;
		timed_feat_to_char(ch, &timed);
//		}

		af.type = SPELL_BERSERK;
		af.duration = pc_duration(ch, 1, 60, 30, 0, 0);
		af.modifier = 0;
		af.location = APPLY_NONE;
		af.battleflag = 0;

		prob = IS_NPC(ch) ? 601 : (751 - GET_LEVEL(ch) * 5);
		if (number(1, 1000) <  prob)
		{
			af.bitvector = AFF_BERSERK;
			act("Вас обуяла предсмертная ярость!", FALSE, ch, 0, 0, TO_CHAR);
			act("$n0 исступленно взвыл$g и бросил$u на противника!", FALSE, ch, 0, 0, TO_ROOM);
		}
		else
		{
			af.bitvector = 0;
			act("Вы истошно завопили, пытаясь напугать противника. Без толку.", FALSE, ch, 0, 0, TO_CHAR);
			act("$n0 истошно завопил$g, пытаясь напугать противника. Забавно...", FALSE, ch, 0, 0, TO_ROOM);
		}
		affect_join(ch, &af, TRUE, FALSE, TRUE, FALSE);
	}
}
Пример #12
0
static void event_fill_zone_with_mobs(int rnum, struct room_data *rp,
				      struct event_mob_in_zone *mobs)
{
    int                                     i = 0;
    int                                     j = 0;
    int                                     couldbe = 0;
    int                                     exit_found = FALSE;
    struct char_data                       *monster = NULL;
    struct obj_data                        *object = NULL;

    if (DEBUG > 1)
	log_info("called %s with %d, %08zx, %08zx", __PRETTY_FUNCTION__, rnum, (size_t) rp,
		 (size_t) mobs);

    if (!rp || rp->number < mobs->bottom || rp->number > mobs->top)
	return;
    if (IS_SET(rp->room_flags, (NO_MOB | PEACEFUL | PRIVATE)))
	return;
    exit_found = 0;
    for (i = 0; i < MAX_NUM_EXITS; i++)			       /* neswud */
	if (rp->dir_option[i]) {
	    exit_found = 1;
	    break;
	}
    if (!exit_found)
	return;
    couldbe = number(mobs->atleast, mobs->atmost);
    for (j = 0; j < couldbe; j++) {
	if (number(0, 99) >= mobs->chance)
	    continue;
	i = number(1, mobs->count) - 1;
	if (!(monster = read_mobile(mobs->mobset[i].vnum, VIRTUAL)))
	    continue;
	monster->points.max_hit = dice(mobs->mobset[i].hp_dice,
				       mobs->mobset[i].hp_die) + mobs->mobset[i].hp_mod;
	GET_HIT(monster) = GET_MAX_HIT(monster);
	GET_EXP(monster) = (dice(mobs->mobset[i].exp_dice, mobs->mobset[i].exp_die)
			    + mobs->mobset[i].exp_mod) * GET_MAX_HIT(monster);
	GET_GOLD(monster) = number(mobs->mobset[i].gold_dice, mobs->mobset[i].gold_die)
	    + mobs->mobset[i].gold_mod;
	if (mobs->mobset[i].obj_vnum >= 0) {
	    if (number(0, 99) < mobs->mobset[i].obj_chance) {
		if ((object = read_object(mobs->mobset[i].obj_vnum, VIRTUAL)))
		    obj_to_char(object, monster);
	    }
	}
	char_to_room(monster, rnum);
	mob_count++;
	act("In a shimmering column of blue light, $N appears!", FALSE,
	    monster, 0, monster, TO_ROOM);
    }
}
Пример #13
0
/* nb, also mess up anyone affected by AFF_POISON */
void pulse_heal(void)
{
    CharData *ch;
    int gain = number(18,24);

    for (ch = character_list; ch; ch = ch->next) {
        if(ch->in_room == NOWHERE)
            continue;

        if(!(pvpFactor() > 1)) {
            if( GET_POS(ch) == POS_INCAP )      damage(ch, ch, 1, TYPE_SUFFERING);
            else if( GET_POS(ch) == POS_MORTALLYW )  damage(ch, ch, 2, TYPE_SUFFERING);
            else if( GET_POS(ch) == POS_DEAD) {
                if(IN_ARENA(ch) || IN_QUEST_FIELD(ch) ||
                   ZONE_FLAGGED(world[ch->in_room].zone, ZONE_ARENA) ||
                   ZONE_FLAGGED(world[ch->in_room].zone, ZONE_SLEEPTAG))
                    // If they're dying in the arena, they eventually get better (or killed by someone)
                {
                    GET_HIT(ch) = number(GET_HIT(ch), 1);
                    sendChar(ch, "You slowly recover.\r\n");
                    update_pos(ch);
                }
                else {
                    raw_kill(ch, NULL);
                    continue;
                }
            }
        }

        if (IS_AFFECTED(ch, AFF_PULSE_HIT))
            if (GET_HIT(ch) < GET_MAX_HIT(ch)) GET_HIT(ch) += gain;
        if (IS_AFFECTED(ch, AFF_PULSE_MANA))
            if (GET_MANA(ch) < GET_MAX_MANA(ch)) GET_MANA(ch) += gain;
        if (IS_AFFECTED(ch, AFF_POISON)) doPoison(ch);
        if (IS_AFFECTED(ch, AFF_DISEASE)) doDisease(ch);
	if (affected_by_spell(ch, SKILL_INVIGORATE)) doInvigorate(ch);
        if (IS_BOUNTY_HUNTER(ch) && GET_ADVANCE_LEVEL(ch) >= 1 && IS_AFFECTED(ch, AFF_HIDE)) GET_MOVE(ch) = MIN(GET_MOVE(ch) + 3*gain, GET_MAX_MOVE(ch));
        if (IS_PRESTIDIGITATOR(ch)) GET_MANA(ch) = MIN(GET_MANA(ch) + GET_ADVANCE_LEVEL(ch) * 2, GET_MAX_MANA(ch));
        if (affected_by_spell(ch, SPELL_HIPPOCRATIC_OATH)) GET_MANA(ch) = MIN(GET_MANA(ch) + 25, GET_MAX_MANA(ch));
        if (affected_by_spell(ch, SKILL_PET_MEND)) GET_HIT(ch) = MIN(GET_HIT(ch) * 115 / 100, GET_MAX_HIT(ch));
        if (IS_HOLY_PRIEST(ch)) GET_MANA(ch) = MIN(GET_MANA(ch) + 10 + 2*GET_ADVANCE_LEVEL(ch), GET_MAX_MANA(ch));

        /* The room might be poisoned! (Or later, otherwise dangerous) */
        if (ch->in_room != NOWHERE) {
            if (ROOM_FLAGGED(ch->in_room, ROOM_POISONED)) {
                if (!mag_savingthrow(ch, SAVING_SPELL)) {
                    act("$n chokes and gags!", TRUE, ch, 0, 0, TO_ROOM);
                    act("You choke and gag!", TRUE, ch, 0, 0, TO_CHAR);
                    add_affect( ch, ch, SPELL_POISON, 30, APPLY_NONE, 0, 5 TICKS,
                            AFF_POISON, FALSE, FALSE, FALSE, FALSE);
                }
            }
        }

        if(IS_DEFENDER(ch) && !affected_by_spell(ch, SKILL_DEFENDER_HEALTH))
            add_affect(ch, ch, SKILL_DEFENDER_HEALTH, GET_LEVEL(ch), APPLY_HIT, GET_ADVANCE_LEVEL(ch)*5, -1, FALSE, FALSE, FALSE, FALSE, FALSE);

    }
}
Пример #14
0
/* Some initializations for characters, including initial skills */
void do_start(struct char_data *ch)
{
  GET_LEVEL(ch) = 1;
  GET_TOT_LEVEL(ch) = 1;
  GET_EXP(ch) = 1;
  GET_CLASS_1(ch) = GET_CLASS(ch);
  GET_MULTIS(ch) = 1;

  set_title(ch, NULL);
  roll_real_abils(ch);

  GET_MAX_HIT(ch)  = 10;
  GET_MAX_MANA(ch) = 100;
  GET_MAX_MOVE(ch) = 100;

  switch (GET_CLASS(ch)) {

  case CLASS_ADEPT:
    break;

  case CLASS_MEDIC:
    break;

  case CLASS_BANDIT:
    SET_SKILL(ch, SKILL_SNEAK, 10);
    SET_SKILL(ch, SKILL_HIDE, 5);
    SET_SKILL(ch, SKILL_STEAL, 15);
    SET_SKILL(ch, SKILL_BACKSTAB, 10);
    SET_SKILL(ch, SKILL_PICK_LOCK, 10);
    SET_SKILL(ch, SKILL_TRACK, 10);
    break;

  case CLASS_SOLDIER:
    break;
  }

  advance_level(ch);

  GET_HIT(ch) = GET_MAX_HIT(ch);
  GET_MANA(ch) = GET_MAX_MANA(ch);
  GET_MOVE(ch) = GET_MAX_MOVE(ch);

  GET_COND(ch, THIRST) = 24;
  GET_COND(ch, HUNGER) = 24;
  GET_COND(ch, DRUNK) = 0;

  if (CONFIG_SITEOK_ALL)
    SET_BIT_AR(PLR_FLAGS(ch), PLR_SITEOK);
}
Пример #15
0
void js_hitpercent_triggers(Character * ch, Character * victim)
{
    if (!ch->js_scripts || ch->js_scripts->size() == 0 || !FIGHTING(ch))
        return;
    for (int i = 0; i < ch->js_scripts->size(); ++i)
    {
        if (ch->js_scripts->at(i)->isFlagged(JS::CHARACTER_HITPERCENT))
        {
            JSTrigger* trig = ch->js_scripts->at(i);
        
            if (is_allowed_violent(ch, victim, trig) && GET_MAX_HIT(ch) && (((GET_HIT(ch) * 100) / GET_MAX_HIT(ch)) <= trig->narg))
            {
                JSManager::get()->execute(trig, ch, victim);
            }
        }
    }
}
Пример #16
0
void TrapDamage(struct char_data *v, int damtype, int amnt, struct obj_data *t)
{
  struct char_data *tmp_ch;
  char buf[132];

  if(DEBUG) dlog("TrapDamage");
  amnt = SkipImmortals(v, amnt);
  if (amnt == -1) 
    return;

  if (IS_AFFECTED(v, AFF_SANCTUARY))
    amnt = MAX((int)(amnt/2), 0);  /* Max 1/2 damage when sanct'd */
        
   amnt = PreProcDam(v, damtype, amnt);

   if (saves_spell(v, SAVING_PETRI))
     amnt = MAX((int)(amnt/2),0);

   DamageStuff(v, damtype, amnt);
   amnt=MAX(amnt,0);
   GET_HIT(v)-=amnt;
   update_pos(v);
   TrapDam(v, damtype, amnt, t);
   InformMess(v);
   if (GET_POS(v) == POSITION_DEAD) 
   {
     if (!IS_NPC(v)) 
     {
       if (real_roomp(v->in_room)->name)
         sprintf(buf, "%s killed by a trap at %s",
	   GET_NAME(v),real_roomp(v->in_room)->name);
       log(buf);
			/* remove the hatreds of this character */
     }

     for (tmp_ch=character_list; tmp_ch; tmp_ch=tmp_ch->next) 
     {
       if (Hates(tmp_ch, v)) 
       {
         RemHated(tmp_ch, v);
       }
     }
     die(v);
  }
} 
Пример #17
0
int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd)
{
  char ldesc[MAX_STRING_LENGTH], ddesc[MAX_STRING_LENGTH];

  ldesc[MAX_STRING_LENGTH - 1] = '\0';
  ddesc[MAX_STRING_LENGTH - 1] = '\0';
  strip_cr(strncpy(ldesc, GET_LDESC(mob), MAX_STRING_LENGTH - 1));
  strip_cr(strncpy(ddesc, GET_DDESC(mob), MAX_STRING_LENGTH - 1));

  fprintf(fd,	"#%d\n"
		"%s%c\n"
		"%s%c\n"
		"%s%c\n"
		"%s%c\n",
	mvnum,
	GET_ALIAS(mob), STRING_TERMINATOR,
	GET_SDESC(mob), STRING_TERMINATOR,
	ldesc, STRING_TERMINATOR,
	ddesc, STRING_TERMINATOR
  );
  fprintf(fd,	"%ld %ld %d E\n"
		"%d %d %d %dd%d+%d %dd%d+%d\n",
		MOB_FLAGS(mob), AFF_FLAGS(mob), GET_ALIGNMENT(mob),
		GET_LEVEL(mob), 20 - GET_HITROLL(mob), GET_AC(mob) / 10, GET_HIT(mob),
		GET_MANA(mob), GET_MOVE(mob), GET_NDD(mob), GET_SDD(mob),
		GET_DAMROLL(mob)
  );
  fprintf(fd, 	"%d %d\n"
		"%d %d %d\n",
		GET_GOLD(mob), GET_EXP(mob),
		GET_POS(mob), GET_DEFAULT_POS(mob), GET_SEX(mob)
  );

  if (write_mobile_espec(mvnum, mob, fd) < 0)
    log("SYSERR: GenOLC: Error writing E-specs for mobile #%d.", mvnum);

  script_save_to_disk(fd, mob, MOB_TRIGGER);

#if CONFIG_GENOLC_MOBPROG
  if (write_mobile_mobprog(mvnum, mob, fd) < 0)
    log("SYSERR: GenOLC: Error writing MobProgs for mobile #%d.", mvnum);
#endif

  return TRUE;
}
Пример #18
0
/*
 * Ideally, this function should be in db.c, but I'll put it here for
 * portability.
 */
void init_mobile(struct char_data *mob)
{
  clear_char(mob);

  GET_HIT(mob) = GET_MANA(mob) = 1;
  GET_MAX_MANA(mob) = GET_MAX_MOVE(mob) = 100;
  GET_NDD(mob) = GET_SDD(mob) = 1;
  GET_WEIGHT(mob) = 200;
  GET_HEIGHT(mob) = 198;
  GET_MOB_WEIGHT(mob) = 1;

  mob->real_abils.str = mob->real_abils.intel = mob->real_abils.wis = 11;
  mob->real_abils.dex = mob->real_abils.con = mob->real_abils.cha = 11;
  mob->aff_abils = mob->real_abils;

  SET_BIT(MOB_FLAGS(mob), MOB_ISNPC);
  mob->player_specials = &dummy_mob;
}
Пример #19
0
void hitprcnt_mtrigger(char_data *ch)
{
  trig_data *t;
  char buf[MAX_INPUT_LENGTH];
  
  if (!SCRIPT_CHECK(ch, MTRIG_HITPRCNT) || !FIGHTING(ch) ||
      AFF_FLAGGED(ch, AFF_CHARM))
    return;
  
  for (t = TRIGGERS(SCRIPT(ch)); t; t = t->next) {
    if (TRIGGER_CHECK(t, MTRIG_HITPRCNT) && GET_MAX_HIT(ch) &&
	(((GET_HIT(ch) * 100) / GET_MAX_HIT(ch)) <= GET_TRIG_NARG(t))) {

      ADD_UID_VAR(buf, t, FIGHTING(ch), "actor", 0)
      script_driver(ch, t, MOB_TRIGGER, TRIG_NEW);
      break;
    }
  }
}
Пример #20
0
void
psionic_activity(struct creature *ch)
{
    if (room_is_dark(ch->in_room)
        && !has_dark_sight(ch)
        && can_cast_spell(ch, SPELL_RETINA))
        cast_spell(ch, ch, NULL, NULL, SPELL_RETINA);
    else if (GET_HIT(ch) < GET_MAX_HIT(ch) * 0.80) {
        if (can_cast_spell(ch, SPELL_CELL_REGEN))
            cast_spell(ch, ch, NULL, NULL, SPELL_CELL_REGEN);
        else if (can_cast_spell(ch, SPELL_WOUND_CLOSURE))
            cast_spell(ch, ch, NULL, NULL, SPELL_WOUND_CLOSURE);
    } else if (!AFF_FLAGGED(ch, AFF_NOPAIN)
        && !AFF_FLAGGED(ch, AFF_SANCTUARY)
        && can_cast_spell(ch, SPELL_NOPAIN))
        cast_spell(ch, ch, NULL, NULL, SPELL_NOPAIN);
    else if (!room_has_air(ch->in_room) &&
        !can_travel_sector(ch, ch->in_room->sector_type, 0) &&
        can_cast_spell(ch, SPELL_BREATHING_STASIS) &&
        !AFF3_FLAGGED(ch, AFF3_NOBREATHE))
        cast_spell(ch, ch, NULL, NULL, SPELL_BREATHING_STASIS);
    else if (!AFF2_FLAGGED(ch, AFF2_TELEKINESIS)
        && can_cast_spell(ch, SPELL_TELEKINESIS))
        cast_spell(ch, ch, NULL, NULL, SPELL_TELEKINESIS);
    else if (!affected_by_spell(ch, SPELL_DERMAL_HARDENING)
        && can_cast_spell(ch, SPELL_DERMAL_HARDENING))
        cast_spell(ch, ch, NULL, NULL, SPELL_DERMAL_HARDENING);
    else if (!AFF3_FLAGGED(ch, AFF3_PSISHIELD)
        && can_cast_spell(ch, SPELL_PSISHIELD))
        cast_spell(ch, ch, NULL, NULL, SPELL_PSISHIELD);
    else if (can_cast_spell(ch, SPELL_PSYCHIC_RESISTANCE) &&
        !affected_by_spell(ch, SPELL_PSYCHIC_RESISTANCE))
        cast_spell(ch, ch, NULL, NULL, SPELL_PSYCHIC_RESISTANCE);
    else if (can_cast_spell(ch, SPELL_POWER)
        && !affected_by_spell(ch, SPELL_POWER))
        cast_spell(ch, ch, NULL, NULL, SPELL_POWER);
    else if (!AFF_FLAGGED(ch, AFF_CONFIDENCE)
        && can_cast_spell(ch, SPELL_CONFIDENCE))
        cast_spell(ch, ch, NULL, NULL, SPELL_CONFIDENCE);
}
Пример #21
0
/* Ideally, this function should be in db.c, but I'll put it here for portability. */
static void init_mobile(struct char_data *mob) {
    clear_char(mob);

    GET_HIT(mob) = GET_MANA(mob) = 1;
    GET_MAX_MANA(mob) = GET_MAX_MOVE(mob) = 100;
    GET_NDD(mob) = GET_SDD(mob) = 1;
    GET_WEIGHT(mob) = 200;
    GET_HEIGHT(mob) = 198;

    mob->real_abils.str = mob->real_abils.intel = mob->real_abils.wis = 11;
    mob->real_abils.dex = mob->real_abils.con = mob->real_abils.cha = 11;
    mob->aff_abils = mob->real_abils;

    GET_SAVE(mob, SAVING_PARA) = 0;
    GET_SAVE(mob, SAVING_ROD) = 0;
    GET_SAVE(mob, SAVING_PETRI) = 0;
    GET_SAVE(mob, SAVING_BREATH) = 0;
    GET_SAVE(mob, SAVING_SPELL) = 0;

    SET_BIT_AR(MOB_FLAGS(mob), MOB_ISNPC);
    mob->player_specials = &dummy_mob;
}
Пример #22
0
void medit_autoroll_stats(struct descriptor_data *d)
{
  int mob_lev;

  mob_lev = GET_LEVEL(OLC_MOB(d));
  mob_lev = GET_LEVEL(OLC_MOB(d)) = LIMIT(mob_lev, 1, LVL_IMPL);

  GET_MOVE(OLC_MOB(d))    = mob_lev*10;          /* hit point bonus (mobs don't use movement points */
  GET_HIT(OLC_MOB(d))     = mob_lev/5;           /* number of hitpoint dice */
  GET_MANA(OLC_MOB(d))    = mob_lev/5;           /* size of hitpoint dice   */

  GET_NDD(OLC_MOB(d))     = MAX(1, mob_lev/6);   /* number damage dice 1-5  */
  GET_SDD(OLC_MOB(d))     = MAX(2, mob_lev/6);   /* size of damage dice 2-5 */
  GET_DAMROLL(OLC_MOB(d)) = mob_lev/6;           /* damroll (dam bonus) 0-5 */

  GET_HITROLL(OLC_MOB(d)) = mob_lev/3;           /* hitroll 0-10            */
  GET_EXP(OLC_MOB(d))     = (mob_lev*mob_lev*100);
  GET_GOLD(OLC_MOB(d))    = (mob_lev*10);
  GET_AC(OLC_MOB(d))      = (100-(mob_lev*6));   /* AC 94 to -80            */

  /* 'Advanced' stats are only rolled if advanced options are enabled */
  if (CONFIG_MEDIT_ADVANCED) {
    GET_STR(OLC_MOB(d))     = LIMIT((mob_lev*2)/3, 11, 18); /* 2/3 level in range 11 to 18 */
    GET_INT(OLC_MOB(d))     = LIMIT((mob_lev*2)/3, 11, 18);
    GET_WIS(OLC_MOB(d))     = LIMIT((mob_lev*2)/3, 11, 18);
    GET_DEX(OLC_MOB(d))     = LIMIT((mob_lev*2)/3, 11, 18);
    GET_CON(OLC_MOB(d))     = LIMIT((mob_lev*2)/3, 11, 18);
    GET_CHA(OLC_MOB(d))     = LIMIT((mob_lev*2)/3, 11, 18);

    GET_SAVE(OLC_MOB(d), SAVING_PARA)   = mob_lev / 4;  /* All Saving throws */
    GET_SAVE(OLC_MOB(d), SAVING_ROD)    = mob_lev / 4;  /* set to a quarter  */
    GET_SAVE(OLC_MOB(d), SAVING_PETRI)  = mob_lev / 4;  /* of the mobs level */
    GET_SAVE(OLC_MOB(d), SAVING_BREATH) = mob_lev / 4;
    GET_SAVE(OLC_MOB(d), SAVING_SPELL)  = mob_lev / 4;
  }

}
Пример #23
0
void trap_damage(struct char_data *v, int damtype, int amnt,
                 struct obj_data *t) {
  amnt = skip_immortals(v, amnt);
  if (amnt == -1) {
    return;
  }

  if (IS_AFFECTED(v, AFF_SANCTUARY))
    amnt = MAX((int)(amnt / 2), 0);     /* Max 1/2 damage when sanct'd */

  amnt = pre_proc_dam(v, damtype, amnt);

  if (saves_spell(v, SAVING_PETRI))
    amnt = MAX((int)(amnt / 2), 0);

  damage_stuff(v, damtype, amnt);

  amnt = MAX(amnt, 0);

  GET_HIT(v) -= amnt;

  update_pos(v);

  trap_dam(v, damtype, amnt, t);

  inform_mess(v);
  if (GET_POS(v) == POSITION_DEAD) {
    if (!IS_NPC(v)) {
      if (real_roomp(v->in_room)->name)
        log_msgf("%s killed by a trap at %s",
                 GET_NAME(v), real_roomp(v->in_room)->name);
    }

    die(v);
  }
}
Пример #24
0
void medit_parse(struct descriptor_data *d, char *arg)
{
  int i = -1, j;
  char *oldtext = NULL;

  if (OLC_MODE(d) > MEDIT_NUMERICAL_RESPONSE) {
    i = atoi(arg);
    if (!*arg || (!isdigit(arg[0]) && ((*arg == '-') && !isdigit(arg[1])))) {
      write_to_output(d, "Try again : ");
      return;
    }
  } else {	/* String response. */
    if (!genolc_checkstring(d, arg))
      return;
  }
  switch (OLC_MODE(d)) {
  case MEDIT_CONFIRM_SAVESTRING:
    /* Ensure mob has MOB_ISNPC set. */
    SET_BIT_AR(MOB_FLAGS(OLC_MOB(d)), MOB_ISNPC);
    switch (*arg) {
    case 'y':
    case 'Y':
      /* Save the mob in memory and to disk. */
      medit_save_internally(d);
      mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, "OLC: %s edits mob %d", GET_NAME(d->character), OLC_NUM(d));
      if (CONFIG_OLC_SAVE) {
        medit_save_to_disk(zone_table[real_zone_by_thing(OLC_NUM(d))].number);
        write_to_output(d, "Mobile saved to disk.\r\n");
      } else
        write_to_output(d, "Mobile saved to memory.\r\n");
      cleanup_olc(d, CLEANUP_ALL);
      return;
    case 'n':
    case 'N':
      /* If not saving, we must free the script_proto list. We do so by
       * assigning it to the edited mob and letting free_mobile in
       * cleanup_olc handle it. */
      OLC_MOB(d)->proto_script = OLC_SCRIPT(d);
      cleanup_olc(d, CLEANUP_ALL);
      return;
    default:
      write_to_output(d, "Invalid choice!\r\n");
      write_to_output(d, "Do you wish to save your changes? : ");
      return;
    }
    break;

  case MEDIT_MAIN_MENU:
    i = 0;
    switch (*arg) {
    case 'q':
    case 'Q':
      if (OLC_VAL(d)) {	/* Anything been changed? */
	write_to_output(d, "Do you wish to save your changes? : ");
	OLC_MODE(d) = MEDIT_CONFIRM_SAVESTRING;
      } else
	cleanup_olc(d, CLEANUP_ALL);
      return;
    case '1':
      OLC_MODE(d) = MEDIT_SEX;
      medit_disp_sex(d);
      return;
    case '2':
      OLC_MODE(d) = MEDIT_KEYWORD;
      i--;
      break;
    case '3':
      OLC_MODE(d) = MEDIT_S_DESC;
      i--;
      break;
    case '4':
      OLC_MODE(d) = MEDIT_L_DESC;
      i--;
      break;
    case '5':
      OLC_MODE(d) = MEDIT_D_DESC;
      send_editor_help(d);
      write_to_output(d, "Enter mob description:\r\n\r\n");
      if (OLC_MOB(d)->player.description) {
	write_to_output(d, "%s", OLC_MOB(d)->player.description);
	oldtext = strdup(OLC_MOB(d)->player.description);
      }
      string_write(d, &OLC_MOB(d)->player.description, MAX_MOB_DESC, 0, oldtext);
      OLC_VAL(d) = 1;
      return;
    case '6':
      OLC_MODE(d) = MEDIT_POS;
      medit_disp_positions(d);
      return;
    case '7':
      OLC_MODE(d) = MEDIT_DEFAULT_POS;
      medit_disp_positions(d);
      return;
    case '8':
      OLC_MODE(d) = MEDIT_ATTACK;
      medit_disp_attack_types(d);
      return;
    case '9':
      OLC_MODE(d) = MEDIT_STATS_MENU;
      medit_disp_stats_menu(d);
      return;
    case 'a':
    case 'A':
      OLC_MODE(d) = MEDIT_NPC_FLAGS;
      medit_disp_mob_flags(d);
      return;
    case 'b':
    case 'B':
      OLC_MODE(d) = MEDIT_AFF_FLAGS;
      medit_disp_aff_flags(d);
      return;
    case 'w':
    case 'W':
      write_to_output(d, "Copy what mob? ");
      OLC_MODE(d) = MEDIT_COPY;
      return;
    case 'x':
    case 'X':
      write_to_output(d, "Are you sure you want to delete this mobile? ");
      OLC_MODE(d) = MEDIT_DELETE;
      return;
    case 's':
    case 'S':
      OLC_SCRIPT_EDIT_MODE(d) = SCRIPT_MAIN_MENU;
      dg_script_menu(d);
      return;
    default:
      medit_disp_menu(d);
      return;
    }
    if (i == 0)
      break;
    else if (i == 1)
      write_to_output(d, "\r\nEnter new value : ");
    else if (i == -1)
      write_to_output(d, "\r\nEnter new text :\r\n] ");
    else
      write_to_output(d, "Oops...\r\n");
    return;

  case MEDIT_STATS_MENU:
    i=0;
    switch(*arg) {
    case 'q':
    case 'Q':
      medit_disp_menu(d);
      return;
    case '1':  /* Edit level */
      OLC_MODE(d) = MEDIT_LEVEL;
      i++;
      break;
    case '2':  /* Autoroll stats */
      medit_autoroll_stats(d);
      medit_disp_stats_menu(d);
      OLC_VAL(d) = TRUE;
      return;
    case '3':
      OLC_MODE(d) = MEDIT_NUM_HP_DICE;
      i++;
      break;
    case '4':
      OLC_MODE(d) = MEDIT_SIZE_HP_DICE;
      i++;
      break;
    case '5':
      OLC_MODE(d) = MEDIT_ADD_HP;
      i++;
      break;
    case '6':
      OLC_MODE(d) = MEDIT_NDD;
      i++;
      break;
    case '7':
      OLC_MODE(d) = MEDIT_SDD;
      i++;
      break;
    case '8':
      OLC_MODE(d) = MEDIT_DAMROLL;
      i++;
      break;
    case 'a':
    case 'A':
      OLC_MODE(d) = MEDIT_AC;
      i++;
      break;
    case 'b':
    case 'B':
      OLC_MODE(d) = MEDIT_EXP;
      i++;
      break;
    case 'c':
    case 'C':
      OLC_MODE(d) = MEDIT_GOLD;
      i++;
      break;
    case 'd':
    case 'D':
      OLC_MODE(d) = MEDIT_HITROLL;
      i++;
      break;
    case 'e':
    case 'E':
      OLC_MODE(d) = MEDIT_ALIGNMENT;
      i++;
      break;
    case 'f':
    case 'F':
      if (!CONFIG_MEDIT_ADVANCED) {
        write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
        return;
	  }
      OLC_MODE(d) = MEDIT_STR;
      i++;
      break;
    case 'g':
    case 'G':
      if (!CONFIG_MEDIT_ADVANCED) {
        write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
        return;
	  }
      OLC_MODE(d) = MEDIT_INT;
      i++;
      break;
    case 'h':
    case 'H':
      if (!CONFIG_MEDIT_ADVANCED) {
        write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
        return;
	  }
      OLC_MODE(d) = MEDIT_WIS;
      i++;
      break;
    case 'i':
    case 'I':
      if (!CONFIG_MEDIT_ADVANCED) {
        write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
        return;
	  }
      OLC_MODE(d) = MEDIT_DEX;
      i++;
      break;
    case 'j':
    case 'J':
      if (!CONFIG_MEDIT_ADVANCED) {
        write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
        return;
	  }
      OLC_MODE(d) = MEDIT_CON;
      i++;
      break;
    case 'k':
    case 'K':
      if (!CONFIG_MEDIT_ADVANCED) {
        write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
        return;
	  }
      OLC_MODE(d) = MEDIT_CHA;
      i++;
      break;
    case 'l':
    case 'L':
      if (!CONFIG_MEDIT_ADVANCED) {
        write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
        return;
	  }
      OLC_MODE(d) = MEDIT_PARA;
      i++;
      break;
    case 'm':
    case 'M':
      if (!CONFIG_MEDIT_ADVANCED) {
        write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
        return;
	  }
      OLC_MODE(d) = MEDIT_ROD;
      i++;
      break;
    case 'n':
    case 'N':
      if (!CONFIG_MEDIT_ADVANCED) {
        write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
        return;
	  }
      OLC_MODE(d) = MEDIT_PETRI;
      i++;
      break;
    case 'o':
    case 'O':
      if (!CONFIG_MEDIT_ADVANCED) {
        write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
        return;
	  }
      OLC_MODE(d) = MEDIT_BREATH;
      i++;
      break;
    case 'p':
    case 'P':
      if (!CONFIG_MEDIT_ADVANCED) {
        write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
        return;
	  }
      OLC_MODE(d) = MEDIT_SPELL;
      i++;
      break;
    default:
      medit_disp_stats_menu(d);
      return;
    }
    if (i == 0)
      break;
    else if (i == 1)
      write_to_output(d, "\r\nEnter new value : ");
    else if (i == -1)
      write_to_output(d, "\r\nEnter new text :\r\n] ");
    else
      write_to_output(d, "Oops...\r\n");
    return;

  case OLC_SCRIPT_EDIT:
    if (dg_script_edit_parse(d, arg)) return;
    break;

  case MEDIT_KEYWORD:
    smash_tilde(arg);
    if (GET_ALIAS(OLC_MOB(d)))
      free(GET_ALIAS(OLC_MOB(d)));
    GET_ALIAS(OLC_MOB(d)) = str_udup(arg);
    break;

  case MEDIT_S_DESC:
    smash_tilde(arg);
    if (GET_SDESC(OLC_MOB(d)))
      free(GET_SDESC(OLC_MOB(d)));
    GET_SDESC(OLC_MOB(d)) = str_udup(arg);
    break;

  case MEDIT_L_DESC:
    smash_tilde(arg);
    if (GET_LDESC(OLC_MOB(d)))
      free(GET_LDESC(OLC_MOB(d)));
    if (arg && *arg) {
      char buf[MAX_INPUT_LENGTH];
      snprintf(buf, sizeof(buf), "%s\r\n", arg);
      GET_LDESC(OLC_MOB(d)) = strdup(buf);
    } else
      GET_LDESC(OLC_MOB(d)) = strdup("undefined");

    break;

  case MEDIT_D_DESC:
    /*
     * We should never get here.
     */
    cleanup_olc(d, CLEANUP_ALL);
    mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: medit_parse(): Reached D_DESC case!");
    write_to_output(d, "Oops...\r\n");
    break;

  case MEDIT_NPC_FLAGS:
    if ((i = atoi(arg)) <= 0)
      break;
    else if ( (j = medit_get_mob_flag_by_number(i)) == -1) {
       write_to_output(d, "Invalid choice!\r\n");
       write_to_output(d, "Enter mob flags (0 to quit) :");
       return;
    } else if (j <= NUM_MOB_FLAGS) {
      TOGGLE_BIT_AR(MOB_FLAGS(OLC_MOB(d)), (j));
    }
    medit_disp_mob_flags(d);
    return;

  case MEDIT_AFF_FLAGS:
    if ((i = atoi(arg)) <= 0)
      break;
    else if (i <= NUM_AFF_FLAGS)
      TOGGLE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), i);

    /* Remove unwanted bits right away. */
    REMOVE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), AFF_CHARM);
    REMOVE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), AFF_POISON);
    REMOVE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), AFF_GROUP);
    REMOVE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), AFF_SLEEP);
    medit_disp_aff_flags(d);
    return;

/* Numerical responses. */

  case MEDIT_SEX:
    GET_SEX(OLC_MOB(d)) = LIMIT(i - 1, 0, NUM_GENDERS - 1);
    break;

  case MEDIT_HITROLL:
    GET_HITROLL(OLC_MOB(d)) = LIMIT(i, 0, 50);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_DAMROLL:
    GET_DAMROLL(OLC_MOB(d)) = LIMIT(i, 0, 50);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_NDD:
    GET_NDD(OLC_MOB(d)) = LIMIT(i, 0, 30);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_SDD:
    GET_SDD(OLC_MOB(d)) = LIMIT(i, 0, 127);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_NUM_HP_DICE:
    GET_HIT(OLC_MOB(d)) = LIMIT(i, 0, 30);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_SIZE_HP_DICE:
    GET_MANA(OLC_MOB(d)) = LIMIT(i, 0, 1000);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_ADD_HP:
    GET_MOVE(OLC_MOB(d)) = LIMIT(i, 0, 30000);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_AC:
    GET_AC(OLC_MOB(d)) = LIMIT(i, -200, 200);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_EXP:
    GET_EXP(OLC_MOB(d)) = LIMIT(i, 0, MAX_MOB_EXP);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_GOLD:
    GET_GOLD(OLC_MOB(d)) = LIMIT(i, 0, MAX_MOB_GOLD);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_STR:
    GET_STR(OLC_MOB(d)) = LIMIT(i, 11, 25);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_INT:
    GET_INT(OLC_MOB(d)) = LIMIT(i, 11, 25);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_WIS:
    GET_WIS(OLC_MOB(d)) = LIMIT(i, 11, 25);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_DEX:
    GET_DEX(OLC_MOB(d)) = LIMIT(i, 11, 25);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_CON:
    GET_CON(OLC_MOB(d)) = LIMIT(i, 11, 25);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_CHA:
    GET_CHA(OLC_MOB(d)) = LIMIT(i, 11, 25);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_PARA:
    GET_SAVE(OLC_MOB(d), SAVING_PARA) = LIMIT(i, 0, 100);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_ROD:
    GET_SAVE(OLC_MOB(d), SAVING_ROD) = LIMIT(i, 0, 100);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_PETRI:
    GET_SAVE(OLC_MOB(d), SAVING_PETRI) = LIMIT(i, 0, 100);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_BREATH:
    GET_SAVE(OLC_MOB(d), SAVING_BREATH) = LIMIT(i, 0, 100);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_SPELL:
    GET_SAVE(OLC_MOB(d), SAVING_SPELL) = LIMIT(i, 0, 100);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_POS:
    GET_POS(OLC_MOB(d)) = LIMIT(i - 1, 0, NUM_POSITIONS - 1);
    break;

  case MEDIT_DEFAULT_POS:
    GET_DEFAULT_POS(OLC_MOB(d)) = LIMIT(i - 1, 0, NUM_POSITIONS - 1);
    break;

  case MEDIT_ATTACK:
    GET_ATTACK(OLC_MOB(d)) = LIMIT(i, 0, NUM_ATTACK_TYPES - 1);
    break;

  case MEDIT_LEVEL:
    GET_LEVEL(OLC_MOB(d)) = LIMIT(i, 1, LVL_IMPL);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_ALIGNMENT:
    GET_ALIGNMENT(OLC_MOB(d)) = LIMIT(i, -1000, 1000);
    OLC_VAL(d) = TRUE;
    medit_disp_stats_menu(d);
    return;

  case MEDIT_COPY:
    if ((i = real_mobile(atoi(arg))) != NOWHERE) {
      medit_setup_existing(d, i);
    } else
      write_to_output(d, "That mob does not exist.\r\n");
    break;

  case MEDIT_DELETE:
    if (*arg == 'y' || *arg == 'Y') {
      if (delete_mobile(GET_MOB_RNUM(OLC_MOB(d))) != NOBODY)
        write_to_output(d, "Mobile deleted.\r\n");
      else
        write_to_output(d, "Couldn't delete the mobile!\r\n");

      cleanup_olc(d, CLEANUP_ALL);
      return;
    } else if (*arg == 'n' || *arg == 'N') {
      medit_disp_menu(d);
      OLC_MODE(d) = MEDIT_MAIN_MENU;
      return;
    } else
      write_to_output(d, "Please answer 'Y' or 'N': ");
    break;

  default:
    /* We should never get here. */
    cleanup_olc(d, CLEANUP_ALL);
    mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: medit_parse(): Reached default case!");
    write_to_output(d, "Oops...\r\n");
    break;
  }

/* END OF CASE If we get here, we have probably changed something, and now want
   to return to main menu.  Use OLC_VAL as a 'has changed' flag */

  OLC_VAL(d) = TRUE;
  medit_disp_menu(d);
}
Пример #25
0
/* Display main menu. */
static void medit_disp_stats_menu(struct descriptor_data *d)
{
  struct char_data *mob;
  char buf[MAX_STRING_LENGTH];

  mob = OLC_MOB(d);
  get_char_colors(d->character);
  clear_screen(d);

  /* Color codes have to be used here, for count_color_codes to work */
  sprintf(buf, "(range \ty%d\tn to \ty%d\tn)", GET_HIT(mob) + GET_MOVE(mob), (GET_HIT(mob) * GET_MANA(mob)) + GET_MOVE(mob));

  /* Top section - standard stats */
  write_to_output(d,
  "-- Mob Number:  %s[%s%d%s]%s\r\n"
  "(%s1%s) Level:       %s[%s%4d%s]%s\r\n"
  "(%s2%s) %sAuto Set Stats (based on level)%s\r\n\r\n"
  "Hit Points  (xdy+z):        Bare Hand Damage (xdy+z): \r\n"
  "(%s3%s) HP NumDice:  %s[%s%5d%s]%s    (%s6%s) BHD NumDice:  %s[%s%5d%s]%s\r\n"
  "(%s4%s) HP SizeDice: %s[%s%5d%s]%s    (%s7%s) BHD SizeDice: %s[%s%5d%s]%s\r\n"
  "(%s5%s) HP Addition: %s[%s%5d%s]%s    (%s8%s) DamRoll:      %s[%s%5d%s]%s\r\n"
  "%-*s(range %s%d%s to %s%d%s)\r\n\r\n"

  "(%sA%s) Armor Class: %s[%s%4d%s]%s        (%sD%s) Hitroll:   %s[%s%5d%s]%s\r\n"
  "(%sB%s) Exp Points:  %s[%s%10d%s]%s  (%sE%s) Alignment: %s[%s%5d%s]%s\r\n"
  "(%sC%s) Gold:        %s[%s%10d%s]%s\r\n\r\n",
      cyn, yel, OLC_NUM(d), cyn, nrm,
      cyn, nrm, cyn, yel, GET_LEVEL(mob), cyn, nrm,
      cyn, nrm, cyn, nrm,
      cyn, nrm, cyn, yel, GET_HIT(mob), cyn, nrm,   cyn, nrm, cyn, yel, GET_NDD(mob), cyn, nrm,
      cyn, nrm, cyn, yel, GET_MANA(mob), cyn, nrm,  cyn, nrm, cyn, yel, GET_SDD(mob), cyn, nrm,
      cyn, nrm, cyn, yel, GET_MOVE(mob), cyn, nrm,  cyn, nrm, cyn, yel, GET_DAMROLL(mob), cyn, nrm,

      count_color_chars(buf)+28, buf,
      yel, GET_NDD(mob) + GET_DAMROLL(mob), nrm,
      yel, (GET_NDD(mob) * GET_SDD(mob)) + GET_DAMROLL(mob), nrm,

      cyn, nrm, cyn, yel, GET_AC(mob), cyn, nrm,   cyn, nrm, cyn, yel, GET_HITROLL(mob), cyn, nrm,
      cyn, nrm, cyn, yel, GET_EXP(mob), cyn, nrm,  cyn, nrm, cyn, yel, GET_ALIGNMENT(mob), cyn, nrm,
      cyn, nrm, cyn, yel, GET_GOLD(mob), cyn, nrm
      );

  if (CONFIG_MEDIT_ADVANCED) {
    /* Bottom section - non-standard stats, togglable in cedit */
    write_to_output(d,
    "(%sF%s) Str: %s[%s%2d/%3d%s]%s   Saving Throws\r\n"
    "(%sG%s) Int: %s[%s%3d%s]%s      (%sL%s) Paralysis     %s[%s%3d%s]%s\r\n"
    "(%sH%s) Wis: %s[%s%3d%s]%s      (%sM%s) Rods/Staves   %s[%s%3d%s]%s\r\n"
    "(%sI%s) Dex: %s[%s%3d%s]%s      (%sN%s) Petrification %s[%s%3d%s]%s\r\n"
    "(%sJ%s) Con: %s[%s%3d%s]%s      (%sO%s) Breath        %s[%s%3d%s]%s\r\n"
    "(%sK%s) Cha: %s[%s%3d%s]%s      (%sP%s) Spells        %s[%s%3d%s]%s\r\n\r\n",
        cyn, nrm, cyn, yel, GET_STR(mob), GET_ADD(mob), cyn, nrm,
        cyn, nrm, cyn, yel, GET_INT(mob), cyn, nrm,   cyn, nrm, cyn, yel, GET_SAVE(mob, SAVING_PARA), cyn, nrm,
        cyn, nrm, cyn, yel, GET_WIS(mob), cyn, nrm,   cyn, nrm, cyn, yel, GET_SAVE(mob, SAVING_ROD), cyn, nrm,
        cyn, nrm, cyn, yel, GET_DEX(mob), cyn, nrm,   cyn, nrm, cyn, yel, GET_SAVE(mob, SAVING_PETRI), cyn, nrm,
        cyn, nrm, cyn, yel, GET_CON(mob), cyn, nrm,   cyn, nrm, cyn, yel, GET_SAVE(mob, SAVING_BREATH), cyn, nrm,
        cyn, nrm, cyn, yel, GET_CHA(mob), cyn, nrm,   cyn, nrm, cyn, yel, GET_SAVE(mob, SAVING_SPELL), cyn, nrm
        );
  }

  /* Quit to previous menu option */
  write_to_output(d, "(%sQ%s) Quit to main menu\r\nEnter choice : ", cyn, nrm);

  OLC_MODE(d) = MEDIT_STATS_MENU;
}
Пример #26
0
/* Update PCs, NPCs, and objects */
void point_update(void)
{
  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;
	
    gain_condition(i, FULL, -1);
    gain_condition(i, DRUNK, -1);
    gain_condition(i, THIRST, -1);
	
    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 (AFF_FLAGGED(i, AFF_POISON))
	if (damage(i, i, 2, SPELL_POISON) == -1)
	  continue;	/* Oops, they died. -gg 6/24/98 */
      if (GET_POS(i) <= POS_STUNNED)
	update_pos(i);
    } else if (GET_POS(i) == POS_INCAP) {
      if (damage(i, i, 1, TYPE_SUFFERING) == -1)
	continue;
    } else if (GET_POS(i) == POS_MORTALLYW) {
      if (damage(i, i, 2, TYPE_SUFFERING) == -1)
	continue;
    }
    if (!IS_NPC(i)) {
      update_char_objects(i);
      if (GET_LEVEL(i) < idle_max_level)
	check_idling(i);
    }
  }

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

    /* If this is a corpse */
    if (IS_CORPSE(j)) {
      /* 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 ((IN_ROOM(j) != NOWHERE) && (world[IN_ROOM(j)].people)) {
	  act("A quivering horde of maggots consumes $p.",
	      TRUE, world[IN_ROOM(j)].people, j, 0, TO_ROOM);
	  act("A quivering horde of maggots consumes $p.",
	      TRUE, world[IN_ROOM(j)].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, IN_ROOM(j->carried_by));
	  else if (IN_ROOM(j) != NOWHERE)
	    obj_to_room(jj, IN_ROOM(j));
	  else
	    core_dump();
	}
	extract_obj(j);
      }
    }
    /* If the timer is set, count it down and at 0, try the trigger */
    /* note to .rej hand-patchers: make this last in your point-update() */
    else if (GET_OBJ_TIMER(j)>0) {
      GET_OBJ_TIMER(j)--; 
      if (!GET_OBJ_TIMER(j))
        timer_otrigger(j);
    }
  }
}
Пример #27
0
void regen_update( void ) {
    CharData *i, *next_char;
    int hit, mana, move;
    int vivify_level;

    for( i = character_list; i; i = next_char )
    {
        next_char = i->next;

        if(affected_by_spell(i, SKILL_EMACIATED) && (GET_COND(i, HUNGER) != 0 || IS_VAMPIRE(i)) && GET_COND(i, THIRST) != 0) {
            if(!affected_by_spell(i, SKILL_EMACIATED_MANA) && !affected_by_spell(i, SKILL_EMACIATED_HIT))
                affect_from_char(i, SKILL_EMACIATED);
            else if(percentSuccess(4)) {
                affect_from_char(i, SKILL_EMACIATED_MANA);
                affect_from_char(i, SKILL_EMACIATED_HIT);
            }
        }

        // Dwarves sober up 3x faster than most races (unless they drink more...)
        if(IS_DWARF(i) && !number(0, 35))
            gain_condition(i, DRUNK, -1);

        vivify_level = spell_level(i, SPELL_VIVIFY);
        affect_from_char(i, SPELL_VIVIFY);
        if(GET_POS(i) <= POS_MEDITATING) {
            add_affect(i, i, SPELL_VIVIFY, MIN(vivify_level + 1, 100), APPLY_NONE, 0, -1,
                    0, FALSE, FALSE, FALSE, FALSE);
        }

        if(GET_POS(i) >= POS_MORTALLYW)
        {
            hit = hit_gain(i);
            mana = mana_gain(i);
            move = move_gain(i);

            if(affected_by_spell(i, SPELL_VIVIFY)) {
                if(hit > 0)
                    hit += spell_level(i, SPELL_VIVIFY) * GET_MAX_HIT(i)/600;
                if(mana > 0)
                    mana += spell_level(i, SPELL_VIVIFY) * GET_MAX_MANA(i)/600;
                if(move > 0)
                    move += spell_level(i, SPELL_VIVIFY) * GET_MAX_MOVE(i)/600;
            }

            // Regeneration is increased on pvp holidays.  If you're incapactitated, you will
            // eventually recover.
            if(pvpHoliday(i)) {
                if (GET_POS(i) < POS_SLEEPING)
                    hit = 20;
                else {
                    hit  = (hit  > 0) ? hit *3 : 20;
                    mana = (mana > 0) ? mana*2 : 40;
                    move = (move > 0) ? move*2 : 40;
                }
            }
                

            // 72 seconds per tick...
            if(hit < 0 || GET_HIT(i) < GET_MAX_HIT(i)) {
                if(hit>0)
                    GET_HIT(i) += hit/72 + (hit % 72 > number(0, 71)? 1:0);
                else
                    GET_HIT(i)  = MAX(GET_HIT(i) + hit/72 + (-hit % 72 > number(0, 71)?-1:0), -9);
            }
            else {
                int surplus = (GET_HIT(i) - GET_MAX_HIT(i));
                GET_HIT(i) -= surplus / 72 + (surplus % 72 > number(0, 71)? 1:0);
            }


            if(mana>0)
                GET_MANA(i) = MAX(MIN(GET_MANA(i) + mana/72 + (mana % 72 > number(0, 71)?1:0), GET_MAX_MANA(i)), 0);
            else
                GET_MANA(i) = MIN(GET_MANA(i) + mana/72 + (-mana % 72 > number(0, 71)?-1:0), GET_MAX_MANA(i));

            if(move>0)
                GET_MOVE(i) = MIN(GET_MOVE(i) + move/72 + (move % 72 > number(0, 71)?1:0), GET_MAX_MOVE(i));
            else
                GET_MOVE(i) = MAX(MIN(GET_MOVE(i) + move/72 + (-move % 72 > number(0, 71)?-1:0), GET_MAX_MOVE(i)), 0);

            update_pos(i);
        }
    }
}
Пример #28
0
void
check_idling( CharData * ch )
{
#define VOID_TIME 8
#define EXTRACT_TIME 32
  void Crash_rentsave(CharData *ch, int cost);
  void Crash_cryosave(CharData *ch, int cost);

  /*
  ** CONJURED timer
  */
  int i = 0;

  for(;i < 4;i++) {
      if( GET_CONJ_CNT(ch, i) > 0)
      {
          SET_CONJ_CNT(ch, i) -= 1;
          
          if(SET_CONJ_CNT(ch, i) == 0)
              switch(GET_CLASS(ch)) {
                  case CLASS_RANGER:
                      sendChar( ch, "The creatures of the wild will answer your call again.\r\n" );
                      break;
                  case CLASS_NECROMANCER:
                      sendChar(ch, "The dead will heed your summons once more.\r\n");
                  case CLASS_MAGIC_USER:
                      switch(i) {
                          case TIMER_GATE: sendChar(ch, "Demons will answer your summons again.\r\n"); break;
                          case TIMER_MONSTER: sendChar(ch, "Monsters will answer your summons again.\r\n"); break;
                          case TIMER_ELEMENTAL: sendChar(ch, "Elementals will answer your summons again.\r\n"); break;
                      }
                      break;
                  default:
                      sendChar( ch, "Conjured creatures will answer your summons again.\r\n" );
              }
      }
  }
  
  /*
  ** HUNTED timer
  */
  if( IS_SET_AR( PLR_FLAGS(ch), PLR_HUNTED ) && ch->desc &&
    (--(ch)->player_specials->saved.phunt_countdown <= 0))
  {
    sendChar( ch, "You are no longer hunted.\r\n" );
    unset_hunted_player(ch);
  }
  /*
  ** THIEF timer
  */
  if( IS_SET_AR(PLR_FLAGS(ch), PLR_THIEF) && ch->desc &&
    (--(ch)->player_specials->saved.pthief_countdown <= 0))
  {
    REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_THIEF);
    send_to_char("You are no longer a registered thief.\r\n", ch);
    (ch)->player_specials->saved.pthief_countdown = 0;
  }
  /* KILLER timer */
  if (IS_SET_AR(PLR_FLAGS(ch), PLR_KILLER)
     && (--(ch)->player_specials->saved.pkill_countdown <= 0))
  {
    REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_KILLER);
    send_to_char("You are no longer a registered killer.\r\n", ch);
    (ch)->player_specials->saved.pkill_countdown = 0;
  }
  /* JAILED timer */
  if (IS_SET_AR(PLR_FLAGS(ch), PLR_JAILED)
     && (--(ch)->player_specials->saved.jail_timer <= 0))
  {
    int jail_exit_room;
    REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_JAILED);

    if (PRF_FLAGGED(ch, PRF_GOLD_TEAM) && IN_ROOM(ch) == real_room(GOLD_TEAM_JAIL))
    {
      jail_exit_room = real_room(GOLD_TEAM_START_ROOM);
      GET_HIT(ch) = GET_MAX_HIT(ch);
      GET_MANA(ch) = GET_MAX_MANA(ch);
      GET_MOVE(ch) = GET_MAX_MOVE(ch);
      char_from_room(ch);
      char_to_room(ch, jail_exit_room);
      look_at_room(ch, 0);
    }
    if (PRF_FLAGGED(ch, PRF_BLACK_TEAM) && IN_ROOM(ch) == real_room(BLACK_TEAM_JAIL))
    {
      jail_exit_room = real_room(BLACK_TEAM_START_ROOM);
      GET_HIT(ch) = GET_MAX_HIT(ch);
      GET_MANA(ch) = GET_MAX_MANA(ch);
      GET_MOVE(ch) = GET_MAX_MOVE(ch);
      char_from_room(ch);
      char_to_room(ch, jail_exit_room);
      look_at_room(ch, 0);
    }    
    if (PRF_FLAGGED(ch, PRF_ROGUE_TEAM) && IN_ROOM(ch) == real_room(ROGUE_TEAM_JAIL))
    {
      jail_exit_room = real_room(ROGUE_TEAM_START_ROOM);
      GET_HIT(ch) = GET_MAX_HIT(ch);
      GET_MANA(ch) = GET_MAX_MANA(ch);
      GET_MOVE(ch) = GET_MAX_MOVE(ch);
      char_from_room(ch);
      char_to_room(ch, jail_exit_room);
      look_at_room(ch, 0);
    }    
    sendChar(ch, "Your imprisonement is over.\r\n");
//    if (PRF_FLAGGED(ch, PRF_GOLD_TEAM))
//	jail_exit_room = IN_ROOM(ch);
//    else if (PRF_FLAGGED(ch, PRF_BLACK_TEAM))
//	jail_exit_room = IN_ROOM(ch);
//	else if (PRF_FLAGGED(ch, PRF_ROGUE_TEAM))
//	jail_exit_room = IN_ROOM(ch);
//    else
//	jail_exit_room = getStartRoom(ch);

//    char_to_room(ch, jail_exit_room);
//    look_at_room(ch, 0);
  }
  /*
  ** If your hunted there is NO escape.
  */
  if(( ++(ch->char_specials.timer) > VOID_TIME ) &&
    !IS_SET_AR(PLR_FLAGS(ch), PLR_HUNTED))
  {
    if (GET_WAS_IN(ch) == NOWHERE && ch->in_room != NOWHERE)
    {
      GET_WAS_IN(ch) = ch->in_room;
      end_fight(ch);
      act("$n disappears into the void.", TRUE, ch, 0, 0, TO_ROOM);
      send_to_char("You have been idle, and are pulled into a void.\r\n", ch);
      save_char(ch, NOWHERE);
      Crash_crashsave(ch);
      GET_WAS_IN(ch) = ch->in_room;
      char_from_room(ch);
      char_to_room(ch, 1);
    }
    //else if (ch->char_specials.timer > EXTRACT_TIME)
    //{
      //if (ch->in_room != NOWHERE)
	//char_from_room(ch);
      //char_to_room(ch, 1);
      //if (ch->desc)
	//SET_DCPENDING(ch->desc);
      //ch->desc = NULL;

      //Crash_idlesave(ch);	/* apparently causing problems? */
      //crashRentSave(ch, -1);

      //mudlog( NRM, LVL_LRGOD, TRUE, "%s force-rented and extracted (idle).", GET_NAME(ch));
      //extract_char(ch);
    //}
  }
#undef VOID_TIME
#undef EXTRACT_TIME
}
Пример #29
0
/*
 * Every spell that does damage comes through here.  This calculates the
 * amount of damage, adds in any modifiers, determines what the saves are,
 * tests for save and calls damage().
 *
 * -1 = dead, otherwise the amount of damage done.
 */
int mag_damage(int level, struct char_data *ch, struct char_data *victim,
		     int spellnum, int savetype)
{
  int dam = 0;

  if (victim == NULL || ch == NULL)
    return (0);

  switch (spellnum) {
    /* Mostly mages */
  case SPELL_MAGIC_MISSILE:
  case SPELL_CHILL_TOUCH:	/* chill touch also has an affect */
    if (IS_MAGIC_USER(ch))
      dam = dice(1, 8) + 1;
    else
      dam = dice(1, 6) + 1;
    break;
  case SPELL_BURNING_HANDS:
    if (IS_MAGIC_USER(ch))
      dam = dice(3, 8) + 3;
    else
      dam = dice(3, 6) + 3;
    break;
  case SPELL_SHOCKING_GRASP:
    if (IS_MAGIC_USER(ch))
      dam = dice(5, 8) + 5;
    else
      dam = dice(5, 6) + 5;
    break;
  case SPELL_LIGHTNING_BOLT:
    if (IS_MAGIC_USER(ch))
      dam = dice(7, 8) + 7;
    else
      dam = dice(7, 6) + 7;
    break;
  case SPELL_COLOR_SPRAY:
    if (IS_MAGIC_USER(ch))
      dam = dice(9, 8) + 9;
    else
      dam = dice(9, 6) + 9;
    break;
  case SPELL_FIREBALL:
    if (IS_MAGIC_USER(ch))
      dam = dice(11, 8) + 11;
    else
      dam = dice(11, 6) + 11;
    break;

    /* Mostly clerics */
  case SPELL_DISPEL_EVIL:
    dam = dice(6, 8) + 6;
    if (IS_EVIL(ch)) {
      victim = ch;
      dam = GET_HIT(ch) - 1;
    } else if (IS_GOOD(victim)) {
      act("The gods protect $N.", FALSE, ch, 0, victim, TO_CHAR);
      return (0);
    }
    break;
  case SPELL_DISPEL_GOOD:
    dam = dice(6, 8) + 6;
    if (IS_GOOD(ch)) {
      victim = ch;
      dam = GET_HIT(ch) - 1;
    } else if (IS_EVIL(victim)) {
      act("The gods protect $N.", FALSE, ch, 0, victim, TO_CHAR);
      return (0);
    }
    break;


  case SPELL_CALL_LIGHTNING:
    dam = dice(7, 8) + 7;
    break;

  case SPELL_HARM:
    dam = dice(8, 8) + 8;
    break;

  case SPELL_ENERGY_DRAIN:
    if (GET_LEVEL(victim) <= 2)
      dam = 100;
    else
      dam = dice(1, 10);
    break;

    /* Area spells */
  case SPELL_EARTHQUAKE:
    dam = dice(2, 8) + level;
    break;

  } /* switch(spellnum) */


  /* divide damage by two if victim makes his saving throw */
  if (mag_savingthrow(victim, savetype, 0))
    dam /= 2;

  /* and finally, inflict the damage */
  return (damage(ch, victim, dam, spellnum));
}
Пример #30
0
/*
 * Alert: As of bpl14, this function returns the following codes:
 *	< 0	Victim died.
 *	= 0	No damage.
 *	> 0	How much damage done.
 */
int damage(struct char_data *ch, struct char_data *victim, int dam, int attacktype)
{
  if (GET_POS(victim) <= POS_DEAD) {
    /* This is "normal"-ish now with delayed extraction. -gg 3/15/2001 */
    if (PLR_FLAGGED(victim, PLR_NOTDEADYET) || MOB_FLAGGED(victim, MOB_NOTDEADYET))
      return (-1);

    log("SYSERR: Attempt to damage corpse '%s' in room #%d by '%s'.",
		GET_NAME(victim), GET_ROOM_VNUM(IN_ROOM(victim)), GET_NAME(ch));
    die(victim);
    return (-1);			/* -je, 7/7/92 */
  }

  /* peaceful rooms */
  if (ch != victim && ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) {
    send_to_char(ch, "This room just has such a peaceful, easy feeling...\r\n");
    return (0);
  }

  /* shopkeeper protection */
  if (!ok_damage_shopkeeper(ch, victim))
    return (0);

  /* You can't damage an immortal! */
  if (!IS_NPC(victim) && (GET_LEVEL(victim) >= LVL_IMMORT))
    dam = 0;

  if (victim != ch) {
    /* Start the attacker fighting the victim */
    if (GET_POS(ch) > POS_STUNNED && (FIGHTING(ch) == NULL))
      set_fighting(ch, victim);

    /* Start the victim fighting the attacker */
    if (GET_POS(victim) > POS_STUNNED && (FIGHTING(victim) == NULL)) {
      set_fighting(victim, ch);
      if (MOB_FLAGGED(victim, MOB_MEMORY) && !IS_NPC(ch))
	remember(victim, ch);
    }
  }

  /* If you attack a pet, it hates your guts */
  if (victim->master == ch)
    stop_follower(victim);

  /* If the attacker is invisible, he becomes visible */
  if (AFF_FLAGGED(ch, AFF_INVISIBLE | AFF_HIDE))
    appear(ch);

  /* Cut damage in half if victim has sanct, to a minimum 1 */
  if (AFF_FLAGGED(victim, AFF_SANCTUARY) && dam >= 2)
    dam /= 2;

  /* Check for PK if this is not a PK MUD */
  if (!pk_allowed) {
    check_killer(ch, victim);
    if (PLR_FLAGGED(ch, PLR_KILLER) && (ch != victim))
      dam = 0;
  }

  /* Set the maximum damage per round and subtract the hit points */
  dam = MAX(MIN(dam, 100), 0);
  GET_HIT(victim) -= dam;

  /* Gain exp for the hit */
  if (ch != victim)
    gain_exp(ch, GET_LEVEL(victim) * dam);

  update_pos(victim);

  /*
   * skill_message sends a message from the messages file in lib/misc.
   * dam_message just sends a generic "You hit $n extremely hard.".
   * skill_message is preferable to dam_message because it is more
   * descriptive.
   * 
   * If we are _not_ attacking with a weapon (i.e. a spell), always use
   * skill_message. If we are attacking with a weapon: If this is a miss or a
   * death blow, send a skill_message if one exists; if not, default to a
   * dam_message. Otherwise, always send a dam_message.
   */
  if (!IS_WEAPON(attacktype))
    skill_message(dam, ch, victim, attacktype);
  else {
    if (GET_POS(victim) == POS_DEAD || dam == 0) {
      if (!skill_message(dam, ch, victim, attacktype))
	dam_message(dam, ch, victim, attacktype);
    } else {
      dam_message(dam, ch, victim, attacktype);
    }
  }

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

  default:			/* >= POSITION SLEEPING */
    if (dam > (GET_MAX_HIT(victim) / 4))
      send_to_char(victim, "That really did HURT!\r\n");

    if (GET_HIT(victim) < (GET_MAX_HIT(victim) / 4)) {
      send_to_char(victim, "%sYou wish that your wounds would stop BLEEDING so much!%s\r\n",
		CCRED(victim, C_SPR), CCNRM(victim, C_SPR));
      if (ch != victim && MOB_FLAGGED(victim, MOB_WIMPY))
	do_flee(victim, NULL, 0, 0);
    }
    if (!IS_NPC(victim) && GET_WIMP_LEV(victim) && (victim != ch) &&
	GET_HIT(victim) < GET_WIMP_LEV(victim) && GET_HIT(victim) > 0) {
      send_to_char(victim, "You wimp out, and attempt to flee!\r\n");
      do_flee(victim, NULL, 0, 0);
    }
    break;
  }

  /* Help out poor linkless people who are attacked */
  if (!IS_NPC(victim) && !(victim->desc) && GET_POS(victim) > POS_STUNNED) {
    do_flee(victim, NULL, 0, 0);
    if (!FIGHTING(victim)) {
      act("$n is rescued by divine forces.", FALSE, victim, 0, 0, CommTarget::TO_ROOM);
      GET_WAS_IN(victim) = IN_ROOM(victim);
      char_from_room(victim);
      char_to_room(victim, 0);
    }
  }

  /* stop someone from fighting if they're stunned or worse */
  if (GET_POS(victim) <= POS_STUNNED && FIGHTING(victim) != NULL)
    stop_fighting(victim);

  /* Uh oh.  Victim died. */
  if (GET_POS(victim) == POS_DEAD) {
    if (ch != victim && (IS_NPC(victim) || victim->desc)) {
      if (AFF_FLAGGED(ch, AFF_GROUP))
	group_gain(ch, victim);
      else
        solo_gain(ch, victim);
    }

    if (!IS_NPC(victim)) {
      mudlog(BRF, LVL_IMMORT, TRUE, "%s killed by %s at %s", GET_NAME(victim), GET_NAME(ch), world[IN_ROOM(victim)].name);
      if (MOB_FLAGGED(ch, MOB_MEMORY))
	forget(ch, victim);
    }
    die(victim);
    return (-1);
  }
  return (dam);
}