Пример #1
0
/*
 * Inflict damage from a hit.
 */
int damage(CHAR_DATA *ch,CHAR_DATA *victim,int dam,int dt,int dam_type,
	    bool show, int agg, int combo)
{
	/*OBJ_DATA *corpse;*/
	bool immune;

	if ( victim->position == P_DEAD )
		return P_DEAD;

	/* @@@@@ FIX TORPOR
    if ( victim->position == P_TORPOR )
	return P_TORPOR;
	 */

	/* damage reduction */
	if ( dam > 15)
		dam = (dam - 5)/2 + 5;

	if(IS_SET(ch->form, FORM_HORRID)) dam++;

	/* @@@@@ FIX BITE DAMAGE FOR SERPENTIS 3
    if(is_affected(ch, skill_lookup("skin of the adder"))
	&& dam_type == DAM_BITE)
	    dam++;
	 */

	/* In case of -ve agg ratings */
	if (agg < 0) agg = 0;

	/* soakage */
	dam = do_soak(victim, dam, agg);

	if ( victim != ch )
	{
		if ( victim->position > P_STUN )
		{
			if ( victim->fighting == NULL )
			{
				set_fighting( victim, ch );
				if ( IS_NPC( victim ) && HAS_TRIGGER( victim, TRIG_KILL ) )
					mp_percent_trigger( victim, ch, NULL, NULL, TRIG_KILL );
			}
			if (victim->timer <= 4)
				victim->position = P_FIGHT;
		}

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

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

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

	/*
	 * Damage modifiers.
	 */

	if ( dam > 1 && !IS_NPC(victim)
			&&   victim->condition[COND_DRUNK]  > 10 )
		dam = 9 * dam / 10;
	if ( dam > 1 && !IS_NPC(victim)
			&&   victim->condition[COND_HIGH]  > 10 )
		dam = 9 * dam / 10;

	if ( dam > 1 && ((IS_AFFECTED(victim, AFF_PROTECT_EVIL) && !IS_NATURAL(ch) )) )
		dam -= dam / 4;

	immune = FALSE;


	/*
	 * Check for parry, and dodge.

    if ( dt >= TYPE_HIT && ch != victim)
    {
        if ( check_parry( ch, victim ) )
	    return -1;
	if ( check_dodge( ch, victim ) )
	    return -1;
    }
	 */

	switch(check_immune(victim,dam_type))
	{
	case(IS_IMMUNE):
	    		immune = TRUE;
	dam = 0;
	break;
	case(IS_RESISTANT):
	    		dam -= dam/3;
	break;
	case(IS_VULNERABLE):
	    		dam += dam/2;
	break;
	}

	if (show)
		dam_message( ch, victim, dam, dt, immune, combo );

	if(dam > (victim->health + victim->agghealth -7))
	{
		victim->position = P_MORT;
		stop_fighting(ch, TRUE);
	}
	else if(dam == (victim->health + victim->agghealth -7))
	{
		victim->position = P_INCAP;
		stop_fighting(ch, TRUE);
	}

	if (dam == 0)
		return -1;
	else if(IS_SET(ch->off_flags, BANDAGED))
		REMOVE_BIT(ch->off_flags, BANDAGED);

	/*
	 * Hurt the victim.
	 * Inform the victim of his new state.
	 */
	if( (victim->race == race_lookup("vampire")) && (dt == DAM_FIRE) )
	{
		victim->agghealth -= dam;
		update_pos( victim, UMAX(1, agg) );
		if(agg <= 0) agg = 1;
	}
	else if( (victim->race == race_lookup("werewolf")) && (dt == DAM_SILVER) )
	{
		victim->agghealth -= dam;
		update_pos( victim, UMAX(1, agg) );
		if(agg <= 0) agg = 1;
	}
	else if( (victim->race == race_lookup("faerie")) && (dt == DAM_IRON) )
	{
		victim->health -= dam;
		victim->GHB += dam/3;
		update_pos( victim, agg );
	}
	else if(agg)
	{
		victim->agghealth -= dam;
		update_pos( victim, agg );
	}
	else
	{
		victim->health -= dam;
		update_pos( victim, 0 );
	}

	switch( victim->position )
	{
	case P_MORT:
		act( "$n is mortally wounded, and will die soon, if not aided.", victim, NULL, NULL, TO_ROOM, 0 );
		send_to_char("You are mortally wounded, and may die soon, if not aided.\n\r", victim );
		break;

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

	case P_TORPOR:
		act( "$n is mortally wounded, and will slowly die if not aided.", victim, NULL, NULL, TO_ROOM, 0 );
		send_to_char("You enter torpor.\n\r", victim );
		break;

	case P_STUN:
		act( "$n is stunned, but will probably recover.", victim, NULL, NULL, TO_ROOM, 0 );
		send_to_char("You are stunned, but will probably recover.\n\r", victim );
		break;

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

	default:
		if ( dam > MAX_HEALTH / 4 )
			send_to_char( "That really did HURT!\n\r", victim );
		if ( (victim->health + victim->agghealth - 7) < MAX_HEALTH / 4 )
			send_to_char( "You sure are BLEEDING!\n\r", victim );
		break;
	}

	if(dam_type == DAM_FIRE)
		fire_effect((void *) victim, agg+dam/2, dam, TARGET_CHAR);
	if(dam_type == DAM_COLD)
		cold_effect((void *) victim, agg+dam/2, dam, TARGET_CHAR);
	if(dam_type == DAM_LIGHTNING)
		shock_effect((void *) victim, agg+dam/2, dam, TARGET_CHAR);
	if(dam_type == DAM_ACID)
		acid_effect((void *) victim, agg+dam/2, dam, TARGET_CHAR);
	if(dam_type == DAM_POISON)
		poison_effect((void *) victim, agg+dam/2, dam, TARGET_CHAR);

	/*
	 * Sleep spells and extremely wounded folks.
	 */
	if ( !IS_AWAKE(victim) )
		stop_fighting( victim, FALSE );

	/*
	 * Payoff for killing things.
	 */
	if ( (victim->position == P_INCAP && IS_NPC(victim))
			|| victim->position == P_DEAD
			|| victim->position == P_TORPOR )
	{
		if ( !IS_NPC(victim) )
		{
			log_string( LOG_GAME, Format("%s killed by %s at %d", victim->name, (IS_NPC(ch) ? ch->short_descr : ch->name), ch->in_room->vnum) );
		}

		snprintf( log_buf, 2*MIL, "\tY[WIZNET]\tn %s got toasted by %s at %s [room %d]",
				(IS_NPC(victim) ? victim->short_descr : victim->name),
				(IS_NPC(ch) ? ch->short_descr : ch->name), ch->in_room->name, ch->in_room->vnum);

		if (IS_NPC(victim))
			wiznet(log_buf,NULL,NULL,WIZ_MOBDEATHS,0,0);
		else
			wiznet(log_buf,NULL,NULL,WIZ_DEATHS,0,0);

		/*
		 * Death trigger
		 */
		if ( IS_NPC( victim ) && HAS_TRIGGER( victim, TRIG_DEATH) )
		{
			victim->position = P_STAND;
			mp_percent_trigger( victim, ch, NULL, NULL, TRIG_DEATH );
		}

		if((!str_cmp(ch->description, "") || strlen(ch->description) < 10)
				&& ch->played > 10*60*60)
		{
			send_to_char("No experience without a description.\n\r", ch);
		}
		else
		{
			if(ch->ooc_xp_count < 2) {
				send_to_char("You learn from your encounter.\n\r", ch);
				ch->oocxp += 1;
				ch->ooc_xp_count++;
			} else if(IS_SET(victim->act2, ACT2_HUNTER) && ch->ooc_xp_count < 50) {
				send_to_char("You learn from your encounter.\n\r", ch);
				ch->exp += 1;
				ch->ooc_xp_count++;
			}
		}

		if(ch->quest)
		{
			if(ch->quest->quest_type == Q_HITMAN && ch->quest->victim == victim)
				(*quest_table[ch->quest->quest_type].q_fun) (ch, 2);

			if(victim->quest != NULL && victim->quest->quest_type == Q_HITMAN
					&& victim->quest->victim == victim
					&& victim->quest->questor != ch)
				(*quest_table[victim->quest->quest_type].q_fun)
				(victim->quest->questor, 3);

			if(victim->quest != NULL && (victim->quest->quest_type == Q_BODYGUARD
					|| victim->quest->quest_type == Q_RESCUE)
					&& victim->quest->victim == victim)
				(*quest_table[victim->quest->quest_type].q_fun)
				(victim->quest->questor, 3);
		}

		if(victim->position != P_TORPOR || agg) update_pos( victim, agg );

		return victim->position;
	}

	if ( victim == ch )
		return ch->position;

	/* Link dead salvation. */
	if ( !IS_NPC(victim) && victim->desc == NULL )
	{
		do_function(victim, &do_flee,"");
	}

	tail_chain( );
	return victim->position;
}
Пример #2
0
void poison_effect(void *vo,int level, int dam, int target)
{
	if (target == TARGET_ROOM)  /* nail objects on the floor */
	{
		ROOM_INDEX_DATA *room = (ROOM_INDEX_DATA *) vo;
		OBJ_DATA *obj, *obj_next;

		for (obj = room->contents; obj != NULL; obj = obj_next)
		{
			obj_next = obj->next_content;
			poison_effect(obj,level,dam,TARGET_OBJ);
		}
		return;
	}

	if (target == TARGET_CHAR)   /* do the effect on a victim */
	{
		CHAR_DATA *victim = (CHAR_DATA *) vo;
		OBJ_DATA *obj, *obj_next;

	/* chance of poisoning */
		if (!saves_spell(level / 4 + dam / 20,victim,DAM_POISON))
		{
			AFFECT_DATA af;

			send_to_char("You feel poison coursing through your veins.\n\r", victim);
			act("$n looks very ill.",victim,NULL,NULL,TO_ROOM);

			af.where     = TO_AFFECTS;
			af.type      = gsn_poison;
			af.level     = level;
			af.duration  = level / 2;
			af.location  = APPLY_STR;
			af.modifier  = -1;
			af.bitvector = AFF_POISON;
			affect_join( victim, &af );
		}

	/* equipment */
		for (obj = victim->carrying; obj != NULL; obj = obj_next)
		{
			obj_next = obj->next_content;
			poison_effect(obj,level,dam,TARGET_OBJ);
		}
		return;
	}

	if (target == TARGET_OBJ)  /* do some poisoning */
	{
		OBJ_DATA *obj = (OBJ_DATA *) vo;
		int chance  = level / 4 + dam / 10;

		if (IS_OBJ_STAT(obj,ITEM_BURN_PROOF)
			||  IS_OBJ_STAT(obj,ITEM_BLESS)
			||  number_range(0,4) == 0)
			return;

		if (chance > 25)
			chance = (chance - 25) / 2 + 25;
		if (chance > 50)
			chance = (chance - 50) / 2 + 50;

		chance -= obj->level * 2;

		switch (obj->item_type)
		{
			default:
			return;
			case ITEM_FOOD:
			break;
			case ITEM_DRINK_CON:
			if (obj->value[0] == obj->value[1])
				return;
			break;
		}

		chance = URANGE(5,chance,95);

		if (number_percent() > chance)
			return;

		obj->value[3] = 1;
		return;
	}
}
Пример #3
0
void poison_effect( void *vo, int level, int dam, int target )
{
    if ( target == TARGET_ROOM )   /* nail objects on the floor */
    {
        ROOM_INDEX_DATA * room = ( ROOM_INDEX_DATA * ) vo;
        OBJ_DATA *obj, *obj_next;

        for ( obj = room->contents; obj != NULL; obj = obj_next )
        {
            OBJ_NEXT_CONTENT( obj, obj_next );

            if ( IS_OBJ_STAT( obj, ITEM_NOPURGE ) )
                continue;

            poison_effect( obj, level, dam, TARGET_OBJ );
        }
        return ;
    }

    if ( target == TARGET_CHAR )    /* do the effect on a victim */
    {
        CHAR_DATA * victim = ( CHAR_DATA * ) vo;
        OBJ_DATA *obj, *obj_next;

        if ( !victim->in_room )
            return ;

		if ( is_affected(victim, gsn_mirrorfall) )
		{
			affect_strip(victim, gsn_mirrorfall);
			return;
		}

        /* chance of poisoning */
        /*        if (!saves_spell_new(victim, SAVE_DEATH, 0))
                {
        	    AFFECT_DATA af;

                    send_to_char("Czujesz jak trucizna rozprzestrzenia siê w twoich zylach.\n\r",victim);
                    act("$n wyglada bardzo niezdrowo.",victim,NULL,NULL,TO_ROOM);

                    af.where     = TO_AFFECTS;
                    af.type      = gsn_poison;
                    af.level     = 4;
                    af.duration  = dice(poison_table[4].duration[0],poison_table[4].duration[1]) + poison_table[4].duration[2];
                    af.rt_duration = 0;
                    af.location  = APPLY_NONE;
                    af.modifier  = 0;
                    af.bitvector = &AFF_POISON;
                    affect_join( victim, &af );
                }*/

        /* equipment */

		if ( is_affected(victim, gsn_mirrorfall) )
		{
			affect_strip(victim, gsn_mirrorfall);
			return;
		}

		for ( obj = victim->carrying; obj != NULL; obj = obj_next )
        {
            OBJ_NEXT_CONTENT( obj, obj_next );
            poison_effect( obj, level, dam, TARGET_OBJ );
        }
        return ;
    }

    if ( target == TARGET_OBJ )   /* do some poisoning */
    {
        OBJ_DATA * obj = ( OBJ_DATA * ) vo;
        int chance;

        if ( IS_OBJ_STAT( obj, ITEM_BLESS ))
            return ;

	/* Tener: dodanie szansy na unikniêcie w zale¿no¶ci od poziomu czaru [20080512] */
	//2008-11-20, Brohacz: wylaczam. Spelle powyzej 25 levela nie psuja przeciez przez to gratow!
	/*if ( URANGE( 1, number_range( 1, 30 - level ), 10 ) < 5 )
	   return;*/

        chance = level + dam / 7;

 		switch ( obj->item_type )
        {
            default:
                return ;
            case ITEM_FOOD:
                break;
            case ITEM_DRINK_CON:
                if ( obj->value[ 0 ] == obj->value[ 1 ] )
                    return ;
                break;
        }

        if ( number_percent() > chance )
            return ;

        obj->value[ 3 ] = 1;
        return ;
    }
}