예제 #1
0
void char_bash( char_data* ch, char_data* victim )
{
  int delay;

  if( victim == ch ) {
    send( ch, "Bashing yourself is not very productive.\n\r" );
    return;
    }

  if( victim->species != NULL ) { 
    if( is_set( &victim->species->act_flags, ACT_NO_BASH ) ) {
      send( ch, "Bashing that does not make sense.\n\r" );
      return;
      }
    if( is_set( &victim->species->act_flags, ACT_GHOST ) ) {
      send( ch, "Bashing a ghost is a completely futile exercise.\n\r" );
      return;
      }
    }

  if( victim->position < POS_FIGHTING ) {
    send( ch, "Your victim is already on the ground!\n\r" );
    return;
    }

  if( victim->Size( ) > ch->Size( )+1 ) {
    send( ch, "%s is way too large for you to successfully bash %s.\n\r",
      victim, victim->Him_Her( ) );
    return;
    }

  if( !can_kill( ch, victim ) )
    return;

  check_killer( ch, victim );
  ch->fighting = victim;
  react_attack( ch, victim );  

  remove_bit( &ch->status, STAT_LEAPING );
  remove_bit( &ch->status, STAT_WIMPY );

  ch->improve_skill( SKILL_BASH );

  delay = bash_attack( ch, victim );
  add_queue( &ch->active, delay );
}
예제 #2
0
/* start one char fighting another (yes, it is horrible, I know... )  */
void set_fighting(struct char_data *ch, struct char_data *vict)
{
  if (ch == vict)
    return;

  if (FIGHTING(ch)) {
    core_dump();
    return;
  }

  ch->next_fighting = combat_list;
  combat_list = ch;

  if (AFF_FLAGGED(ch, AFF_SLEEP))
    affect_from_char(ch, SPELL_SLEEP);

  FIGHTING(ch) = vict;
  GET_POS(ch) = POS_FIGHTING;

  if (!pk_allowed)
    check_killer(ch, vict);
}
예제 #3
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);
}
예제 #4
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;

}
예제 #5
0
void do_recite( char_data* ch, char* argument )
{
  char            arg  [ MAX_STRING_LENGTH ];
  cast_data*     cast;
  obj_data*    scroll;
  int           level;
  int        duration;
  int           spell;

  if( not_player( ch ) )
    return;

  if( is_set( &ch->status, STAT_BERSERK ) ) {
    send( ch, "Your mind is on killing, not reading scrolls.\r\n" );
    return;
    }

  argument = one_argument( argument, arg );

  if( ( scroll = one_object( ch, arg, "recite", &ch->contents ) ) == NULL )
    return;

  if( scroll->pIndexData->item_type != ITEM_SCROLL ) {
    send( ch, "%s isn't a scroll.\r\n", scroll );
    return;
    }

  if( !is_set( ch->pcdata->pfile->flags, PLR_HOLYLIGHT )
    && ( is_set( ch->affected_by, AFF_BLIND )
    || ch->in_room->is_dark( ) ) ) {
    send( ch, "It is too dark for you read any writing.\r\n" );
    return;
    }

  if( ( spell = scroll->pIndexData->value[0] ) < 0
    || spell >= MAX_SPELL ) {
    send( ch, "That scroll contains a non-existent spell.\r\n" );
    bug( "Recite: Scroll spell out of range." );
    bug( "-- Scroll = %s", scroll->Seen_Name( NULL ) );
    return;
    }

  cast        = new cast_data;
  cast->spell = spell;

  if( !get_target( ch, cast, argument ) ) {
    delete cast;
    return;
    }

  thing_data*  target  = cast->target;
  char_data*   victim  = character( target );

  delete cast;

  if( spell_table[ spell ].type == STYPE_OFFENSIVE ) {
    check_killer( ch, victim );
    ch->fighting = victim;
    react_attack( ch, victim );
    }

  if( spell == SPELL_RECALL-SPELL_FIRST 
    && is_set( &ch->in_room->room_flags, RFLAG_NO_RECALL ) ) {
    send( ch, "You attempt to pronounce the words on the scroll but\
 absolutely nothing\r\nhappens.\r\n" );
    return;
    }
예제 #6
0
파일: cls_thf.c 프로젝트: rayhe/stormgate
int skill_double_backstab( int sn, int level, CHAR_DATA *ch, void *vo )
{
    OBJ_DATA  *obj;
    CHAR_DATA *victim;
    char       arg [ MAX_INPUT_LENGTH ];
    
    one_argument( target_name, arg );
        
    if ( arg[0] == '\0' )
    {
	send_to_char(C_DEFAULT, "Double Backstab whom?\n\r", ch );
	return SKPELL_MISSED;
    }
    
    if ( !( victim = get_char_room( ch, arg ) ) )
    {
	send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
	return SKPELL_MISSED;
    }
  
    if ( victim == ch )   
    {
	send_to_char(C_DEFAULT, "How can you sneak up on yourself?\n\r", ch );
	return SKPELL_MISSED;
    } 
   
    if ( !( obj = get_eq_char( ch, WEAR_WIELD ) ) || obj->value[3] != 11 )
    {
	send_to_char(C_DEFAULT, "You need to wield a piercing weapon.\n\r", ch );
	return SKPELL_MISSED;
    }
    
    if ( victim->fighting )
    {
	send_to_char(C_DEFAULT, "You can't double backstab a fighting person.\n\r", ch );
	return SKPELL_MISSED;
    }
      
    if ( victim->hit < (victim->max_hit - 200) )
    {
	act(C_DEFAULT, "$N is hurt and suspicious ... you can't sneak up.", ch, NULL, victim, TO_CHAR );
	return SKPELL_MISSED;
    }
     
    if ( !is_pkillable( ch, victim ) )
    {
	return SKPELL_MISSED;
    }
     
    if ( IS_AFFECTED2( ch, AFF_SHADOW_PLANE ))
    {
	send_to_char(AT_WHITE, "You must leave the shadow realm.\n\r", ch);
	return SKPELL_MISSED;
    }

    if ( IS_AFFECTED4( ch, AFF_BURROW ))
    {
	send_to_char(AT_WHITE, "You must wait until the earth heals you.\n\r", ch);
	return SKPELL_MISSED;
    }
    
    if ( IS_AFFECTED2( victim, AFF_SHADOW_PLANE ))
    {
	send_to_char(AT_WHITE, "You can not attack someone who is in the shadow plane.\n\r", ch);
	return SKPELL_MISSED;
    }

    if ( IS_AFFECTED4( victim, AFF_BURROW ))
    {
	send_to_char(AT_WHITE, "You can not attack someone who is burrowed.\n\r", ch);
	return SKPELL_MISSED;
    }
 
    if ( IS_AFFECTED( victim, AFF_PEACE ) )
    {
	send_to_char(AT_WHITE, "A wave of peace overcomes you.\n\r", ch);
	return SKPELL_MISSED;
    }
  
    if (!IS_NPC(victim))
	ch->pkill_timer = 0;
  
    check_killer( ch, victim );
    WAIT_STATE( ch, skill_table[sn].beats );
    if ( !IS_AWAKE( victim ) || IS_NPC( ch ) || number_percent( ) < ( ch->pcdata->learned[sn] / 10 ) )
    {
	multi_hit( ch, victim, sn );
	multi_hit( ch, victim, sn );
    }
    else
    {
	return SKPELL_ZERO_DAMAGE;
    }
   
    return SKPELL_NO_DAMAGE;
}