dawn/notes/
dawn/src/
dawn/src/docs/
/**************************************************************************/
// magic_da.cpp - spells/skills written for Dawn by anyone 
/***************************************************************************
 * The Dawn of Time v1.69r (c)1997-2004 Michael Garratt                    *
 * >> A number of people have contributed to the Dawn codebase, with the   *
 *    majority of code written by Michael Garratt - www.dawnoftime.org     *
 * >> To use this source code, you must fully comply with all the licenses *
 *    in licenses.txt... In particular, you may not remove this copyright  *
 *    notice.                                                              *
 **************************************************************************/ 
#include "include.h"
#include "magic.h"

DECLARE_DO_FUN(do_bug);
/**************************************************************************/
// By Thaddeus
void do_lay_on_hands(char_data * ch, char * argument)
{
	int heal;
	int skill;
	char arg[MIL];
	char_data *victim;
    
	one_argument( argument, arg );
	
	if ( IS_OOC( ch )) {
		ch->printf( "Not in an OOC room.\r\n" );
		return;
	}
	
    if ( arg[0] == '\0' )
    {
		ch->printf( "Lay your hands on whom?\r\n" );
		return;
    }
	
	
	if ( ( victim = get_char_room( ch, arg ) ) == NULL )
	{
		ch->printf( "You don't see anyone like that here.\r\n" );
		return;
	}
	
	if ( !IS_IMMORTAL( ch ))
		WAIT_STATE( ch, skill_table[gsn_lay_on_hands].beats );
	
	// dont spam message
	if (ch->desc && ch->desc->repeat>8)
	{
		ch->printf( "The lay on hands skill has no effect when used on yourself.\r\n" );
		ch->printf( "(learn to read the help files - read help lay)\r\n" );
		return;
	}
	
	if ( (victim == ch) )
	{
		act("$n lays $s hands on $mself.", ch, NULL,NULL, TO_ROOM);
		act("You lay your hands on yourself.", ch, NULL, NULL, TO_CHAR); 
		return;
	}
	
	act("$n lays $s hands on $N.", ch, NULL, victim, TO_NOTVICT);
	act("You lay your hands on $N.", ch, NULL, victim, TO_CHAR); 
	act("$n lays $s hands on you.", ch, NULL, victim, TO_VICT); 

    if (!(skill=get_skill(ch,gsn_lay_on_hands)))
        return;   
    if (IS_NPC(ch))   
        return;
    if (ch->pcdata->lays<=0)
        return;
    ch->pcdata->lays--;
	
    
    heal = UMAX(number_range(1,(ch->level/10)+1),
		number_range(1,(ch->level/10)+1));
	
    heal=(heal * skill)/100;
    victim->hit = UMIN( victim->hit + heal, victim->max_hit );
    
    update_pos( victim );
    victim->printf( "You feel better!\r\n" );
	ch->printf( "Your hands glow softly as a sense of divine power travels through you.\r\n" );
	
	check_improve( ch, gsn_lay_on_hands, true, 1 );
	
    return; 
}
/**************************************************************************/
// By Kirion and Kalahn
SPRESULT spell_mindspeak( int, int, char_data *ch, void *, int )
{
    static int mindspeakmon=0;
	char arg[MIL],buf[MSL],buf2[MSL];
	char tellname[MIL];
	char *argument;
    char_data *victim;
    
	// unswitched mobs can't send mindspeaks
    if (IS_UNSWITCHED_MOB(ch))
    {
		return NO_MANA;
    }

    target_name = one_argument( target_name, arg );
	argument = target_name;


    if ( arg[0] == '\0' || argument[0] == '\0' )
    {
        ch->printf( "Mindspeak whom what?\r\n" );
        return NO_MANA;
    }

    // remove a , from the name field if required
	if (arg[str_len(arg)-1]==','){
		arg[str_len(arg)-1]=0;
	}

    // cannot send mindspeaks to mobs or to players which are not logged or are inside of ooc rooms
    if (( victim = get_whovis_player_world( ch, arg ))==NULL
		|| IS_NPC(victim)
		|| IS_SET(victim->in_room->room_flags, ROOM_OOC)) 
    {
        ch->printf( "Their mind is unreachable.\r\n" );
        return NO_MANA;
    }

	//cannot mindspeak to yourself
	if (victim==ch)
	{
		ch->printf( "You are always mindspeaking to yourself!\r\n");
		return NO_MANA;
	}

	//cannot mindspeak while with a pkill-norecall, pkill-ool or pkill-noquit timer
	if((ch->pknorecall>0) || (ch->pknoquit>0) || (ch->pkool>2000))
	{
		ch->printf( "Your mind is too troubled for you to focus on any one idea.\r\n" );
		return HALF_MANA;
	}

	// Mindspeaking to asleep people, or people affected with cause fear
    if ( (!IS_AWAKE(victim)) || (IS_AFFECTED(victim, AFF_FEAR)) || 
		 (IS_AFFECTED2(victim, AFF2_FEAR_MAGIC)) )
    {
        act( "Your thoughts could not remain in $S mind for long.", ch, 0, victim, TO_CHAR );
        return HALF_MANA;
    }

	// If caster is invisible, target receives it as a someone, instead of his desc
	sprintf (tellname,(can_see_who(TRUE_CH(victim), TRUE_CH(ch))?
		TRUE_CH(ch)->name:"someone"));

	// Mortals cannot mindspeak if AFK
    if (IS_SET(ch->comm,COMM_AFK) && !IS_IMMORTAL(ch))
	{
		ch->printf( "You can't mindspeak while AFK!\r\n" );
		return NO_MANA;
	}

	// cannot mindspeak to an AFK victim, but immortals get it nevertheless
    if (IS_SET(victim->comm,COMM_AFK))
    {
        act("$E is AFK, and thus, unable to receive mindspeaks",ch,NULL,victim,TO_CHAR);

		if IS_IMMORTAL(victim)
		{
			victim->printf( "%s just tried to mindspeak you '%s' "
				"(you are marked as afk)`x\r\n",
			PERS(ch, victim), argument);
			return NO_MANA;
		}

        return NO_MANA;
    }

    // wiznet mindspeak - needed to monitor possible abuses
    if (!IS_NPC(ch))
	{
		if (!IS_OOC(ch)) 
		{
			mindspeakmon++;
			if (mindspeakmon>=10)
			{
				sprintf (buf2, "Wiznet mindspeak: %s mindspeaked `s'%s'`x to %s", 
					ch->name, argument, victim->name);	
				wiznet(buf2,ch,NULL,WIZ_QUESTING,0,get_trust(ch));
				mindspeakmon=0;
			}
			ch->pcdata->did_ic=true;
		}
	}

	//Check to see if the next char is a '!' or a ',' , in which case, does a Mental emote
	if ((argument[0]=='!') || (argument[0]==','))
	{
		argument++;
		if (argument[0]==' ') argument++;
	    if(!IS_NPC(ch)) ch->pcdata->did_ooc=true;
	    ch->printf( "`bWithin the mind of %s, your image %s`x\r\n",	
			PERS(victim, ch), argument);
	    victim->printf( "`bWithin your mind. the image of %s %s`x\r\n",
			PERS(ch, victim), argument);
	 
		return FULL_MANA;
	}

	// Languages still influence mindspeaks, you think in a specific language, so
	// mindspeaks cannot be used for universal communication.

	translate_language(ch->language, false, ch, victim, argument, buf);

	//At last! The Mindspeak.
    if(!IS_NPC(ch)){
		ch->pcdata->did_ooc=true;
	}

    ch->printf( "`BYou speak your thoughts into the mind of %s: "
		"'%s`B'`x\r\n", PERS(victim, ch), argument);
    victim->printf( "`BYou hear the voice of %s within your mind: "	
		"'%s`B'`x\r\n", PERS(ch, victim), buf);
		
 	return FULL_MANA;
}
/**************************************************************************/
SPRESULT spell_naturespeak( int, int, char_data *ch, void *, int ) //Kirion with slight tweaks by Ker
{
	static int naturespeakmon=0;
	char arg[MIL],buf[MSL],buf2[MSL];
	char tellname[MIL];
	char *argument;
	char_data *victim, *to;
    
	// unswitched mobs can't naturespeak
    if (IS_UNSWITCHED_MOB(ch))
    {
		ch->printf( "Unswitched mobs cannot naturespeak." );
		return NO_MANA;
    }
	
    target_name = one_argument( target_name, arg );
	argument = target_name;
	
    if ( arg[0] == '\0' || argument[0] == '\0' )
    {
        ch->printf( "Deliver which message, and to whom?\r\n" );
        return NO_MANA;
    }
	
    // remove a , from the name field if required
	if (arg[str_len(arg)-1]==',') arg[str_len(arg)-1]=0;
	
    // cannot naturespeak to mobs or to players which are not logged or are inside of ooc rooms
    if (( victim = get_whovis_player_world( ch, arg ))==NULL
		|| IS_NPC(victim)
		|| IS_SET(victim->in_room->room_flags, ROOM_OOC)) 
    {
        ch->printf( "They are nowhere to be found.\r\n" );
        return NO_MANA;
    }
	
	//cannot mindcast to yourself
	if (victim==ch)
	{
		ch->printf( "You think of a message and mentally say it to yourself.\r\n");
		return NO_MANA;
	}
	
	//cannot naturespeak while with a pkill-norecall, pkill-ool or pkill-noquit timer
	if((ch->pknorecall>0) || (ch->pknoquit>0) || (ch->pkool>0))
	{
		ch->printf( "You can't seem to focus enough to naturespeak.\r\n" );
		return HALF_MANA;
	}
	
	// Naturespeaking to asleep people, or people affected with cause fear
    if ( (!IS_AWAKE(victim)) || (IS_AFFECTED(victim, AFF_FEAR)) 
		|| (IS_AFFECTED2(victim, AFF2_FEAR_MAGIC)) )
    {
        act( "$S mind is drifting aimessly, you can't lock onto it.", ch, 0, victim, TO_CHAR );
        return HALF_MANA;
    }
	
	// If caster is invisible, target receives it as a someone, instead of his desc
	sprintf (tellname,(can_see_who(TRUE_CH(victim), TRUE_CH(ch)) ?
		TRUE_CH(ch)->name:"someone"));
	
	// Mortals cannot naturespeak if AFK
    if (IS_SET(ch->comm,COMM_AFK))
		if (!IS_IMMORTAL(ch))
		{
			ch->printf( "You can't naturespeak while AFK!\r\n" );
			return NO_MANA;
		}
		
		// cannot naturespeak to an AFK victim, but immortals get it nevertheless
		if (IS_SET(victim->comm,COMM_AFK))
		{
			act("$E is AFK, and thus, unable to receive a naturespeak.",ch,NULL,victim,TO_CHAR);
			
			if IS_IMMORTAL(victim)
			{
				victim->printf( "%s just tried to naturespeak to you '%s' (you are marked as afk)`x\r\n",
					PERS(ch, victim), argument);
				return NO_MANA;
			}
			
			return NO_MANA;
		}
		
		// wiznet NATURESPEAK - needed to monitor possible abuses
		if (!IS_NPC(ch))
		{
			if (!IS_OOC(ch)) 
			{
				naturespeakmon++;
				if (naturespeakmon>=10)
				{
					sprintf (buf2, "Wiznet naturespeaks: %s	naturespoke `s'%s'`x to %s", ch->name, argument, victim->name);
					wiznet(buf2,ch,NULL,WIZ_QUESTING,0,get_trust(ch));
					naturespeakmon=0;
					buf2[0]='\0';
				}
				ch->pcdata->did_ic=true;
			}	
		}
		
		// Caster feedback
		switch ( victim->in_room->sector_type )
		{
			case SECT_UNDERWATER:
			case SECT_WATER_SWIM:
			case SECT_WATER_NOSWIM:
			case SECT_SWAMP:
				ch->println( "The spirits of water, the undines, have answered your call.");
				break;
			case SECT_CAVE:
			case SECT_MOUNTAIN:
			case SECT_CITY:
			case SECT_HILLS:
				ch->println( "The spirits of earth, the grendels, have answered your call.");
				break;
			case SECT_DESERT:
				ch->println( "The spirits of fire, the salamanders, have answered your call.");
				break;
			case SECT_AIR:
				ch->println( "The spirits of air, the sylphs, have answered your call.");
				break;
			case SECT_FOREST:
			case SECT_FIELD:
				ch->println( "The spirits of nature, the dryads, have answered your call.");
				break;
			default:
				ch->println( "No spirit could reach the target.");
				return NO_MANA;
				break;
		}
		
		buf2[0]='\0';
		
		//At last! The Naturespeak.
		if(!IS_NPC(ch)) ch->pcdata->did_ooc=true;
		
		switch ( victim->in_room->sector_type )
		{
			case SECT_FOREST:
				strcat(buf2, "`gA nearby tree takes the shape of");
				break;
			case SECT_HILLS:
				strcat(buf2, "`sA group of stones and grasses rise in the shape of");
				break;
			case SECT_FIELD:
				strcat(buf2, "`sA nearby bush shifts into the form of");
				break;
			case SECT_MOUNTAIN:
				strcat(buf2, "`sA large boulder shifts into the form of");
				break;
			case SECT_WATER_SWIM:
			case SECT_WATER_NOSWIM:
				strcat(buf2, "`bA column of water rises in the form of");
				break;
			case SECT_SWAMP:
				strcat(buf2, "`mA pool of mud grows into the shape of");
				break;
			case SECT_AIR:
				strcat(buf2, "`cA small cloud forms, resembling");
				break;
			case SECT_DESERT:
				strcat(buf2, "`yA small dune shapes into the form of");
				break;
			case SECT_CAVE:
				strcat(buf2, "`rA nearby stone morphs into the form of");
				break;
			case SECT_UNDERWATER:
				strcat(buf2, "`BBubbles form in the water on the shape of");
				break;
			case SECT_CITY:
				strcat(buf2, "`wStones from a nearby wall morphs into the shape of");
				break;
			default:
				strcat(buf2, "`wVapour from nowhere appears in the shape of");
				break;
		}

		for( to = victim->in_room->people; to ; to = to->next_in_room )
		{
			//Check to see if the next char is a '!' or a ',' , in which case, does a nature emote
			if ((argument[0]=='!') || (argument[0]==','))
			{
				argument++;
				if (argument[0]==' ') argument++;
				if(!IS_NPC(ch)) ch->pcdata->did_ooc=true;
				to->printf( "%s %s and %s`x\r\n", buf2, PERS (ch, to), argument); 
			}
			else
			{
				// Languages still influence naturespeaks
				translate_language(ch->language, false, ch, victim, argument, buf);
				to->printf( "%s %s and says to %s:'%s'`x\r\n", buf2, PERS (ch, to),
					YOU_PERS(victim, to), buf); 
			}
		}
		
	return FULL_MANA;
}

/***************************************************************************
 *  Cause Headache - Adds -20 to SD                                        *
 *  By Ylerin, February 1999                                               *
 ***************************************************************************/

SPRESULT spell_cause_headache(int sn,int level,char_data *ch,void *vo,int )
{
	char_data *victim = (char_data *) vo;
	AFFECT_DATA af;

	if ( is_affected( victim, sn ))
	{
		if (victim == ch)
			ch->printf( "Your head already aches tremendously! You surely don't want to increase it.\r\n" );
		else
			act("$N already suffers from a terrible headache. Have a bit of pity on $m.",ch,NULL,victim,TO_CHAR);
		return HALF_MANA;
	}

	af.where		= WHERE_AFFECTS;
	af.type			= sn;
	af.level		= level;
	af.duration		= level;
	af.location		= APPLY_SD;
	af.modifier		= - level/5;
	af.bitvector	= 0;
	affect_to_char( victim, &af );
	victim->printf( "Your head seems to explode with a sudden wave of indescribable pain!\r\n" );
	act("$n grimaces in pain.",victim,NULL,NULL,TO_ROOM);
	return FULL_MANA;
}

/***************************************************************************
 *  Cure Headache - Cures headache :p                                      *
 *  By Ylerin, Auguts 1999                                                 *
 ***************************************************************************/

SPRESULT spell_cure_headache( int , int level, char_data *ch, void *vo,int  )
{
	char_data *victim = (char_data *) vo;
 
	if ( !is_affected( victim, gsn_cause_headache ) )
	{
		if (victim == ch)
			ch->printf( "You don't have a headache.\r\n" );
		else
			act("$N appears to be well.",ch,NULL,victim,TO_CHAR);
		return HALF_MANA;
	}
 
	if (check_dispel(level,victim,gsn_cause_headache))
	{
		victim->printf( "Your headache is gone, what a relief!\r\n" );
		act("$n looks much relieved.",victim,NULL,NULL,TO_ROOM);
	}
	else
		ch->printf( "Your spell failed.\r\n" );
	return FULL_MANA;
}

/**************************************************************************/
// Kal
SPRESULT spell_restore_mana( int, int level, char_data *ch, void *vo,int)
{
	char_data *victim = (char_data *) vo;

	victim->mana = UMIN( victim->mana + UMIN(number_range(level, level*3),150), victim->max_mana );
	victim->println( "A warm glow passes through you.");

	if ( ch != victim ){
		ch->println( "Ok.");
	}
	return FULL_MANA;
}

/**************************************************************************/
// balo
SPRESULT spell_remove_alignment( int sn, int level, char_data *ch, void *vo,int target)
{
    OBJ_DATA *obj = (OBJ_DATA *) vo;
    int result, fail;
    AFFECT_DATA *paf;

    if (obj->wear_loc != -1)
    {
        ch->println("The item must be carried to remove it's alignment.");
        return NO_MANA;
    }

    if ((!IS_OBJ_STAT(obj,OBJEXTRA_ANTI_GOOD))
       && (!IS_OBJ_STAT(obj,OBJEXTRA_ANTI_EVIL))
       && (!IS_OBJ_STAT(obj,OBJEXTRA_ANTI_NEUTRAL)))
    {
        ch->println("The item has no alignment.");
        return HALF_MANA;
    }

    fail = 25;  // base 25% chance of failure 

    // find the bonuses (Its harder to remove align from a powerful object) 

    if (!obj->affected) // enchanted dosn`t seem to exist ? (!obj->enchanted)
        for ( paf = obj->pIndexData->affected; paf != NULL; paf = paf->next )
        {
            fail += 20;
        }

    for ( paf = obj->affected; paf != NULL; paf = paf->next )
    {
        fail += 20;
    }


    // apply other modifiers 
    fail += obj->level;
    fail -= 3 * level / 2;

    // harder to remove align from objects inherently blessed or evil 
    if (IS_OBJ_STAT(obj,OBJEXTRA_BLESS)){
        fail += 5;
	}
    if (IS_OBJ_STAT(obj,OBJEXTRA_EVIL)){
        fail += 5;
	}

    fail = URANGE(5,fail,90);

    result = number_percent();

    // the moment of truth 
    if (result < (fail / 5))  // item destroyed 
    {
        act("$p shivers and shudders... then implodes!",ch,obj,NULL,TO_CHAR);
        act("$p shivers and shudders... then implodes!",ch,obj,NULL,TO_ROOM);
        extract_obj(obj);
        return FULL_MANA;
    }

    if ( result <= fail )  // failed, no bad result 
    {
        ch->printf("Nothing seemed to happen.\n\r");
        return FULL_MANA;
    }

    // Success!  Remove the item's alignment 
    REMOVE_BIT(obj->extra_flags,OBJEXTRA_ANTI_EVIL);
    REMOVE_BIT(obj->extra_flags,OBJEXTRA_ANTI_GOOD);
    REMOVE_BIT(obj->extra_flags,OBJEXTRA_ANTI_NEUTRAL);
    act("You remove $p's alignment!",ch,obj,NULL,TO_CHAR);
    act("$n removes $p's alignment!",ch,obj,NULL,TO_ROOM);
    return FULL_MANA;
}

/***************************************************************************/
SPRESULT spell_enchant_item(int sn,int level, char_data *ch, void *vo,int )
{
	OBJ_DATA *obj = (OBJ_DATA *) vo;
	AFFECT_DATA *paf; 
	int result, fail;
	int added;
	bool hit_found = false, dam_found = false;

	// do standard checks - if spell can be cast 
    if ((obj->item_type != ITEM_LIGHT)		&& (obj->item_type != ITEM_TREASURE)
      && (obj->item_type != ITEM_CLOTHING)	&& (obj->item_type != ITEM_CONTAINER)
      && (obj->item_type != ITEM_GEM)		&& (obj->item_type != ITEM_JEWELRY))
	{
		ch->println( "That isn't enchantable." );
		return NO_MANA;
    }

    if(obj->wear_loc!=-1){
        ch->printf( "The item must be carried to be enchanted.\r\n" );
        return NO_MANA;
    }

    fail = 25;	// base 25% chance of failure 

    // find the current bonuses - affect success 
	for (paf=OBJECT_AFFECTS(obj); paf; paf=paf->next )
    {
        if ( paf->location == APPLY_HITROLL ){
            hit_found = true;
            fail += 2 * paf->modifier * paf->modifier;
            if (paf->duration == -1) // can't add to a perm weapon enchant 
            {
                ch->printf( "%s starts to pulsate then it dissolves before your eyes!!!",
                    capitalize(format_obj_to_char(obj, ch, true)));
                extract_obj(obj);
                return FULL_MANA;
            }
        }else if (paf->location == APPLY_DAMROLL ){
            dam_found = true;
            fail += 2 * paf->modifier * paf->modifier;
            if (paf->duration == -1) // can't add to a perm weapon enchant 
            {
                ch->printf( "%s starts to pulsate then it dissolves before your eyes!!!\r\n",
                    format_obj_to_char(obj, ch, true));
                extract_obj(obj);
                return FULL_MANA;
            }
        }else{
            fail += 20;
        }
    }

    // apply other modifiers 
    fail -= 3 * level/2;
    if (IS_OBJ_STAT(obj,OBJEXTRA_BLESS)){
        fail -= 15;
    }if (IS_OBJ_STAT(obj,OBJEXTRA_GLOW)){
        fail -= 5;
	}

    fail = URANGE(5,fail,95);
    result = number_percent();

    // the moment of truth 
    if (result < (fail / 5)){  // item destroyed 
        act("$p shivers violently and explodes!",ch,obj,NULL,TO_CHAR);
        act("$p shivers violently and explodes!",ch,obj,NULL,TO_ROOM);
        extract_obj(obj);
        return FULL_MANA;
    }

    if (result < (fail / 2)){ // item disenchanted 
		AFFECT_DATA *paf_next;

		act("$p glows brightly, then fades...oops.",ch,obj,NULL,TO_CHAR);
		act("$p glows brightly, then fades.",ch,obj,NULL,TO_ROOM);

        // free all affects 
        for (paf = obj->affected; paf; paf = paf_next)
        {
            paf_next = paf->next; 
            free_affect(paf);
        }
        obj->affected = NULL;
        obj->no_affects = true; // flag the object as no_affects so 
								// the olc template's affects arent used.
        // clear all flags 
        obj->extra_flags = 0;
		return FULL_MANA;
	}

    if ( result <= fail )  // failed, no bad result
    {
        ch->printf( "Nothing seemed to happen.\r\n" );
        return FULL_MANA;
    }

    // **** ALL SUCCESSFUL ENCHANTS BELOW HERE ****
	// now setup all the enchants:
	// - if it enchants, weren't stored on the object, copy the enchants
    //   from the object vnums enchants.   
	affects_from_template_to_obj(obj); 

    if (result <= (100 - level/5)){  // success! 
        act("$p glows blue.",ch,obj,NULL,TO_CHAR);
        act("$p glows blue.",ch,obj,NULL,TO_ROOM);
        SET_BIT(obj->extra_flags, OBJEXTRA_MAGIC);
        added = 1;
    }else{  // exceptional enchant     
        act("$p glows a brillant blue!",ch,obj,NULL,TO_CHAR);
        act("$p glows a brillant blue!",ch,obj,NULL,TO_ROOM);
        SET_BIT(obj->extra_flags,OBJEXTRA_MAGIC);
        SET_BIT(obj->extra_flags,OBJEXTRA_GLOW);
        added = 2;
    }
		
    // now add the enchantments 
    if (dam_found){
        for ( paf = obj->affected; paf != NULL; paf = paf->next)
        {
            if ( paf->location == APPLY_DAMROLL)
            {
                paf->type = sn;
                paf->modifier += added;
                if (ch->level>paf->level) // up the level if caster is higher
                    paf->level = ch->level;
                if (paf->modifier > 4 && (number_range(1,100)<95))
                    SET_BIT(obj->extra_flags,OBJEXTRA_HUM);
            }
        }
    }else{ // add a new damroll affect 
        paf = new_affect();
        paf->where      = WHERE_OBJEXTRA;
        paf->type       = sn;
        paf->level      = ch->level;
        paf->duration   = level * 20;
        paf->location   = APPLY_DAMROLL;
        paf->modifier   = added;
        paf->bitvector  = 0;
        paf->next       = obj->affected;
        obj->affected   = paf;
    }

    if (hit_found){
        for ( paf = obj->affected; paf != NULL; paf = paf->next)
        {
            if ( paf->location == APPLY_HITROLL)
            {
                paf->type = sn;
                paf->modifier += added;
                paf->level = UMAX(paf->level,level)/2;
                if (paf->modifier > 4){
					SET_BIT(obj->extra_flags,OBJEXTRA_HUM);
				}
            }
        }
    }else{ // add a new affect 
        paf = new_affect();
        paf->type       = sn;
        paf->level      = ch->level;
        paf->duration   = level * 20;
        paf->location   = APPLY_HITROLL;
        paf->modifier   = added;
        paf->bitvector  = 0;
        paf->next       = obj->affected;
        obj->affected   = paf;
    }
	return FULL_MANA;
}
/**************************************************************************/
/**************************************************************************/