예제 #1
0
void die(struct char_data *ch)
{
  gain_exp(ch, -(GET_EXP(ch) / 2));
  if (!IS_NPC(ch))
    REMOVE_BIT(PLR_FLAGS(ch), PLR_KILLER | PLR_THIEF);
  raw_kill(ch);
}
예제 #2
0
파일: spec_rom.c 프로젝트: vcosta/greedmud
/*
 * Special procedures for rooms.
 */
bool spec_deathtrap( ROOM_INDEX_DATA *room )
{
    CHAR_DATA *rch;
    int        found;

    found = FALSE;
    for ( rch = room->people; rch; rch = rch->next_in_room )
    {
	found = TRUE;

	do_look( rch, "dt" );

	if ( rch->position == POS_STANDING && rch->hit > 20 )
	{
	    rch->position = POS_RESTING;
	    rch->hit /= 2;
	    send_to_char( "You better get out of here fast!\n\r", rch );
	}
	else
	{
	    raw_kill( rch, rch );
	    send_to_char( "You are dead.\n\r", rch );
	}
    }

    return found;
}
예제 #3
0
void loss_breath(struct char_data * ch, int breath)
{

	if (AFF2_FLAGGED(ch, AFF2_IRON_BODY))
		return;

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

	if(GET_LEVEL(ch) < LVL_IMMORT && breath > 0)
	{
		if(GET_OXI(ch) >= 1)
		{
			GET_OXI(ch) -= breath;
			send_to_char("Your breath becomes deeper and slower...\r\n", ch);
		} else {
			if(GET_HIT(ch) > 0)
			{
            	GET_HIT(ch) -= (GET_MAX_HIT(ch)*0.15);
            	send_to_char("&RYou need some oxygen, your life is almost extinguished!&n\r\n", ch);
			} else {
	           	GET_HIT(ch) = 0;
	           	send_to_char("&RYour breath becomes so slow that you die because of it.&n\r\n", ch);
            	raw_kill(ch, NULL);
			}
		}
	}
}
예제 #4
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);

    }
}
예제 #5
0
void death( char_data* victim, char_data* ch, char* dt )
{
  char               tmp  [ TWO_LINES ];
  obj_data*       corpse;
  content_array*   where  = victim->array;
  char_data*         rch;
  bool           survive;
 
  remove_bit( &victim->status, STAT_BERSERK );

  if( ch == NULL ) 
    for( int i = 0; i < *where; i++ ) 
      if( ( rch = character( where->list[i] ) ) != NULL 
        && includes( rch->aggressive, victim ) ) {
        ch = rch;
        break;
        }

  stop_fight( victim );
  clear_queue( victim );

  if( !can_die( victim ) )
    return;
 
  disburse_exp( victim );
  register_death( victim, ch, dt );

  clear_queue( victim );
  death_cry( victim );

  if( survive = !die_forever( victim ) )
    raw_kill( victim );

  corpse = make_corpse( victim, where );
  loot_corpse( corpse, ch, victim );

  if( survive ) 
    return;

  if( mob( victim ) != NULL ) {
    victim->Extract( );
    return;
    }

  sprintf( tmp, "%s's soul is taken by death.", victim->Name( ) );
  info( tmp, LEVEL_BUILDER, tmp, IFLAG_DEATHS, 1, victim );

  clear_screen( victim );
  reset_screen( victim );

  send( victim, "Death is surprisingly peaceful.\n\r" );
  send( victim, "Good night.\n\r" );

  purge( player( victim ) );
}
예제 #6
0
void do_slay( CHAR_DATA *ch, char *argument )
{
	CHAR_DATA *victim;
	char arg[MIL]={'\0'};

	one_argument( argument, arg );
	if ( IS_NULLSTR(arg) )
	{
		send_to_char( "Slay whom?\n\r", ch );
		return;
	}

	if ( ( victim = get_char_room( ch, arg ) ) == NULL )
	{
		send_to_char( "They aren't here.\n\r", ch );
		return;
	}

	if ( ch == victim )
	{
		send_to_char( "Suicide is a mortal sin.\n\r", ch );
		return;
	}

	if ( !IS_NPC(victim) && victim->trust >= get_trust(ch) )
	{
		send_to_char( "You failed.\n\r", ch );
		return;
	}

	act( "You slay $M in cold blood!",  ch, NULL, victim, TO_CHAR, 1 );
	act( "$n slays you in cold blood!", ch, NULL, victim, TO_VICT, 1 );
	act( "$n slays $N in cold blood!",  victim, NULL, ch, TO_NOTVICT, 0 );
	raw_kill( victim, TRUE );
	return;
}
예제 #7
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;

}
예제 #8
0
파일: slay.c 프로젝트: smaugmuds/xsmaug
/** Function: do_slay
  * Descr   : Slays (kills) a player, optionally sending one of several
  *           predefined "slay option" messages to those involved.
  * Returns : (void)
  * Syntax  : slay (who) [option]
  * Written : v1.0 12/97
  * Author  : Gary McNickle <*****@*****.**>
  * Ported to Smaug 1.02a by: Samson
  * Updated to work with Smaug 1.4 by Samson 8-3-98
  * v2.0 added support for online editing
  */
void do_slay( CHAR_DATA * ch, char *argument )
{
   CHAR_DATA *victim;
   SLAY_DATA *slay;
   char type[MAX_INPUT_LENGTH];
   char who[MAX_INPUT_LENGTH];
   bool found = FALSE;

   if( IS_NPC( ch ) )
   {
      send_to_char( "Mobs can't use the slay command.\r\n", ch );
      return;
   }

   argument = one_argument( argument, who );
   argument = one_argument( argument, type );

   if( !str_prefix( who, "list" ) || who == NULL )
   {
      set_char_color( AT_GREEN, ch );
      send_to_char( "Syntax: slay <victim> [type]\r\n", ch );
      send_to_char( "Where type is one of the above...\r\n", ch );

      send_to_pager_color( "&YSlay 			  &ROwner\r\n", ch );
      send_to_pager_color( "&g-------------------------+---------------\r\n", ch );
      for( slay = first_slay; slay; slay = slay->next )
         pager_printf_color( ch, "&G%-14s	&g%13s\r\n", slay->type, slay->owner );

      send_to_char( "\r\nTyping just 'slay <player>' will work too...\r\n", ch );
      return;
   }

   if( ( victim = get_char_room( ch, who ) ) == NULL )
   {
      send_to_char( "They aren't here.\r\n", ch );
      return;
   }

   if( ch == victim )
   {
      send_to_char( "Suicide is a mortal sin.\r\n", ch );
      return;
   }

   if( !IS_NPC( victim ) && victim->level > ch->level )
   {
      send_to_char( "You cannot slay someone who is above your level.\r\n", ch );
      return;
   }

   if( type[0] == '\0' )
   {
      act( AT_IMMORT, "You brutally slay $N!", ch, NULL, victim, TO_CHAR );
      act( AT_IMMORT, "$n chops you up into little pieces!", ch, NULL, victim, TO_VICT );
      act( AT_IMMORT, "$n brutally slays $N!", ch, NULL, victim, TO_NOTVICT );
      set_cur_char( victim );
      raw_kill( ch, victim );
      return;
   }
   else
   {
      for( slay = first_slay; slay; slay = slay->next )
      {
         if( ( !str_cmp( type, slay->type ) && !str_cmp( "Any", slay->owner ) )
             || ( !str_cmp( slay->owner, ch->name ) && !str_cmp( type, slay->type ) ) )
         {
            found = TRUE;
            act( slay->color, slay->cmsg, ch, NULL, victim, TO_CHAR );
            act( slay->color, slay->vmsg, ch, NULL, victim, TO_VICT );
            act( slay->color, slay->rmsg, ch, NULL, victim, TO_NOTVICT );
            set_cur_char( victim );
            raw_kill( ch, victim );
            return;
         }
      }
   }

   if( !found )
      send_to_char
         ( "&RSlay type not defined, or not owned by you. Type \"slay list\" for a complete listing of types available to you.\r\n",
           ch );

   return;
}  /* end of func: "do_slay" */
예제 #9
0
static void __attribute__((constructor)) startup(void)
{
#else
#define RETURN_VALUE 0
static void *ignore_ud2_addr;
// scratch test code
int main(void)
{
#endif

	char *debug_level_str = getenv("TRAP_SYSCALLS_DEBUG");
	char *footprint_fd_str = getenv("TRAP_SYSCALLS_FOOTPRINT_FD");
	char *trace_fd_str = getenv("TRAP_SYSCALLS_TRACE_FD");
	char *sleep_for_seconds_str = getenv("TRAP_SYSCALLS_SLEEP_FOR_SECONDS");
	char *stop_self_str = getenv("TRAP_SYSCALLS_STOP_SELF");
	stop_self = (stop_self_str != NULL);
	footprints_spec_filename = getenv("TRAP_SYSCALLS_FOOTPRINT_SPEC_FILENAME");
	struct timespec one_second = { /* seconds */ 1, /* nanoseconds */ 0 };
	if (debug_level_str) debug_level = atoi(debug_level_str);
	if (trace_fd_str) trace_fd = atoi(trace_fd_str);
	if (footprint_fd_str) footprint_fd = atoi(footprint_fd_str);
	if (sleep_for_seconds_str) sleep_for_seconds = atoi(sleep_for_seconds_str);
	debug_printf(0, "Debug level is %s=%d.\n", debug_level_str, debug_level);
	if (stop_self) {
		self_pid = raw_getpid();
		debug_printf(0, "TRAP_SYSCALLS_STOP_SELF is set, sending SIGSTOP to self (pid %d)\n", self_pid);
		raw_kill(self_pid, SIGSTOP);
	}
	debug_printf(0, "TRAP_SYSCALLS_SLEEP_FOR_SECONDS is %s, pausing for %d seconds", sleep_for_seconds_str, sleep_for_seconds);
	for (int i = 0; i < sleep_for_seconds; i++) {
		raw_nanosleep(&one_second, NULL);
		debug_printf(0, ".");
	}
	debug_printf(0, "\n");

	/* Is fd open? If so, it's the input fd for our sanity check info
	 * from systemtap. */
	debug_printf(0, "TRAP_SYSCALLS_FOOTPRINT_FD is %s, ", footprint_fd_str);
	if (footprint_fd > 2)
	{
		struct stat buf;
		int stat_ret = raw_fstat(footprint_fd, &buf);
		if (stat_ret == 0) {
			debug_printf(0, "fd %d is open; outputting systemtap cross-check info.\n", footprint_fd);
			/* PROBLEM: ideally we'd read in the stap script's output ourselves, and process
			 * it at every system call. But by reading in stuff from stap, we're doing more
			 * copying to/from userspace, so creating a feedback loop which would blow up.
			 *
			 * Instead we write out what we think we touched, and do a diff outside the process.
			 * This also adds noise to stap's output, but without the feedback cycle: we ourselves
			 * won't read the extra output, hence won't write() more stuff in response.
			 */
			__write_footprints = 1;
			footprints_out = fdopen(footprint_fd, "a");
			if (!footprints_out)
				{
					debug_printf(0, "Could not open footprints output stream for writing!\n");
				}

			if (footprints_spec_filename) {

				 footprints = parse_footprints_from_file(footprints_spec_filename, &footprints_env);
				 
			} else {
				 debug_printf(0, "no footprints spec filename provided\n", footprints_spec_filename);
			}

			
		} else {
			debug_printf(0, "fd %d is closed; skipping systemtap cross-check info.\n", footprint_fd);
		}

	}
	else
	{
		debug_printf(0, "skipping systemtap cross-check info\n");
	}

	debug_printf(0, "TRAP_SYSCALLS_TRACE_FD is %s, ", trace_fd_str);
	if (!trace_fd_str || trace_fd == 2) {
		debug_printf(0, "dup'ing stderr, ");
		trace_fd = dup(2);
	}
	
	if (trace_fd >= 0) {
		struct stat buf;
		int stat_ret = raw_fstat(trace_fd, &buf);
		if (stat_ret == 0) {
			debug_printf(0, "fd %d is open; outputting traces there.\n", trace_fd);
			__write_traces = 1;
			traces_out = fdopen(trace_fd, "a");
			if (!traces_out)
				{
					debug_printf(0, "Could not open traces output stream for writing!\n");
				}
		} else {
			debug_printf(0, "fd %d is closed; not outputting traces.\n", trace_fd);
		}
	} else {
		debug_printf(0, "not outputting traces.\n");
	}

	int fd = raw_open("/proc/self/maps", O_RDONLY);

	if (fd != -1)
	{
		// we use a simple buffer and a read loop
		char buf[8192];
		unsigned int ret;
		char *buf_pos = &buf[0]; // the next position to fill in the buffer
		char *entry_start_pos = &buf[0]; // the position
		size_t size_requested;
		do
		{
			// read some stuff, perhaps filling up the buffer
			size_requested = sizeof buf - (buf_pos - buf);
			ret = raw_read(fd, buf_pos, size_requested);
			char *buf_limit = buf_pos + ret;
			assert(buf_limit <= &buf[sizeof buf]);

			// we have zero or more complete entries in the buffer; iterate over them
			char *seek_pos;
			while (1)
			{
				seek_pos = entry_start_pos;
				// search forward for a newline
				while (seek_pos != buf_limit && *seek_pos != '\n')
				{ ++seek_pos; }

				// did we find one?
				if (seek_pos == buf_limit)
				{
					// no!
					// but we have a partial entry in the buffer
					// between entry_start_pos and seek_pos;
					// copy it to the start, re-set and continue
					__builtin_memmove(&buf[0], entry_start_pos, seek_pos - entry_start_pos);
					buf_pos = &buf[seek_pos - entry_start_pos];
					entry_start_pos = &buf[0];
					break;
				}
				else
				{
					assert(*seek_pos == '\n');
					// we have a complete entry; read it and advance entry_start_pos
					char debug_buf1[seek_pos - entry_start_pos + 1];
					strncpy(debug_buf1, entry_start_pos, seek_pos - entry_start_pos);
					debug_buf1[sizeof debug_buf1 - 1] = '\0';
					debug_printf(1, "DEBUG: entry is: %s\n", debug_buf1);
					char debug_buf2[buf_pos - buf];
					strncpy(debug_buf2, buf, buf_pos - buf);
					debug_buf2[sizeof debug_buf2 - 1] = '\0';
					debug_printf(1, "DEBUG: buffer is: %s", debug_buf2);
					saw_mapping(entry_start_pos, seek_pos);
					entry_start_pos = seek_pos + 1;
					// if the newline was the last in the buffer, break and read more
					if (entry_start_pos == buf_pos + sizeof buf)
					{ buf_pos = entry_start_pos = &buf[0]; break; }

					// else we might have another entry; go round again
					continue;
				}
			}
		} while (ret > 0);
		raw_close(fd);
	}

	/* Install our SIGILL (was SIGTRAP, but that interferes with gdb) handler.
	 * Linux seems to require us to provide a restorer; the code is in restore_rt. */
	struct sigaction action = {
		//.sa_sigaction = &handle_sigtrap,
		.sa_handler = &handle_sigill,
		.sa_mask = 0,
		.sa_flags = /*SA_SIGINFO |*/ 0x04000000u /* SA_RESTORER */ | /*SA_RESTART |*/ SA_NODEFER,
		.sa_restorer = restore_rt
	};
	struct sigaction oldaction;
	raw_rt_sigaction(SIGILL, &action, &oldaction);

	/* Un-executablize our own code, except for the signal handler and the remainder of
	 * this function and those afterwards.
	 *
	 * For this, we need our load address. How can we get this? We've already seen it! */
	// long int len = &&exit_and_return - our_text_begin_address;
	// long int ret;
	// long int longprot = PROT_NONE;
	// long int op = SYS_mprotect;

	//	__asm__ (".align 4096");
exit_and_return:
	//__asm__ volatile ("movq %0, %%rdi      # \n\
	//		   movq %1, %%rsi      # \n\
	//		   movq %2, %%rdx      # \n\
	//		  "FIX_STACK_ALIGNMENT " \n\
	//		   movq %3, %%rax      # \n\
	//		   syscall	     # do the syscall \n\
	//		  "UNFIX_STACK_ALIGNMENT " \n"
	//  : /* no output*/ : "rm"(our_text_begin_address), "rm"(len), "rm"(longprot), "rm"(op) :  "%rax", "r12", SYSCALL_CLOBBER_LIST);

#ifdef EXECUTABLE
	// HACK for testing: do a ud2 right now!
	ignore_ud2_addr = &&ud2_addr;
ud2_addr:
	__asm__ ("ud2\n");

	// we must also exit without running any libdl exit handlers,
	// because we're an executable so our csu/startfiles include some cleanup
	// that will now cause traps (this isn't necessary in the shared library case)
	raw_exit(0);
#endif
	return RETURN_VALUE;
}

// For debug printing inside handle_sigill we have to know
// that it's our own debug printing in order to filter it
// out of the footprints, hence this noinline function
// rather than using the normal macro
__attribute__ ((noinline)) static void _handle_sigill_debug_printf(int level, const char *fmt, ...) {
	 va_list vl;
	 va_start(vl, fmt);
	 if ((level) <= debug_level) {
		  vfprintf(*p_err_stream, fmt, vl);
		  fflush(*p_err_stream);
	 }
	 va_end(vl);
}
예제 #10
0
파일: slay.c 프로젝트: onjin/astral
/** Function: do_slay
  * Descr   : Slays (kills) a player, optionally sending one of several
  *           predefined "slay option" messages to those involved.
  * Returns : (void)
  * Syntax  : slay (who) [option]
  * Written : v1.0 12/97
  * Author  : Gary McNickle <*****@*****.**>
  * Ported to Smaug 1.02a by: Roger Libiez <*****@*****.**>
  */
void do_slay( CHAR_DATA *ch, char *argument )
{
    CHAR_DATA *victim;
    char type[MAX_INPUT_LENGTH];
    char who[MAX_INPUT_LENGTH];
    char buf[MAX_STRING_LENGTH];
    int i = 0;
    int color = AT_IMMORT;
    bool found = FALSE;

    argument = one_argument( argument, who );
    argument = one_argument( argument, type );

    if ( !str_prefix( who, "list" ) || who == NULL )
    {
	set_char_color( AT_GREEN, ch );
      send_to_char( "Syntax: slay <victim> [type]\n\r", ch );
      send_to_char( "Where type is one of the following...\n\r\n\r", ch);

      for ( i=0; i < MAX_SLAY_TYPES-1; i++ )

        if ( ( slay_table[i].owner == NULL )               ||
             ( !str_prefix( slay_table[i].owner, ch->name )  &&
              slay_table[i].title[0] != '\0' ) )
        {
           sprintf( buf, "%s\n\r", slay_table[i].title );
           send_to_char( buf, ch );
        }

       send_to_char( "\n\rTyping just 'slay <player>' will work too...\n\r",ch );
       return;
    }
     
    if ( ( victim = get_char_room( ch, who ) ) == NULL )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if ( ch == victim )
    {
	send_to_char( "Suicide is a mortal sin.\n\r", ch );
	return;
    }

    if ( !IS_NPC(victim) && victim->level >= ch->level )
    {
	send_to_char( "You cannot slay someone who is above your level.\n\r", ch );
	return;
    }
     
    if ( type[0] == '\0' )
    {
	 act( AT_IMMORT, "You brutally slay $N!", ch, NULL, victim, TO_CHAR );
       act( AT_IMMORT, "$n chops you up into little pieces!", ch, NULL, victim, TO_VICT );
       act( AT_IMMORT, "$n brutally slays $N!", ch, NULL, victim, TO_NOTVICT );
       set_cur_char( victim );
       raw_kill( ch, victim );
       return;
    }
    else
    {
       for (i=0; i < MAX_SLAY_TYPES; i++)
       {
          if (
               !str_prefix(type, slay_table[i].title) &&
               ( slay_table[i].owner ==  NULL        ||
                 !str_prefix(slay_table[i].owner, ch->name ) )
             )
          {
             found = TRUE;
		 color = slay_table[i].color;
             sprintf( buf, "%s", slay_table[i].char_msg );
             act( color , buf, ch, NULL, victim, TO_CHAR );
             sprintf( buf, "%s", slay_table[i].vict_msg );
             act( color , buf, ch, NULL, victim, TO_VICT );
             sprintf( buf, "%s", slay_table[i].room_msg );
             act( color , buf, ch, NULL, victim, TO_NOTVICT );
             set_cur_char( victim );
             raw_kill( ch, victim );
             return;
          }
       }
    }

    if (!found)
      send_to_char( "Slay type not defined. Type \"slay list\" for a complete listing of types available to you.\n\r", ch );

    return;
} /* end of func: "do_slay" */
예제 #11
0
void die(struct char_data *ch)
{
	gain_exp(ch, -(GET_EXP(ch)/2));
	raw_kill(ch);
}