Beispiel #1
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);

    }
}
Beispiel #2
0
void mag_affects(int level, struct char_data *ch, struct char_data *victim,
		      int spellnum, int savetype)
{
  struct affected_type af[MAX_SPELL_AFFECTS];
  bool accum_affect = FALSE, accum_duration = FALSE;
  const char *to_vict = NULL, *to_room = NULL;
  int i;


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

  for (i = 0; i < MAX_SPELL_AFFECTS; i++) {
    af[i].type = spellnum;
    af[i].bitvector = 0;
    af[i].modifier = 0;
    af[i].location = APPLY_NONE;
  }

  switch (spellnum) {

  case SPELL_CHILL_TOUCH:
    af[0].location = APPLY_STR;
    if (mag_savingthrow(victim, savetype, 0))
      af[0].duration = 1;
    else
      af[0].duration = 4;
    af[0].modifier = -1;
    accum_duration = TRUE;
    to_vict = "You feel your strength wither!";
    break;

  case SPELL_ARMOR:
    af[0].location = APPLY_AC;
    af[0].modifier = -20;
    af[0].duration = 24;
    accum_duration = TRUE;
    to_vict = "You feel someone protecting you.";
    break;

  case SPELL_BLESS:
    af[0].location = APPLY_HITROLL;
    af[0].modifier = 2;
    af[0].duration = 6;

    af[1].location = APPLY_SAVING_SPELL;
    af[1].modifier = -1;
    af[1].duration = 6;

    accum_duration = TRUE;
    to_vict = "You feel righteous.";
    break;

  case SPELL_BLINDNESS:
    if (MOB_FLAGGED(victim,MOB_NOBLIND) || mag_savingthrow(victim, savetype, 0)) {
      send_to_char(ch, "You fail.\r\n");
      return;
    }

    af[0].location = APPLY_HITROLL;
    af[0].modifier = -4;
    af[0].duration = 2;
    af[0].bitvector = AFF_BLIND;

    af[1].location = APPLY_AC;
    af[1].modifier = 40;
    af[1].duration = 2;
    af[1].bitvector = AFF_BLIND;

    to_room = "$n seems to be blinded!";
    to_vict = "You have been blinded!";
    break;

  case SPELL_CURSE:
    if (mag_savingthrow(victim, savetype, 0)) {
      send_to_char(ch, "%s", NOEFFECT);
      return;
    }

    af[0].location = APPLY_HITROLL;
    af[0].duration = 1 + (GET_LEVEL(ch) / 2);
    af[0].modifier = -1;
    af[0].bitvector = AFF_CURSE;

    af[1].location = APPLY_DAMROLL;
    af[1].duration = 1 + (GET_LEVEL(ch) / 2);
    af[1].modifier = -1;
    af[1].bitvector = AFF_CURSE;

    accum_duration = TRUE;
    accum_affect = TRUE;
    to_room = "$n briefly glows red!";
    to_vict = "You feel very uncomfortable.";
    break;

  case SPELL_DETECT_ALIGN:
    af[0].duration = 12 + level;
    af[0].bitvector = AFF_DETECT_ALIGN;
    accum_duration = TRUE;
    to_vict = "Your eyes tingle.";
    break;

  case SPELL_DETECT_INVIS:
    af[0].duration = 12 + level;
    af[0].bitvector = AFF_DETECT_INVIS;
    accum_duration = TRUE;
    to_vict = "Your eyes tingle.";
    break;

  case SPELL_DETECT_MAGIC:
    af[0].duration = 12 + level;
    af[0].bitvector = AFF_DETECT_MAGIC;
    accum_duration = TRUE;
    to_vict = "Your eyes tingle.";
    break;

  case SPELL_INFRAVISION:
    af[0].duration = 12 + level;
    af[0].bitvector = AFF_INFRAVISION;
    accum_duration = TRUE;
    to_vict = "Your eyes glow red.";
    to_room = "$n's eyes glow red.";
    break;

  case SPELL_INVISIBLE:
    if (!victim)
      victim = ch;

    af[0].duration = 12 + (GET_LEVEL(ch) / 4);
    af[0].modifier = -40;
    af[0].location = APPLY_AC;
    af[0].bitvector = AFF_INVISIBLE;
    accum_duration = TRUE;
    to_vict = "You vanish.";
    to_room = "$n slowly fades out of existence.";
    break;

  case SPELL_POISON:
    if (mag_savingthrow(victim, savetype, 0)) {
      send_to_char(ch, "%s", NOEFFECT);
      return;
    }

    af[0].location = APPLY_STR;
    af[0].duration = GET_LEVEL(ch);
    af[0].modifier = -2;
    af[0].bitvector = AFF_POISON;
    to_vict = "You feel very sick.";
    to_room = "$n gets violently ill!";
    break;

  case SPELL_PROT_FROM_EVIL:
    af[0].duration = 24;
    af[0].bitvector = AFF_PROTECT_EVIL;
    accum_duration = TRUE;
    to_vict = "You feel invulnerable!";
    break;

  case SPELL_SANCTUARY:
    af[0].duration = 4;
    af[0].bitvector = AFF_SANCTUARY;

    accum_duration = TRUE;
    to_vict = "A white aura momentarily surrounds you.";
    to_room = "$n is surrounded by a white aura.";
    break;

  case SPELL_SLEEP:
    if (!pk_allowed && !IS_NPC(ch) && !IS_NPC(victim))
      return;
    if (MOB_FLAGGED(victim, MOB_NOSLEEP))
      return;
    if (mag_savingthrow(victim, savetype, 0))
      return;

    af[0].duration = 4 + (GET_LEVEL(ch) / 4);
    af[0].bitvector = AFF_SLEEP;

    if (GET_POS(victim) > POS_SLEEPING) {
      send_to_char(victim, "You feel very sleepy...  Zzzz......\r\n");
      act("$n goes to sleep.", TRUE, victim, 0, 0, TO_ROOM);
      GET_POS(victim) = POS_SLEEPING;
    }
    break;

  case SPELL_STRENGTH:
    if (GET_ADD(victim) == 100)
      return;

    af[0].location = APPLY_STR;
    af[0].duration = (GET_LEVEL(ch) / 2) + 4;
    af[0].modifier = 1 + (level > 18);
    accum_duration = TRUE;
    accum_affect = TRUE;
    to_vict = "You feel stronger!";
    break;

  case SPELL_SENSE_LIFE:
    to_vict = "Your feel your awareness improve.";
    af[0].duration = GET_LEVEL(ch);
    af[0].bitvector = AFF_SENSE_LIFE;
    accum_duration = TRUE;
    break;

  case SPELL_WATERWALK:
    af[0].duration = 24;
    af[0].bitvector = AFF_WATERWALK;
    accum_duration = TRUE;
    to_vict = "You feel webbing between your toes.";
    break;
  }

  /*
   * If this is a mob that has this affect set in its mob file, do not
   * perform the affect.  This prevents people from un-sancting mobs
   * by sancting them and waiting for it to fade, for example.
   */
  if (IS_NPC(victim) && !affected_by_spell(victim, spellnum))
    for (i = 0; i < MAX_SPELL_AFFECTS; i++)
      if (AFF_FLAGGED(victim, af[i].bitvector)) {
	send_to_char(ch, "%s", NOEFFECT);
	return;
      }

  /*
   * If the victim is already affected by this spell, and the spell does
   * not have an accumulative effect, then fail the spell.
   */
  if (affected_by_spell(victim,spellnum) && !(accum_duration||accum_affect)) {
    send_to_char(ch, "%s", NOEFFECT);
    return;
  }

  for (i = 0; i < MAX_SPELL_AFFECTS; i++)
    if (af[i].bitvector || (af[i].location != APPLY_NONE))
      affect_join(victim, af+i, accum_duration, FALSE, accum_affect, FALSE);

  if (to_vict != NULL)
    act(to_vict, FALSE, victim, 0, ch, TO_CHAR);
  if (to_room != NULL)
    act(to_room, TRUE, victim, 0, ch, TO_ROOM);
}
Beispiel #3
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));
}
Beispiel #4
0
void
perform_psidrain(struct creature *ch, struct creature *vict)
{
    int find_distance(struct room_data *tmp, struct room_data *location);
    int dist, drain, prob, percent;

    if (!can_psidrain(ch, vict, &dist, true))
        return;


    if (AFF3_FLAGGED(vict, AFF3_PSISHIELD) && creature_distrusts(vict, ch)) {
        prob = CHECK_SKILL(ch, SKILL_PSIDRAIN) + GET_INT(ch);
        prob += skill_bonus(ch, SKILL_PSIDRAIN);

        percent = skill_bonus(vict, SPELL_PSISHIELD);
        percent += number(1, 120);

        if (mag_savingthrow(vict, GET_LEVEL(ch), SAVING_PSI))
            percent *= 2;

        if (GET_INT(vict) > GET_INT(ch))
            percent += (GET_INT(vict) - GET_INT(ch)) * 8;

        if (percent >= prob) {
            act("Your attack is deflected by $N's psishield!",
                false, ch, NULL, vict, TO_CHAR);
            act("$n's psychic attack is deflected by your psishield!",
                false, ch, NULL, vict, TO_VICT);
            act("$n staggers under an unseen force.",
                true, ch, NULL, vict, TO_NOTVICT);

            return;
        }
    }

    if (GET_MANA(vict) <= 0) {
        act("$E is completely drained of psychic energy.",
            true, ch, NULL, vict, TO_CHAR);
        return;
    }

    drain = dice(GET_LEVEL(ch), GET_INT(ch) + GET_REMORT_GEN(ch)) +
        CHECK_SKILL(ch, SKILL_PSIDRAIN);
    if (dist > 0)
        drain /= dist + 1;

    drain /= 4;

    drain = MAX(0, MIN(GET_MANA(vict), drain));

    prob = CHECK_SKILL(ch, SKILL_PSIDRAIN) + GET_INT(ch) +
        (AFF3_FLAGGED(vict, AFF3_PSISHIELD) ? -20 : 0);

    if (is_fighting(vict))
        prob += 15;

    if (dist > 0)
        prob -= dist * 3;

    act("$n strains against an unseen force.", false, ch, NULL, vict, TO_ROOM);

    //
    // failure
    //

    if (number(0, 121) > prob) {
        send_to_char(ch, "You are unable to create the drainage link!\r\n");
        WAIT_STATE(ch, 2 RL_SEC);

        if (IS_NPC(vict) && !is_fighting(vict)) {

            if (ch->in_room == vict->in_room) {
                add_combat(vict, ch, false);
                add_combat(ch, vict, true);
            } else {
                remember(vict, ch);
                if (NPC2_FLAGGED(vict, NPC2_HUNT))
                    start_hunting(vict, ch);
            }
        }
    }
    //
    // success
    //
    else {

        act("A torrent of psychic energy is ripped out of $N's mind!",
            false, ch, NULL, vict, TO_CHAR);
        if (ch->in_room != vict->in_room &&
            GET_LEVEL(vict) + number(0, CHECK_SKILL(vict, SKILL_PSIDRAIN)) >
            GET_LEVEL(ch))
            act("Your psychic energy is ripped from you from afar!",
                false, ch, NULL, vict, TO_VICT);
        else
            act("Your psychic energy is ripped from you by $n!",
                false, ch, NULL, vict, TO_VICT);
        GET_MANA(vict) -= drain;
        GET_MANA(ch) = MIN(GET_MAX_MANA(ch), GET_MANA(ch) + drain);
        GET_MOVE(ch) -= 20;
        WAIT_STATE(vict, 1 RL_SEC);
        WAIT_STATE(ch, 5 RL_SEC);
        gain_skill_prof(ch, SKILL_PSIDRAIN);

        if (IS_NPC(vict) && !(is_fighting(vict))) {
            if (ch->in_room == vict->in_room) {
                remember(vict, ch);
                if (NPC2_FLAGGED(vict, NPC2_HUNT))
                    start_hunting(vict, ch);
                add_combat(vict, ch, false);
                add_combat(ch, vict, true);
            }
        }
    }
}
Beispiel #5
0
/*
 * Remove an affected_type structure from a char (called when duration
 * reaches zero). Pointer *af must never be NIL!  Frees mem and calls
 * affect_location_apply
 */
void affect_remove(struct char_data * ch, struct affected_type * af, int output)
{
  struct affected_type *temp;
  struct affected_type aff;
  bool accum_affect = FALSE;
  int k;

  if (ch->affected == NULL) {
    core_dump();
    return;
  }

  switch (af->type)
  {

    case SPELL_CHARM:
    { 
      struct char_data* victim = ch->master;
      if (output == 0) break;

      affect_modify(ch, af->location, af->modifier, af->bitvector, FALSE);
      REMOVE_FROM_LIST(af, ch->affected, next);
      free(af);
      affect_total(ch);

      if (ch->master)
      {
        stop_follower(ch);
      }

      if (victim)
      {
        if(IS_NPC(ch))
        {
          SET_BIT(MOB_FLAGS(ch), MOB_AGGRESSIVE | MOB_MEMORY);
        }
        if (mag_savingthrow(victim, SAVING_SPELL))
        {
          hit(victim, ch, TYPE_UNDEFINED);
        }
      }
      return;
    }

    case SPELL_LIGHT:
      if (output == 0) break;
      if (!af->next || (af->next->type != af->type) ||
         (af->next->duration > 0)) 
      {
        if (world[ch->in_room].name != (char*) NULL)
        {
          world[ch->in_room].light -= 10;
        }
      }
      break;
    case SPELL_DARKNESS:
      if (output == 0) break;
      if (!af->next || (af->next->type != af->type) ||
         (af->next->duration > 0)) 
      {
        if (world[ch->in_room].name != (char*) NULL)
        {
          world[ch->in_room].light += 10;
        }
      }
      break;
    case SPELL_BLACK_PLAGUE:
      mag_affects(30, ch, ch, SPELL_BREATH_OF_LIFE, SAVING_SPELL);
      break;
    case SPELL_CALL_ANIMAL_SPIRIT:
    case SPELL_ANIMAL_SUMMONING:
    case SPELL_ANIMAL_SUMMONING_II:
    case SPELL_ANIMAL_SUMMONING_III:
    case SPELL_CONJURE_ELEMENTAL:
    case SPELL_GREATER_ELEMENTAL:
    case SPELL_DUST_DEVIL:
    case SPELL_STICKS_TO_SNAKES:
    case SPELL_SUMMON_INSECTS:
    case SPELL_AERIAL_SERVANT:
    case SPELL_SUMMON_GUARD:
      if (IS_NPC(ch))
      {
        if (GET_POS(ch) > POS_DEAD)
        {
          if (output == 1)
          {
            affect_modify(ch, af->location, af->modifier, af->bitvector, FALSE);
            REMOVE_FROM_LIST(af, ch->affected, next);
            free(af);
            affect_total(ch);

            GET_NAME(ch, chname);
	    stop_fighting(ch); /*Fighting Bug Fix Jasrags*/
            sprintf(buf, "%s disappears into thin air as the summoning ends.", 
              chname);
            act(buf, FALSE, world[ch->in_room].people, 0, 0, TO_ROOM);
            FREE_NAME(chname);
            extract_char(ch);
            ch = NULL;
            return;
          }
        }
      }
      break;
   case SPELL_POLYMORPH:
   if (!PRF_FLAGGED(ch, PRF_NOTSELF)) {
          affect_modify(ch, af->location, af->modifier, af->bitvector, FALSE);
          REMOVE_FROM_LIST(af, ch->affected, next);
          free(af);
          affect_total(ch);
          return;
   }
   break;
   case SPELL_DONTUSEME:
   if(AFF_FLAGGED(ch, AFF_STANCE) && !AFF_FLAGGED(ch, AFF_TIRED)) {
      aff.type = SKILL_STANCE;
      aff.duration = 2;
      aff.location = APPLY_STR;
      aff.modifier = -2;
      aff.bitvector = AFF_TIRED;
      accum_affect = FALSE;

      affect_to_char(ch, &aff);
    }
   break;
    default:
      break;
  }

  if (output && (af->type > 0) && (af->type <= MAX_SPELLS) && af->type != SPELL_POLYMORPH && af->type != SPELL_DONTUSEME) {
    if (!af->next || (af->next->type != af->type) ||
        (af->next->duration > 0)) {
      if (*spell_wear_off_msg[af->type]) {
        send_to_char(spell_wear_off_msg[af->type], ch);
        send_to_char("\r\n", ch);
      }
  }
}

if (output && (af->type > 0) && (af->type <= MAX_SPELLS) && af->type == SPELL_POLYMORPH)  {

  if (!af->next || (af->next->type != af->type) ||
        (af->next->duration > 0)) {
   if (PLR_FLAGGED(ch, PLR_RABBIT)){
REMOVE_BIT(PLR_FLAGS(ch), PLR_RABBIT);
REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);
send_to_char("You feel yourself growing, and your ears shrinking. You no longer feel like a rabbit.\r\n", ch);
act("$n's body grows, $s ears shrinking. $n no longer looks like a rabbit.\r\n", 0, ch, 0, 0, TO_ROOM);

}
if (PLR_FLAGGED(ch, PLR_BIRD)) {
REMOVE_BIT(PLR_FLAGS(ch), PLR_BIRD);
REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);
send_to_char("You feel yourself growing and your feathers falling away. You no longer feel like a bird.\r\n", ch);
act("$n's body grows, $s feathers falling away as it expands. $n no longer looks like a bird.\r\n", 0, ch, 0, 0, TO_ROOM);

}
if (PLR_FLAGGED(ch, PLR_WOLF)) {
REMOVE_BIT(PLR_FLAGS(ch), PLR_WOLF);
REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);
send_to_char("You feel your your fur shed and your teeth shrink. You no longer feel like a wolf.\r\n", ch);
act("$n's teeth shrink, $s fur shedding. $n no longer looks like a wolf.\r\n", 0, ch, 0, 0, TO_ROOM);
}
if (PLR_FLAGGED(ch, PLR_BEAR)) {
REMOVE_BIT(PLR_FLAGS(ch), PLR_BEAR);
REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);
send_to_char("Your claws shrink as does the rest of your body. You no longer feel like a bear.\r\n", ch);
act("$n's claws shrink as does the rest of $s body. $n no longer looks like a bear.\r\n", 0, ch, 0, 0, TO_ROOM);
}
if (PLR_FLAGGED(ch, PLR_CAT)){
REMOVE_BIT(PLR_FLAGS(ch), PLR_CAT);
REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);
send_to_char("You feel your body growing, and your fur shedding. You no longer feel like a cat.\r\n", ch);
act("$n's body slowly grows, $s fur shedding. $n no longer looks like a cat.\r\n", 0, ch, 0, 0, TO_ROOM);
}

for (k = 0; k < NUM_WEARS; k++)
  if (GET_EQ(ch, k)){
    GET_OBJ_DISGUISE(GET_EQ(ch, k)) = 0;
  }

}
} 

  affect_modify(ch, af->location, af->modifier, af->bitvector, FALSE);
  REMOVE_FROM_LIST(af, ch->affected, next);
  free(af);
  affect_total(ch);
}
Beispiel #6
0
/* the main engine of charm spell, and similar */
void effect_charm(struct char_data *ch, struct char_data *victim,
        int spellnum) {
  struct affected_type af;
  int elf_bonus = 0;

  if (!IS_NPC(victim) && (GET_RACE(victim) == RACE_ELF || //elven enchantment resistance
          GET_RACE(victim) == RACE_H_ELF)) // added check for IS_NPC because NPCRACE_HUMAN == RACE_ELF and NPCRACE_ABERRATION == RACE_H_ELF
    elf_bonus += 2;

  if (victim == ch)
    send_to_char(ch, "You like yourself even better!\r\n");

  else if (MOB_FLAGGED(victim, MOB_NOCHARM)) {
    send_to_char(ch, "Your victim doesn't seem vulnerable to this "
            "enchantments!\r\n");
    if (IS_NPC(victim))
      hit(victim, ch, TYPE_UNDEFINED, DAM_RESERVED_DBC, 0, FALSE);
  }
  
  else if (IS_AFFECTED(victim, AFF_MIND_BLANK)) {
    send_to_char(ch, "Your victim is protected from this "
            "enchantment!\r\n");
    if (IS_NPC(victim))
      hit(victim, ch, TYPE_UNDEFINED, DAM_RESERVED_DBC, 0, FALSE);
  }
  
  else if (AFF_FLAGGED(ch, AFF_CHARM))
    send_to_char(ch, "You can't have any followers of your own!\r\n");

  else if (AFF_FLAGGED(victim, AFF_CHARM))
    send_to_char(ch, "Your victim is already charmed.\r\n");

  else if (spellnum == SPELL_CHARM && (CASTER_LEVEL(ch) < GET_LEVEL(victim) ||
          GET_LEVEL(victim) >= 8))
    send_to_char(ch, "Your victim is too powerful.\r\n");

  else if ((spellnum == SPELL_DOMINATE_PERSON || spellnum == SPELL_MASS_DOMINATION) &&
          CASTER_LEVEL(ch) < GET_LEVEL(victim))
    send_to_char(ch, "Your victim is too powerful.\r\n");

    /* player charming another player - no legal reason for this */
  else if (!CONFIG_PK_ALLOWED && !IS_NPC(victim))
    send_to_char(ch, "You fail - shouldn't be doing it anyway.\r\n");

  else if (circle_follow(victim, ch))
    send_to_char(ch, "Sorry, following in circles is not allowed.\r\n");

  else if (mag_resistance(ch, victim, 0)) {
    send_to_char(ch, "You failed to penetrate the spell resistance!");
    if (IS_NPC(victim))
      hit(victim, ch, TYPE_UNDEFINED, DAM_RESERVED_DBC, 0, FALSE);
  }
  else if (mag_savingthrow(ch, victim, SAVING_WILL, elf_bonus)) {
    send_to_char(ch, "Your victim resists!\r\n");
    if (IS_NPC(victim))
      hit(victim, ch, TYPE_UNDEFINED, DAM_RESERVED_DBC, 0, FALSE);

  } else {
    /* slippery mind gives a second save */
    if (!IS_NPC(victim) && GET_SKILL(victim, SKILL_SLIPPERY_MIND)) {
      increase_skill(victim, SKILL_SLIPPERY_MIND);
      send_to_char(victim, "\tW*Slippery Mind*\tn  ");
      if (mag_savingthrow(ch, victim, SAVING_WILL, 0)) {
        return;
      }
    }

    if (victim->master)
      stop_follower(victim);

    add_follower(victim, ch);

    new_affect(&af);
    if (spellnum == SPELL_CHARM)
      af.spell = SPELL_CHARM;
    if (spellnum == SPELL_CHARM_ANIMAL)
      af.spell = SPELL_CHARM_ANIMAL;
    else if (spellnum == SPELL_DOMINATE_PERSON)
      af.spell = SPELL_DOMINATE_PERSON;
    else if (spellnum == SPELL_MASS_DOMINATION)
      af.spell = SPELL_MASS_DOMINATION;
    af.duration = 100;
    if (GET_CHA_BONUS(ch))
      af.duration += GET_CHA_BONUS(ch) * 4;
    SET_BIT_AR(af.bitvector, AFF_CHARM);
    affect_to_char(victim, &af);

    act("Isn't $n just such a nice fellow?", FALSE, ch, 0, victim, TO_VICT);
    //    if (IS_NPC(victim))
    //      REMOVE_BIT_AR(MOB_FLAGS(victim), MOB_SPEC);
  }
  // should never get here
}