Exemplo n.º 1
0
void do_confuse(CHAR_DATA *ch, char *argument) {

	CHAR_DATA *victim;

	if (IS_NPC(ch)) return;

	if (!IS_CLASS(ch, CLASS_DROW) || !IS_SET(ch->pcdata->powers[1], DPOWER_CONFUSE)) {
	send_to_char("Huh?\n\r",  ch);
	return;}

	if ((victim = ch->fighting) == NULL) {
	send_to_char("You are not fighting anyone.\n\r",  ch);
	return;}

	if (ch->move < 75) {
	send_to_char("You need 75 move to confuse your opponent.\n\r",ch);
	return;}

	act("$n attempts to confuse you.",ch,NULL,victim,TO_VICT);
	act("You attempt to confuse $N.",ch,NULL,victim,TO_CHAR);
	act("$n attempts to confuse $N.",ch,NULL,victim,TO_NOTVICT);

	ch->move -=75;

	if ( number_percent() > 25 ) {
	send_to_char("You failed.\n\r", ch );
	return;}

	else {
		do_flee(victim,"");	
	WAIT_STATE(ch, 16);
	return;	}

	return;
}
Exemplo n.º 2
0
int KyussSon( struct char_data *pChar, int nCmd, const char *szArg, 
              struct char_data *pMob, int nType )
{
  struct char_data *pTar;
  struct room_data *pRoom;

  if( pMob == NULL )
  {
    mudlog( LOG_SYSERR, "pMob == NULL in KyussSon( carceri.c )" );
    return FALSE;
  }

  if( nType == EVENT_TICK )
  {
    UpdateList( (CharElem **)&pMob->act_ptr );
    
    if( ( pRoom = real_roomp( pMob->in_room ) ) != NULL )
    {
      struct char_data *pNext;
      for( pTar = pRoom->people; pTar; pTar = pNext )
      {
        pNext = pTar->next_in_room;
        if( CAN_SEE( pTar, pMob ) && 
            !IsInList( (CharElem *)pMob->act_ptr, pTar ) && 
            ( ( IS_PC( pTar ) && 
                !IS_SET( pTar->specials.act, PLR_NOHASSLE ) ) ||
              ( IS_NPC( pTar ) && 
                ( ( pTar->specials.zone != pMob->specials.zone &&
                    !strchr( zone_table[ pTar->specials.zone ].races, 
                             GET_RACE( pTar ) ) ) ||
                  IS_SET( pTar->specials.act, ACT_ANNOYING ) ) ) ) )
        {
          if( !saves_spell( pTar, SAVING_PARA ) )
          {
            act( "Quando vedi $N, sei preso da un incontrollabile panico!",
                 TRUE, pTar, 0, pMob, TO_CHAR );
            do_flee( pTar, "", 0 );
          }
          else
          {
            InsertInList( (CharElem **)&pMob->act_ptr, pTar, 
                          ( SECS_PER_MUD_HOUR * 48 ) / PULSE_MOBILE );
          }
        }
      }
    }
    else
      mudlog( LOG_SYSERR, "pMob in invalid room in KyussSon( carceri.c )" );
  }
  else if( nType == EVENT_DEATH )
    FreeList( (CharElem **)&pMob->act_ptr );
  return FALSE;
}
Exemplo n.º 3
0
void mob_regen_check( CHAR_DATA * ch, CHAR_DATA * target, bool need_flee )
{
    char buf[MAX_STRING_LENGTH];

    if ( target == NULL )
        target = ch;

    if ( ch->mana >= mana_cost( ch, skill_lookup( "heal" ) ) )
        snprintf( buf, MSL, "'heal' %s", target->name.c_str() );
    else if ( ch->mana >= mana_cost( ch, skill_lookup( "cure critical" ) ) )
        snprintf( buf, MSL, "'cure critical' %s", target->name.c_str() );
    else if ( ch->mana >= mana_cost( ch, skill_lookup( "cure serious" ) ) )
        snprintf( buf, MSL, "'cure serious' %s", target->name.c_str() );
    else if ( need_flee == TRUE )
    {
        do_flee( ch, "" );
        return;
    }
    else if ( need_flee == FALSE )
        return;

    do_cast( ch, buf );
    return;
}
Exemplo n.º 4
0
/* do_simple_move assumes
 *    1. That there is no master and no followers.
 *    2. That the direction exists.
 *
 *   Returns :
 *   1 : If succes.
 *   0 : If fail
 */
int do_simple_move(struct char_data *ch, int dir, int need_specials_check)
{
  room_rnum was_in;
  struct char_data *i;
  /*
   * Check for special routines (North is 1 in command list, but 0 here) Note
   * -- only check if following; this avoids 'double spec-proc' bug
   */
  if (need_specials_check && special(ch, dir + 1, "")) { 
    return (0);
  }

  /* charmed? */
  if (AFF_FLAGGED(ch, AFF_CHARM) && ch->master && ch->in_room == ch->master->in_room) {
    send_to_char("The thought of leaving your master makes you weep.\r\n", ch);
    act("$n bursts into tears.", FALSE, ch, 0, 0, TO_ROOM);
    return (0);
  }

  /* if this room or the one we're going to needs a boat, check for one */
  if ((SECT(ch->in_room) == SECT_WATER_NOSWIM) ||
      (SECT(EXIT(ch, dir)->to_room) == SECT_WATER_NOSWIM)) {
    if (!has_boat(ch)) {
      send_to_char("You need a boat to go there.\r\n", ch);
      return (0);
    }
  }

  if((IS_CARRYING_W(ch) > (CAN_CARRY_W(ch) * 2) && GET_LEVEL(ch) < LVL_GOD && !IS_NPC(ch))) {
    send_to_char("You are to heavy to move! Drop something!\r\n", ch);
    return (0);
  }
  
  if(IS_NPC_FISH(ch)) {
    if(SECT(EXIT(ch, dir)->to_room) != SECT_BRIDGE && SECT(EXIT(ch, dir)->to_room) != SECT_WATER_SWIM && SECT(EXIT(ch, dir)->to_room) !=  SECT_WATER_NOSWIM) {
//       sprintf(buf, "%s %d", dirs[dir], SECT(EXIT(ch, dir)->to_room));
//       mobsay(ch, buf);
       return FALSE;

     }
     if(GET_MOB_VNUM(ch) < 1500 && ROOM_FLAGGED(EXIT(ch, dir)->to_room, ROOM_SALT_FISH)) {
       return FALSE;
     }
   }

  if (SECT(EXIT(ch, dir)->to_room) != SECT_FOREST) {
    if (IS_NPC_WOLF(ch) || IS_NPC_CRAB(ch) || IS_NPC_SKELETON(ch)) {
       return (0);
   }
  }

  /* move points needed is avg. move loss for src and destination sect type */
  if (ROOM_FLAGGED(EXIT(ch, dir)->to_room, ROOM_TUNNEL) &&
      num_pc_in_room(&(world[EXIT(ch, dir)->to_room])) > 1) {
    send_to_char("There isn't enough room there for more than one person!\r\n", ch);
    return (0);
  }
  /* Mortals and low level gods cannot enter greater god rooms. */
  if (ROOM_FLAGGED(EXIT(ch, dir)->to_room, ROOM_GODROOM) &&
	GET_LEVEL(ch) < LVL_GRGOD) {
    send_to_char("You aren't godly enough to use that room!\r\n", ch);
    return (0);
  }


  /* Now we know we're allow to go into the room. */

  if(AFF_FLAGGED(ch, AFF_FISHING) || GET_FISHON(ch)) {
    REMOVE_BIT(AFF_FLAGS(ch), AFF_FISHING);
    GET_FISHON(ch) = 0;
    GET_REELIN(ch) = 0;
    send_to_char("You stop fishing.\r\n", ch);
    act("$n stops fishing.", FALSE, ch, 0, 0, TO_ROOM);
  }

  if (!AFF_FLAGGED(ch, AFF_SNEAK) && !AFF_FLAGGED(ch, AFF_INVISIBLE)) {
    if(IS_NPC(ch)) { 
      switch(GET_RACE(ch)) {
        case RACE_NPC_MAMMAL:
        case RACE_NPC_HIGHHUMAN:
        case RACE_NPC_GOBLIN:
        case RACE_NPC_PIG:
        case RACE_NPC_WOLF:
        case RACE_NPC_CHICKEN:
          sprintf(buf2, "$n walks %s.", dirs[dir]);
          break;
        case RACE_NPC_AVIAN:
          sprintf(buf2, "$n flits %s.", dirs[dir]); 
          break;
        case RACE_NPC_SHEEP:
        case RACE_NPC_GOAT:
          sprintf(buf2, "$n walks %s.", dirs[dir]);
          break;
        case RACE_NPC_SKELETON:
          sprintf(buf2, "$n shambles %s.", dirs[dir]);
          break;
        case RACE_NPC_COW:
          sprintf(buf2, "$n walks %s.", dirs[dir]);
          break;
        case RACE_NPC_CRAB:
          sprintf(buf2, "$n scurries %s.", dirs[dir]);
          break;
        case RACE_NPC_FISH:
          sprintf(buf2, "$n swims %s.", dirs[dir]);
          break;
        case RACE_NPC_INSECT:
          sprintf(buf2, "$n buzzes %s.", dirs[dir]);
          break;
        default:
          sprintf(buf2, "$n leaves %s.", dirs[dir]);
          break;
      }
    }
    else {
       sprintf(buf2, "$n leaves %s.", dirs[dir]);
    }
    if(SECT(ch->in_room) == SECT_WATER_SWIM && !IS_NPC_FISH(ch)) {
       sprintf(buf2, "$n splashes through the water, heading %s.", dirs[dir]);
    }
    act(buf2, FALSE, ch, 0, 0, TO_ROOM);
  }
  was_in = ch->in_room;


  char_from_room(ch);
  char_to_room(ch, world[was_in].dir_option[dir]->to_room);

  if (!AFF_FLAGGED(ch, AFF_SNEAK)) {
    if(!AFF_FLAGGED(ch, AFF_INVISIBLE)) {
      act("$n has arrived.", FALSE, ch, 0, 0, TO_ROOM);
    }
  }
  if (ch->desc != NULL)
    look_at_room(ch, 0);

  if(IS_NPC_CRAB(ch) || IS_NPC_LIVESTOCK(ch)) {
    for (i = world[ch->in_room].people; i; i = i->next_in_room) {
    
       if(IS_NPC_WOLF(i) && IS_NPC_CRAB(ch)) {
            sprintf(buf, "%s sees %s and tries to run!\r\n", GET_NAME(ch), GET_NAME(i));
            send_to_room(buf, ch->in_room);
            if(!number(0, 2)) {
              do_flee(ch, NULL, 0, 0);
            }
            if(i->in_room == ch->in_room && !number(0, 2)) {
              hit(i, ch, TYPE_UNDEFINED);
            }
      }
      if((IS_NPC_SKELETON(i) || IS_NPC_WOLF(i)) && IS_NPC_LIVESTOCK(ch)) {
          if(ch->master) {
            sprintf(buf, "%s sees %s and %s in absolute terror!\r\n", GET_NAME(ch), GET_NAME(i), livestock_afraid_vocals[(int)GET_RACE(ch)]);
            send_to_room(buf, ch->in_room);
            if(!number(0, 2)) {
              do_flee(ch, NULL, 0, 0);
            }
            if(i->in_room == ch->in_room && !number(0, 2)) {
              hit(i, ch, TYPE_UNDEFINED);
            }
          }
      }
    }
    return (1);
  }
  if (ROOM_FLAGGED(ch->in_room, ROOM_DEATH) && GET_LEVEL(ch) < LVL_IMMORT) {
    log_death_trap(ch);
    death_cry(ch);
    extract_char(ch);
    return (0);
  }
  return (1);
}
Exemplo n.º 5
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);
}
Exemplo n.º 6
0
bool sp_damage( OBJ_DATA * obj, CHAR_DATA * ch, CHAR_DATA * victim, int dam, int type, int sn, bool show_msg )
{
    int ch_strong, ch_weak, ch_race, ch_suscept, ch_resist, vi_strong, vi_weak, vi_race, vi_suscept, vi_resist;
    float dam_modifier = 1.0;
    float tmp = 0;
    bool can_reflect = TRUE;
    bool can_absorb = TRUE;

    if ( victim == NULL )
        return FALSE;

    /*
     *  First, check caster's strengths and weaknesses.
     *
     */

    if ( IS_SET( type, NO_REFLECT ) )
    {
        REMOVE_BIT( type, NO_REFLECT );
        can_reflect = FALSE;
    }
    if ( IS_SET( type, NO_ABSORB ) )
    {
        REMOVE_BIT( type, NO_ABSORB );
        can_absorb = FALSE;
    }
    if ( obj == NULL )
    {
        if ( ( can_reflect )
                && ( skill_table[sn].target == TAR_CHAR_OFFENSIVE )
                && ( IS_AFFECTED( victim, AFF_CLOAK_REFLECTION ) )
                && ( ch != victim ) && ( number_percent(  ) < ( victim->get_level("psuedo") - 70 ) ) )
        {

            act( "@@N$n's @@lc@@el@@ro@@ya@@ak@@N glows brightly as $Nn's spell hits it, and the spell is reflected@@N!!", ch,
                 victim, NULL, TO_ROOM );
            act( "@@N$N's @@lc@@el@@ro@@ya@@ak@@N glows brightly, and reflects your spell back on you@@N!!", ch, NULL, victim,
                 TO_CHAR );
            act( "@@NYour @@lc@@el@@ro@@ya@@ak@@N glows brightly, and reflects the spell back on $N@@N!!!", victim, NULL, ch,
                 TO_CHAR );
            ( *skill_table[sn].spell_fun ) ( sn, 60, ch, ( void * )ch, NULL );
            return FALSE;

        }


        else if ( ( can_reflect )
                  && ( skill_table[sn].target == TAR_CHAR_OFFENSIVE )
                  && ( IS_AFFECTED( victim, AFF_CLOAK_ABSORPTION ) )
                  && ( ch != victim ) && ( number_percent(  ) < ( victim->get_level("psuedo") - 55 ) ) )
        {
            int mana;
            mana = mana_cost( ch, sn );
            victim->mana = UMIN( victim->max_mana, victim->mana + mana );

            act( "@@N$n's @@lcloak@@N glows brightly as $N's spell hits it, then fades@@N!!", victim, NULL, ch, TO_ROOM );
            act( "@@N$N's @@lcloak@@N glows brightly, and absorbs your spell@@N!!", ch, NULL, victim, TO_CHAR );
            act( "@@NYour @@lcloak@@N glows brightly, and absorbs $N's spell@@N!!!", victim, NULL, ch, TO_CHAR );
            return FALSE;
        }




        ch_strong = ( IS_NPC( ch ) ?
                      ( ( ( ch->race > 0 )
                          && ( ch->race < MAX_RACE ) ) ?
                        race_table[ch->race].strong_realms : ch->npcdata->strong_magic ) : race_table[ch->race].strong_realms );
        ch_resist = ( IS_NPC( ch ) ?
                      ( ( ( ch->race > 0 )
                          && ( ch->race < MAX_RACE ) ) ?
                        race_table[ch->race].resist_realms : ch->npcdata->resist ) : race_table[ch->race].resist_realms );
        ch_weak = ( IS_NPC( ch ) ?
                    ( ( ( ch->race > 0 )
                        && ( ch->race < MAX_RACE ) ) ?
                      race_table[ch->race].weak_realms : ch->npcdata->weak_magic ) : race_table[ch->race].weak_realms );
        ch_suscept = ( IS_NPC( ch ) ?
                       ( ( ( ch->race > 0 )
                           && ( ch->race < MAX_RACE ) ) ?
                         race_table[ch->race].suscept_realms : ch->npcdata->suscept ) : race_table[ch->race].suscept_realms );
        ch_race = ( IS_NPC( ch ) ?
                    ( ( ( ch->race > 0 )
                        && ( ch->race < MAX_RACE ) ) ?
                      race_table[ch->race].race_flags : ch->race_mods ) : race_table[ch->race].race_flags );

        if ( IS_SET( ch_strong, type ) )
        {
            dam_modifier += .35;
        }
        else if ( IS_SET( ch_weak, type ) )
        {
            dam_modifier -= .35;
        }

        if ( IS_SET( ch_race, RACE_MOD_STRONG_MAGIC ) )
        {
            dam_modifier += .25;
        }
        else if ( IS_SET( ch_race, RACE_MOD_WEAK_MAGIC ) )
        {
            dam_modifier -= .25;
        }
        else if ( IS_SET( ch_race, RACE_MOD_NO_MAGIC ) )
        {
            dam_modifier -= .50;
        }

        if ( ch->stance == STANCE_CASTER )
            dam_modifier += .10;
        else if ( ch->stance == STANCE_WIZARD )
            dam_modifier += .25;
        else if ( ch->stance == STANCE_MAGI )
            dam_modifier += .30;

        if ( ( !IS_NPC( ch ) ) && ( !IS_SET( type, REALM_MIND ) ) )
        {
            if ( ch->pcdata->learned[gsn_potency] > 0 )
            {
                dam_modifier += ( get_curr_int( ch ) * ch->pcdata->learned[gsn_potency] / 5000 );
            }

            if ( ch->pcdata->learned[gsn_thaumatergy] > 0 )
            {
                dam_modifier += ( get_curr_int( ch ) * ch->pcdata->learned[gsn_thaumatergy] / 2500 );
            }
        }
        if ( is_affected( ch, skill_lookup( "mystical focus" ) ) )
        {
            dam_modifier += .5;
        }
    }  /* obj == NULL */
    else if ( obj->carried_by != NULL )
    {
        ch = obj->carried_by;
    }
    else
    {
        snprintf( log_buf, (2 * MIL), "Error, object %s casting spell, but not carried by anyone.", obj->short_descr );
        monitor_chan( log_buf, MONITOR_DEBUG );
        return FALSE;
    }

    /*
     *  Next, the victim
     *
     */
    vi_strong = ( IS_NPC( victim ) ?
                  ( ( ( victim->race > 0 )
                      && ( victim->race < MAX_RACE ) ) ?
                    race_table[victim->race].strong_realms :
                    victim->npcdata->strong_magic ) : race_table[victim->race].strong_realms );
    vi_resist = ( IS_NPC( victim ) ?
                  ( ( ( victim->race > 0 )
                      && ( victim->race < MAX_RACE ) ) ?
                    race_table[victim->race].resist_realms : victim->npcdata->resist ) : race_table[victim->race].resist_realms );
    vi_weak = ( IS_NPC( victim ) ?
                ( ( ( victim->race > 0 )
                    && ( victim->race < MAX_RACE ) ) ?
                  race_table[victim->race].weak_realms : victim->npcdata->weak_magic ) : race_table[victim->race].weak_realms );
    vi_suscept = ( IS_NPC( victim ) ?
                   ( ( ( victim->race > 0 )
                       && ( victim->race < MAX_RACE ) ) ?
                     race_table[victim->race].suscept_realms : victim->npcdata->suscept ) : race_table[victim->race].suscept_realms );
    vi_race = ( IS_NPC( victim ) ?
                ( ( ( victim->race > 0 )
                    && ( victim->race < MAX_RACE ) ) ?
                  race_table[victim->race].race_flags : victim->race_mods ) : race_table[victim->race].race_flags );

    if ( IS_SET( vi_suscept, type ) )
    {
        dam_modifier += .45;
    }
    else if ( IS_SET( vi_resist, type ) )
    {
        dam_modifier -= .45;
    }

    else if ( IS_SET( vi_race, RACE_MOD_NO_MAGIC ) )
    {
        dam_modifier -= .25;
    }

    if ( MAGIC_STANCE( ch ) )
        dam_modifier += .15;

    if ( ( IS_SET( type, REALM_MIND ) ) && ( !HAS_MIND( victim ) ) )
        dam_modifier = 0.0;
    else if ( ( ( IS_SET( type, REALM_IMPACT ) )
                || ( IS_SET( type, REALM_ACID ) ) || ( IS_SET( type, REALM_GAS ) ) ) && ( !HAS_BODY( victim ) ) )
        dam_modifier = 0.0;

    if ( ( IS_SET( type, REALM_POISON ) ) && ( IS_SET( vi_race, RACE_MOD_IMMUNE_POISON ) ) )
        dam_modifier = 0.0;

    if ( ( IS_SET( type, REALM_DRAIN ) ) && ( IS_UNDEAD( victim ) ) )
        dam_modifier = 0.0;

    tmp = dam;
    tmp *= dam_modifier;

    if ( check_charm_aff(ch, CHARM_AFF_MAGE) )
        tmp *= ((100 + get_charm_bonus(ch, CHARM_AFF_MAGE)) / 100);

    dam = static_cast<int>(tmp);
    dam += number_range(static_cast<int>((dam * -0.10)), static_cast<int>((dam * 0.10))); /* Lets add a little randomness to things. --Kline */

    if ( victim != ch )
    {
        /*
         * Certain attacks are forbidden.
         * Most other attacks are returned.
         */
        if ( is_safe( ch, victim ) )
            return FALSE;
        if ( victim != ch->fighting )
            check_killer( ch, victim );

        if ( victim->position > POS_STUNNED )
        {
            if ( victim->fighting == NULL )
                set_fighting( victim, ch, FALSE );
            victim->position = POS_FIGHTING;
        }

        if ( victim->position > POS_STUNNED )
        {
            if ( ch->fighting == NULL )
            {
                set_fighting( ch, victim, TRUE );
            }


            /*
             * If victim is charmed, ch might attack victim's master.
             */
            if ( IS_NPC( ch )
                    && IS_NPC( victim )
                    && IS_AFFECTED( victim, AFF_CHARM )
                    && victim->master != NULL && victim->master->in_room == ch->in_room && number_bits( 3 ) == 0 )
            {
                stop_fighting( ch );
                one_hit( ch, victim->master, TYPE_UNDEFINED );
            }
        }

        /*
         * More charm stuff.
         */
        if ( victim->master == ch )
            stop_follower( victim );

        /*
         * Inviso attacks ... not.
         */
        if ( IS_AFFECTED( ch, AFF_INVISIBLE ) )
        {
            affect_strip( ch, gsn_invis );
            affect_strip( ch, gsn_mass_invis );
            REMOVE_BIT( ch->affected_by, AFF_INVISIBLE );
            act( "$n shimmers into existence.", ch, NULL, NULL, TO_ROOM );
        }

        /*
         * Damage modifiers.
         */

        if ( dam < 0 )
            dam = 0;

        /*
         * Stop up any residual loopholes.
         */
        if ( dam > sysdata.damcap )
        {
            char buf[MAX_STRING_LENGTH];
            snprintf( buf, MSL, "Spell: %d damage by %s, spell %s", dam, ( obj == NULL ) ? ch->get_name() : obj->short_descr, skill_table[sn].name );
            if ( ch->level < 82 )
                monitor_chan( buf, MONITOR_MAGIC );
            log_f( "%s", buf );
            dam = sysdata.damcap;
        }


        if ( ( show_msg ) && ( dam >= 0 ) )
            sp_dam_message( obj, ch, victim, dam, type, sn );

    }

    /*
     * Hurt the victim.
     * Inform the victim of his new state.
     */
    victim->hit -= dam;

    if ( !IS_NPC(ch) )
    {
        if ( dam > ch->pcdata->records->mdam_amt )
        {
            send_to_char("@@yYou've broken your magical damage record!@@N\r\n", ch);
            ch->pcdata->records->mdam_amt = dam;
            ch->pcdata->records->mdam_gsn = sn;
        }
    }

    if ( !IS_NPC( victim ) )
        check_adrenaline( victim, dam );

    if ( !IS_NPC( victim ) && IS_WOLF( victim ) && ( dam > 350 ) )
        do_rage( victim, "FORCE" );

    update_pos( victim );

    if ( ( IS_NPC( victim ) || !IS_VAMP( victim ) ) && !( deathmatch ) )
    {
        switch ( victim->position )
        {
            case POS_MORTAL:
                act( "$n is mortally wounded, and will die soon, if not aided.", victim, NULL, NULL, TO_ROOM );
                send_to_char( "You are mortally wounded, and will die soon, if not aided.\r\n", victim );
                break;

            case POS_INCAP:
                act( "$n is incapacitated and will slowly die, if not aided.", victim, NULL, NULL, TO_ROOM );
                send_to_char( "You are incapacitated and will slowly die, if not aided.\r\n", victim );
                break;

            case POS_STUNNED:
                act( "$n is too stunned to do anything!", victim, NULL, NULL, TO_ROOM );
                send_to_char( "You are too stunned to do anything!\r\n", victim );
                break;

            case POS_DEAD:
                act( "$n is DEAD!!", victim, 0, 0, TO_ROOM );
                send_to_char( "You have been KILLED!!\r\n\r\n", victim );
                break;

            default:
                if ( dam > victim->max_hit / 4 )
                    send_to_char( "That really did HURT!\r\n", victim );
                if ( victim->hit < victim->max_hit / 4 )
                    send_to_char( "You sure are BLEEDING!\r\n", victim );
                break;
        }
    }  /* end of if statement */
    /*
     * Sleep spells and extremely wounded folks.
     */
    if ( !IS_AWAKE( victim ) )
        stop_fighting( victim );

    /*
     * Payoff for killing things.
     */



    if ( victim->position == POS_DEAD && ( IS_NPC( victim ) || !IS_VAMP( victim ) || ( deathmatch ) ) )
    {
        group_gain( ch, victim );

        /*
         * Sort out kill counts.....
         */
        if ( !IS_NPC( ch ) )
        {
            if ( !IS_NPC( victim ) )
                ch->pcdata->records->pk++;
            else
                ch->pcdata->records->mk++;
        }

        if ( !IS_NPC( victim ) )
        {
            if ( !IS_NPC( ch ) )
                victim->pcdata->records->pd++;
            else
                victim->pcdata->records->md++;
        }

        if ( !IS_NPC( victim ) || victim->act.test(ACT_INTELLIGENT) )
        {


            snprintf( log_buf, (2 * MIL), "%s killed by %s at %d", victim->get_name(), ch->get_name(), victim->in_room->vnum );
            log_string( log_buf );

            notify( log_buf, 82 );

            /*
             * As level gain is no longer automatic, a dead char loses
             * * 1/2 their gained exp.  -S-
             * * Fixed my bug here too, hehe!
             */

            if ( victim->exp > 0 )
            {
                int lose = (victim->exp / 2);
                lose *= -1;
                victim->gain_exp(lose);
            }

        }

        if ( IS_NPC( ch ) )
            raw_kill( victim, "" );
        else
        {
            char name_buf[MAX_STRING_LENGTH];
            snprintf( name_buf, MSL, "%s", ch->name.c_str() );
            raw_kill( victim, name_buf );
        }

        if ( deathmatch && !IS_NPC( victim ) )
            do_quit( victim, "" );

        if ( IS_NPC( ch ) && IS_NPC( victim ) && ch->act.test(ACT_INTELLIGENT) )
        {
            do_get( ch, "all corpse" );
            do_sacrifice( ch, "corpse" );
        }

        if ( !IS_NPC( ch ) && IS_NPC( victim ) )
        {
            if ( ch->act.test(ACT_AUTOLOOT) )
                do_get( ch, "all corpse" );
            else
                do_look( ch, "in corpse" );

            if ( ch->act.test(ACT_AUTOSAC) )
                do_sacrifice( ch, "corpse" );
        }

        return FALSE;
    }

    if ( victim == ch )
        return TRUE;

    /*
     * Take care of link dead people.
     */
    if ( !IS_NPC( victim ) && victim->desc == NULL )
    {
        if ( number_range( 0, victim->wait ) == 0 )
        {
            do_recall( victim, "" );
            return TRUE;
        }
    }

    /*
     * Wimp out?
     */
    if ( IS_NPC( victim ) && dam > 0 )
    {
        if ( ( victim->act.test(ACT_WIMPY) && number_bits( 1 ) == 0
                && victim->hit < victim->max_hit / 2 )
                || ( IS_AFFECTED( victim, AFF_CHARM ) && victim->master != NULL && victim->master->in_room != victim->in_room ) )
            do_flee( victim, "" );
    }

    if ( !IS_NPC( victim ) && victim->hit > 0 && victim->hit <= victim->wimpy && victim->wait == 0 )
        do_flee( victim, "" );

    return TRUE;

}
Exemplo n.º 7
0
/* i have condensed this function to just three states: MOB_FIGHTING,
 * MOB_RESTING/ MOB_SLEEPING, and MOB_STANDING. each of these three states
 * will call it's appropriate function. */
void int_group_handler( NPC_GROUP_DATA * ngroup )
{
    CHAR_DATA *follower = NULL;
    CHAR_DATA *leader = ngroup->leader;
    DL_LIST *follower_ptr;
//  short followers_want = GRP_STATE_NO_CHANGE;
    short leader_wants = GRP_STATE_NO_CHANGE;
    short group_count = 1; // start with leader
    char monbuf[MSL];

    if ( leader == NULL )
    {
        monitor_chan( "No Leader in NPC_GROUP", MONITOR_MOB );
        return;
    }

// check for followers needs
    for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next )
    {
        // check for needing healing, levelling
        follower = (CHAR_DATA *)follower_ptr->this_one;
        group_count++;
        continue;
    }

// check for leader's needs

    if ( leader->hit < leader->max_hit * 25 / 100 )
    {
        leader_wants = GRP_STATE_CRIT_HEAL;
    }
    else if ( leader->mana < leader->max_mana * 25 / 100 )
    {
        leader_wants = GRP_STATE_CRIT_MANA;
    }
    else if ( leader->hit < leader->max_hit * 60 / 100 )
    {
        leader_wants = GRP_STATE_NORM_HEAL;
    }
    else if ( leader->mana < leader->max_mana * 50 / 100 )
    {
        leader_wants = GRP_STATE_NORM_MANA;
    }
    else if ( able_to_level( leader ) )
    {
        leader_wants = GRP_STATE_LEVELING;
    }
    snprintf( monbuf, MSL, "NPC Group Handler, Leader is %s, state is %s", ngroup->leader->name.c_str(), group_state_table[ngroup->state] );
    monitor_chan( monbuf, MONITOR_MOB );

    switch ( ngroup->state )
    {


        case GRP_STATE_CRIT_HEAL:
        case GRP_STATE_CRIT_MANA:
        case GRP_STATE_NORM_HEAL:
        case GRP_STATE_NORM_MANA:
            {
                bool everyone_ready = TRUE;
                bool room_ready = FALSE;
//      ready_heal_room( leader );
                if ( ( leader->mana < leader->max_mana * 85 / 100 ) || ( leader->hit < leader->max_hit * 85 / 100 ) )
                {
                    everyone_ready = FALSE;
                    if ( ( ( room_ready = ready_heal_room( leader ) ) == TRUE ) || ( leader->mana < leader->max_mana * 20 / 100 ) )
                    {
                        do_sleep( leader, "" );
                    }
                }
                else
                {
                    do_stand( leader, "" );
                }
                for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next )
                {
                    follower = (CHAR_DATA *)follower_ptr->this_one;
                    if ( ( follower->mana < follower->max_mana * 75 / 100 ) || ( follower->hit < follower->max_hit * 75 / 100 ) )
                    {
                        everyone_ready = FALSE;
                        do_sleep( follower, "" );
                    }
                    else
                    {
                        do_stand( follower, "" );
                    }
                }
                if ( everyone_ready == TRUE )
                {
                    ngroup->state = GRP_STATE_IDLE;
                }
                break;
            }
        case GRP_STATE_FIGHT:
            {  // violence_update will handle
                if ( ( leader_wants < GRP_STATE_HUNTING ) || ( leader->fighting == NULL ) )
                {
                    bool someone_still_fighting = FALSE;

                    ngroup->state = GRP_STATE_FLEE;
                    for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next )
                    {
                        follower = (CHAR_DATA *)follower_ptr->this_one;
                        if ( follower->fighting != NULL )
                        {
                            do_flee( follower, "" );
                            someone_still_fighting = TRUE;
                        }
                    }
                    if ( someone_still_fighting == FALSE )
                    {
                        ngroup->state = GRP_STATE_REFORM;
                    }
                    if ( leader->fighting != NULL )
                    {
                        do_flee( leader, "" );
                    }
                }

                break;
            }

        case GRP_STATE_FLEE:
            {
                bool someone_still_fighting = FALSE;
                for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next )
                {
                    follower = (CHAR_DATA *)follower_ptr->this_one;
                    if ( follower->fighting != NULL )
                    {
                        do_flee( follower, "" );
                        someone_still_fighting = TRUE;
                    }
                }
                if ( leader->fighting != NULL )
                {
                    do_flee( leader, "" );
                    someone_still_fighting = TRUE;
                }
                if ( someone_still_fighting == FALSE )
                {
                    ngroup->state = GRP_STATE_REFORM;
                }

                break;
            }
        case GRP_STATE_IDLE:
            {
//      check_re_equip( leader );
//      check_rewield( leader );
                if ( leader_wants < GRP_STATE_NO_CHANGE )
                {
                    ngroup->state = leader_wants;
                    break;
                }
                else if ( number_percent(  ) < 40 )
                {
                    select_target( ngroup->leader );
                    ngroup->state = GRP_STATE_HUNTING;
                    break;
                }
            }
        case GRP_STATE_HUNTING:
            {  // poll followers later
                short move_dir;

                if ( leader->fighting != NULL )
                {
                    ngroup->state = GRP_STATE_FIGHT;
                    break;
                }
                if ( leader->hunting == NULL )
                {
//        snprintf( monbuf, MSL, "Leader %s not hunting anything in GRP_STATE_HUNTING",
//              leader->name );
//        monitor_chan( monbuf, MONITOR_MOB );
                    select_target( ngroup->leader );
                    break;
                }
                if ( leader->in_room == leader->hunting->in_room )
                {
                    ngroup->state = GRP_STATE_FIGHT;
                    one_hit( leader, leader->hunting, TYPE_UNDEFINED );
                    break;
                }
                move_dir = h_find_dir( leader->in_room, leader->hunting->in_room,
                                       HUNT_WORLD | HUNT_OPENDOOR | HUNT_UNLOCKDOOR | HUNT_PICKDOOR );
                if ( move_dir < 0 )  // can't get there from here
                {
                    ngroup->state = GRP_STATE_LOST;
                    break;
                }
                hunt_move( leader, move_dir );
                break;
            }
        case GRP_STATE_LEVELING:
            {
                char_from_room( leader );
                char_to_room( leader, get_room_index( 3758 ) );
                if ( able_to_level( leader ) )
                {
                    gain_level( leader );
                }
                for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next )
                {
                    follower = (CHAR_DATA *)follower_ptr->this_one;
                    if ( able_to_level( follower ) )
                    {
                        gain_level( follower );
                    }
                }
                ngroup->state = GRP_STATE_IDLE;
                break;
            }
        case GRP_STATE_REFORM:
            {
                bool all_are_here = TRUE;
                for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next )
                {
                    follower = (CHAR_DATA *)follower_ptr->this_one;
                    if ( follower->in_room != leader->in_room )
                    {
                        short move_dir;
                        all_are_here = FALSE;
                        move_dir = h_find_dir( follower->in_room, leader->in_room,
                                               HUNT_WORLD | HUNT_OPENDOOR | HUNT_UNLOCKDOOR | HUNT_PICKDOOR );
                        if ( move_dir < 0 )  // can't get there from here
                        {
                            ngroup->state = GRP_STATE_LOST;
                            break;
                        }
                        hunt_move( follower, move_dir );
                    }
                }
                if ( all_are_here == TRUE )
                {
                    ngroup->state = GRP_STATE_IDLE;
                }
                break;
            }

    }
}
Exemplo n.º 8
0
void damage(struct char_data *ch, struct char_data *victim,
            int dam, int attacktype)
{
	char buf[MAX_STRING_LENGTH];
	struct message_type *messages;
	int i,j,nr,max_hit,exp;

	int hit_limit(struct char_data *ch);

	assert(GET_POS(victim) > POSITION_DEAD);

	if ((GET_LEVEL(victim)>20) && !IS_NPC(victim)) /* You can't damage an immortal! */
		dam=0;
		
	if (victim != ch) {
		if (GET_POS(victim) > POSITION_STUNNED) {
			if (!(victim->specials.fighting))
				set_fighting(victim, ch);
			GET_POS(victim) = POSITION_FIGHTING;
		}

		if (GET_POS(ch) > POSITION_STUNNED) {
			if (!(ch->specials.fighting))
				set_fighting(ch, victim);

			if (IS_NPC(ch) && IS_NPC(victim) &&
          victim->master &&
			    !number(0,10) && IS_AFFECTED(victim, AFF_CHARM) &&
			    (victim->master->in_room == ch->in_room)) {
				if (ch->specials.fighting)
					stop_fighting(ch);
				hit(ch, victim->master, TYPE_UNDEFINED);
				return;
			}
		}
	}

	if (victim->master == ch)
		stop_follower(victim);
			
	if (IS_AFFECTED(ch, AFF_INVISIBLE))
		appear(ch);

	if (IS_AFFECTED(victim, AFF_SANCTUARY))
		dam = MIN(dam, 18);  /* Max 18 damage when sanctuary */

	dam=MIN(dam,100);

	dam=MAX(dam,0);

	GET_HIT(victim)-=dam;

	if (ch != victim)
		gain_exp(ch,GET_LEVEL(victim)*dam);

	update_pos(victim);


	if ((attacktype >= TYPE_HIT) && (attacktype <= TYPE_SLASH)) {
		if (!ch->equipment[WIELD]) {
			dam_message(dam, ch, victim, TYPE_HIT);
		} else {
			dam_message(dam, ch, victim, attacktype);
		}
	} else {

	for(i = 0; i < MAX_MESSAGES; i++) {
		if (fight_messages[i].a_type == attacktype) {
			nr=dice(1,fight_messages[i].number_of_attacks);
			for(j=1,messages=fight_messages[i].msg;(j<nr)&&(messages);j++)
				messages=messages->next;

			if (!IS_NPC(victim) && (GET_LEVEL(victim) > 20)) {
				act(messages->god_msg.attacker_msg, FALSE, ch, ch->equipment[WIELD], victim, TO_CHAR);
				act(messages->god_msg.victim_msg, FALSE, ch, ch->equipment[WIELD], victim, TO_VICT);
				act(messages->god_msg.room_msg, FALSE, ch, ch->equipment[WIELD], victim, TO_NOTVICT);
			} else if (dam != 0) {
				if (GET_POS(victim) == POSITION_DEAD) {
					act(messages->die_msg.attacker_msg, FALSE, ch, ch->equipment[WIELD], victim, TO_CHAR);
					act(messages->die_msg.victim_msg, FALSE, ch, ch->equipment[WIELD], victim, TO_VICT);
					act(messages->die_msg.room_msg, FALSE, ch, ch->equipment[WIELD], victim, TO_NOTVICT);
				} else {
					act(messages->hit_msg.attacker_msg, FALSE, ch, ch->equipment[WIELD], victim, TO_CHAR);
					act(messages->hit_msg.victim_msg, FALSE, ch, ch->equipment[WIELD], victim, TO_VICT);
					act(messages->hit_msg.room_msg, FALSE, ch, ch->equipment[WIELD], victim, TO_NOTVICT);
				}
			} else { /* Dam == 0 */
				act(messages->miss_msg.attacker_msg, FALSE, ch, ch->equipment[WIELD], victim, TO_CHAR);
				act(messages->miss_msg.victim_msg, FALSE, ch, ch->equipment[WIELD], victim, TO_VICT);
				act(messages->miss_msg.room_msg, FALSE, ch, ch->equipment[WIELD], victim, TO_NOTVICT);
			}
		}
	}
	}
	switch (GET_POS(victim)) {
		case POSITION_MORTALLYW:
			act("$n is mortally wounded, and will die soon, if not aided.", TRUE, victim, 0, 0, TO_ROOM);
			act("You are mortally wounded, and will die soon, if not aided.", FALSE, victim, 0, 0, TO_CHAR);
			break;
		case POSITION_INCAP:
			act("$n is incapacitated and will slowly die, if not aided.", TRUE, victim, 0, 0, TO_ROOM);
			act("You are incapacitated an will slowly die, if not aided.", FALSE, victim, 0, 0, TO_CHAR);
			break;
		case POSITION_STUNNED:
			act("$n is stunned, but will probably regain conscience again.", TRUE, victim, 0, 0, TO_ROOM);
			act("You're stunned, but will probably regain conscience again.", FALSE, victim, 0, 0, TO_CHAR);
			break;
		case POSITION_DEAD:
			act("$n is dead! R.I.P.", TRUE, victim, 0, 0, TO_ROOM);
			act("You are dead!  Sorry...", FALSE, victim, 0, 0, TO_CHAR);
			break;

		default:  /* >= POSITION SLEEPING */

			max_hit=hit_limit(victim);

			if (dam > (max_hit/5))
				act("That Really did HURT!",FALSE, victim, 0, 0, TO_CHAR);

			if (GET_HIT(victim) < (max_hit/5)) {

				act("You wish that your wounds would stop BLEEDING that much!",FALSE,victim,0,0,TO_CHAR);
				if (IS_NPC(victim))
					if (IS_SET(victim->specials.act, ACT_WIMPY))
						do_flee(victim, "", 0);
			}
			break;		
	}

	if (!IS_NPC(victim) && !(victim->desc)) {
		do_flee(victim, "", 0);
		if (!victim->specials.fighting) {
			act("$n is rescued by divine forces.", FALSE, victim, 0, 0, TO_ROOM);
			victim->specials.was_in_room = victim->in_room;
			char_from_room(victim);
			char_to_room(victim, 0);
		}
	}

	if (GET_POS(victim) < POSITION_STUNNED)
		if (ch->specials.fighting == victim)
			stop_fighting(ch);

	if (!AWAKE(victim))
		if (victim->specials.fighting)
			stop_fighting(victim);

	if (GET_POS(victim) == POSITION_DEAD) {
		if (IS_NPC(victim) || victim->desc)
			if (IS_AFFECTED(ch, AFF_GROUP)) {
					group_gain(ch, victim);
			} else {
				/* Calculate level-difference bonus */
				exp = GET_EXP(victim)/3;
				if (IS_NPC(ch))
					exp += (exp*MIN(4, (GET_LEVEL(victim) - GET_LEVEL(ch))))>>3;
				else
					exp += (exp*MIN(8, (GET_LEVEL(victim) - GET_LEVEL(ch))))>>3;
				exp = MAX(exp, 1);
				gain_exp(ch, exp);
				change_alignment(ch, victim);
			}
		if (!IS_NPC(victim)) {
			sprintf(buf, "%s killed by %s at %s",
				GET_NAME(victim),
				(IS_NPC(ch) ? ch->player.short_descr : GET_NAME(ch)),
				world[victim->in_room].name);
			log(buf);
		}
		die(victim);
	}