dawn/notes/
dawn/src/
dawn/src/docs/
/**************************************************************************/
// mount.cpp - mob mounting system written by Thaddeus
/***************************************************************************
 * 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 the dawn license *
 *    in licenses.txt... In particular, you may not remove this copyright  *
 *    notice.                                                              *
 **************************************************************************/
#include "include.h" //default dawn include files

/**************************************************************************/
void mount(char_data * rider, char_data * ridee)
{
    if (is_affected(rider, gsn_sneak))
    {
        rider->println( "You cannot sneak while riding." );
        affect_strip(rider, gsn_sneak);
    }
    if (is_affected(rider, gsn_hide))
    {
        rider->println("You cannot hide while riding." );
        affect_strip(rider, gsn_hide);
    }
   
    ridee->tethered=false; 
    if (!(ridee->bucking))
       SET_BIT(ridee->act, ACT_SENTINEL); 
    
    if (ridee->position==POS_SLEEPING)
    {
        act("$N wakes up.", rider, NULL, ridee, TO_ROOM);
    }
    
    if (ridee->position<POS_STANDING)
    {
        act("$N stands up.", rider, NULL, ridee, TO_ROOM);
    }
    ridee->position = POS_STANDING;

    if (!IS_NPC(rider))
    {
        if (get_skill(rider, gsn_riding)<75)
        {
            check_improve(rider, gsn_riding, true, 1);
        }
    }
   
    ridee->ridden_by=rider;
    rider->mounted_on=ridee;
}

/**************************************************************************/
void tame_a_little(char_data * ch, char_data * victim)
{
    int beats = (101 - ch->level + victim->level)*2;
    int skill_level = get_skill(ch, gsn_domesticate);
    if (skill_level==0)
    {
		ch->println( "You don't know how to tame." );
		return;
    }

    
    act("You try to tame $N.", ch, NULL, victim, TO_CHAR);
    switch(number_range(1,3))
    {
		case 1:
			act("$n tries to tame $N.", ch, NULL, victim, TO_ROOM);
			break;
       
		case 2:
			act("$n trains $N a little.", ch, NULL, victim, TO_ROOM);
			break;

		case 3:
			act("$n works a bit with $N.", ch, NULL, victim, TO_ROOM);
			break;
    }
    
    if (victim->wildness>80)
       {
       act("$N still seems quite wild.", ch, NULL, victim, TO_CHAR);
       act("$N still seems quite wild.", ch, NULL, victim, TO_ROOM);
       }
    else if (victim->wildness>60)
       {
       act("$N is not so wary of you.", ch, NULL, victim, TO_CHAR);
       act("$N doesn't seem as afraid of $n.", ch, NULL, victim, TO_ROOM);
       }
    else if (victim->wildness>40)
       {
       act("$N seems to be getting used to the idea.", ch, NULL, victim, TO_CHAR);
       act("$N seems to be getting used to the idea.", ch, NULL, victim, TO_ROOM);
       }
    else if (victim->wildness>20)
       {
       act("$N will allow you to pat it.", ch, NULL, victim, TO_CHAR);
       act("$N will allow $n to pat it.", ch, NULL, victim, TO_ROOM);
       }
    else
       {
       act("$N will eat out of your hand.", ch, NULL, victim, TO_CHAR);
       act("$N will eat out of $n's hand.", ch, NULL, victim, TO_ROOM);
       }

    
    if (skill_level < 10)
        beats = beats * 2;
    else if (skill_level < 20)
        beats = (beats * 7)/ 4;
    else if (skill_level < 30)
        beats = (beats * 3)/ 2;
    else if (skill_level < 40)
        beats = (beats * 5) / 4;
    else if (skill_level > 60)
        beats = (beats * 5) / 6;
    else if (skill_level > 70)
        beats = (beats * 4) / 5;
    else if (skill_level > 80)
        beats = (beats * 3) / 4;
    else if (skill_level > 90)
        beats = (beats * 2) / 3;
    else if (skill_level == 100)
        beats = (beats * 1) / 2;
    
    skill_level = 1+(ch->level - victim->level)/8;
	skill_level +=ch->modifiers[STAT_PR]/3;
    
    if (IS_SET(victim->act, ACT_AGGRESSIVE))
       skill_level /=2;
    if (IS_SET(victim->form, FORM_SENTIENT))
       skill_level/=3;
    
	if (skill_level<1 
		&& number_range(1,get_skill(ch, gsn_domesticate))<60)
    {
       ch->println( "Your efforts seem to be futile." );
       return;
    }
    
    victim->wildness-=skill_level;   
    
    check_improve(ch, gsn_domesticate, true, 3);
    

    if (IS_SET(victim->form, FORM_MOUNTABLE))
    {
       beats/=2;
       victim->wildness--;
    }
     

    if (victim->wildness<=0)
    {   
        victim->wildness=0;   
        victim->will/=2;
        // make a pet out of it 
        SET_BIT(victim->act, ACT_PET);
        SET_BIT(victim->affected_by, AFF_CHARM);
        REMOVE_BIT(victim->affected_by, ACT_AGGRESSIVE);

        victim->comm = COMM_NOTELL|COMM_NOSHOUT|COMM_NOCHANNELS;
        add_follower( victim, ch );
        victim->leader = ch;
        ch->pet = victim;
        act( "You have finished taming $N!", ch, NULL, victim, TO_CHAR);
        act( "$n has tamed $N as a pet!", ch, NULL, victim, TO_ROOM );
    }
    else
    {
        WAIT_STATE(ch, beats); 
    }
    
    return;
}

/**************************************************************************/
void dismount(char_data * rider)
{
    if (rider->mounted_on==NULL)
    {
        bug("Error in dismount, rider isn't riding anything!");
        return;
    }
    rider->mounted_on->ridden_by=NULL;
    rider->mounted_on=NULL;
}

/**************************************************************************/
// get on
void do_ride( char_data *ch, char *argument )  
{
    char arg[MIL];
    char_data *victim;
    
    one_argument( argument, arg );

    if( IS_NULLSTR(arg) ){
		if(	ch->pet 
			&& ch->pet->in_room==ch->in_room 
			&& IS_SET(ch->pet->form, FORM_MOUNTABLE)
			&& ch->pet->size>race_table[ch->race]->size)
		{
			victim=ch->pet;
		}else{
			ch->println( "syntax: ride <animal>" );
			ch->println( "or just: ride    (if you have a rideable pet in the room)" );
			ch->println( "(for this message to be displayed, there is no rideable pet of yours in the room)." );
			return;
		}
	}else{
		if ( ( victim = get_char_room( ch, arg ) ) == NULL )
		{
			ch->println( "You don't see that here." );
			return;
		}
	}
   
    if (!(IS_NPC(victim)))
    {
        ch->println( "You cannot mount other players!" );
        return;
    }

    if (ch->mounted_on)
    {
        ch->println( "You are already mounted on something else!" );
        return;
    }

    if (victim->ridden_by)
    {
        ch->println( "That is already mounted by someone else!" );
        return;
    }
   
    if (!IS_SET(ch->form, FORM_BIPED))
    {
        ch->println( "Your body is not built for that." );
        return;
    }
   
    if (!IS_SET(victim->form, FORM_MOUNTABLE))
    {
        ch->println( "It is not that kind of creature." );
        return;
    }
   
    if ( IS_AFFECTED(ch, AFF_FEAR) || IS_AFFECTED2(ch, AFF2_FEAR_MAGIC) )
    {
        ch->println( "You are too afraid of it." );
        return;
    }

	if ( !IS_NPC( ch ))
	{
		if (victim->size <= race_table[TRUE_CH(ch)->race]->size)
		{
			ch->println( "It is too small for you to mount." );
			return;
		}
	}
   
    if (victim->position<POS_SLEEPING)
    { 
		act("$N doesn't look well enough for that.", ch, NULL, victim, TO_CHAR);
		return;
    }

    if (victim->position==POS_SLEEPING)
    { 
		act("$N appears to be sleeping.", ch, NULL, victim, TO_CHAR);
		return;
    }

    
    if ((!IS_SET(victim->act, ACT_DOCILE))
       &&(!IS_NPC(ch))
       &&(victim->master != ch))
    {
        if (get_skill(ch, gsn_animal_training)==0)
        {
            act("$N will not allow you to mount it!",ch, NULL, victim, TO_CHAR);
            act("$n tries to mount $N but is soundly rebuffed.",ch, NULL, victim, TO_ROOM);
            return;
        }
        else
        {
            act("You mount $N in an attempt to break them.",ch, NULL, victim, TO_CHAR);
            act("$n mounts $N in an attempt to break them.",ch, NULL, victim, TO_ROOM);
            victim->bucking=true;
            mount(ch, victim);
            return;
        }
    }
       
    if((!IS_SET(victim->act, ACT_DOCILE))
       &&(IS_NPC(ch))
       &&(victim->master != ch))   
    {
        act("$N will not allow you to mount it!",ch, NULL, victim, TO_CHAR);
        act("$n tries to mount $N but is soundly rebuffed.",ch, NULL, victim, TO_ROOM);
        return;
    }

    if(IS_SET(race_table[ch->race]->aff, AFF_FLYING))
    {
        act("$n flies up and alights on $N.",ch, NULL, victim, TO_ROOM);
        act("You fly up and alight on $N.",ch, NULL, victim, TO_CHAR);
        mount(ch, victim);
        return;
    }
   
   
    if(!IS_NPC(ch))
    {
        if (get_skill(ch, gsn_riding)==0)   
        {
            if (number_range(1,3)!=1)
            {
                act("$n tries to mount $N, but fails.",ch, NULL, victim, TO_ROOM);
                act("You try to mount $N, but fail.",ch, NULL, victim, TO_CHAR);
                return;
            }
            else 
            {
                act("$n is barely able to mount $N.",ch, NULL, victim, TO_ROOM);
                act("You barely manage to pull yourself onto $N.",ch, NULL, victim, TO_CHAR);
                mount(ch, victim);
                return;
            }
        }
    }
   
   
    act("$n mounts $N.",ch, NULL, victim, TO_ROOM);
    act("You mount $N.",ch, NULL, victim, TO_CHAR);

    if (IS_NEWBIE(ch))
    {
        ch->println( "Type dismount or tether to climb off when you want to." );
    }
    mount(ch,victim);
    return;
}
/**************************************************************************/
void do_untether( char_data *ch, char *argument)
{
    char_data *victim;
    char arg[MIL];
    
    one_argument( argument, arg );

	if(IS_NULLSTR(arg))
	{
		ch->println( "Untether what?" );
		return;
	}

    if ( ( victim = get_char_room( ch, arg ) ) == NULL )
    {
        ch->printlnf("You don't see any '%s' here.", arg);
		return;
    }
  
	if(victim->tethered!=true){
        ch->printlnf("%s is not tethered.", PERS(victim, ch));
        return;
	}

    if (!(IS_NPC(victim)))
    {
        ch->printlnf("%s doesn't appear to want to be untethered.", PERS(victim, ch));
        return;
    }

 
    if ( IS_AFFECTED(ch, AFF_FEAR) || IS_AFFECTED2(ch, AFF2_FEAR_MAGIC) )
    {
        ch->println( "You are too afraid of it." );
        return;
    }
      
    if ((!IS_SET(victim->act, ACT_DOCILE))
       &&(!IS_NPC(ch))
       &&(victim->master != ch))
    {
        if (get_skill(ch, gsn_animal_training)==0)
        {
            act("$N will not allow you to untether it!",ch, NULL, victim, TO_CHAR);
            act("$n tries to untether $N but is soundly rebuffed.",ch, NULL, victim, TO_ROOM);
            return;
        }
    }
       
    if ((!IS_SET(victim->act, ACT_DOCILE))
       &&(IS_NPC(ch))
       &&(victim->master != ch))   
    {
        act("$N will not allow you to untether it!",ch, NULL, victim, TO_CHAR);
        act("$n tries to untether $N but is soundly rebuffed.",ch, NULL, victim, TO_ROOM);
        return;
    }

    act("$n untethers $N.",ch, NULL, victim, TO_ROOM);
    act("You untether $N.",ch, NULL, victim, TO_CHAR);
   
    victim->tethered=false;
}
/**************************************************************************/
void tether_not_riding( char_data *ch, char *arg)
{
    char_data *victim;

    if ( ( victim = get_char_room( ch, arg ) ) == NULL )
    {
        ch->printlnf("You don't see any '%s' here.", arg);
		return;
    }

	assert(!ch->mounted_on);

	if (victim->ridden_by)
    {
        ch->printlnf("%s is being ridden by %s.", 
			PERS(victim, ch), PERS(victim->ridden_by, ch));
        return;
    }

	if(victim->tethered==true){
        ch->printlnf("Someone else is riding %s.", PERS(victim, ch));
        return;
	}

    if (!(IS_NPC(victim)))
    {
        ch->printlnf("%s doesn't appear to want to be tethered.", PERS(victim, ch));
        return;
    }

    if (!IS_SET(victim->form, FORM_MOUNTABLE))
    {
        ch->println( "It is not that kind of creature." );
        return;
    }
   
    if ( IS_AFFECTED(ch, AFF_FEAR) || IS_AFFECTED2(ch, AFF2_FEAR_MAGIC) )
    {
        ch->println( "You are too afraid of it." );
        return;
    }
      
    if ((!IS_SET(victim->act, ACT_DOCILE))
       &&(!IS_NPC(ch))
       &&(victim->master != ch))
    {
        if (get_skill(ch, gsn_animal_training)==0)
        {
            act("$N will not allow you to tether it!",ch, NULL, victim, TO_CHAR);
            act("$n tries to tether $N but is soundly rebuffed.",ch, NULL, victim, TO_ROOM);
            return;
        }
    }
       
    if ((!IS_SET(victim->act, ACT_DOCILE))
       &&(IS_NPC(ch))
       &&(victim->master != ch))   
    {
        act("$N will not allow you to tether it!",ch, NULL, victim, TO_CHAR);
        act("$n tries to tether $N but is soundly rebuffed.",ch, NULL, victim, TO_ROOM);
        return;
    }

    act("$n tethers $N.",ch, NULL, victim, TO_ROOM);
    act("You tether $N.",ch, NULL, victim, TO_CHAR);
   
    victim->tethered=true;
}

/**************************************************************************/
// get off and tether creature
void do_tether( char_data *ch, char *argument)
{
    char arg[MIL];
    
    one_argument( argument, arg );

	// support tethering a mob that isn't being ridden
    if ( !ch->mounted_on){
		if(IS_NULLSTR(arg))
	    {
			ch->println( "Tether what?" );
			return;
		}else{
			tether_not_riding(ch, arg);
			return;
		}
	}

    act("$n dismounts and tethers $N.",ch, NULL, ch->mounted_on, TO_ROOM);
    act("You dismount and tether $N.",ch, NULL, ch->mounted_on, TO_CHAR);
   
    ch->mounted_on->tethered=true;

    dismount(ch);
   
    if (get_skill(ch, gsn_riding))
    {
        check_improve(ch, gsn_riding, true, 1);
    }
    
    return;  
}

/**************************************************************************/
// dismount creature
void do_dismount( char_data *ch, char *)
{
    if (!ch->mounted_on)
    {
        ch->println( "You have to be on a creature to dismount it." );  
        return;
    }
    act("$n dismounts $N.",ch, NULL, ch->mounted_on, TO_ROOM);
    act("You dismount $N.",ch, NULL, ch->mounted_on, TO_CHAR);
   
	ch->mounted_on->tethered=false;
    dismount(ch);
   
    if (get_skill(ch, gsn_riding))
    {
        check_improve(ch, gsn_riding, true, 1);
    }
    
    return;
   
}


/**************************************************************************/
void do_tame( char_data *ch, char *argument )  
{
    char arg[MIL];
    char_data *victim;
    
    one_argument( argument, arg );

    if ( arg[0] == '\0' ){
        ch->println( "Tame what?" );
        return;
    }

    if ( ( victim = get_char_room( ch, arg ) ) == NULL ){
        ch->println( "You don't see that here." );
        return;
    }
    
    if (IS_NPC(ch)){
        ch->println( "Only characters can tame." );
        return;
    }
    
    if (!IS_NPC(victim)){
       ch->println( "Don't you wish!" );
       return;
    }
    
    if (ch->pet){
        act("$N would be too jealous of your other pet.", ch, NULL, victim, TO_CHAR); 
        return;
    }
    
    if (victim->ridden_by){
        act("$N seems to belong to someone else.", ch, NULL, victim, TO_CHAR); 
        return;
    }
    
    if (IS_SET(victim->act, ACT_PET)){ 
		ch->println( "It is already quite tame." );
        return;
    }
    
    if (IS_SET(victim->act, ACT_NO_TAME)){                 
        ch->println( "That creature will never make a good pet." );
        return;
    }
    
    if (ch->level < victim->level){
       act("$N would probably tame YOU if you tried that!", ch, NULL, victim, TO_CHAR);
       return;
    }  

    if (victim->position<POS_SLEEPING){ 
		act("$N doesn't look well enough for that.", ch, NULL, victim, TO_CHAR);
		return;
    }

    if (victim->position==POS_SLEEPING){ 
		act("$N appears to be sleeping.", ch, NULL, victim, TO_CHAR);
		return;
    }

	if( victim->fighting ){
		act("$N didn't seem to pay much attention to you.", ch, NULL, victim, TO_CHAR);
		return;
	}
	if( ch->fighting ){
		ch->println("Not while you are fighting.");
		return;
	}

	// doubletame on mountable mobs
	if (IS_SET(victim->form, FORM_MOUNTABLE)){
        tame_a_little(ch, victim);
    }
   
    tame_a_little(ch, victim);
    
    return;
}
/**************************************************************************/