Kohl Desenee
------------
revamped push_drag

Originally coded by Ferris
Modded by Kohl Desenee

This was originally coded by Ferris (if I recall correctly that version
was someone else's to begin with as well, but who that was I don't know so
I couldn't tell you even if I wanted to :) and was somewhat enhanced by
myself because I absolutely abhorred the lack of neat messages anywhere in
the entire damn thing. *snicker*

There are also some other changes I don't really recall, most of which
include smoother checks to see if you can or can not push something (such
as an hp of victim vs. str of char check.. haven't exactly imped anything
regarding weight or prettier ways to give npcs stats just yet, so it
seemed the best idea at the time :), messages to everyone and their
drunken French whore of a dog regarding pushed/dragged objects/people
going in and out of the room (some of that is a bit hackish, but it works,
by Bowie!), etc.

I would be very happy if you accredited both myself and Ferris for this
work. I could have done it from scratch but I'm lazy.. If you don't feel
like putting such a credit anywhere on your mud, just don't use this
snippet. I put a lot of thought into it. ;)

Any questions, comments, problems (!?!?!?) email me at foxyrev@hotmail.com

Anthony Michael Tregre.


mud code begins here
--------------------

void do_push_drag( CHAR_DATA *ch, char *argument, char *verb )
{
    char arg1[MAX_INPUT_LENGTH];
    char arg2[MAX_INPUT_LENGTH];
    char buf[MAX_STRING_LENGTH];
    ROOM_INDEX_DATA *in_room;
    ROOM_INDEX_DATA *to_room;
    CHAR_DATA *victim;
    EXIT_DATA *pexit;
    OBJ_DATA *obj;
    int door;

    argument = one_argument( argument, arg1 );
    argument = one_argument( argument, arg2 );
    victim = get_char_room(ch,arg1);
    obj = get_obj_list( ch, arg1, ch->in_room->contents );

    if ( arg1[0] == '\0' || arg2[0] == '\0' )
    {
	sprintf( buf, "%s whom or what where?\n\r", capitalize(verb));
	send_to_char( buf, ch );
	return;
    }

    if ( (!victim || !can_see(ch,victim))
    && (!obj || !can_see_obj(ch,obj)) )
    {
	sprintf(buf,"%s whom or what where?\n\r", capitalize(verb));
	send_to_char( buf, ch );
        return;
    }

         if ( !str_cmp( arg2, "n" ) || !str_cmp( arg2, "north" ) ) door = 0;
    else if ( !str_cmp( arg2, "e" ) || !str_cmp( arg2, "east"  ) ) door = 1;
    else if ( !str_cmp( arg2, "s" ) || !str_cmp( arg2, "south" ) ) door = 2;
    else if ( !str_cmp( arg2, "w" ) || !str_cmp( arg2, "west"  ) ) door = 3;
    else if ( !str_cmp( arg2, "u" ) || !str_cmp( arg2, "up"    ) ) door = 4;
    else if ( !str_cmp( arg2, "d" ) || !str_cmp( arg2, "down"  ) ) door = 5;
    else
    {
      sprintf( buf, "Alas, you cannot %s in that direction.\n\r", verb );
      send_to_char( buf, ch );
      return;
    }

  if ( obj )
  {
    in_room = obj->in_room;
    if ( ( pexit   = in_room->exit[door] ) == NULL
    ||   ( to_room = pexit->u1.to_room   ) == NULL 
    ||	 !can_see_room(ch,pexit->u1.to_room))
    {
        sprintf( buf, "Alas, you cannot %s in that direction.\n\r", verb );
        send_to_char( buf, ch );
	return;
    }

    if ( IS_SET(pexit->exit_info, EX_CLOSED)
    || IS_SET(pexit->exit_info,EX_NOPASS) )
    {
	act( "You cannot $t it through the $d.", ch, verb, pexit->keyword, TO_CHAR );
	act( "$n decides to $t $P around!", ch, verb, obj, TO_ROOM );
	return;
    }

    act( "You attempt to $T $p out of the room.", ch, obj, verb, TO_CHAR );
    act( "$n is attempting to $T $p out of the room.", ch, obj, verb, TO_ROOM );

    if ( obj->weight >  (2 * can_carry_w (ch)) )
    {
      act( "$p is too heavy to $T.\n\r", ch, obj, verb, TO_CHAR);
      act( "$n attempts to $T $p, but it is too heavy.\n\r", ch, obj, verb, TO_ROOM);
      return;
    }
    if 	 ( !IS_IMMORTAL(ch)
    ||   IS_SET(ch->in_room->room_flags, ROOM_SAFE)
    ||   IS_SET(ch->in_room->room_flags, ROOM_PRIVATE)
    ||   IS_SET(ch->in_room->room_flags, ROOM_SOLITARY) )
    {
	send_to_char( "It won't budge.\n\r", ch );
	return;
    }

    if ( ch->move > 10 )
    {
	ch->move -= 10;
	send_to_char( "You succeed!\n\r", ch );
	act( "$n succeeds!", ch, NULL, NULL, TO_ROOM );
	if (!str_cmp( verb, "drag" ))
	{
	act( "$n drags $p $T!", ch, obj, dir_name[door], TO_ROOM );
	char_from_room( ch );
	char_to_room( ch, pexit->u1.to_room );
	do_look( ch, "auto" );
	obj_from_room( obj );
	obj_to_room( obj, to_room );
	act( "$n drags $p into the room.", ch, obj, dir_name[door], TO_ROOM );
	}
	else if (!str_cmp( verb, "push" ))
	{
	act( "$p {Wflies{x $T!", ch, obj, dir_name[door], TO_ROOM );
	act( "$p {Wflies{x $T!", ch, obj, dir_name[door], TO_CHAR );
	char_from_room( ch );
	char_to_room( ch, pexit->u1.to_room );
	act( "You notice movement from nearby to the $T.",
		ch, NULL, rev_name[door], TO_ROOM );
	act( "$p {Wflies{x into the room!", ch, obj, dir_name[door], TO_ROOM );
	char_from_room( ch );
	char_to_room( ch, in_room );
	obj_from_room( obj );
	obj_to_room( obj, to_room );
	}
    }
    else
    {
      sprintf( buf, "You are too tired to %s anything around!\n\r", verb );
      send_to_char( buf, ch );
    }
  }
  else
  {
    if ( ch == victim )
    {
	act( "You $t yourself about the room and look very silly.", ch, verb, NULL, TO_CHAR );
	act( "$n decides to be silly and $t $mself about the room.", ch, verb, NULL, TO_ROOM );
	return;
    }

    in_room = victim->in_room;
    if ( ( pexit   = in_room->exit[door] ) == NULL
    ||   ( to_room = pexit->u1.to_room   ) == NULL 
    ||	 !can_see_room(victim,pexit->u1.to_room))
    {
        sprintf( buf, "Alas, you cannot %s them that way.\n\r", verb );
        send_to_char( buf, ch );
	return;
    }

    if (IS_SET(pexit->exit_info, EX_CLOSED)
    &&  (!IS_AFFECTED(victim, AFF_PASS_DOOR) || IS_SET(pexit->exit_info,EX_NOPASS)))
    {
	act( "You try to $t them through the $d.", ch, verb, pexit->keyword, TO_CHAR );
	act( "$n decides to $t you around!", ch, verb, victim, TO_VICT );
	act( "$n decides to $t $N around!", ch, verb, victim, TO_NOTVICT );
	return;
    }

    act( "You attempt to $t $N out of the room.", ch, verb, victim, TO_CHAR );
    act( "$n is attempting to $t you out of the room!", ch, verb, victim, TO_VICT );
    act( "$n is attempting to $t $N out of the room.", ch, verb, victim, TO_NOTVICT );

    if 	 ( !IS_IMMORTAL(ch)
    ||   (IS_NPC(victim)
    &&	 (IS_SET(victim->act,ACT_TRAIN)
    ||	 IS_SET(victim->act,ACT_PRACTICE)
    ||	 IS_SET(victim->act,ACT_IS_HEALER)
    ||	 IS_SET(victim->act,ACT_IS_CHANGER)
    ||	 IS_SET(victim->imm_flags,IMM_SUMMON)
    ||	 victim->pIndexData->pShop ))
    ||   victim->in_room == NULL
    ||   IS_SET(victim->in_room->room_flags, ROOM_SAFE)
    ||   IS_SET(victim->in_room->room_flags, ROOM_PRIVATE)
    ||   IS_SET(victim->in_room->room_flags, ROOM_SOLITARY)
    ||   (!str_cmp( verb, "push" ) && victim->position != POS_STANDING)
    || 	 is_safe(ch,victim)
    || 	 (number_percent() > 90)
    ||   (victim->max_hit > (ch->max_hit + (get_curr_stat(ch,STAT_STR)*20))) )
    {
	send_to_char( "They won't budge.\n\r", ch );
	return;
    }

    if ( ch->move > 10 )
    {
	ch->move -= 10;
	send_to_char( "You succeed!\n\r", ch );
	act( "$n succeeds!", ch, NULL, NULL, TO_ROOM );
	if (!str_cmp( verb, "drag" ))
	{
	move_char( ch, door, FALSE );
	act( "$n is dragged $T!", victim, NULL, dir_name[door], TO_ROOM );
	act( "You are dragged $T!\n\r", victim, NULL, dir_name[door], TO_CHAR );
	char_from_room( victim );
	char_to_room( victim, pexit->u1.to_room );
	do_look( victim, "auto" );
	act( "$N drags $n into the room.", victim, NULL, ch, TO_NOTVICT );
	}
	else if (!str_cmp( verb, "push" ))
	{
	act( "$n {Wflies{x $T!", victim, NULL, dir_name[door], TO_ROOM );
	act( "You {Wfly{x $T!\n\r", victim, NULL, dir_name[door], TO_CHAR );
	char_from_room( victim );
	char_to_room( victim, pexit->u1.to_room );
	do_look( victim, "auto" );
	act( "You notice movement from nearby to the $T.",
		victim, NULL, rev_name[door], TO_ROOM );
	act( "$n {Wflies{x into the room!", victim, NULL, NULL, TO_ROOM );
	}
    }
    else
    {
      sprintf( buf, "You are too tired to %s anybody around!\n\r", verb );
      send_to_char( buf, ch );
    }
  }

  return;
}
               
void do_push( CHAR_DATA *ch, char *argument )
{
    do_push_drag( ch, argument, "push" );
    return;
}

void do_drag( CHAR_DATA *ch, char *argument )
{
    do_push_drag( ch, argument, "drag" );
    return;
}
